| |
| /* |
| * 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 "SkMakeUnique.h" |
| #include "SkPictureRecorder.h" |
| #include "SkString.h" |
| |
| |
| SkDebugger::SkDebugger() |
| : fDebugCanvas(skstd::make_unique<SkDebugCanvas>(0, 0)) |
| , fIndex(-1) { } |
| |
| SkDebugger::~SkDebugger() {} |
| |
| void SkDebugger::loadPicture(SkPicture* picture) { |
| fPicture = sk_ref_sp(picture); |
| fDebugCanvas = skstd::make_unique<SkDebugCanvas>( |
| SkScalarCeilToInt(this->pictureCull().width()), |
| SkScalarCeilToInt(this->pictureCull().height())); |
| fDebugCanvas->setPicture(picture); |
| picture->playback(fDebugCanvas.get()); |
| fDebugCanvas->setPicture(nullptr); |
| fIndex = fDebugCanvas->getSize() - 1; |
| } |
| |
| sk_sp<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(this->pictureCull().width(), |
| this->pictureCull().height()); |
| |
| bool vizMode = fDebugCanvas->getMegaVizMode(); |
| fDebugCanvas->setMegaVizMode(false); |
| bool overDraw = fDebugCanvas->getOverdrawViz(); |
| fDebugCanvas->setOverdrawViz(false); |
| bool pathOps = fDebugCanvas->getAllowSimplifyClip(); |
| fDebugCanvas->setAllowSimplifyClip(false); |
| |
| fDebugCanvas->draw(canvas); |
| |
| fDebugCanvas->setMegaVizMode(vizMode); |
| fDebugCanvas->setOverdrawViz(overDraw); |
| fDebugCanvas->setAllowSimplifyClip(pathOps); |
| |
| return recorder.finishRecordingAsPicture(); |
| } |
| |
| void SkDebugger::getOverviewText(const SkTDArray<double>* typeTimes, |
| double totTime, |
| SkString* overview, |
| int numRuns) { |
| const SkTDArray<SkDrawCommand*>& commands = this->getDrawCommands(); |
| |
| SkTDArray<int> counts; |
| counts.setCount(SkDrawCommand::kOpTypeCount); |
| for (int i = 0; i < SkDrawCommand::kOpTypeCount; ++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 < SkDrawCommand::kOpTypeCount; ++i) { |
| if (0 == counts[i]) { |
| // if there were no commands of this type then they should've consumed no time |
| SkASSERT(nullptr == typeTimes || 0.0 == (*typeTimes)[i]); |
| continue; |
| } |
| |
| overview->append(SkDrawCommand::GetCommandString((SkDrawCommand::OpType) i)); |
| overview->append(": "); |
| overview->appendS32(counts[i]); |
| if (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 (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/>SkPicture L: "); |
| overview->appendScalar(this->pictureCull().fLeft); |
| overview->append(" T: "); |
| overview->appendScalar(this->pictureCull().fTop); |
| overview->append(" R: "); |
| overview->appendScalar(this->pictureCull().fRight); |
| overview->append(" B: "); |
| overview->appendScalar(this->pictureCull().fBottom); |
| overview->append("<br/>"); |
| } |
| |
| void SkDebugger::getClipStackText(SkString* clipStack) { |
| clipStack->set(fDebugCanvas->clipStackData()); |
| } |