Add new experimental API to SkPicture to get "id" of current op

When gathering information about a picture (in the new SkDevice::EXPERIMENTAL_optimize entry point) it is necessary to be able to correlate the gathered information with the command in the SkPicture (so the information can later be combined with the similarly indexed information from the BBH). This entry point exposes that information to friend classes.

R=reed@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/206853003

git-svn-id: http://skia.googlecode.com/svn/trunk@13919 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index ba316ff..8053bb2 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -348,12 +348,20 @@
     */
     const OperationList& EXPERIMENTAL_getActiveOps(const SkIRect& queryRect);
 
+    /** PRIVATE / EXPERIMENTAL -- do not call
+        Return the ID of the operation currently being executed when playing
+        back. 0 indicates no call is active.
+    */
+    size_t EXPERIMENTAL_curOpID() const;
+
     void createHeader(SkPictInfo* info) const;
     static bool IsValidPictInfo(const SkPictInfo& info);
 
     friend class SkFlatPicture;
     friend class SkPicturePlayback;
     friend class SkGpuDevice;
+    friend class GrGatherDevice;
+    friend class SkDebugCanvas;
 
     typedef SkRefCnt INHERITED;
 };
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 41fc374..ae0347c 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -281,6 +281,13 @@
     return OperationList::InvalidList();
 }
 
+size_t SkPicture::EXPERIMENTAL_curOpID() const {
+    if (NULL != fPlayback) {
+        return fPlayback->curOpID();
+    }
+    return 0;
+}
+
 void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
     this->endRecording();
     if (NULL != fPlayback) {
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index a570c4c..8320335 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -261,6 +261,7 @@
     fBoundingHierarchy = NULL;
     fStateTree = NULL;
     fCachedActiveOps = NULL;
+    fCurOffset = 0;
 }
 
 SkPicturePlayback::~SkPicturePlayback() {
@@ -838,7 +839,23 @@
     return *fCachedActiveOps;
 }
 
+class SkAutoResetOpID {
+public:
+    SkAutoResetOpID(SkPicturePlayback* playback) : fPlayback(playback) { }
+    ~SkAutoResetOpID() {
+        if (NULL != fPlayback) {
+            fPlayback->resetOpID();
+        }
+    }
+
+private:
+    SkPicturePlayback* fPlayback;
+};
+
 void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) {
+    SkAutoResetOpID aroi(this);
+    SkASSERT(0 == fCurOffset);
+
 #ifdef ENABLE_TIME_DRAW
     SkAutoTime  at("SkPicture::draw", 50);
 #endif
@@ -919,18 +936,18 @@
         opCount++;
 #endif
 
-        size_t curOffset = reader.offset();
+        fCurOffset = reader.offset();
         uint32_t size;
         DrawType op = read_op_and_size(&reader, &size);
         size_t skipTo = 0;
         if (NOOP == op) {
             // NOOPs are to be ignored - do not propagate them any further
-            skipTo = curOffset + size;
+            skipTo = fCurOffset + size;
 #ifdef SK_DEVELOPER
         } else {
             opIndex++;
             if (this->preDraw(opIndex, op)) {
-                skipTo = curOffset + size;
+                skipTo = fCurOffset + size;
             }
 #endif
         }
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index 1162420..89d70a1 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -102,6 +102,9 @@
     void abort() { fAbortCurrentPlayback = true; }
 #endif
 
+    size_t curOpID() const { return fCurOffset; }
+    void resetOpID() { fCurOffset = 0; }
+
 protected:
     bool parseStream(SkStream*, const SkPictInfo&,
                      SkPicture::InstallPixelRefProc);
@@ -264,6 +267,10 @@
 
     SkTypefacePlayback fTFPlayback;
     SkFactoryPlayback* fFactoryPlayback;
+
+    // The offset of the current operation when within the draw method
+    size_t fCurOffset;
+
 #ifdef SK_BUILD_FOR_ANDROID
     SkMutex fDrawMutex;
     bool fAbortCurrentPlayback;