| Index: src/core/SkPicturePlayback.cpp
|
| ===================================================================
|
| --- src/core/SkPicturePlayback.cpp (revision 8010)
|
| +++ src/core/SkPicturePlayback.cpp (working copy)
|
| @@ -124,6 +124,8 @@
|
| }
|
| }
|
|
|
| + fHasRecordedBounds = record.recordBounds();
|
| +
|
| #ifdef SK_DEBUG_SIZE
|
| int overall = fPlayback->size(&overallBytes);
|
| bitmaps = fPlayback->bitmaps(&bitmapBytes);
|
| @@ -176,7 +178,7 @@
|
|
|
| fBoundingHierarchy = src.fBoundingHierarchy;
|
| fStateTree = src.fStateTree;
|
| -
|
| + fHasRecordedBounds = src.fHasRecordedBounds;
|
| SkSafeRef(fBoundingHierarchy);
|
| SkSafeRef(fStateTree);
|
|
|
| @@ -270,6 +272,7 @@
|
| fFactoryPlayback = NULL;
|
| fBoundingHierarchy = NULL;
|
| fStateTree = NULL;
|
| + fHasRecordedBounds = false;
|
| }
|
|
|
| SkPicturePlayback::~SkPicturePlayback() {
|
| @@ -586,7 +589,7 @@
|
| SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info,
|
| SkPicture::InstallPixelRefProc proc) {
|
| this->init();
|
| -
|
| + fHasRecordedBounds = info.fFlags & SkPictInfo::kHasRecordedBounds_Flag;
|
| for (;;) {
|
| uint32_t tag = stream->readU32();
|
| if (PICT_EOF_TAG == tag) {
|
| @@ -671,21 +674,38 @@
|
| TextContainer text;
|
| SkTDArray<void*> results;
|
|
|
| + bool initialClipBoundsSet = false;
|
| + SkIRect initialClipBounds; // only computed if needed
|
| if (NULL != fStateTree && NULL != fBoundingHierarchy) {
|
| SkRect clipBounds;
|
| if (canvas.getClipBounds(&clipBounds)) {
|
| - SkIRect query;
|
| - clipBounds.roundOut(&query);
|
| - fBoundingHierarchy->search(query, &results);
|
| + clipBounds.roundOut(&initialClipBounds);
|
| + initialClipBoundsSet = true;
|
| + fBoundingHierarchy->search(initialClipBounds, &results);
|
| if (results.count() == 0) {
|
| return;
|
| }
|
| SkTQSort<SkPictureStateTree::Draw>(
|
| reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()),
|
| reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1));
|
| + } else {
|
| + return;
|
| }
|
| }
|
|
|
| + if (fHasRecordedBounds) {
|
| + // TODO(junov): temporarily disable quickReject testing on 'canvas'
|
| + // because it is redundant with early bounds check.
|
| + if (!initialClipBoundsSet) {
|
| + SkRect clipBounds;
|
| + if (canvas.getClipBounds(&clipBounds)) {
|
| + clipBounds.roundOut(&initialClipBounds);
|
| + } else {
|
| + return;
|
| + }
|
| + }
|
| + }
|
| +
|
| SkPictureStateTree::Iterator it = (NULL == fStateTree) ?
|
| SkPictureStateTree::Iterator() :
|
| fStateTree->getIterator(results, &canvas);
|
| @@ -715,23 +735,43 @@
|
| size_t curOffset = reader.offset();
|
| uint32_t size;
|
| DrawType op = read_op_and_size(&reader, &size);
|
| + size_t skipTo = 0;
|
| if (NOOP == op) {
|
| // NOOPs are to be ignored - do not propagate them any further
|
| - reader.setOffset(curOffset+size);
|
| - continue;
|
| + skipTo = curOffset + size;
|
| }
|
| + if (fHasRecordedBounds && SkPictureRecord::canRecordBounds(op)) {
|
| + const SkIRect& clippedBounds = reader.skipT<SkIRect>();
|
| + // recording canvas device bounds are in the same coordinate space as
|
| + // local clip bounds at start of playback.
|
| + if (!SkIRect::Intersects(clippedBounds, initialClipBounds)) {
|
| + // This test replaces SkCanvas::quickReject when using
|
| + // kRecordBounds_RecordingFlag
|
| + skipTo = curOffset + size;
|
| + }
|
| + }
|
|
|
| #ifdef SK_DEVELOPER
|
| // TODO: once chunk sizes are in all .skps just use "curOffset + size"
|
| - size_t skipTo = this->preDraw(curOffset, op);
|
| + skipTo = this->preDraw(curOffset, op);
|
| +#endif
|
| if (0 != skipTo) {
|
| + if (it.isValid()) {
|
| + // If using a bounding box hierarchy, advance the state tree
|
| + // iterator until at or after skipTo
|
| + uint32_t adjustedSkipTo = it.draw();
|
| + while (adjustedSkipTo < skipTo) {
|
| + adjustedSkipTo = it.draw();
|
| + }
|
| + skipTo = adjustedSkipTo;
|
| + }
|
| if (kDrawComplete == skipTo) {
|
| break;
|
| }
|
| reader.setOffset(skipTo);
|
| continue;
|
| }
|
| -#endif
|
| +
|
| switch (op) {
|
| case CLIP_PATH: {
|
| const SkPath& path = getPath(reader);
|
|
|