1 2 /* 3 * Copyright 2012 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #include "SkDebugger.h" 10 #include "SkMakeUnique.h" 11 #include "SkPictureRecorder.h" 12 #include "SkString.h" 13 14 15 SkDebugger::SkDebugger() 16 : fDebugCanvas(skstd::make_unique<SkDebugCanvas>(0, 0)) 17 , fIndex(-1) { } 18 19 SkDebugger::~SkDebugger() {} 20 21 void SkDebugger::loadPicture(SkPicture* picture) { 22 fPicture = sk_ref_sp(picture); 23 fDebugCanvas = skstd::make_unique<SkDebugCanvas>( 24 SkScalarCeilToInt(this->pictureCull().width()), 25 SkScalarCeilToInt(this->pictureCull().height())); 26 fDebugCanvas->setPicture(picture); 27 picture->playback(fDebugCanvas.get()); 28 fDebugCanvas->setPicture(nullptr); 29 fIndex = fDebugCanvas->getSize() - 1; 30 } 31 32 sk_sp<SkPicture> SkDebugger::copyPicture() { 33 // We can't just call clone here since we want to removed the "deleted" 34 // commands. Playing back will strip those out. 35 SkPictureRecorder recorder; 36 SkCanvas* canvas = recorder.beginRecording(this->pictureCull().width(), 37 this->pictureCull().height()); 38 39 bool vizMode = fDebugCanvas->getMegaVizMode(); 40 fDebugCanvas->setMegaVizMode(false); 41 bool overDraw = fDebugCanvas->getOverdrawViz(); 42 fDebugCanvas->setOverdrawViz(false); 43 bool pathOps = fDebugCanvas->getAllowSimplifyClip(); 44 fDebugCanvas->setAllowSimplifyClip(false); 45 46 fDebugCanvas->draw(canvas); 47 48 fDebugCanvas->setMegaVizMode(vizMode); 49 fDebugCanvas->setOverdrawViz(overDraw); 50 fDebugCanvas->setAllowSimplifyClip(pathOps); 51 52 return recorder.finishRecordingAsPicture(); 53 } 54 55 void SkDebugger::getOverviewText(const SkTDArray<double>* typeTimes, 56 double totTime, 57 SkString* overview, 58 int numRuns) { 59 const SkTDArray<SkDrawCommand*>& commands = this->getDrawCommands(); 60 61 SkTDArray<int> counts; 62 counts.setCount(SkDrawCommand::kOpTypeCount); 63 for (int i = 0; i < SkDrawCommand::kOpTypeCount; ++i) { 64 counts[i] = 0; 65 } 66 67 for (int i = 0; i < commands.count(); i++) { 68 counts[commands[i]->getType()]++; 69 } 70 71 overview->reset(); 72 int total = 0; 73 #ifdef SK_DEBUG 74 double totPercent = 0, tempSum = 0; 75 #endif 76 for (int i = 0; i < SkDrawCommand::kOpTypeCount; ++i) { 77 if (0 == counts[i]) { 78 // if there were no commands of this type then they should've consumed no time 79 SkASSERT(nullptr == typeTimes || 0.0 == (*typeTimes)[i]); 80 continue; 81 } 82 83 overview->append(SkDrawCommand::GetCommandString((SkDrawCommand::OpType) i)); 84 overview->append(": "); 85 overview->appendS32(counts[i]); 86 if (typeTimes && totTime >= 0.0) { 87 overview->append(" - "); 88 overview->appendf("%.2f", (*typeTimes)[i]/(float)numRuns); 89 overview->append("ms"); 90 overview->append(" - "); 91 double percent = 100.0*(*typeTimes)[i]/totTime; 92 overview->appendf("%.2f", percent); 93 overview->append("%"); 94 #ifdef SK_DEBUG 95 totPercent += percent; 96 tempSum += (*typeTimes)[i]; 97 #endif 98 } 99 overview->append("<br/>"); 100 total += counts[i]; 101 } 102 #ifdef SK_DEBUG 103 if (typeTimes) { 104 SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(totPercent), 105 SkDoubleToScalar(100.0))); 106 SkASSERT(SkScalarNearlyEqual(SkDoubleToScalar(tempSum), 107 SkDoubleToScalar(totTime))); 108 } 109 #endif 110 111 if (totTime > 0.0) { 112 overview->append("Total Time: "); 113 overview->appendf("%.2f", totTime/(float)numRuns); 114 overview->append("ms"); 115 #ifdef SK_DEBUG 116 overview->append(" "); 117 overview->appendScalar(SkDoubleToScalar(totPercent)); 118 overview->append("% "); 119 #endif 120 overview->append("<br/>"); 121 } 122 123 SkString totalStr; 124 totalStr.append("Total Draw Commands: "); 125 totalStr.appendScalar(SkDoubleToScalar(total)); 126 totalStr.append("<br/>"); 127 overview->insert(0, totalStr); 128 129 overview->append("<br/>SkPicture L: "); 130 overview->appendScalar(this->pictureCull().fLeft); 131 overview->append(" T: "); 132 overview->appendScalar(this->pictureCull().fTop); 133 overview->append(" R: "); 134 overview->appendScalar(this->pictureCull().fRight); 135 overview->append(" B: "); 136 overview->appendScalar(this->pictureCull().fBottom); 137 overview->append("<br/>"); 138 } 139 140 void SkDebugger::getClipStackText(SkString* clipStack) { 141 clipStack->set(fDebugCanvas->clipStackData()); 142 } 143