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
diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp
index 25e0c57..b301fce 100644
--- a/debugger/QT/SkDebuggerGUI.cpp
+++ b/debugger/QT/SkDebuggerGUI.cpp
@@ -141,11 +141,13 @@
 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 @@
 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 @@
     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 @@
             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 @@
 #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 @@
     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 @@
         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 @@
     }
 
     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 @@
         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 @@
     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 @@
 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 @@
 
     fOffsets = picture->offsets();
 
+    fSkipCommands.setCount(fOffsets.count());
+    for (int i = 0; i < fOffsets.count(); ++i) {
+        fSkipCommands[i] = false;
+    }
+
     SkSafeUnref(stream);
     SkSafeUnref(picture);
 
diff --git a/debugger/QT/SkDebuggerGUI.h b/debugger/QT/SkDebuggerGUI.h
index aed4072..75d3f28 100644
--- a/debugger/QT/SkDebuggerGUI.h
+++ b/debugger/QT/SkDebuggerGUI.h
@@ -260,6 +260,7 @@
     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;
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index d0a29d3..a337264 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -577,7 +577,8 @@
 #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 @@
     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 @@
         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 @@
 #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 @@
 #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);
         }
     }
 
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index 9e495fa..8f52b19 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -79,7 +79,7 @@
 
 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