From 5a63f24558b84610e93c6d7b67d849b5ab435e51 Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Tue, 4 Feb 2014 20:07:50 +0000 Subject: Update SkPictureRecord to allow some ops to be written separately https://codereview.chromium.org/153883002/ git-svn-id: http://skia.googlecode.com/svn/trunk@13311 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/core/SkPictureRecord.cpp | 146 ++++++++++++++++++++++++++++--------------- src/core/SkPictureRecord.h | 19 +++++- 2 files changed, 111 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 4279ac3c2c..463c91517d 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -27,13 +27,13 @@ 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(uint32_t flags, SkBaseDevice* device) : - INHERITED(device), - fBoundingHierarchy(NULL), - fStateTree(NULL), - fFlattenableHeap(HEAP_BLOCK_SIZE), - fPaints(&fFlattenableHeap), - fRecordFlags(flags) { +SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device) + : INHERITED(device) + , fBoundingHierarchy(NULL) + , fStateTree(NULL) + , fFlattenableHeap(HEAP_BLOCK_SIZE) + , fPaints(&fFlattenableHeap) + , fRecordFlags(flags) { #ifdef SK_DEBUG_SIZE fPointBytes = fRectBytes = fTextBytes = 0; fPointWrites = fRectWrites = fTextWrites = 0; @@ -141,14 +141,17 @@ int SkPictureRecord::save(SaveFlags flags) { // record the offset to us, making it non-positive to distinguish a save // from a clip entry. fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); + this->recordSave(flags); + return this->INHERITED::save(flags); +} +void SkPictureRecord::recordSave(SaveFlags flags) { // op + flags uint32_t size = kSaveSize; size_t initialOffset = this->addDraw(SAVE, &size); addInt(flags); this->validate(initialOffset, size); - return this->INHERITED::save(flags); } int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, @@ -156,7 +159,24 @@ int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, // record the offset to us, making it non-positive to distinguish a save // from a clip entry. fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); + this->recordSaveLayer(bounds, paint, flags); + if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { + fFirstSavedLayerIndex = fRestoreOffsetStack.count(); + } + /* Don't actually call INHERITED::saveLayer, because that will try to allocate + an offscreen device (potentially very big) which we don't actually need + at this time (and may not be able to afford since during record our + clip starts out the size of the picture, which is often much larger + than the size of the actual device we'll use during playback). + */ + int count = this->INHERITED::save(flags); + this->clipRectBounds(bounds, flags, NULL); + return count; +} + +void SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) { // op + bool for 'bounds' uint32_t size = 2 * kUInt32Size; if (NULL != bounds) { @@ -173,20 +193,7 @@ int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, addPaintPtr(paint); addInt(flags); - if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { - fFirstSavedLayerIndex = fRestoreOffsetStack.count(); - } - this->validate(initialOffset, size); - /* Don't actually call saveLayer, because that will try to allocate an - offscreen device (potentially very big) which we don't actually need - at this time (and may not be able to afford since during record our - clip starts out the size of the picture, which is often much larger - than the size of the actual device we'll use during playback). - */ - int count = this->INHERITED::save(flags); - this->clipRectBounds(bounds, flags, NULL); - return count; } bool SkPictureRecord::isDrawingToLayer() const { @@ -321,7 +328,6 @@ static bool remove_save_layer1(SkWriter32* writer, int32_t offset, return false; } - return merge_savelayer_paint_into_drawbitmp(writer, paintDict, result[0], result[1]); } @@ -601,17 +607,22 @@ void SkPictureRecord::restore() { if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) || SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { // No optimization fired so add the RESTORE - fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten()); - size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code - initialOffset = this->addDraw(RESTORE, &size); + this->recordRestore(); } fRestoreOffsetStack.pop(); - this->validate(initialOffset, size); return this->INHERITED::restore(); } +void SkPictureRecord::recordRestore() { + uint32_t initialOffset, size; + fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten()); + size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code + initialOffset = this->addDraw(RESTORE, &size); + this->validate(initialOffset, size); +} + bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { // op + dx + dy uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); @@ -652,13 +663,17 @@ bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { } bool SkPictureRecord::concat(const SkMatrix& matrix) { + this->recordConcat(matrix); + return this->INHERITED::concat(matrix); +} + +void SkPictureRecord::recordConcat(const SkMatrix& matrix) { this->validate(fWriter.bytesWritten(), 0); // op + matrix uint32_t size = kUInt32Size + matrix.writeToMemory(NULL); size_t initialOffset = this->addDraw(CONCAT, &size); addMatrix(matrix); this->validate(initialOffset, size); - return this->INHERITED::concat(matrix); } void SkPictureRecord::setMatrix(const SkMatrix& matrix) { @@ -715,9 +730,9 @@ void SkPictureRecord::endRecording() { this->restoreToCount(fInitialSaveCount); } -void SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { +int SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { if (fRestoreOffsetStack.isEmpty()) { - return; + return -1; } // The RestoreOffset field is initially filled with a placeholder @@ -742,9 +757,16 @@ void SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { size_t offset = fWriter.bytesWritten(); addInt(prevOffset); fRestoreOffsetStack.top() = offset; + return offset; } bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { + this->recordClipRect(rect, op, doAA); + return this->INHERITED::clipRect(rect, op, doAA); +} + +int SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { + // id + rect + clip params uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; // recordRestoreOffsetPlaceholder doesn't always write an offset @@ -752,13 +774,14 @@ bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { // + restore offset size += kUInt32Size; } + size_t initialOffset = this->addDraw(CLIP_RECT, &size); addRect(rect); addInt(ClipParams_pack(op, doAA)); - recordRestoreOffsetPlaceholder(op); + int offset = this->recordRestoreOffsetPlaceholder(op); this->validate(initialOffset, size); - return this->INHERITED::clipRect(rect, op, doAA); + return offset; } bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { @@ -766,6 +789,16 @@ bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); } + this->recordClipRRect(rrect, op, doAA); + if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { + return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); + } else { + return this->INHERITED::clipRRect(rrect, op, doAA); + } +} + +int SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { + // op + rrect + clip params uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; // recordRestoreOffsetPlaceholder doesn't always write an offset @@ -776,15 +809,10 @@ bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA size_t initialOffset = this->addDraw(CLIP_RRECT, &size); addRRect(rrect); addInt(ClipParams_pack(op, doAA)); - recordRestoreOffsetPlaceholder(op); + int offset = recordRestoreOffsetPlaceholder(op); this->validate(initialOffset, size); - - if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { - return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); - } else { - return this->INHERITED::clipRRect(rrect, op, doAA); - } + return offset; } bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { @@ -794,6 +822,19 @@ bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { return this->clipRect(r, op, doAA); } + int pathID = this->addPathToHeap(path); + this->recordClipPath(pathID, op, doAA); + + if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { + return this->updateClipConservativelyUsingBounds(path.getBounds(), op, + path.isInverseFillType()); + } else { + return this->INHERITED::clipPath(path, op, doAA); + } +} + +int SkPictureRecord::recordClipPath(int pathID, SkRegion::Op op, bool doAA) { + // op + path index + clip params uint32_t size = 3 * kUInt32Size; // recordRestoreOffsetPlaceholder doesn't always write an offset @@ -802,21 +843,20 @@ bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { size += kUInt32Size; } size_t initialOffset = this->addDraw(CLIP_PATH, &size); - addPath(path); + addInt(pathID); addInt(ClipParams_pack(op, doAA)); - recordRestoreOffsetPlaceholder(op); + int offset = recordRestoreOffsetPlaceholder(op); this->validate(initialOffset, size); - - if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { - return this->updateClipConservativelyUsingBounds(path.getBounds(), op, - path.isInverseFillType()); - } else { - return this->INHERITED::clipPath(path, op, doAA); - } + return offset; } bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { + this->recordClipRegion(region, op); + return this->INHERITED::clipRegion(region, op); +} + +int SkPictureRecord::recordClipRegion(const SkRegion& region, SkRegion::Op op) { // op + clip params + region uint32_t size = 2 * kUInt32Size + region.writeToMemory(NULL); // recordRestoreOffsetPlaceholder doesn't always write an offset @@ -827,10 +867,10 @@ bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { size_t initialOffset = this->addDraw(CLIP_REGION, &size); addRegion(region); addInt(ClipParams_pack(op, false)); - recordRestoreOffsetPlaceholder(op); + int offset = recordRestoreOffsetPlaceholder(op); this->validate(initialOffset, size); - return this->INHERITED::clipRegion(region, op); + return offset; } void SkPictureRecord::clear(SkColor color) { @@ -1307,11 +1347,15 @@ void SkPictureRecord::addFlatPaint(const SkFlatData* flatPaint) { this->addInt(index); } -void SkPictureRecord::addPath(const SkPath& path) { +int SkPictureRecord::addPathToHeap(const SkPath& path) { if (NULL == fPathHeap) { fPathHeap = SkNEW(SkPathHeap); } - addInt(fPathHeap->append(path)); + return fPathHeap->append(path); +} + +void SkPictureRecord::addPath(const SkPath& path) { + addInt(this->addPathToHeap(path)); } void SkPictureRecord::addPicture(SkPicture& picture) { diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index d09891601b..51ae0b29ec 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -108,9 +108,8 @@ public: private: void handleOptimization(int opt); - void recordRestoreOffsetPlaceholder(SkRegion::Op); - void fillRestoreOffsetPlaceholdersForCurrentStackLevel( - uint32_t restoreOffset); + int recordRestoreOffsetPlaceholder(SkRegion::Op); + void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset); SkTDArray fRestoreOffsetStack; int fFirstSavedLayerIndex; @@ -237,6 +236,20 @@ protected: const SkScalar xpos[], SkScalar constY, const SkPaint& paint, const SkFlatData* flatPaintData); + int addPathToHeap(const SkPath& path); // does not write to ops stream + + // These entry points allow the writing of matrices, clips, saves & + // restores to be deferred (e.g., if the MC state is being collapsed and + // only written out as needed). + void recordConcat(const SkMatrix& matrix); + int recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA); + int recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA); + int recordClipPath(int pathID, SkRegion::Op op, bool doAA); + int recordClipRegion(const SkRegion& region, SkRegion::Op op); + void recordSave(SaveFlags flags); + void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags); + void recordRestore(); + // These are set to NULL in our constructor, but may be changed by // subclasses, in which case they will be SkSafeUnref'd in our destructor. SkBBoxHierarchy* fBoundingHierarchy; -- cgit v1.2.3