OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkPicturePlayback.h" | 8 #include "SkPicturePlayback.h" |
9 #include "SkPictureRecord.h" | 9 #include "SkPictureRecord.h" |
10 #include "SkTypeface.h" | 10 #include "SkTypeface.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 for (int i = 0; i < fPictureCount; i++) { | 117 for (int i = 0; i < fPictureCount; i++) { |
118 if (deepCopy) { | 118 if (deepCopy) { |
119 fPictureRefs[i] = pictures[i]->clone(); | 119 fPictureRefs[i] = pictures[i]->clone(); |
120 } else { | 120 } else { |
121 fPictureRefs[i] = pictures[i]; | 121 fPictureRefs[i] = pictures[i]; |
122 fPictureRefs[i]->ref(); | 122 fPictureRefs[i]->ref(); |
123 } | 123 } |
124 } | 124 } |
125 } | 125 } |
126 | 126 |
127 fHasRecordedBounds = record.recordBounds(); | |
128 | |
127 #ifdef SK_DEBUG_SIZE | 129 #ifdef SK_DEBUG_SIZE |
128 int overall = fPlayback->size(&overallBytes); | 130 int overall = fPlayback->size(&overallBytes); |
129 bitmaps = fPlayback->bitmaps(&bitmapBytes); | 131 bitmaps = fPlayback->bitmaps(&bitmapBytes); |
130 paints = fPlayback->paints(&paintBytes); | 132 paints = fPlayback->paints(&paintBytes); |
131 paths = fPlayback->paths(&pathBytes); | 133 paths = fPlayback->paths(&pathBytes); |
132 pictures = fPlayback->pictures(&pictureBytes); | 134 pictures = fPlayback->pictures(&pictureBytes); |
133 regions = fPlayback->regions(®ionBytes); | 135 regions = fPlayback->regions(®ionBytes); |
134 SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall); | 136 SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall); |
135 if (bitmaps != 0) | 137 if (bitmaps != 0) |
136 SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps); | 138 SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 | 171 |
170 fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get())); | 172 fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get())); |
171 fPathHeap.reset(SkSafeRef(src.fPathHeap.get())); | 173 fPathHeap.reset(SkSafeRef(src.fPathHeap.get())); |
172 | 174 |
173 fMatrices = SkSafeRef(src.fMatrices); | 175 fMatrices = SkSafeRef(src.fMatrices); |
174 fRegions = SkSafeRef(src.fRegions); | 176 fRegions = SkSafeRef(src.fRegions); |
175 fOpData = SkSafeRef(src.fOpData); | 177 fOpData = SkSafeRef(src.fOpData); |
176 | 178 |
177 fBoundingHierarchy = src.fBoundingHierarchy; | 179 fBoundingHierarchy = src.fBoundingHierarchy; |
178 fStateTree = src.fStateTree; | 180 fStateTree = src.fStateTree; |
179 | 181 fHasRecordedBounds = src.fHasRecordedBounds; |
180 SkSafeRef(fBoundingHierarchy); | 182 SkSafeRef(fBoundingHierarchy); |
181 SkSafeRef(fStateTree); | 183 SkSafeRef(fStateTree); |
182 | 184 |
183 if (deepCopyInfo) { | 185 if (deepCopyInfo) { |
184 int paintCount = SafeCount(src.fPaints); | 186 int paintCount = SafeCount(src.fPaints); |
185 | 187 |
186 if (src.fBitmaps) { | 188 if (src.fBitmaps) { |
187 fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src. fBitmaps->count()); | 189 fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src. fBitmaps->count()); |
188 } | 190 } |
189 | 191 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 fBitmaps = NULL; | 265 fBitmaps = NULL; |
264 fMatrices = NULL; | 266 fMatrices = NULL; |
265 fPaints = NULL; | 267 fPaints = NULL; |
266 fPictureRefs = NULL; | 268 fPictureRefs = NULL; |
267 fRegions = NULL; | 269 fRegions = NULL; |
268 fPictureCount = 0; | 270 fPictureCount = 0; |
269 fOpData = NULL; | 271 fOpData = NULL; |
270 fFactoryPlayback = NULL; | 272 fFactoryPlayback = NULL; |
271 fBoundingHierarchy = NULL; | 273 fBoundingHierarchy = NULL; |
272 fStateTree = NULL; | 274 fStateTree = NULL; |
275 fHasRecordedBounds = false; | |
273 } | 276 } |
274 | 277 |
275 SkPicturePlayback::~SkPicturePlayback() { | 278 SkPicturePlayback::~SkPicturePlayback() { |
276 fOpData->unref(); | 279 fOpData->unref(); |
277 | 280 |
278 SkSafeUnref(fBitmaps); | 281 SkSafeUnref(fBitmaps); |
279 SkSafeUnref(fMatrices); | 282 SkSafeUnref(fMatrices); |
280 SkSafeUnref(fPaints); | 283 SkSafeUnref(fPaints); |
281 SkSafeUnref(fRegions); | 284 SkSafeUnref(fRegions); |
282 SkSafeUnref(fBoundingHierarchy); | 285 SkSafeUnref(fBoundingHierarchy); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
579 for (size_t i = 0; i < size; ++i) { | 582 for (size_t i = 0; i < size; ++i) { |
580 buffer.readRegion(&fRegions->writableAt(i)); | 583 buffer.readRegion(&fRegions->writableAt(i)); |
581 } | 584 } |
582 } break; | 585 } break; |
583 } | 586 } |
584 } | 587 } |
585 | 588 |
586 SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info, | 589 SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info, |
587 SkPicture::InstallPixelRefProc proc) { | 590 SkPicture::InstallPixelRefProc proc) { |
588 this->init(); | 591 this->init(); |
589 | 592 fHasRecordedBounds = info.fFlags & SkPictInfo::kHasRecordedBounds_Flag; |
590 for (;;) { | 593 for (;;) { |
591 uint32_t tag = stream->readU32(); | 594 uint32_t tag = stream->readU32(); |
592 if (PICT_EOF_TAG == tag) { | 595 if (PICT_EOF_TAG == tag) { |
593 break; | 596 break; |
594 } | 597 } |
595 | 598 |
596 uint32_t size = stream->readU32(); | 599 uint32_t size = stream->readU32(); |
597 this->parseStreamTag(stream, info, tag, size, proc); | 600 this->parseStreamTag(stream, info, tag, size, proc); |
598 } | 601 } |
599 } | 602 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
664 #endif | 667 #endif |
665 | 668 |
666 // kDrawComplete will be the signal that we have reached the end of | 669 // kDrawComplete will be the signal that we have reached the end of |
667 // the command stream | 670 // the command stream |
668 static const uint32_t kDrawComplete = SK_MaxU32; | 671 static const uint32_t kDrawComplete = SK_MaxU32; |
669 | 672 |
670 SkReader32 reader(fOpData->bytes(), fOpData->size()); | 673 SkReader32 reader(fOpData->bytes(), fOpData->size()); |
671 TextContainer text; | 674 TextContainer text; |
672 SkTDArray<void*> results; | 675 SkTDArray<void*> results; |
673 | 676 |
677 bool initialClipBoundsSet = false; | |
678 SkIRect initialClipBounds; // only computed if needed | |
674 if (NULL != fStateTree && NULL != fBoundingHierarchy) { | 679 if (NULL != fStateTree && NULL != fBoundingHierarchy) { |
675 SkRect clipBounds; | 680 SkRect clipBounds; |
676 if (canvas.getClipBounds(&clipBounds)) { | 681 if (canvas.getClipBounds(&clipBounds)) { |
677 SkIRect query; | 682 clipBounds.roundOut(&initialClipBounds); |
678 clipBounds.roundOut(&query); | 683 initialClipBoundsSet = true; |
679 fBoundingHierarchy->search(query, &results); | 684 fBoundingHierarchy->search(initialClipBounds, &results); |
680 if (results.count() == 0) { | 685 if (results.count() == 0) { |
681 return; | 686 return; |
682 } | 687 } |
683 SkTQSort<SkPictureStateTree::Draw>( | 688 SkTQSort<SkPictureStateTree::Draw>( |
684 reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()), | 689 reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()), |
685 reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1)); | 690 reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1)); |
691 } else { | |
692 return; | |
693 } | |
694 } | |
695 | |
696 if (fHasRecordedBounds) { | |
697 // TODO(junov): temporarily disable quickReject testing on 'canvas' | |
698 // because it is redundant with early bounds check. | |
699 if (!initialClipBoundsSet) { | |
robertphillips
2013/03/07 18:37:40
Would it make sense to have a "bool get_initial_cl
| |
700 SkRect clipBounds; | |
701 if (canvas.getClipBounds(&clipBounds)) { | |
702 clipBounds.roundOut(&initialClipBounds); | |
robertphillips
2013/03/07 18:37:40
initialClipBoundsSet = true;?
| |
703 } else { | |
704 return; | |
705 } | |
686 } | 706 } |
687 } | 707 } |
688 | 708 |
689 SkPictureStateTree::Iterator it = (NULL == fStateTree) ? | 709 SkPictureStateTree::Iterator it = (NULL == fStateTree) ? |
690 SkPictureStateTree::Iterator() : | 710 SkPictureStateTree::Iterator() : |
691 fStateTree->getIterator(results, &canvas); | 711 fStateTree->getIterator(results, &canvas); |
692 | 712 |
693 if (it.isValid()) { | 713 if (it.isValid()) { |
694 uint32_t skipTo = it.draw(); | 714 uint32_t skipTo = it.draw(); |
695 if (kDrawComplete == skipTo) { | 715 if (kDrawComplete == skipTo) { |
(...skipping 12 matching lines...) Expand all Loading... | |
708 while (!reader.eof()) { | 728 while (!reader.eof()) { |
709 #ifdef SK_BUILD_FOR_ANDROID | 729 #ifdef SK_BUILD_FOR_ANDROID |
710 if (fAbortCurrentPlayback) { | 730 if (fAbortCurrentPlayback) { |
711 return; | 731 return; |
712 } | 732 } |
713 #endif | 733 #endif |
714 | 734 |
715 size_t curOffset = reader.offset(); | 735 size_t curOffset = reader.offset(); |
716 uint32_t size; | 736 uint32_t size; |
717 DrawType op = read_op_and_size(&reader, &size); | 737 DrawType op = read_op_and_size(&reader, &size); |
738 size_t skipTo = 0; | |
718 if (NOOP == op) { | 739 if (NOOP == op) { |
719 // NOOPs are to be ignored - do not propagate them any further | 740 // NOOPs are to be ignored - do not propagate them any further |
720 reader.setOffset(curOffset+size); | 741 skipTo = curOffset + size; |
721 continue; | 742 } |
robertphillips
2013/03/07 18:37:40
add else here?
| |
743 if (fHasRecordedBounds && SkPictureRecord::canRecordBounds(op)) { | |
744 const SkIRect& clippedBounds = reader.skipT<SkIRect>(); | |
745 // recording canvas device bounds are in the same coordinate space a s | |
746 // local clip bounds at start of playback. | |
robertphillips
2013/03/07 18:37:40
SkASSERT(initialClipBoundsSet);?
| |
747 if (!SkIRect::Intersects(clippedBounds, initialClipBounds)) { | |
748 // This test replaces SkCanvas::quickReject when using | |
749 // kRecordBounds_RecordingFlag | |
750 skipTo = curOffset + size; | |
751 } | |
722 } | 752 } |
723 | 753 |
724 #ifdef SK_DEVELOPER | 754 #ifdef SK_DEVELOPER |
725 // TODO: once chunk sizes are in all .skps just use "curOffset + size" | 755 // TODO: once chunk sizes are in all .skps just use "curOffset + size" |
726 size_t skipTo = this->preDraw(curOffset, op); | 756 skipTo = this->preDraw(curOffset, op); |
757 #endif | |
727 if (0 != skipTo) { | 758 if (0 != skipTo) { |
759 if (it.isValid()) { | |
760 // If using a bounding box hierarchy, advance the state tree | |
761 // iterator until at or after skipTo | |
reed1
2013/03/07 20:36:44
do {
adjusted = it.draw()
} while (adjusted < s
| |
762 uint32_t adjustedSkipTo = it.draw(); | |
763 while (adjustedSkipTo < skipTo) { | |
764 adjustedSkipTo = it.draw(); | |
765 } | |
766 skipTo = adjustedSkipTo; | |
767 } | |
728 if (kDrawComplete == skipTo) { | 768 if (kDrawComplete == skipTo) { |
729 break; | 769 break; |
730 } | 770 } |
731 reader.setOffset(skipTo); | 771 reader.setOffset(skipTo); |
732 continue; | 772 continue; |
733 } | 773 } |
734 #endif | 774 |
735 switch (op) { | 775 switch (op) { |
736 case CLIP_PATH: { | 776 case CLIP_PATH: { |
737 const SkPath& path = getPath(reader); | 777 const SkPath& path = getPath(reader); |
738 uint32_t packed = reader.readInt(); | 778 uint32_t packed = reader.readInt(); |
739 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); | 779 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); |
740 bool doAA = ClipParams_unpackDoAA(packed); | 780 bool doAA = ClipParams_unpackDoAA(packed); |
741 size_t offsetToRestore = reader.readInt(); | 781 size_t offsetToRestore = reader.readInt(); |
742 SkASSERT(!offsetToRestore || \ | 782 SkASSERT(!offsetToRestore || \ |
743 offsetToRestore >= reader.offset()); | 783 offsetToRestore >= reader.offset()); |
744 if (!canvas.clipPath(path, regionOp, doAA) && offsetToRestore) { | 784 if (!canvas.clipPath(path, regionOp, doAA) && offsetToRestore) { |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1570 for (index = 0; index < fRegionCount; index++) | 1610 for (index = 0; index < fRegionCount; index++) |
1571 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ), | 1611 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ), |
1572 "region%p, ", &fRegions[index]); | 1612 "region%p, ", &fRegions[index]); |
1573 if (fRegionCount > 0) | 1613 if (fRegionCount > 0) |
1574 SkDebugf("%s0};\n", pBuffer); | 1614 SkDebugf("%s0};\n", pBuffer); |
1575 | 1615 |
1576 const_cast<SkPicturePlayback*>(this)->dumpStream(); | 1616 const_cast<SkPicturePlayback*>(this)->dumpStream(); |
1577 } | 1617 } |
1578 | 1618 |
1579 #endif | 1619 #endif |
OLD | NEW |