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;
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.
*/
// 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;
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;
};
#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.
/** 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
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
void partialReplay(SkCanvas* canvas) const;
#endif
- SkAutoTUnref<SkPicture> fPicture;
+ SkAutoTUnref<SkPicture> fPicture;
+ SkPictureRecord* fCanvas; // ref counted
typedef SkNoncopyable INHERITED;
};
SkPicture::SkPicture()
: fAccelData(NULL) {
this->needsNewGenID();
- fRecord = NULL;
fPlayback = NULL;
fWidth = fHeight = 0;
}
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
*/
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;
}
}
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);
clone->needsNewGenID();
clone->fWidth = fWidth;
clone->fHeight = fHeight;
- SkSafeSetNull(clone->fRecord);
SkDELETE(clone->fPlayback);
clone->fContentInfo.set(fContentInfo);
}
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;
}
///////////////////////////////////////////////////////////////////////////////
-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);
}
}
void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) const {
- SkASSERT(NULL != fPlayback && NULL == fRecord);
+ SkASSERT(NULL != fPlayback);
if (NULL != fPlayback) {
fPlayback->draw(*surface, callback);
}
SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height)
: fPlayback(playback)
- , fRecord(NULL)
, fWidth(width)
, fHeight(height)
, fAccelData(NULL) {
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));
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));
}
uint32_t SkPicture::uniqueID() const {
- if (NULL != fRecord) {
- SkASSERT(NULL == fPlayback);
- return SK_InvalidGenID;
- }
-
if (SK_InvalidGenID == fUniqueID) {
fUniqueID = next_picture_generation_id();
}
* 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
return;
}
- SkASSERT(NULL != fPicture->fRecord);
+ SkASSERT(NULL != fCanvas);
SkAutoTDelete<SkPicturePlayback> playback(SkPicture::FakeEndRecording(fPicture.get(),
- *fPicture->fRecord,
+ *fCanvas,
false));
playback->draw(*canvas, NULL);
}