First step in pulling SkPicturePlayback & SkPictureRecord out of SkPicture
This CL begins the process of making SkPicturePlayback & SkPictureRecord independent of SkPicture. It just moves the PathHeap into SkPicture to get a feel for where all this is going to lead. Some items of note: SkTimedPicture (debugger/QT) should wind up being just an SkPicturePlayback-derived object. All the flattening & unflattening should migrate out of SkPicturePlayback and into SkPicture. SkPicture::initForPlayback should eventually become something just SkPictureRecorder::endRecording calls. SkPicture is passed into SkPicturePlayback's & SkPictureRecord's constructors. SkPicturePlayback only holds onto a "const SkPicture*". The SkPicturePlayback:: CreateFromStream & CreateFromBuffer methods pass a non-const SkPicture* down the call stack. BUG=skia:2315 R=reed@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/249453002 git-svn-id: http://skia.googlecode.com/svn/trunk@14341 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
dcbc360567
commit
8f831f262f
@ -159,20 +159,23 @@ void SkDebuggerGUI::showDeletes() {
|
||||
// offsets to individual commands.
|
||||
class SkTimedPicturePlayback : public SkPicturePlayback {
|
||||
public:
|
||||
static SkTimedPicturePlayback* CreateFromStream(SkStream* stream, const SkPictInfo& info,
|
||||
static SkTimedPicturePlayback* CreateFromStream(SkPicture* picture,
|
||||
SkStream* stream, const SkPictInfo& info,
|
||||
SkPicture::InstallPixelRefProc proc,
|
||||
const SkTDArray<bool>& deletedCommands) {
|
||||
// Mimics SkPicturePlayback::CreateFromStream
|
||||
SkAutoTDelete<SkTimedPicturePlayback> playback(SkNEW_ARGS(SkTimedPicturePlayback,
|
||||
(deletedCommands, info)));
|
||||
if (!playback->parseStream(stream, proc)) {
|
||||
(picture, deletedCommands, info)));
|
||||
if (!playback->parseStream(picture, stream, proc)) {
|
||||
return NULL; // we're invalid
|
||||
}
|
||||
return playback.detach();
|
||||
}
|
||||
|
||||
SkTimedPicturePlayback(const SkTDArray<bool>& deletedCommands, const SkPictInfo& info)
|
||||
: INHERITED(info)
|
||||
SkTimedPicturePlayback(SkPicture* picture,
|
||||
const SkTDArray<bool>& deletedCommands,
|
||||
const SkPictInfo& info)
|
||||
: INHERITED(picture, info)
|
||||
, fSkipCommands(deletedCommands)
|
||||
, fTot(0.0)
|
||||
, fCurCommand(0) {
|
||||
@ -268,19 +271,21 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkTimedPicturePlayback* playback;
|
||||
SkTimedPicture* newPict = SkNEW_ARGS(SkTimedPicture, (NULL, info.fWidth, info.fHeight));
|
||||
// Check to see if there is a playback to recreate.
|
||||
if (stream->readBool()) {
|
||||
playback = SkTimedPicturePlayback::CreateFromStream(stream, info, proc,
|
||||
SkTimedPicturePlayback* playback = SkTimedPicturePlayback::CreateFromStream(
|
||||
newPict, stream,
|
||||
info, proc,
|
||||
deletedCommands);
|
||||
if (NULL == playback) {
|
||||
SkDELETE(newPict);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
playback = NULL;
|
||||
newPict->fPlayback = playback;
|
||||
}
|
||||
|
||||
return SkNEW_ARGS(SkTimedPicture, (playback, info.fWidth, info.fHeight));
|
||||
return newPict;
|
||||
}
|
||||
|
||||
void resetTimes() { ((SkTimedPicturePlayback*) fPlayback)->resetTimes(); }
|
||||
|
@ -23,6 +23,7 @@ class SkBBoxHierarchy;
|
||||
class SkCanvas;
|
||||
class SkDrawPictureCallback;
|
||||
class SkData;
|
||||
class SkPathHeap;
|
||||
class SkPicturePlayback;
|
||||
class SkPictureRecord;
|
||||
class SkStream;
|
||||
@ -358,6 +359,23 @@ protected:
|
||||
SkCanvas* beginRecording(int width, int height, SkBBHFactory* factory, uint32_t recordFlags);
|
||||
|
||||
private:
|
||||
friend class SkPictureRecord;
|
||||
friend class SkPictureTester; // for unit testing
|
||||
|
||||
SkAutoTUnref<SkPathHeap> fPathHeap; // reference counted
|
||||
|
||||
const SkPath& getPath(int index) const;
|
||||
int addPathToHeap(const SkPath& path);
|
||||
|
||||
void flattenToBuffer(SkWriteBuffer& buffer) const;
|
||||
bool parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size);
|
||||
|
||||
static void WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size);
|
||||
static void WriteTagSize(SkWStream* stream, uint32_t tag, size_t size);
|
||||
|
||||
void initForPlayback() const;
|
||||
void dumpSize() const;
|
||||
|
||||
// An OperationList encapsulates a set of operation offsets into the picture byte
|
||||
// stream along with the CTMs needed for those operation.
|
||||
class OperationList : ::SkNoncopyable {
|
||||
|
@ -9,10 +9,11 @@
|
||||
#include "SkBBoxHierarchyRecord.h"
|
||||
#include "SkPictureStateTree.h"
|
||||
|
||||
SkBBoxHierarchyRecord::SkBBoxHierarchyRecord(const SkISize& size,
|
||||
SkBBoxHierarchyRecord::SkBBoxHierarchyRecord(SkPicture* picture,
|
||||
const SkISize& size,
|
||||
uint32_t recordFlags,
|
||||
SkBBoxHierarchy* h)
|
||||
: INHERITED(size, recordFlags) {
|
||||
: INHERITED(picture, size, recordFlags) {
|
||||
fStateTree = SkNEW(SkPictureStateTree);
|
||||
fBoundingHierarchy = h;
|
||||
fBoundingHierarchy->ref();
|
||||
|
@ -19,7 +19,8 @@
|
||||
class SkBBoxHierarchyRecord : public SkBBoxRecord, public SkBBoxHierarchyClient {
|
||||
public:
|
||||
/** This will take a ref of h */
|
||||
SkBBoxHierarchyRecord(const SkISize& size, uint32_t recordFlags, SkBBoxHierarchy* h);
|
||||
SkBBoxHierarchyRecord(SkPicture* picture, const SkISize& size,
|
||||
uint32_t recordFlags, SkBBoxHierarchy* h);
|
||||
|
||||
virtual void handleBBox(const SkRect& bounds) SK_OVERRIDE;
|
||||
|
||||
|
@ -19,7 +19,9 @@
|
||||
class SkBBoxRecord : public SkPictureRecord {
|
||||
public:
|
||||
|
||||
SkBBoxRecord(const SkISize& size, uint32_t recordFlags) : INHERITED(size, recordFlags) {}
|
||||
SkBBoxRecord(SkPicture* picture, const SkISize& size, uint32_t recordFlags)
|
||||
: INHERITED(picture, size, recordFlags) {
|
||||
}
|
||||
virtual ~SkBBoxRecord() { }
|
||||
|
||||
/**
|
||||
|
@ -31,6 +31,10 @@
|
||||
#include "GrContext.h"
|
||||
#endif
|
||||
|
||||
template <typename T> int SafeCount(const T* obj) {
|
||||
return obj ? obj->count() : 0;
|
||||
}
|
||||
|
||||
#define DUMP_BUFFER_SIZE 65536
|
||||
|
||||
//#define ENABLE_TIME_DRAW // dumps milliseconds for each draw
|
||||
@ -139,17 +143,48 @@ SkPicture::SkPicture(const SkPicture& src)
|
||||
it (since it is destructive, and we don't want to change src).
|
||||
*/
|
||||
if (src.fPlayback) {
|
||||
fPlayback = SkNEW_ARGS(SkPicturePlayback, (*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) {
|
||||
SkPictInfo info;
|
||||
this->createHeader(&info);
|
||||
// here we do a fake src.endRecording()
|
||||
fPlayback = SkNEW_ARGS(SkPicturePlayback, (*src.fRecord, info));
|
||||
fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *src.fRecord, info));
|
||||
} else {
|
||||
fPlayback = NULL;
|
||||
}
|
||||
|
||||
fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
|
||||
}
|
||||
|
||||
const SkPath& SkPicture::getPath(int index) const {
|
||||
return (*fPathHeap.get())[index];
|
||||
}
|
||||
|
||||
int SkPicture::addPathToHeap(const SkPath& path) {
|
||||
if (NULL == fPathHeap) {
|
||||
fPathHeap.reset(SkNEW(SkPathHeap));
|
||||
}
|
||||
#ifdef SK_DEDUP_PICTURE_PATHS
|
||||
return fPathHeap->insert(path);
|
||||
#else
|
||||
return fPathHeap->append(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkPicture::initForPlayback() const {
|
||||
// ensure that the paths bounds are pre-computed
|
||||
if (NULL != fPathHeap.get()) {
|
||||
for (int i = 0; i < fPathHeap->count(); i++) {
|
||||
(*fPathHeap.get())[i].updateBoundsCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkPicture::dumpSize() const {
|
||||
SkDebugf("--- picture size: paths=%d\n",
|
||||
SafeCount(fPathHeap.get()));
|
||||
}
|
||||
|
||||
SkPicture::~SkPicture() {
|
||||
@ -171,6 +206,7 @@ void SkPicture::swap(SkPicture& other) {
|
||||
SkTSwap(fAccelData, other.fAccelData);
|
||||
SkTSwap(fWidth, other.fWidth);
|
||||
SkTSwap(fHeight, other.fHeight);
|
||||
fPathHeap.swap(&other.fPathHeap);
|
||||
}
|
||||
|
||||
SkPicture* SkPicture::clone() const {
|
||||
@ -198,15 +234,17 @@ void SkPicture::clone(SkPicture* pictures, int count) const {
|
||||
it (since it is destructive, and we don't want to change src).
|
||||
*/
|
||||
if (fPlayback) {
|
||||
clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fPlayback, ©Info));
|
||||
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) {
|
||||
// here we do a fake src.endRecording()
|
||||
clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info, true));
|
||||
clone->fPlayback = SkNEW_ARGS(SkPicturePlayback, (clone, *fRecord, info, true));
|
||||
} else {
|
||||
clone->fPlayback = NULL;
|
||||
}
|
||||
|
||||
clone->fPathHeap.reset(SkSafeRef(fPathHeap.get()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,6 +304,7 @@ SkCanvas* SkPicture::beginRecording(int width, int height,
|
||||
}
|
||||
SkSafeUnref(fAccelData);
|
||||
SkSafeSetNull(fRecord);
|
||||
SkASSERT(NULL == fPathHeap);
|
||||
|
||||
this->needsNewGenID();
|
||||
|
||||
@ -277,12 +316,12 @@ SkCanvas* SkPicture::beginRecording(int width, int height,
|
||||
if (NULL != bbhFactory) {
|
||||
SkAutoTUnref<SkBBoxHierarchy> tree((*bbhFactory)(width, height));
|
||||
SkASSERT(NULL != tree);
|
||||
fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size,
|
||||
fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (this, size,
|
||||
recordingFlags|
|
||||
kOptimizeForClippedPlayback_RecordingFlag,
|
||||
tree.get()));
|
||||
} else {
|
||||
fRecord = SkNEW_ARGS(SkPictureRecord, (size, recordingFlags));
|
||||
fRecord = SkNEW_ARGS(SkPictureRecord, (this, size, recordingFlags));
|
||||
}
|
||||
fRecord->beginRecording();
|
||||
|
||||
@ -323,7 +362,7 @@ void SkPicture::endRecording() {
|
||||
fRecord->endRecording();
|
||||
SkPictInfo info;
|
||||
this->createHeader(&info);
|
||||
fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
|
||||
fPlayback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
|
||||
SkSafeSetNull(fRecord);
|
||||
}
|
||||
}
|
||||
@ -424,18 +463,20 @@ SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkPicturePlayback* playback;
|
||||
SkPicture* newPict = SkNEW_ARGS(SkPicture, (NULL, info.fWidth, info.fHeight));
|
||||
|
||||
// Check to see if there is a playback to recreate.
|
||||
if (stream->readBool()) {
|
||||
playback = SkPicturePlayback::CreateFromStream(stream, info, proc);
|
||||
SkPicturePlayback* playback = SkPicturePlayback::CreateFromStream(newPict, stream,
|
||||
info, proc);
|
||||
if (NULL == playback) {
|
||||
SkDELETE(newPict);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
playback = NULL;
|
||||
newPict->fPlayback = playback;
|
||||
}
|
||||
|
||||
return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
|
||||
return newPict;
|
||||
}
|
||||
|
||||
SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
|
||||
@ -445,18 +486,19 @@ SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkPicturePlayback* playback;
|
||||
SkPicture* newPict = SkNEW_ARGS(SkPicture, (NULL, info.fWidth, info.fHeight));
|
||||
|
||||
// Check to see if there is a playback to recreate.
|
||||
if (buffer.readBool()) {
|
||||
playback = SkPicturePlayback::CreateFromBuffer(buffer, info);
|
||||
SkPicturePlayback* playback = SkPicturePlayback::CreateFromBuffer(newPict, buffer, info);
|
||||
if (NULL == playback) {
|
||||
SkDELETE(newPict);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
playback = NULL;
|
||||
newPict->fPlayback = playback;
|
||||
}
|
||||
|
||||
return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
|
||||
return newPict;
|
||||
}
|
||||
|
||||
void SkPicture::createHeader(SkPictInfo* info) const {
|
||||
@ -484,7 +526,7 @@ void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
|
||||
SkPictInfo info;
|
||||
this->createHeader(&info);
|
||||
if (NULL == playback && fRecord) {
|
||||
playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
|
||||
playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
|
||||
}
|
||||
|
||||
stream->write(&info, sizeof(info));
|
||||
@ -500,13 +542,49 @@ void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
|
||||
}
|
||||
}
|
||||
|
||||
void SkPicture::WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
|
||||
buffer.writeUInt(tag);
|
||||
buffer.writeUInt(SkToU32(size));
|
||||
}
|
||||
|
||||
void SkPicture::WriteTagSize(SkWStream* stream, uint32_t tag, size_t size) {
|
||||
stream->write32(tag);
|
||||
stream->write32(SkToU32(size));
|
||||
}
|
||||
|
||||
bool SkPicture::parseBufferTag(SkReadBuffer& buffer,
|
||||
uint32_t tag,
|
||||
uint32_t size) {
|
||||
switch (tag) {
|
||||
case SK_PICT_PATH_BUFFER_TAG:
|
||||
if (size > 0) {
|
||||
fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// The tag was invalid.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // success
|
||||
}
|
||||
|
||||
void SkPicture::flattenToBuffer(SkWriteBuffer& buffer) const {
|
||||
int n;
|
||||
|
||||
if ((n = SafeCount(fPathHeap.get())) > 0) {
|
||||
WriteTagSize(buffer, SK_PICT_PATH_BUFFER_TAG, n);
|
||||
fPathHeap->flatten(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void SkPicture::flatten(SkWriteBuffer& buffer) const {
|
||||
SkPicturePlayback* playback = fPlayback;
|
||||
|
||||
SkPictInfo info;
|
||||
this->createHeader(&info);
|
||||
if (NULL == playback && fRecord) {
|
||||
playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord, info));
|
||||
playback = SkNEW_ARGS(SkPicturePlayback, (this, *fRecord, info));
|
||||
}
|
||||
|
||||
buffer.writeByteArray(&info, sizeof(info));
|
||||
|
@ -23,14 +23,18 @@ template <typename T> int SafeCount(const T* obj) {
|
||||
*/
|
||||
#define SPEW_CLIP_SKIPPINGx
|
||||
|
||||
SkPicturePlayback::SkPicturePlayback(const SkPictInfo& info) : fInfo(info) {
|
||||
SkPicturePlayback::SkPicturePlayback(const SkPicture* picture, const SkPictInfo& info)
|
||||
: fPicture(picture)
|
||||
, fInfo(info) {
|
||||
this->init();
|
||||
}
|
||||
|
||||
SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record,
|
||||
SkPicturePlayback::SkPicturePlayback(const SkPicture* picture,
|
||||
const SkPictureRecord& record,
|
||||
const SkPictInfo& info,
|
||||
bool deepCopy)
|
||||
: fInfo(info) {
|
||||
: fPicture(picture)
|
||||
, fInfo(info) {
|
||||
#ifdef SK_DEBUG_SIZE
|
||||
size_t overallBytes, bitmapBytes, matricesBytes,
|
||||
paintBytes, pathBytes, pictureBytes, regionBytes;
|
||||
@ -95,14 +99,8 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record,
|
||||
fPaints = record.fPaints.unflattenToArray();
|
||||
|
||||
fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap));
|
||||
fPathHeap.reset(SkSafeRef(record.fPathHeap));
|
||||
|
||||
// ensure that the paths bounds are pre-computed
|
||||
if (fPathHeap.get()) {
|
||||
for (int i = 0; i < fPathHeap->count(); i++) {
|
||||
(*fPathHeap)[i].updateBoundsCache();
|
||||
}
|
||||
}
|
||||
picture->initForPlayback();
|
||||
|
||||
const SkTDArray<SkPicture* >& pictures = record.getPictureRefs();
|
||||
fPictureCount = pictures.count();
|
||||
@ -160,12 +158,13 @@ static bool needs_deep_copy(const SkPaint& paint) {
|
||||
paint.getImageFilter();
|
||||
}
|
||||
|
||||
SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo)
|
||||
: fInfo(src.fInfo) {
|
||||
SkPicturePlayback::SkPicturePlayback(const SkPicture* picture, const SkPicturePlayback& src,
|
||||
SkPictCopyInfo* deepCopyInfo)
|
||||
: fPicture(picture)
|
||||
, fInfo(src.fInfo) {
|
||||
this->init();
|
||||
|
||||
fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
|
||||
fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
|
||||
|
||||
fOpData = SkSafeRef(src.fOpData);
|
||||
|
||||
@ -286,11 +285,11 @@ SkPicturePlayback::~SkPicturePlayback() {
|
||||
}
|
||||
|
||||
void SkPicturePlayback::dumpSize() const {
|
||||
SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] paints=%d [%d] paths=%d\n",
|
||||
SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] paints=%d [%d]\n",
|
||||
fOpData->size(),
|
||||
SafeCount(fBitmaps), SafeCount(fBitmaps) * sizeof(SkBitmap),
|
||||
SafeCount(fPaints), SafeCount(fPaints) * sizeof(SkPaint),
|
||||
SafeCount(fPathHeap.get()));
|
||||
SafeCount(fPaints), SafeCount(fPaints) * sizeof(SkPaint));
|
||||
fPicture->dumpSize();
|
||||
}
|
||||
|
||||
bool SkPicturePlayback::containsBitmaps() const {
|
||||
@ -310,16 +309,6 @@ bool SkPicturePlayback::containsBitmaps() const {
|
||||
|
||||
#include "SkStream.h"
|
||||
|
||||
static void write_tag_size(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
|
||||
buffer.writeUInt(tag);
|
||||
buffer.writeUInt(SkToU32(size));
|
||||
}
|
||||
|
||||
static void write_tag_size(SkWStream* stream, uint32_t tag, size_t size) {
|
||||
stream->write32(tag);
|
||||
stream->write32(SkToU32(size));
|
||||
}
|
||||
|
||||
static size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
|
||||
size_t size = 4; // for 'count'
|
||||
|
||||
@ -337,7 +326,7 @@ static size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
|
||||
return size;
|
||||
}
|
||||
|
||||
static void write_factories(SkWStream* stream, const SkFactorySet& rec) {
|
||||
void SkPicturePlayback::WriteFactories(SkWStream* stream, const SkFactorySet& rec) {
|
||||
int count = rec.count();
|
||||
|
||||
SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
|
||||
@ -347,7 +336,7 @@ static void write_factories(SkWStream* stream, const SkFactorySet& rec) {
|
||||
size_t size = compute_chunk_size(array, count);
|
||||
|
||||
// TODO: write_tag_size should really take a size_t
|
||||
write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
|
||||
SkPicture::WriteTagSize(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
|
||||
SkDEBUGCODE(size_t start = stream->bytesWritten());
|
||||
stream->write32(count);
|
||||
|
||||
@ -366,10 +355,10 @@ static void write_factories(SkWStream* stream, const SkFactorySet& rec) {
|
||||
SkASSERT(size == (stream->bytesWritten() - start));
|
||||
}
|
||||
|
||||
static void write_typefaces(SkWStream* stream, const SkRefCntSet& rec) {
|
||||
void SkPicturePlayback::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
|
||||
int count = rec.count();
|
||||
|
||||
write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count);
|
||||
SkPicture::WriteTagSize(stream, SK_PICT_TYPEFACE_TAG, count);
|
||||
|
||||
SkAutoSTMalloc<16, SkTypeface*> storage(count);
|
||||
SkTypeface** array = (SkTypeface**)storage.get();
|
||||
@ -384,32 +373,29 @@ void SkPicturePlayback::flattenToBuffer(SkWriteBuffer& buffer) const {
|
||||
int i, n;
|
||||
|
||||
if ((n = SafeCount(fBitmaps)) > 0) {
|
||||
write_tag_size(buffer, SK_PICT_BITMAP_BUFFER_TAG, n);
|
||||
SkPicture::WriteTagSize(buffer, SK_PICT_BITMAP_BUFFER_TAG, n);
|
||||
for (i = 0; i < n; i++) {
|
||||
buffer.writeBitmap((*fBitmaps)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((n = SafeCount(fPaints)) > 0) {
|
||||
write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
|
||||
SkPicture::WriteTagSize(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
|
||||
for (i = 0; i < n; i++) {
|
||||
buffer.writePaint((*fPaints)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((n = SafeCount(fPathHeap.get())) > 0) {
|
||||
write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n);
|
||||
fPathHeap->flatten(buffer);
|
||||
}
|
||||
fPicture->flattenToBuffer(buffer);
|
||||
}
|
||||
|
||||
void SkPicturePlayback::serialize(SkWStream* stream,
|
||||
SkPicture::EncodeBitmap encoder) const {
|
||||
write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size());
|
||||
SkPicture::WriteTagSize(stream, SK_PICT_READER_TAG, fOpData->size());
|
||||
stream->write(fOpData->bytes(), fOpData->size());
|
||||
|
||||
if (fPictureCount > 0) {
|
||||
write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount);
|
||||
SkPicture::WriteTagSize(stream, SK_PICT_PICTURE_TAG, fPictureCount);
|
||||
for (int i = 0; i < fPictureCount; i++) {
|
||||
fPictureRefs[i]->serialize(stream, encoder);
|
||||
}
|
||||
@ -431,10 +417,10 @@ void SkPicturePlayback::serialize(SkWStream* stream,
|
||||
// We have to write these two sets into the stream *before* we write
|
||||
// the buffer, since parsing that buffer will require that we already
|
||||
// have these sets available to use.
|
||||
write_factories(stream, factSet);
|
||||
write_typefaces(stream, typefaceSet);
|
||||
WriteFactories(stream, factSet);
|
||||
WriteTypefaces(stream, typefaceSet);
|
||||
|
||||
write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
|
||||
SkPicture::WriteTagSize(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
|
||||
buffer.writeToStream(stream);
|
||||
}
|
||||
|
||||
@ -442,11 +428,11 @@ void SkPicturePlayback::serialize(SkWStream* stream,
|
||||
}
|
||||
|
||||
void SkPicturePlayback::flatten(SkWriteBuffer& buffer) const {
|
||||
write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size());
|
||||
SkPicture::WriteTagSize(buffer, SK_PICT_READER_TAG, fOpData->size());
|
||||
buffer.writeByteArray(fOpData->bytes(), fOpData->size());
|
||||
|
||||
if (fPictureCount > 0) {
|
||||
write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
|
||||
SkPicture::WriteTagSize(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
|
||||
for (int i = 0; i < fPictureCount; i++) {
|
||||
fPictureRefs[i]->flatten(buffer);
|
||||
}
|
||||
@ -482,7 +468,8 @@ static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
|
||||
return rbMask;
|
||||
}
|
||||
|
||||
bool SkPicturePlayback::parseStreamTag(SkStream* stream,
|
||||
bool SkPicturePlayback::parseStreamTag(SkPicture* picture,
|
||||
SkStream* stream,
|
||||
uint32_t tag,
|
||||
uint32_t size,
|
||||
SkPicture::InstallPixelRefProc proc) {
|
||||
@ -584,7 +571,7 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream,
|
||||
while (!buffer.eof()) {
|
||||
tag = buffer.readUInt();
|
||||
size = buffer.readUInt();
|
||||
if (!this->parseBufferTag(buffer, tag, size)) {
|
||||
if (!this->parseBufferTag(picture, buffer, tag, size)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -594,7 +581,8 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream,
|
||||
return true; // success
|
||||
}
|
||||
|
||||
bool SkPicturePlayback::parseBufferTag(SkReadBuffer& buffer,
|
||||
bool SkPicturePlayback::parseBufferTag(SkPicture* picture,
|
||||
SkReadBuffer& buffer,
|
||||
uint32_t tag, uint32_t size) {
|
||||
switch (tag) {
|
||||
case SK_PICT_BITMAP_BUFFER_TAG: {
|
||||
@ -614,9 +602,7 @@ bool SkPicturePlayback::parseBufferTag(SkReadBuffer& buffer,
|
||||
}
|
||||
} break;
|
||||
case SK_PICT_PATH_BUFFER_TAG:
|
||||
if (size > 0) {
|
||||
fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
|
||||
}
|
||||
picture->parseBufferTag(buffer, tag, size);
|
||||
break;
|
||||
case SK_PICT_READER_TAG: {
|
||||
SkAutoMalloc storage(size);
|
||||
@ -660,29 +646,32 @@ bool SkPicturePlayback::parseBufferTag(SkReadBuffer& buffer,
|
||||
return true; // success
|
||||
}
|
||||
|
||||
SkPicturePlayback* SkPicturePlayback::CreateFromStream(SkStream* stream,
|
||||
SkPicturePlayback* SkPicturePlayback::CreateFromStream(SkPicture* picture,
|
||||
SkStream* stream,
|
||||
const SkPictInfo& info,
|
||||
SkPicture::InstallPixelRefProc proc) {
|
||||
SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (info)));
|
||||
SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (picture, info)));
|
||||
|
||||
if (!playback->parseStream(stream, proc)) {
|
||||
if (!playback->parseStream(picture, stream, proc)) {
|
||||
return NULL;
|
||||
}
|
||||
return playback.detach();
|
||||
}
|
||||
|
||||
SkPicturePlayback* SkPicturePlayback::CreateFromBuffer(SkReadBuffer& buffer,
|
||||
SkPicturePlayback* SkPicturePlayback::CreateFromBuffer(SkPicture* picture,
|
||||
SkReadBuffer& buffer,
|
||||
const SkPictInfo& info) {
|
||||
SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (info)));
|
||||
SkAutoTDelete<SkPicturePlayback> playback(SkNEW_ARGS(SkPicturePlayback, (picture, info)));
|
||||
buffer.setPictureVersion(info.fVersion);
|
||||
|
||||
if (!playback->parseBuffer(buffer)) {
|
||||
if (!playback->parseBuffer(picture, buffer)) {
|
||||
return NULL;
|
||||
}
|
||||
return playback.detach();
|
||||
}
|
||||
|
||||
bool SkPicturePlayback::parseStream(SkStream* stream,
|
||||
bool SkPicturePlayback::parseStream(SkPicture* picture,
|
||||
SkStream* stream,
|
||||
SkPicture::InstallPixelRefProc proc) {
|
||||
for (;;) {
|
||||
uint32_t tag = stream->readU32();
|
||||
@ -691,14 +680,14 @@ bool SkPicturePlayback::parseStream(SkStream* stream,
|
||||
}
|
||||
|
||||
uint32_t size = stream->readU32();
|
||||
if (!this->parseStreamTag(stream, tag, size, proc)) {
|
||||
if (!this->parseStreamTag(picture, stream, tag, size, proc)) {
|
||||
return false; // we're invalid
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkPicturePlayback::parseBuffer(SkReadBuffer& buffer) {
|
||||
bool SkPicturePlayback::parseBuffer(SkPicture* picture, SkReadBuffer& buffer) {
|
||||
for (;;) {
|
||||
uint32_t tag = buffer.readUInt();
|
||||
if (SK_PICT_EOF_TAG == tag) {
|
||||
@ -706,7 +695,7 @@ bool SkPicturePlayback::parseBuffer(SkReadBuffer& buffer) {
|
||||
}
|
||||
|
||||
uint32_t size = buffer.readUInt();
|
||||
if (!this->parseBufferTag(buffer, tag, size)) {
|
||||
if (!this->parseBufferTag(picture, buffer, tag, size)) {
|
||||
return false; // we're invalid
|
||||
}
|
||||
}
|
||||
|
@ -75,12 +75,17 @@ struct SkPictCopyInfo {
|
||||
|
||||
class SkPicturePlayback {
|
||||
public:
|
||||
SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL);
|
||||
SkPicturePlayback(const SkPictureRecord& record, const SkPictInfo&, bool deepCopy = false);
|
||||
static SkPicturePlayback* CreateFromStream(SkStream*,
|
||||
SkPicturePlayback(const SkPicture* picture, const SkPicturePlayback& src,
|
||||
SkPictCopyInfo* deepCopyInfo = NULL);
|
||||
SkPicturePlayback(const SkPicture* picture, const SkPictureRecord& record, const SkPictInfo&,
|
||||
bool deepCopy = false);
|
||||
static SkPicturePlayback* CreateFromStream(SkPicture* picture,
|
||||
SkStream*,
|
||||
const SkPictInfo&,
|
||||
SkPicture::InstallPixelRefProc);
|
||||
static SkPicturePlayback* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
|
||||
static SkPicturePlayback* CreateFromBuffer(SkPicture* picture,
|
||||
SkReadBuffer&,
|
||||
const SkPictInfo&);
|
||||
|
||||
virtual ~SkPicturePlayback();
|
||||
|
||||
@ -105,10 +110,10 @@ public:
|
||||
void resetOpID() { fCurOffset = 0; }
|
||||
|
||||
protected:
|
||||
explicit SkPicturePlayback(const SkPictInfo& info);
|
||||
explicit SkPicturePlayback(const SkPicture* picture, const SkPictInfo& info);
|
||||
|
||||
bool parseStream(SkStream*, SkPicture::InstallPixelRefProc);
|
||||
bool parseBuffer(SkReadBuffer& buffer);
|
||||
bool parseStream(SkPicture* picture, SkStream*, SkPicture::InstallPixelRefProc);
|
||||
bool parseBuffer(SkPicture* picture, SkReadBuffer& buffer);
|
||||
#ifdef SK_DEVELOPER
|
||||
virtual bool preDraw(int opIndex, int type);
|
||||
virtual void postDraw(int opIndex);
|
||||
@ -139,7 +144,7 @@ private:
|
||||
}
|
||||
|
||||
const SkPath& getPath(SkReader32& reader) {
|
||||
return (*fPathHeap)[reader.readInt() - 1];
|
||||
return fPicture->getPath(reader.readInt() - 1);
|
||||
}
|
||||
|
||||
SkPicture& getPicture(SkReader32& reader) {
|
||||
@ -215,17 +220,20 @@ public:
|
||||
#endif
|
||||
|
||||
private: // these help us with reading/writing
|
||||
bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc);
|
||||
bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
|
||||
bool parseStreamTag(SkPicture* picture, SkStream*, uint32_t tag, uint32_t size,
|
||||
SkPicture::InstallPixelRefProc);
|
||||
bool parseBufferTag(SkPicture* picture, SkReadBuffer&, uint32_t tag, uint32_t size);
|
||||
void flattenToBuffer(SkWriteBuffer&) const;
|
||||
|
||||
private:
|
||||
// The picture that owns this SkPicturePlayback object
|
||||
const SkPicture* fPicture;
|
||||
|
||||
// Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
|
||||
// bitmap allows playback to draw nothing and move on.
|
||||
SkBitmap fBadBitmap;
|
||||
|
||||
SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
|
||||
SkAutoTUnref<SkPathHeap> fPathHeap;
|
||||
|
||||
SkTRefArray<SkBitmap>* fBitmaps;
|
||||
SkTRefArray<SkPaint>* fPaints;
|
||||
@ -269,6 +277,9 @@ private:
|
||||
|
||||
const SkPictInfo fInfo;
|
||||
|
||||
static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
|
||||
static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec);
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
SkMutex fDrawMutex;
|
||||
bool fAbortCurrentPlayback;
|
||||
|
@ -27,7 +27,7 @@ static const uint32_t kSaveSize = 2 * kUInt32Size;
|
||||
static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size;
|
||||
static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect);
|
||||
|
||||
SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags)
|
||||
SkPictureRecord::SkPictureRecord(SkPicture* picture, const SkISize& dimensions, uint32_t flags)
|
||||
: INHERITED(dimensions.width(), dimensions.height())
|
||||
, fBoundingHierarchy(NULL)
|
||||
, fStateTree(NULL)
|
||||
@ -40,9 +40,9 @@ SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags)
|
||||
fPointWrites = fRectWrites = fTextWrites = 0;
|
||||
#endif
|
||||
|
||||
fPicture = picture;
|
||||
fBitmapHeap = SkNEW(SkBitmapHeap);
|
||||
fFlattenableHeap.setBitmapStorage(fBitmapHeap);
|
||||
fPathHeap = NULL; // lazy allocate
|
||||
|
||||
#ifndef SK_COLLAPSE_MATRIX_CLIP_STATE
|
||||
fFirstSavedLayerIndex = kNoSavedLayerIndex;
|
||||
@ -57,7 +57,6 @@ SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags)
|
||||
|
||||
SkPictureRecord::~SkPictureRecord() {
|
||||
SkSafeUnref(fBitmapHeap);
|
||||
SkSafeUnref(fPathHeap);
|
||||
SkSafeUnref(fBoundingHierarchy);
|
||||
SkSafeUnref(fStateTree);
|
||||
fFlattenableHeap.setBitmapStorage(NULL);
|
||||
@ -1590,14 +1589,7 @@ void SkPictureRecord::addFlatPaint(const SkFlatData* flatPaint) {
|
||||
}
|
||||
|
||||
int SkPictureRecord::addPathToHeap(const SkPath& path) {
|
||||
if (NULL == fPathHeap) {
|
||||
fPathHeap = SkNEW(SkPathHeap);
|
||||
}
|
||||
#ifdef SK_DEDUP_PICTURE_PATHS
|
||||
return fPathHeap->insert(path);
|
||||
#else
|
||||
return fPathHeap->append(path);
|
||||
#endif
|
||||
return fPicture->addPathToHeap(path);
|
||||
}
|
||||
|
||||
void SkPictureRecord::addPath(const SkPath& path) {
|
||||
|
@ -33,7 +33,7 @@ class SkPictureStateTree;
|
||||
|
||||
class SkPictureRecord : public SkCanvas {
|
||||
public:
|
||||
SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags);
|
||||
SkPictureRecord(SkPicture* picture, const SkISize& dimensions, uint32_t recordFlags);
|
||||
virtual ~SkPictureRecord();
|
||||
|
||||
virtual void clear(SkColor) SK_OVERRIDE;
|
||||
@ -279,6 +279,9 @@ protected:
|
||||
SkBitmapHeap* fBitmapHeap;
|
||||
|
||||
private:
|
||||
// The owning SkPicture
|
||||
SkPicture* fPicture;
|
||||
|
||||
friend class MatrixClipState; // for access to *Impl methods
|
||||
friend class SkMatrixClipStateMgr; // for access to *Impl methods
|
||||
|
||||
@ -286,7 +289,6 @@ private:
|
||||
|
||||
SkPaintDictionary fPaints;
|
||||
|
||||
SkPathHeap* fPathHeap; // reference counted
|
||||
SkWriter32 fWriter;
|
||||
|
||||
// we ref each item in these arrays
|
||||
|
@ -695,8 +695,8 @@ private:
|
||||
testStep->assertMessage());
|
||||
}
|
||||
REPORTER_ASSERT_MESSAGE(reporter,
|
||||
!referenceRecord->fPathHeap ==
|
||||
!testRecord->fPathHeap,
|
||||
!referenceRecord->fPicture->fPathHeap ==
|
||||
!testRecord->fPicture->fPathHeap,
|
||||
testStep->assertMessage());
|
||||
// The following tests are commented out because they currently
|
||||
// fail. Issue: http://code.google.com/p/skia/issues/detail?id=507
|
||||
|
Loading…
Reference in New Issue
Block a user