Make debugger profiling honor deleted commands
https://codereview.appspot.com/6906043/ git-svn-id: http://skia.googlecode.com/svn/trunk@6713 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
c6b3e48cb3
commit
5f97114fd2
@ -141,11 +141,13 @@ class SkTimedPicturePlayback : public SkPicturePlayback {
|
||||
public:
|
||||
SkTimedPicturePlayback(SkStream* stream, const SkPictInfo& info, bool* isValid,
|
||||
SkSerializationHelpers::DecodeBitmap decoder,
|
||||
const SkTDArray<size_t>& offsets)
|
||||
const SkTDArray<size_t>& offsets,
|
||||
const SkTDArray<bool>& deletedCommands)
|
||||
: INHERITED(stream, info, isValid, decoder)
|
||||
, fTot(0.0)
|
||||
, fCurCommand(0)
|
||||
, fOffsets(offsets) {
|
||||
, fOffsets(offsets)
|
||||
, fSkipCommands(deletedCommands) {
|
||||
fTimes.setCount(fOffsets.count());
|
||||
fTypeTimes.setCount(LAST_DRAWTYPE_ENUM+1);
|
||||
this->resetTimes();
|
||||
@ -172,6 +174,7 @@ public:
|
||||
protected:
|
||||
BenchSysTimer fTimer;
|
||||
SkTDArray<size_t> fOffsets; // offset in the SkPicture for each command
|
||||
SkTDArray<bool> fSkipCommands; // has the command been deleted in the GUI?
|
||||
SkTDArray<double> fTimes; // sum of time consumed for each command
|
||||
SkTDArray<double> fTypeTimes; // sum of time consumed for each type of command (e.g., drawPath)
|
||||
double fTot; // total of all times in 'fTimes'
|
||||
@ -179,7 +182,7 @@ protected:
|
||||
int fCurType;
|
||||
int fCurCommand; // the current command being executed/timed
|
||||
|
||||
virtual void preDraw(size_t offset, int type) {
|
||||
virtual size_t preDraw(size_t offset, int type) SK_OVERRIDE {
|
||||
// This search isn't as bad as it seems. In normal playback mode, the
|
||||
// base class steps through the commands in order and can only skip ahead
|
||||
// a bit on a clip. This class is only used during profiling so we
|
||||
@ -189,6 +192,17 @@ protected:
|
||||
SkASSERT(i <= fOffsets.count()); // should always find the offset in the list
|
||||
}
|
||||
|
||||
if (fSkipCommands[fCurCommand]) {
|
||||
while (fCurCommand < fSkipCommands.count() && fSkipCommands[fCurCommand]) {
|
||||
++fCurCommand;
|
||||
}
|
||||
if (fCurCommand == fSkipCommands.count()) {
|
||||
// Signal SkPicturePlayback to stop playing back
|
||||
return SK_MaxU32;
|
||||
}
|
||||
return fOffsets[fCurCommand];
|
||||
}
|
||||
|
||||
fCurOffset = offset;
|
||||
fCurType = type;
|
||||
// The SkDebugCanvas doesn't recognize these types. This class needs to
|
||||
@ -206,9 +220,11 @@ protected:
|
||||
#else
|
||||
fTimer.startCpu();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void postDraw(size_t offset) {
|
||||
virtual void postDraw(size_t offset) SK_OVERRIDE {
|
||||
#if defined(SK_BUILD_FOR_WIN32)
|
||||
// CPU timer doesn't work well on Windows
|
||||
double time = fTimer.endWall();
|
||||
@ -234,7 +250,8 @@ public:
|
||||
explicit SkTimedPicture(SkStream* stream,
|
||||
bool* success,
|
||||
SkSerializationHelpers::DecodeBitmap decoder,
|
||||
const SkTDArray<size_t>& offsets) {
|
||||
const SkTDArray<size_t>& offsets,
|
||||
const SkTDArray<bool>& deletedCommands) {
|
||||
if (success) {
|
||||
*success = false;
|
||||
}
|
||||
@ -254,7 +271,7 @@ public:
|
||||
if (stream->readBool()) {
|
||||
bool isValid = false;
|
||||
fPlayback = SkNEW_ARGS(SkTimedPicturePlayback,
|
||||
(stream, info, &isValid, decoder, offsets));
|
||||
(stream, info, &isValid, decoder, offsets, deletedCommands));
|
||||
if (!isValid) {
|
||||
SkDELETE(fPlayback);
|
||||
fPlayback = NULL;
|
||||
@ -341,7 +358,8 @@ void SkDebuggerGUI::actionProfile() {
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
SkTimedPicture picture(&inputStream, &success, &SkImageDecoder::DecodeStream, fOffsets);
|
||||
SkTimedPicture picture(&inputStream, &success, &SkImageDecoder::DecodeStream,
|
||||
fOffsets, fSkipCommands);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
@ -407,6 +425,7 @@ void SkDebuggerGUI::actionClearDeletes() {
|
||||
QListWidgetItem* item = fListWidget.item(row);
|
||||
item->setData(Qt::UserRole + 2, QPixmap(":/blank.png"));
|
||||
fDebugger.setCommandVisible(row, true);
|
||||
fSkipCommands[row] = false;
|
||||
}
|
||||
if (fPause) {
|
||||
fCanvasWidget.drawTo(fPausedRow);
|
||||
@ -435,9 +454,11 @@ void SkDebuggerGUI::actionDelete() {
|
||||
if (fDebugger.isCommandVisible(currentRow)) {
|
||||
item->setData(Qt::UserRole + 2, QPixmap(":/delete.png"));
|
||||
fDebugger.setCommandVisible(currentRow, false);
|
||||
fSkipCommands[currentRow] = true;
|
||||
} else {
|
||||
item->setData(Qt::UserRole + 2, QPixmap(":/blank.png"));
|
||||
fDebugger.setCommandVisible(currentRow, true);
|
||||
fSkipCommands[currentRow] = false;
|
||||
}
|
||||
|
||||
if (fPause) {
|
||||
@ -882,8 +903,9 @@ public:
|
||||
protected:
|
||||
SkTDArray<size_t> fOffsets;
|
||||
|
||||
virtual void preDraw(size_t offset, int type) {
|
||||
virtual size_t preDraw(size_t offset, int type) SK_OVERRIDE {
|
||||
*fOffsets.append() = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -956,6 +978,11 @@ void SkDebuggerGUI::loadPicture(const SkString& fileName) {
|
||||
|
||||
fOffsets = picture->offsets();
|
||||
|
||||
fSkipCommands.setCount(fOffsets.count());
|
||||
for (int i = 0; i < fOffsets.count(); ++i) {
|
||||
fSkipCommands[i] = false;
|
||||
}
|
||||
|
||||
SkSafeUnref(stream);
|
||||
SkSafeUnref(picture);
|
||||
|
||||
|
@ -260,6 +260,7 @@ private:
|
||||
QString fPath;
|
||||
SkString fFileName;
|
||||
SkTDArray<size_t> fOffsets; // the offset of each command in the SkPicture
|
||||
SkTDArray<bool> fSkipCommands; // has a specific command been deleted?
|
||||
bool fDirectoryWidgetActive;
|
||||
|
||||
QMenuBar fMenuBar;
|
||||
|
@ -577,7 +577,8 @@ struct SkipClipRec {
|
||||
#endif
|
||||
|
||||
#ifdef SK_PICTURE_PROFILING_STUBS
|
||||
void SkPicturePlayback::preDraw(size_t offset, int type) {
|
||||
size_t SkPicturePlayback::preDraw(size_t offset, int type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SkPicturePlayback::postDraw(size_t offset) {
|
||||
@ -597,6 +598,10 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
SkAutoMutexAcquire autoMutex(fDrawMutex);
|
||||
#endif
|
||||
|
||||
// kDrawComplete will be the signal that we have reached the end of
|
||||
// the command stream
|
||||
static const int kDrawComplete = SK_MaxU32;
|
||||
|
||||
SkReader32 reader(fOpData->bytes(), fOpData->size());
|
||||
TextContainer text;
|
||||
SkTDArray<void*> results;
|
||||
@ -621,11 +626,11 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
fStateTree->getIterator(results, &canvas);
|
||||
|
||||
if (it.isValid()) {
|
||||
uint32_t off = it.draw();
|
||||
if (off == SK_MaxU32) {
|
||||
uint32_t skipTo = it.draw();
|
||||
if (kDrawComplete == skipTo) {
|
||||
return;
|
||||
}
|
||||
reader.setOffset(off);
|
||||
reader.setOffset(skipTo);
|
||||
}
|
||||
|
||||
// Record this, so we can concat w/ it if we encounter a setMatrix()
|
||||
@ -637,7 +642,14 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
#endif
|
||||
int type = reader.readInt();
|
||||
#ifdef SK_PICTURE_PROFILING_STUBS
|
||||
this->preDraw(curOffset, type);
|
||||
size_t skipTo = this->preDraw(curOffset, type);
|
||||
if (0 != skipTo) {
|
||||
if (kDrawComplete == skipTo) {
|
||||
break;
|
||||
}
|
||||
reader.setOffset(skipTo);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
switch (type) {
|
||||
case CLIP_PATH: {
|
||||
@ -887,11 +899,11 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
#endif
|
||||
|
||||
if (it.isValid()) {
|
||||
uint32_t off = it.draw();
|
||||
if (off == SK_MaxU32) {
|
||||
uint32_t skipTo = it.draw();
|
||||
if (kDrawComplete == skipTo) {
|
||||
break;
|
||||
}
|
||||
reader.setOffset(off);
|
||||
reader.setOffset(skipTo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
|
||||
protected:
|
||||
#ifdef SK_PICTURE_PROFILING_STUBS
|
||||
virtual void preDraw(size_t offset, int type);
|
||||
virtual size_t preDraw(size_t offset, int type);
|
||||
virtual void postDraw(size_t offset);
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user