Alter SkCanvas::drawPicture (devirtualize, take const SkPicture, take pointer)

R=reed@google.com, bsalomon@google.com, mtklein@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/313613004
diff --git a/src/core/SkBBoxRecord.cpp b/src/core/SkBBoxRecord.cpp
index b1c229e..a40ea8b 100644
--- a/src/core/SkBBoxRecord.cpp
+++ b/src/core/SkBBoxRecord.cpp
@@ -280,10 +280,10 @@
     }
 }
 
-void SkBBoxRecord::drawPicture(SkPicture& picture) {
-    if (picture.width() > 0 && picture.height() > 0 &&
-        this->transformBounds(SkRect::MakeWH(picture.width(), picture.height()), NULL)) {
-        INHERITED::drawPicture(picture);
+void SkBBoxRecord::onDrawPicture(const SkPicture* picture) {
+    if (picture->width() > 0 && picture->height() > 0 &&
+        this->transformBounds(SkRect::MakeWH(picture->width(), picture->height()), NULL)) {
+        this->INHERITED::onDrawPicture(picture);
     }
 }
 
diff --git a/src/core/SkBBoxRecord.h b/src/core/SkBBoxRecord.h
index f2e9d8d..123a91f 100644
--- a/src/core/SkBBoxRecord.h
+++ b/src/core/SkBBoxRecord.h
@@ -54,7 +54,6 @@
                               const SkColor colors[], SkXfermode* xfer,
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint) SK_OVERRIDE;
-    virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
 
 protected:
     virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
@@ -66,6 +65,7 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
 
 private:
     /**
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 53dec2e..3134c46 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2479,31 +2479,39 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-void SkCanvas::EXPERIMENTAL_optimize(SkPicture* picture) {
+void SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) {
     SkBaseDevice* device = this->getDevice();
     if (NULL != device) {
         device->EXPERIMENTAL_optimize(picture);
     }
 }
 
-void SkCanvas::EXPERIMENTAL_purge(SkPicture* picture) {
+void SkCanvas::EXPERIMENTAL_purge(const SkPicture* picture) {
     SkBaseDevice* device = this->getTopDevice();
     if (NULL != device) {
         device->EXPERIMENTAL_purge(picture);
     }
 }
 
-void SkCanvas::drawPicture(SkPicture& picture) {
+void SkCanvas::drawPicture(const SkPicture* picture) {
+    if (NULL != picture) {
+        this->onDrawPicture(picture);
+    }
+}
+
+void SkCanvas::onDrawPicture(const SkPicture* picture) {
+    SkASSERT(NULL != picture);
+
     SkBaseDevice* device = this->getTopDevice();
     if (NULL != device) {
         // Canvas has to first give the device the opportunity to render
         // the picture itself.
-        if (device->EXPERIMENTAL_drawPicture(this, &picture)) {
+        if (device->EXPERIMENTAL_drawPicture(this, picture)) {
             return; // the device has rendered the entire picture
         }
     }
 
-    picture.draw(this);
+    picture->draw(this);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 36a8a75..6c5c0f3 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -131,15 +131,15 @@
     return NULL;
 }
 
-void SkBaseDevice::EXPERIMENTAL_optimize(SkPicture* picture) {
+void SkBaseDevice::EXPERIMENTAL_optimize(const SkPicture* picture) {
     // The base class doesn't perform any analysis but derived classes may
 }
 
-void SkBaseDevice::EXPERIMENTAL_purge(SkPicture* picture) {
+void SkBaseDevice::EXPERIMENTAL_purge(const SkPicture* picture) {
     // Derived-classes may have data to purge but not the base class
 }
 
-bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, SkPicture* picture) {
+bool SkBaseDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture) {
     // The base class doesn't perform any accelerated picture rendering
     return false;
 }
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 00bcbef..98c0e00 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -366,7 +366,7 @@
     return gInvalid;
 }
 
-const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) {
+const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const {
     SkASSERT(NULL != fPlayback && NULL == fRecord);
     if (NULL != fPlayback) {
         return fPlayback->getActiveOps(queryRect);
@@ -381,7 +381,7 @@
     return 0;
 }
 
-void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
+void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) const {
     SkASSERT(NULL != fPlayback && NULL == fRecord);
     if (NULL != fPlayback) {
         fPlayback->draw(*surface, callback);
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 8c77eeb..63f2d7e 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -129,10 +129,10 @@
 
     picture->initForPlayback();
 
-    const SkTDArray<SkPicture* >& pictures = record.getPictureRefs();
+    const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs();
     fPictureCount = pictures.count();
     if (fPictureCount > 0) {
-        fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
+        fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
         for (int i = 0; i < fPictureCount; i++) {
             if (deepCopy) {
                 fPictureRefs[i] = pictures[i]->clone();
@@ -210,7 +210,7 @@
     }
 
     fPictureCount = src.fPictureCount;
-    fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
+    fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
     for (int i = 0; i < fPictureCount; i++) {
         if (deepCopyInfo) {
             fPictureRefs[i] = src.fPictureRefs[i]->clone();
@@ -505,7 +505,7 @@
         } break;
         case SK_PICT_PICTURE_TAG: {
             fPictureCount = size;
-            fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
+            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
             bool success = true;
             int i = 0;
             for ( ; i < fPictureCount; i++) {
@@ -590,7 +590,7 @@
                 return false;
             }
             fPictureCount = size;
-            fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
+            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
             bool success = true;
             int i = 0;
             for ( ; i < fPictureCount; i++) {
diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h
index d6f0cf1..ea36ca9 100644
--- a/src/core/SkPicturePlayback.h
+++ b/src/core/SkPicturePlayback.h
@@ -150,10 +150,10 @@
         return fPicture->getPath(reader.readInt() - 1);
     }
 
-    SkPicture& getPicture(SkReader32& reader) {
+    const SkPicture* getPicture(SkReader32& reader) {
         int index = reader.readInt();
         SkASSERT(index > 0 && index <= fPictureCount);
-        return *fPictureRefs[index - 1];
+        return fPictureRefs[index - 1];
     }
 
     const SkPaint* getPaint(SkReader32& reader) {
@@ -246,7 +246,7 @@
 
     SkData* fOpData;    // opcodes and parameters
 
-    SkPicture** fPictureRefs;
+    const SkPicture** fPictureRefs;
     int fPictureCount;
 
     SkBBoxHierarchy* fBoundingHierarchy;
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 36b0763..0c59b13 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -1411,7 +1411,7 @@
     this->validate(initialOffset, size);
 }
 
-void SkPictureRecord::drawPicture(SkPicture& picture) {
+void SkPictureRecord::onDrawPicture(const SkPicture* picture) {
 
 #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE
     fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType);
@@ -1618,12 +1618,12 @@
     this->addInt(this->addPathToHeap(path));
 }
 
-void SkPictureRecord::addPicture(SkPicture& picture) {
-    int index = fPictureRefs.find(&picture);
+void SkPictureRecord::addPicture(const SkPicture* picture) {
+    int index = fPictureRefs.find(picture);
     if (index < 0) {    // not found
         index = fPictureRefs.count();
-        *fPictureRefs.append() = &picture;
-        picture.ref();
+        *fPictureRefs.append() = picture;
+        picture->ref();
     }
     // follow the convention of recording a 1-based index
     this->addInt(index + 1);
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 22d2546..d6cdf05 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -55,7 +55,6 @@
                                 const SkRect& dst, const SkPaint*) SK_OVERRIDE;
     virtual void drawSprite(const SkBitmap&, int left, int top,
                             const SkPaint*) SK_OVERRIDE;
-    virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
     virtual void drawVertices(VertexMode, int vertexCount,
                           const SkPoint vertices[], const SkPoint texs[],
                           const SkColor colors[], SkXfermode*,
@@ -70,7 +69,7 @@
     void addFontMetricsTopBottom(const SkPaint& paint, const SkFlatData&,
                                  SkScalar minY, SkScalar maxY);
 
-    const SkTDArray<SkPicture* >& getPictureRefs() const {
+    const SkTDArray<const SkPicture* >& getPictureRefs() const {
         return fPictureRefs;
     }
 
@@ -156,7 +155,7 @@
     const SkFlatData* addPaintPtr(const SkPaint* paint);
     void addFlatPaint(const SkFlatData* flatPaint);
     void addPath(const SkPath& path);
-    void addPicture(SkPicture& picture);
+    void addPicture(const SkPicture* picture);
     void addPoint(const SkPoint& point);
     void addPoints(const SkPoint pts[], int count);
     void addRect(const SkRect& rect);
@@ -236,6 +235,8 @@
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
 
+    virtual void onDrawPicture(const SkPicture* picture) SK_OVERRIDE;
+
     // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been
     // tweaked by paint.computeFastBounds().
     static void ComputeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]);
@@ -295,7 +296,7 @@
     SkWriter32 fWriter;
 
     // we ref each item in these arrays
-    SkTDArray<SkPicture*> fPictureRefs;
+    SkTDArray<const SkPicture*> fPictureRefs;
 
     uint32_t fRecordFlags;
     bool     fOptsEnabled;
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index ecb86e7..81e1375 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -92,7 +92,7 @@
 
         SkCanvas canvas(bm);
         canvas.scale(tileScale.width(), tileScale.height());
-        canvas.drawPicture(*fPicture);
+        canvas.drawPicture(fPicture);
 
         fCachedTileScale = tileScale;
         fCachedLocalMatrix = this->getLocalMatrix();