/* * Copyright 2012 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkDebugger.h" #include "SkPictureRecorder.h" #include "SkString.h" SkDebugger::SkDebugger() { // Create this some other dynamic way? fDebugCanvas = new SkDebugCanvas(100, 100); fPicture = NULL; fPictureWidth = 0; fPictureHeight = 0; fIndex = 0; } SkDebugger::~SkDebugger() { // Need to inherit from SkRef object in order for following to work SkSafeUnref(fDebugCanvas); SkSafeUnref(fPicture); } void SkDebugger::loadPicture(SkPicture* picture) { fPictureWidth = picture->width(); fPictureHeight = picture->height(); delete fDebugCanvas; fDebugCanvas = new SkDebugCanvas(fPictureWidth, fPictureHeight); fDebugCanvas->setBounds(fPictureWidth, fPictureHeight); fDebugCanvas->setPicture(picture); picture->draw(fDebugCanvas); fDebugCanvas->setPicture(NULL); fIndex = fDebugCanvas->getSize() - 1; SkRefCnt_SafeAssign(fPicture, picture); } SkPicture* SkDebugger::copyPicture() { // We can't just call clone here since we want to removed the "deleted" // commands. Playing back will strip those out. SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(fPictureWidth, fPictureHeight, NULL, 0); bool vizMode = fDebugCanvas->getMegaVizMode(); fDebugCanvas->setMegaVizMode(false); bool overDraw = fDebugCanvas->getOverdrawViz(); fDebugCanvas->setOverdrawViz(false); bool pathOps = fDebugCanvas->getAllowSimplifyClip(); fDebugCanvas->setAllowSimplifyClip(false); int saveCount = fDebugCanvas->getOutstandingSaveCount(); fDebugCanvas->setOutstandingSaveCount(0); fDebugCanvas->draw(canvas); int temp = fDebugCanvas->getOutstandingSaveCount(); for (int i = 0; i < temp; ++i) { canvas->restore(); } fDebugCanvas->setMegaVizMode(vizMode); fDebugCanvas->setOverdrawViz(overDraw); fDebugCanvas->setOutstandingSaveCount(saveCount); fDebugCanvas->setAllowSimplifyClip(pathOps); return recorder.endRecording(); } void SkDebugger::getOverviewText(const SkTDArray<double>* typeTimes, double totTime, SkString* overview, int numRuns) { const SkTDArray<SkDrawCommand*>& commands = this->getDrawCommands(); SkTDArray<int> counts; counts.setCount(LAST_DRAWTYPE_ENUM+1); for (int i = 0; i < LAST_DRAWTYPE_ENUM+1; ++i) { counts[i] = 0; } for (int i = 0; i < commands.count(); i++) { counts[commands[i]->getType()]++; } overview->reset(); int total = 0; #ifdef SK_DEBUG double totPercent = 0, tempSum = 0; #endif for (int i = 0; i < LAST_DRAWTYPE_ENUM+1; ++i) { if (0 == counts[i]) { // if there were no commands of this type then they should've consumed no time SkASSERT(NULL == typeTimes || 0.0 == (*typeTimes)[i]); continue; } overview->append(SkDrawCommand::GetCommandString((DrawType) i)); overview->append(": "); overview->appendS32(counts[i]); if (NULL != typeTimes && totTime >= 0.0) { overview->append(" - "); overview->appendf("%.2f", (*typeTimes)[i]/(float)numRuns); overview->append("ms"); overview->append(" - "); double percent = 100.0*(*typeTimes)[i]/totTime; overview->appendf("%.2f", percent); overview->append("%"); #ifdef SK_DEBUG totPercent += percent; tempSum += (*typeTimes)[i]; #endif } overview->append("<br/>"); total += counts[i]; } #ifdef SK_DEBUG if (NULL != typeTimes) { SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(totPercent), SkDoubleToScalar(100.0))); SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(tempSum), SkDoubleToScalar(totTime))); } #endif if (totTime > 0.0) { overview->append("Total Time: "); overview->appendf("%.2f", totTime/(float)numRuns); overview->append("ms"); #ifdef SK_DEBUG overview->append(" "); overview->appendScalar(SkDoubleToScalar(totPercent)); overview->append("% "); #endif overview->append("<br/>"); } SkString totalStr; totalStr.append("Total Draw Commands: "); totalStr.appendScalar(SkDoubleToScalar(total)); totalStr.append("<br/>"); overview->insert(0, totalStr); overview->append("<br/>"); overview->append("SkPicture Width: "); overview->appendS32(pictureWidth()); overview->append("px<br/>"); overview->append("SkPicture Height: "); overview->appendS32(pictureHeight()); overview->append("px"); } void SkDebugger::getClipStackText(SkString* clipStack) { clipStack->set(fDebugCanvas->clipStackData()); }