|  |  | 
|  | /* | 
|  | * 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 "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); | 
|  |  | 
|  | bool vizMode = fDebugCanvas->getMegaVizMode(); | 
|  | fDebugCanvas->setMegaVizMode(false); | 
|  | bool overDraw = fDebugCanvas->getOverdrawViz(); | 
|  | fDebugCanvas->setOverdrawViz(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); | 
|  |  | 
|  | 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"); | 
|  | } |