From 643b8bd6617e333f7a970a57ad9166f3d6675d1a Mon Sep 17 00:00:00 2001 From: robertphillips Date: Sun, 8 Jun 2014 05:55:05 -0700 Subject: [PATCH] First pass at splitting out SkPictureRecord from SkPicture 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 | 37 +----------------- include/core/SkPictureRecorder.h | 28 +++++--------- src/core/SkPicture.cpp | 84 +--------------------------------------- src/core/SkPictureRecorder.cpp | 63 ++++++++++++++++++++++++++---- 4 files changed, 68 insertions(+), 144 deletions(-) diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index a908ab5..fb5e7ff 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -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; }; diff --git a/include/core/SkPictureRecorder.h b/include/core/SkPictureRecorder.h index b496aee..545dc31 100644 --- a/include/core/SkPictureRecorder.h +++ b/include/core/SkPictureRecorder.h @@ -13,9 +13,13 @@ #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 fPicture; + SkAutoTUnref fPicture; + SkPictureRecord* fCanvas; // ref counted typedef SkNoncopyable INHERITED; }; diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index 98c0e00..2fff238 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -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, ©Info)); - 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 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(); } diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp index 1589ec0..31302d0 100644 --- a/src/core/SkPictureRecorder.cpp +++ b/src/core/SkPictureRecorder.cpp @@ -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 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 playback(SkPicture::FakeEndRecording(fPicture.get(), - *fPicture->fRecord, + *fCanvas, false)); playback->draw(*canvas, NULL); } -- 2.7.4