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
This commit is contained in:
parent
52e4f413ff
commit
643b8bd661
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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<SkPicture> fPicture;
|
||||
SkAutoTUnref<SkPicture> fPicture;
|
||||
SkPictureRecord* fCanvas; // ref counted
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
@ -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<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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user