Chromium Code Reviews| 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) { |
|
robertphillips
2013/03/07 18:37:40
Would it make sense to have a "bool get_initial_cl
|
| + SkRect clipBounds; |
| + if (canvas.getClipBounds(&clipBounds)) { |
| + clipBounds.roundOut(&initialClipBounds); |
|
robertphillips
2013/03/07 18:37:40
initialClipBoundsSet = true;?
|
| + } 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; |
| } |
|
robertphillips
2013/03/07 18:37:40
add else here?
|
| + 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. |
|
robertphillips
2013/03/07 18:37:40
SkASSERT(initialClipBoundsSet);?
|
| + 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 |
|
reed1
2013/03/07 20:36:44
do {
adjusted = it.draw()
} while (adjusted < s
|
| + 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); |