split SkPictureRecorder out of SkPicture

https://codereview.chromium.org/214953003/



git-svn-id: http://skia.googlecode.com/svn/trunk@14171 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp
index e0058c4..79c6c36 100644
--- a/samplecode/SampleAll.cpp
+++ b/samplecode/SampleAll.cpp
@@ -302,13 +302,17 @@
 
     virtual void onDrawContent(SkCanvas* canvas) {
         canvas->save();
-        drawPicture(canvas, 0);
+        this->drawPicture(canvas, 0);
         canvas->restore();
 
         {
-            SkPicture picture;
-            SkCanvas* record = picture.beginRecording(320, 480);
-            drawPicture(record, 120);
+            SkPictureRecorder recorder;
+            {
+                SkCanvas* record = recorder.beginRecording(320, 480);
+                this->drawPicture(record, 120);
+            }
+            SkAutoTUnref<SkPicture> picture(recorder.endRecording());
+
             canvas->translate(0, SkIntToScalar(120));
 
             SkRect clip;
@@ -316,7 +320,7 @@
             do {
                 canvas->save();
                 canvas->clipRect(clip);
-                picture.draw(canvas);
+                picture->draw(canvas);
                 canvas->restore();
                 if (clip.fRight < SkIntToScalar(320))
                     clip.offset(SkIntToScalar(160), 0);
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 050fc4a..5020ec2 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -834,8 +834,6 @@
     fclose(f);
 #endif
 
-    fPicture = NULL;
-
     fDeviceType = kRaster_DeviceType;
 
 #if DEFAULT_TO_GPU
@@ -990,7 +988,6 @@
 }
 
 SampleWindow::~SampleWindow() {
-    delete fPicture;
     delete fPdfCanvas;
     fTypeface->unref();
 
@@ -1379,8 +1376,7 @@
         pdfDevice->unref();
         canvas = fPdfCanvas;
     } else if (kPicture_DeviceType == fDeviceType) {
-        fPicture = new SkPicture;
-        canvas = fPicture->beginRecording(9999, 9999);
+        canvas = fRecorder.beginRecording(9999, 9999);
     } else {
 #if SK_SUPPORT_GPU
         if (kNullGPU_DeviceType != fDeviceType)
@@ -1459,16 +1455,16 @@
     }
 
     if (kPicture_DeviceType == fDeviceType) {
+        SkAutoTUnref<SkPicture> picture(fRecorder.endRecording());
+
         if (true) {
-            SkPicture* pict = new SkPicture(*fPicture);
-            fPicture->unref();
+            SkPicture* pict = new SkPicture(*picture);
             this->installDrawFilter(orig);
             orig->drawPicture(*pict);
             pict->unref();
         } else if (true) {
             SkDynamicMemoryWStream ostream;
-            fPicture->serialize(&ostream);
-            fPicture->unref();
+            picture->serialize(&ostream);
 
             SkAutoDataUnref data(ostream.copyToData());
             SkMemoryStream istream(data->data(), data->size());
@@ -1477,10 +1473,8 @@
                 orig->drawPicture(*pict.get());
             }
         } else {
-            fPicture->draw(orig);
-            fPicture->unref();
+            picture->draw(orig);
         }
-        fPicture = NULL;
     }
 
     // Do this after presentGL and other finishing, rather than in afterChild
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index 106931c..13bc697 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -10,6 +10,7 @@
 
 #include "SkOSMenu.h"
 #include "SkPath.h"
+#include "SkPicture.h"
 #include "SkScalar.h"
 #include "SkTDArray.h"
 #include "SkTouchGesture.h"
@@ -21,7 +22,6 @@
 class SkCanvas;
 class SkData;
 class SkEvent;
-class SkPicture;
 class SkTypeface;
 class SkViewFactory;
 
@@ -168,7 +168,7 @@
 
     int fCurrIndex;
 
-    SkPicture* fPicture;
+    SkPictureRecorder fRecorder;
     SkPath fClipPath;
 
     SkTouchGesture fGesture;
diff --git a/samplecode/SamplePictFile.cpp b/samplecode/SamplePictFile.cpp
index ea15524..ab45555 100644
--- a/samplecode/SamplePictFile.cpp
+++ b/samplecode/SamplePictFile.cpp
@@ -122,19 +122,19 @@
     SkSize      fTileSize;
 
     SkPicture* LoadPicture(const char path[], BBoxType bbox) {
-        SkPicture* pic = NULL;
+        SkAutoTUnref<SkPicture> pic;
 
         SkBitmap bm;
         if (SkImageDecoder::DecodeFile(path, &bm)) {
             bm.setImmutable();
-            pic = SkNEW(SkPicture);
-            SkCanvas* can = pic->beginRecording(bm.width(), bm.height());
+            SkPictureRecorder recorder;
+            SkCanvas* can = recorder.beginRecording(bm.width(), bm.height());
             can->drawBitmap(bm, 0, 0, NULL);
-            pic->endRecording();
+            pic.reset(recorder.endRecording());
         } else {
             SkFILEStream stream(path);
             if (stream.isValid()) {
-                pic = SkPicture::CreateFromStream(&stream);
+                pic.reset(SkPicture::CreateFromStream(&stream));
             } else {
                 SkDebugf("coun't load picture at \"path\"\n", path);
             }
@@ -145,32 +145,30 @@
                 surf->unref();
             }
             if (false) { // re-record
-                SkPicture p2;
-                pic->draw(p2.beginRecording(pic->width(), pic->height()));
-                p2.endRecording();
+                SkPictureRecorder recorder;
+                pic->draw(recorder.beginRecording(pic->width(), pic->height()));
+                SkAutoTUnref<SkPicture> p2(recorder.endRecording());
 
                 SkString path2(path);
                 path2.append(".new.skp");
                 SkFILEWStream writer(path2.c_str());
-                p2.serialize(&writer);
+                p2->serialize(&writer);
             }
         }
 
-        if (!pic) {
+        if (NULL == pic) {
             return NULL;
         }
 
-        SkPicture* bboxPicture = NULL;
+        SkAutoTUnref<SkPictureFactory> factory;
         switch (bbox) {
         case kNo_BBoxType:
             // no bbox playback necessary
-            break;
+            return pic.detach();
         case kRTree_BBoxType:
-            bboxPicture = SkNEW(SkPicture);
             break;
         case kQuadTree_BBoxType:
-            bboxPicture = SkNEW_ARGS(SkQuadTreePicture,
-                (SkIRect::MakeWH(pic->width(), pic->height())));
+            factory.reset(SkNEW(SkQuadTreePictureFactory));
             break;
         case kTileGrid_BBoxType: {
             SkASSERT(!fTileSize.isEmpty());
@@ -178,21 +176,17 @@
             gridInfo.fMargin = SkISize::Make(0, 0);
             gridInfo.fOffset = SkIPoint::Make(0, 0);
             gridInfo.fTileInterval = fTileSize.toRound();
-            bboxPicture = SkNEW_ARGS(SkTileGridPicture, (pic->width(), pic->height(), gridInfo));
-        } break;
+            factory.reset(SkNEW_ARGS(SkTileGridPictureFactory, (gridInfo)));
+            break;
+        }
         default:
             SkASSERT(false);
         }
 
-        if (bboxPicture) {
-            pic->draw(bboxPicture->beginRecording(pic->width(), pic->height(),
-                      SkPicture::kOptimizeForClippedPlayback_RecordingFlag));
-            bboxPicture->endRecording();
-            SkDELETE(pic);
-            return bboxPicture;
-        }
-
-        return pic;
+        SkPictureRecorder recorder(factory);
+        pic->draw(recorder.beginRecording(pic->width(), pic->height(),
+                                          SkPicture::kOptimizeForClippedPlayback_RecordingFlag));
+        return recorder.endRecording();
     }
 
     typedef SampleView INHERITED;
diff --git a/samplecode/SamplePicture.cpp b/samplecode/SamplePicture.cpp
index b76f36f..a786750 100644
--- a/samplecode/SamplePicture.cpp
+++ b/samplecode/SamplePicture.cpp
@@ -61,15 +61,18 @@
 
         fBitmap = load_bitmap();
 
-        fPicture = new SkPicture;
-        SkCanvas* canvas = fPicture->beginRecording(100, 100);
+        SkPictureRecorder recorder;
+
+        recorder.beginRecording(100, 100);
+        fSubPicture = recorder.endRecording();
+
+        SkCanvas* canvas = recorder.beginRecording(100, 100);
         SkPaint paint;
         paint.setAntiAlias(true);
 
         canvas->drawBitmap(fBitmap, 0, 0, NULL);
 
         drawCircle(canvas, 50, SK_ColorBLACK);
-        fSubPicture = new SkPicture;
         canvas->drawPicture(*fSubPicture);
         canvas->translate(SkIntToScalar(50), 0);
         canvas->drawPicture(*fSubPicture);
@@ -77,8 +80,11 @@
         canvas->drawPicture(*fSubPicture);
         canvas->translate(SkIntToScalar(-50), 0);
         canvas->drawPicture(*fSubPicture);
-        // fPicture now has (4) references to us. We can release ours, and just
-        // unref fPicture in our destructor, and it will in turn take care of
+
+        fPicture = recorder.endRecording();
+
+        // fPicture now has (4) references to fSubPicture. We can release our ref, 
+        // and just unref fPicture in our destructor, and it will in turn take care of
         // the other references to fSubPicture
         fSubPicture->unref();
     }
@@ -123,13 +129,11 @@
     }
 
     virtual void onDrawContent(SkCanvas* canvas) {
-        drawSomething(canvas);
+        this->drawSomething(canvas);
 
-        SkPicture* pict = new SkPicture;
-        SkAutoUnref aur(pict);
-
-        drawSomething(pict->beginRecording(100, 100));
-        pict->endRecording();
+        SkPictureRecorder recorder;
+        this->drawSomething(recorder.beginRecording(100, 100));
+        SkAutoTUnref<SkPicture> pict(recorder.endRecording());
 
         canvas->save();
         canvas->translate(SkIntToScalar(300), SkIntToScalar(50));
@@ -160,12 +164,11 @@
         }
 #endif
 
-        // test that we can re-record a subpicture, and see the results
+        // This used to re-record the sub-picture and redraw the parent
+        // A capability that is now forbidden!
 
         SkRandom rand(SampleCode::GetAnimTime());
         canvas->translate(SkIntToScalar(10), SkIntToScalar(250));
-        drawCircle(fSubPicture->beginRecording(50, 50), 25,
-                   rand.nextU() | 0xFF000000);
         canvas->drawPicture(*fPicture);
         delayInval(500);
     }
diff --git a/samplecode/SampleTiling.cpp b/samplecode/SampleTiling.cpp
index 9ffcceb..faa8d80 100644
--- a/samplecode/SampleTiling.cpp
+++ b/samplecode/SampleTiling.cpp
@@ -62,21 +62,19 @@
 static const int gHeight = 32;
 
 class TilingView : public SampleView {
-    SkPicture*          fTextPicture;
-    SkBlurDrawLooper    fLooper;
+    SkAutoTUnref<SkPicture> fTextPicture;
+    SkBlurDrawLooper        fLooper;
 public:
     TilingView()
             : fLooper(0x88000000,
                       SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(1)),
                       SkIntToScalar(2), SkIntToScalar(2)) {
-        fTextPicture = new SkPicture();
         for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
             makebm(&fTexture[i], gColorTypes[i], gWidth, gHeight);
         }
     }
 
-    ~TilingView() {
-        fTextPicture->unref();
+    virtual ~TilingView() {
     }
 
     SkBitmap    fTexture[SK_ARRAY_COUNT(gColorTypes)];
@@ -105,12 +103,13 @@
         SkScalar y = SkIntToScalar(24);
         SkScalar x = SkIntToScalar(10);
 
+        SkPictureRecorder recorder;
         SkCanvas* textCanvas = NULL;
         if (fTextPicture->width() == 0) {
-            textCanvas = fTextPicture->beginRecording(1000, 1000);
+            textCanvas = recorder.beginRecording(1000, 1000);
         }
 
-        if (textCanvas) {
+        if (NULL != textCanvas) {
             for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
                 for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
                     SkPaint p;
@@ -160,6 +159,8 @@
             }
         }
 
+        fTextPicture.reset(recorder.endRecording());
+
         canvas->drawPicture(*fTextPicture);
     }