First pass at splitting out SkPictureRecord from SkPicture
authorrobertphillips <robertphillips@google.com>
Sun, 8 Jun 2014 12:55:05 +0000 (05:55 -0700)
committerCommit bot <commit-bot@chromium.org>
Sun, 8 Jun 2014 12:55:05 +0000 (05:55 -0700)
This patch begins the process of splitting apart SkPicture, SkPicturePlayback and SkPictureRecord.

This is still a bit messy. In a follow up CL I hope to delay the creation of SkPictureRecorder's SkPicture until endRecording time.

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

Author: robertphillips@google.com

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

include/core/SkPicture.h
include/core/SkPictureRecorder.h
src/core/SkPicture.cpp
src/core/SkPictureRecorder.cpp

index a908ab5..fb5e7ff 100644 (file)
@@ -147,8 +147,7 @@ public:
         kUsePathBoundsForClip_RecordingFlag = 0x01
     };
 
-    /** Replays the drawing commands on the specified canvas. This internally
-        calls endRecording() if that has not already been called.
+    /** Replays the drawing commands on the specified canvas.
         @param canvas the canvas receiving the drawing commands.
     */
     void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL) const;
@@ -225,14 +224,6 @@ public:
     static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
     static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*);
 
-    /** Enable/disable all the picture recording optimizations (i.e.,
-        those in SkPictureRecord). It is mainly intended for testing the
-        existing optimizations (i.e., to actually have the pattern
-        appear in an .skp we have to disable the optimization). Call right
-        after 'beginRecording'.
-    */
-    void internalOnly_EnableOpts(bool enableOpts);
-
     /** Return true if the picture is suitable for rendering on the GPU.
      */
 
@@ -284,7 +275,6 @@ protected:
     // install their own SkPicturePlayback-derived players,SkPictureRecord-derived
     // recorders and set the picture size
     SkPicturePlayback*    fPlayback;
-    SkPictureRecord*      fRecord;
     int                   fWidth, fHeight;
     mutable const AccelData* fAccelData;
 
@@ -419,31 +409,6 @@ private:
     friend class GrGatherDevice;
     friend class SkDebugCanvas;
 
-    // TODO: beginRecording, getRecordingCanvas & endRecording can now be
-    // be moved out of SkPicture (and, presumably, be directly implemented
-    // in SkPictureRecorder)
-
-    /** Returns the canvas that records the drawing commands.
-        @param width the base width for the picture, as if the recording
-               canvas' bitmap had this width.
-        @param height the base width for the picture, as if the recording
-               canvas' bitmap had this height.
-        @param factory if non-NULL, the factory used to the BBH for the recorded picture
-        @param recordFlags optional flags that control recording.
-        @return the picture canvas.
-    */
-    SkCanvas* beginRecording(int width, int height, SkBBHFactory* factory, uint32_t recordFlags);
-    /** Returns the recording canvas if one is active, or NULL if recording is
-        not active. This does not alter the refcnt on the canvas (if present).
-    */
-    SkCanvas* getRecordingCanvas() const;
-    /** Signal that the caller is done recording. This invalidates the canvas
-        returned by beginRecording/getRecordingCanvas, and prepares the picture
-        for drawing. Note: this happens implicitly the first time the picture
-        is drawn.
-    */
-    void endRecording();
-
     typedef SkRefCnt INHERITED;
 };
 
index b496aee..545dc31 100644 (file)
 #include "SkRefCnt.h"
 
 class SkCanvas;
+class SkPictureRecord;
 
 class SK_API SkPictureRecorder : SkNoncopyable {
 public:
+    SkPictureRecorder() : fCanvas(NULL) { }
+    ~SkPictureRecorder();
+
     /** Returns the canvas that records the drawing commands.
         @param width the base width for the picture, as if the recording
                      canvas' bitmap had this width.
@@ -33,25 +37,14 @@ public:
     /** Returns the recording canvas if one is active, or NULL if recording is
         not active. This does not alter the refcnt on the canvas (if present).
     */
-    SkCanvas* getRecordingCanvas() {
-        if (NULL != fPicture.get()) {
-            return fPicture->getRecordingCanvas();
-        }
-        return NULL;
-    }
+    SkCanvas* getRecordingCanvas();
 
     /** Signal that the caller is done recording. This invalidates the canvas
         returned by beginRecording/getRecordingCanvas, and returns the
         created SkPicture. Note that the returned picture has its creation
         ref which the caller must take ownership of.
     */
-    SkPicture* endRecording() {
-        if (NULL != fPicture.get()) {
-            fPicture->endRecording();
-            return fPicture.detach();
-        }
-        return NULL;
-    }
+    SkPicture* endRecording();
 
     /** Enable/disable all the picture recording optimizations (i.e.,
         those in SkPictureRecord). It is mainly intended for testing the
@@ -59,11 +52,7 @@ public:
         appear in an .skp we have to disable the optimization). Call right
         after 'beginRecording'.
     */
-    void internalOnly_EnableOpts(bool enableOpts) {
-        if (NULL != fPicture.get()) {
-            fPicture->internalOnly_EnableOpts(enableOpts);
-        }
-    }
+    void internalOnly_EnableOpts(bool enableOpts);
 
 private:
 #ifdef SK_BUILD_FOR_ANDROID
@@ -75,7 +64,8 @@ private:
     void partialReplay(SkCanvas* canvas) const;
 #endif
 
-    SkAutoTUnref<SkPicture>         fPicture;
+    SkAutoTUnref<SkPicture> fPicture;
+    SkPictureRecord*        fCanvas;   // ref counted
 
     typedef SkNoncopyable INHERITED;
 };
index 98c0e00..2fff238 100644 (file)
@@ -126,7 +126,6 @@ static void validateMatrix(const SkMatrix* matrix) {
 SkPicture::SkPicture()
     : fAccelData(NULL) {
     this->needsNewGenID();
-    fRecord = NULL;
     fPlayback = NULL;
     fWidth = fHeight = 0;
 }
@@ -149,7 +148,6 @@ SkPicture::SkPicture(const SkPicture& src)
     this->needsNewGenID();
     fWidth = src.fWidth;
     fHeight = src.fHeight;
-    fRecord = NULL;
 
     /*  We want to copy the src's playback. However, if that hasn't been built
         yet, we need to fake a call to endRecording() without actually calling
@@ -157,10 +155,7 @@ SkPicture::SkPicture(const SkPicture& src)
      */
     if (src.fPlayback) {
         fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fPlayback));
-        SkASSERT(NULL == src.fRecord);
         fUniqueID = src.uniqueID();     // need to call method to ensure != 0
-    } else if (src.fRecord) {
-        fPlayback = FakeEndRecording(this, *src.fRecord, false);
     } else {
         fPlayback = NULL;
     }
@@ -198,20 +193,12 @@ void SkPicture::dumpSize() const {
 }
 
 SkPicture::~SkPicture() {
-    SkSafeUnref(fRecord);
     SkDELETE(fPlayback);
     SkSafeUnref(fAccelData);
 }
 
-void SkPicture::internalOnly_EnableOpts(bool enableOpts) {
-    if (NULL != fRecord) {
-        fRecord->internalOnly_EnableOpts(enableOpts);
-    }
-}
-
 void SkPicture::swap(SkPicture& other) {
     SkTSwap(fUniqueID, other.fUniqueID);
-    SkTSwap(fRecord, other.fRecord);
     SkTSwap(fPlayback, other.fPlayback);
     SkTSwap(fAccelData, other.fAccelData);
     SkTSwap(fWidth, other.fWidth);
@@ -235,7 +222,6 @@ void SkPicture::clone(SkPicture* pictures, int count) const {
         clone->needsNewGenID();
         clone->fWidth = fWidth;
         clone->fHeight = fHeight;
-        SkSafeSetNull(clone->fRecord);
         SkDELETE(clone->fPlayback);
         clone->fContentInfo.set(fContentInfo);
 
@@ -287,10 +273,7 @@ void SkPicture::clone(SkPicture* pictures, int count) const {
             }
 
             clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fPlayback, &copyInfo));
-            SkASSERT(NULL == fRecord);
             clone->fUniqueID = this->uniqueID(); // need to call method to ensure != 0
-        } else if (fRecord) {
-            clone->fPlayback = FakeEndRecording(clone, *fRecord, true);
         } else {
             clone->fPlayback = NULL;
         }
@@ -312,62 +295,13 @@ SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkCanvas* SkPicture::beginRecording(int width, int height,
-                                    SkBBHFactory* bbhFactory,
-                                    uint32_t recordingFlags) {
-    if (fPlayback) {
-        SkDELETE(fPlayback);
-        fPlayback = NULL;
-    }
-    SkSafeUnref(fAccelData);
-    SkSafeSetNull(fRecord);
-    SkASSERT(NULL == fPathHeap);
-    fContentInfo.reset();
-
-    this->needsNewGenID();
-
-    fWidth = width;
-    fHeight = height;
-
-    const SkISize size = SkISize::Make(width, height);
-
-    if (NULL != bbhFactory) {
-        SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
-        SkASSERT(NULL != tree);
-        fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size, recordingFlags, tree.get()));
-    } else {
-        fRecord = SkNEW_ARGS(SkPictureRecord, (this, size, recordingFlags));
-    }
-    fRecord->beginRecording();
-
-    return fRecord;
-}
-
-SkCanvas* SkPicture::getRecordingCanvas() const {
-    // will be null if we are not recording
-    return fRecord;
-}
-
-void SkPicture::endRecording() {
-    if (NULL == fPlayback) {
-        if (NULL != fRecord) {
-            fRecord->endRecording();
-            SkPictInfo info;
-            this->createHeader(&info);
-            fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
-            SkSafeSetNull(fRecord);
-        }
-    }
-    SkASSERT(NULL == fRecord);
-}
-
 const SkPicture::OperationList& SkPicture::OperationList::InvalidList() {
     static OperationList gInvalid;
     return gInvalid;
 }
 
 const SkPicture::OperationList& SkPicture::EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const {
-    SkASSERT(NULL != fPlayback && NULL == fRecord);
+    SkASSERT(NULL != fPlayback);
     if (NULL != fPlayback) {
         return fPlayback->getActiveOps(queryRect);
     }
@@ -382,7 +316,7 @@ size_t SkPicture::EXPERIMENTAL_curOpID() const {
 }
 
 void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) const {
-    SkASSERT(NULL != fPlayback && NULL == fRecord);
+    SkASSERT(NULL != fPlayback);
     if (NULL != fPlayback) {
         fPlayback->draw(*surface, callback);
     }
@@ -441,7 +375,6 @@ bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo
 
 SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height)
     : fPlayback(playback)
-    , fRecord(NULL)
     , fWidth(width)
     , fHeight(height)
     , fAccelData(NULL) {
@@ -515,10 +448,6 @@ void SkPicture::createHeader(SkPictInfo* info) const {
 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
     SkPicturePlayback* playback = fPlayback;
 
-    if (NULL == playback && fRecord) {
-        playback = FakeEndRecording(this, *fRecord, false);
-    }
-
     SkPictInfo info;
     this->createHeader(&info);
     stream->write(&info, sizeof(info));
@@ -573,10 +502,6 @@ void SkPicture::flattenToBuffer(SkWriteBuffer& buffer) const {
 void SkPicture::flatten(SkWriteBuffer& buffer) const {
     SkPicturePlayback* playback = fPlayback;
 
-    if (NULL == playback && fRecord) {
-        playback = FakeEndRecording(this, *fRecord, false);
-    }
-
     SkPictInfo info;
     this->createHeader(&info);
     buffer.writeByteArray(&info, sizeof(info));
@@ -642,11 +567,6 @@ static int32_t next_picture_generation_id() {
 }
 
 uint32_t SkPicture::uniqueID() const {
-    if (NULL != fRecord) {
-        SkASSERT(NULL == fPlayback);
-        return SK_InvalidGenID;
-    }
-
     if (SK_InvalidGenID == fUniqueID) {
         fUniqueID = next_picture_generation_id();
     }
index 1589ec0..31302d0 100644 (file)
@@ -5,18 +5,67 @@
  * found in the LICENSE file.
  */
 
-// Need to include SkTypes first, so that SK_BUILD_FOR_ANDROID is defined.
-#include "SkTypes.h"
-#ifdef SK_BUILD_FOR_ANDROID
+#include "SkBBoxHierarchyRecord.h"
 #include "SkPicturePlayback.h"
-#endif
+#include "SkPictureRecord.h"
 #include "SkPictureRecorder.h"
+#include "SkTypes.h" 
+
+SkPictureRecorder::~SkPictureRecorder() {
+    SkSafeSetNull(fCanvas);
+}
 
 SkCanvas* SkPictureRecorder::beginRecording(int width, int height,
                                             SkBBHFactory* bbhFactory /* = NULL */,
                                             uint32_t recordFlags /* = 0 */) {
+    SkSafeSetNull(fCanvas);
     fPicture.reset(SkNEW(SkPicture));
-    return fPicture->beginRecording(width, height, bbhFactory, recordFlags);
+
+    fPicture->fWidth = width;
+    fPicture->fHeight = height;
+
+    const SkISize size = SkISize::Make(width, height);
+
+    if (NULL != bbhFactory) {
+        SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
+        SkASSERT(NULL != tree);
+        fCanvas = SkNEW_ARGS(SkBBoxHierarchyRecord, (fPicture, size, recordFlags, tree.get()));
+    } else {
+        fCanvas = SkNEW_ARGS(SkPictureRecord, (fPicture, size, recordFlags));
+    }
+
+    fCanvas->beginRecording();
+
+    return fCanvas;
+}
+
+SkCanvas* SkPictureRecorder::getRecordingCanvas() {
+    return fCanvas;
+}
+
+SkPicture* SkPictureRecorder::endRecording() {
+    if (NULL == fPicture.get()) {
+        return NULL;
+    }
+
+    SkASSERT(NULL == fPicture->fPlayback);
+    SkASSERT(NULL != fCanvas);
+
+    fCanvas->endRecording();
+
+    SkPictInfo info;
+    fPicture->createHeader(&info);
+    fPicture->fPlayback = SkNEW_ARGS(SkPicturePlayback, (fPicture, *fCanvas, info));
+
+    SkSafeSetNull(fCanvas);
+
+    return fPicture.detach();
+}
+
+void SkPictureRecorder::internalOnly_EnableOpts(bool enableOpts) {
+    if (NULL != fCanvas) {
+        fCanvas->internalOnly_EnableOpts(enableOpts);
+    }
 }
 
 #ifdef SK_BUILD_FOR_ANDROID
@@ -26,10 +75,10 @@ void SkPictureRecorder::partialReplay(SkCanvas* canvas) const {
         return;
     }
 
-    SkASSERT(NULL != fPicture->fRecord);
+    SkASSERT(NULL != fCanvas);
 
     SkAutoTDelete<SkPicturePlayback> playback(SkPicture::FakeEndRecording(fPicture.get(),
-                                                                          *fPicture->fRecord,
+                                                                          *fCanvas,
                                                                           false));
     playback->draw(*canvas, NULL);
 }