| Index: src/core/SkPictureRecord.cpp
|
| diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
|
| index 042e6a39cb9602bf929b8cfaed6e7bbd57c5353a..5b6461084c9c8afe8d463a1933d52d504c7ca1ef 100644
|
| --- a/src/core/SkPictureRecord.cpp
|
| +++ b/src/core/SkPictureRecord.cpp
|
| @@ -76,6 +76,8 @@ static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) {
|
| 0, // CLIP_REGION - no paint
|
| 0, // CLIP_RECT - no paint
|
| 0, // CLIP_RRECT - no paint
|
| + 0, // PUSH_CULL - no paint
|
| + 0, // POP_CULL - no paint
|
| 0, // CONCAT - no paint
|
| 1, // DRAW_BITMAP - right after op code
|
| 1, // DRAW_BITMAP_MATRIX - right after op code
|
| @@ -1530,6 +1532,60 @@ void SkPictureRecord::endCommentGroup() {
|
| this->validate(initialOffset, size);
|
| }
|
|
|
| +// [op/size] [rect] [skip offset]
|
| +static const uint32_t kPushCullOpSize = 2 * kUInt32Size + sizeof(SkRect);
|
| +void SkPictureRecord::onPushCull(const SkRect& cullRect) {
|
| + // Skip identical cull rects.
|
| + if (!fCullOffsetStack.isEmpty()) {
|
| + const SkRect& prevCull = fWriter.readTAt<SkRect>(fCullOffsetStack.top() - sizeof(SkRect));
|
| + if (prevCull == cullRect) {
|
| + // Skipped culls are tracked on the stack, but they point to the previous offset.
|
| + fCullOffsetStack.push(fCullOffsetStack.top());
|
| + return;
|
| + }
|
| + }
|
| +
|
| + uint32_t size = kPushCullOpSize;
|
| + size_t initialOffset = this->addDraw(PUSH_CULL, &size);
|
| + // PUSH_CULL's size should stay constant (used to rewind).
|
| + SkASSERT(size == kPushCullOpSize);
|
| +
|
| + addRect(cullRect);
|
| + fCullOffsetStack.push(fWriter.bytesWritten());
|
| + addInt(0);
|
| + this->validate(initialOffset, size);
|
| +}
|
| +
|
| +void SkPictureRecord::onPopCull() {
|
| + SkASSERT(!fCullOffsetStack.isEmpty());
|
| +
|
| + uint32_t cullSkipOffset = fCullOffsetStack.top();
|
| + fCullOffsetStack.pop();
|
| +
|
| + // Skipped push, do the same for pop.
|
| + if (!fCullOffsetStack.isEmpty() && cullSkipOffset == fCullOffsetStack.top()) {
|
| + return;
|
| + }
|
| +
|
| + // Collapse empty push/pop pairs.
|
| + if ((size_t)(cullSkipOffset + kUInt32Size) == fWriter.bytesWritten()) {
|
| + SkASSERT(fWriter.bytesWritten() >= kPushCullOpSize);
|
| + SkASSERT(fWriter.readTAt<uint32_t>(
|
| + fWriter.bytesWritten() - kPushCullOpSize) >> 24 == PUSH_CULL);
|
| + fWriter.rewindToOffset(fWriter.bytesWritten() - kPushCullOpSize);
|
| + return;
|
| + }
|
| +
|
| + // op only
|
| + uint32_t size = kUInt32Size;
|
| + size_t initialOffset = this->addDraw(POP_CULL, &size);
|
| +
|
| + // update the cull skip offset to point past this op.
|
| + fWriter.overwriteTAt<uint32_t>(cullSkipOffset, fWriter.bytesWritten());
|
| +
|
| + this->validate(initialOffset, size);
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info) {
|
|
|