26a00de4f3
The SkDebugCanvas can be (or is currently) being used to draw to multiple different canvases. If this use-case is intended, then storing draw -related state in the canvas causes bugs. Remove incremental draw from SkDebugCanvas. It can only optimize the case where draw command index is advanced, no other changes are done and no visualization is used. This case is not that critical, as it happens only once per new frame at most. It causes bugs, because one SkDebugCanvas is used to draw to multiple canvases. Leave the draw to canvas in same state as it was passed in. This fixes the debugger bugs where: * Old, stale image would stay on the raster canvas when a new image is loaded. Also happened with resizes. * Proper image for overdraw filter would be visible only for the first frame Review URL: https://codereview.chromium.org/844493003
150 lines
4.7 KiB
C++
150 lines
4.7 KiB
C++
|
|
/*
|
|
* 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()
|
|
: fPicture(NULL)
|
|
, fIndex(-1) {
|
|
// Create this some other dynamic way?
|
|
fDebugCanvas = new SkDebugCanvas(0, 0);
|
|
}
|
|
|
|
SkDebugger::~SkDebugger() {
|
|
// Need to inherit from SkRef object in order for following to work
|
|
SkSafeUnref(fDebugCanvas);
|
|
SkSafeUnref(fPicture);
|
|
}
|
|
|
|
void SkDebugger::loadPicture(SkPicture* picture) {
|
|
SkRefCnt_SafeAssign(fPicture, picture);
|
|
|
|
delete fDebugCanvas;
|
|
fDebugCanvas = new SkDebugCanvas(SkScalarCeilToInt(this->pictureCull().width()),
|
|
SkScalarCeilToInt(this->pictureCull().height()));
|
|
fDebugCanvas->setPicture(picture);
|
|
picture->playback(fDebugCanvas);
|
|
fDebugCanvas->setPicture(NULL);
|
|
fIndex = fDebugCanvas->getSize() - 1;
|
|
}
|
|
|
|
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.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 (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());
|
|
}
|