Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: src/core/SkPicturePlayback.cpp

Issue 12545009: Adding option in SkPicture to record device-space bounds of draw commands. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 #if SK_RECORD_BOUNDS_IN_PICTURE
128 fHasRecordedBounds = true;
129 #else
130 fHasRecordedBounds = false;
131 #endif
132
127 #ifdef SK_DEBUG_SIZE 133 #ifdef SK_DEBUG_SIZE
128 int overall = fPlayback->size(&overallBytes); 134 int overall = fPlayback->size(&overallBytes);
129 bitmaps = fPlayback->bitmaps(&bitmapBytes); 135 bitmaps = fPlayback->bitmaps(&bitmapBytes);
130 paints = fPlayback->paints(&paintBytes); 136 paints = fPlayback->paints(&paintBytes);
131 paths = fPlayback->paths(&pathBytes); 137 paths = fPlayback->paths(&pathBytes);
132 pictures = fPlayback->pictures(&pictureBytes); 138 pictures = fPlayback->pictures(&pictureBytes);
133 regions = fPlayback->regions(&regionBytes); 139 regions = fPlayback->regions(&regionBytes);
134 SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall); 140 SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall);
135 if (bitmaps != 0) 141 if (bitmaps != 0)
136 SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps); 142 SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 175
170 fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get())); 176 fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
171 fPathHeap.reset(SkSafeRef(src.fPathHeap.get())); 177 fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
172 178
173 fMatrices = SkSafeRef(src.fMatrices); 179 fMatrices = SkSafeRef(src.fMatrices);
174 fRegions = SkSafeRef(src.fRegions); 180 fRegions = SkSafeRef(src.fRegions);
175 fOpData = SkSafeRef(src.fOpData); 181 fOpData = SkSafeRef(src.fOpData);
176 182
177 fBoundingHierarchy = src.fBoundingHierarchy; 183 fBoundingHierarchy = src.fBoundingHierarchy;
178 fStateTree = src.fStateTree; 184 fStateTree = src.fStateTree;
179 185 fHasRecordedBounds = src.fHasRecordedBounds;
180 SkSafeRef(fBoundingHierarchy); 186 SkSafeRef(fBoundingHierarchy);
181 SkSafeRef(fStateTree); 187 SkSafeRef(fStateTree);
182 188
183 if (deepCopyInfo) { 189 if (deepCopyInfo) {
184 int paintCount = SafeCount(src.fPaints); 190 int paintCount = SafeCount(src.fPaints);
185 191
186 if (src.fBitmaps) { 192 if (src.fBitmaps) {
187 fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src. fBitmaps->count()); 193 fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src. fBitmaps->count());
188 } 194 }
189 195
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 fBitmaps = NULL; 269 fBitmaps = NULL;
264 fMatrices = NULL; 270 fMatrices = NULL;
265 fPaints = NULL; 271 fPaints = NULL;
266 fPictureRefs = NULL; 272 fPictureRefs = NULL;
267 fRegions = NULL; 273 fRegions = NULL;
268 fPictureCount = 0; 274 fPictureCount = 0;
269 fOpData = NULL; 275 fOpData = NULL;
270 fFactoryPlayback = NULL; 276 fFactoryPlayback = NULL;
271 fBoundingHierarchy = NULL; 277 fBoundingHierarchy = NULL;
272 fStateTree = NULL; 278 fStateTree = NULL;
279 fHasRecordedBounds = false;
273 } 280 }
274 281
275 SkPicturePlayback::~SkPicturePlayback() { 282 SkPicturePlayback::~SkPicturePlayback() {
276 fOpData->unref(); 283 fOpData->unref();
277 284
278 SkSafeUnref(fBitmaps); 285 SkSafeUnref(fBitmaps);
279 SkSafeUnref(fMatrices); 286 SkSafeUnref(fMatrices);
280 SkSafeUnref(fPaints); 287 SkSafeUnref(fPaints);
281 SkSafeUnref(fRegions); 288 SkSafeUnref(fRegions);
282 SkSafeUnref(fBoundingHierarchy); 289 SkSafeUnref(fBoundingHierarchy);
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 for (size_t i = 0; i < size; ++i) { 586 for (size_t i = 0; i < size; ++i) {
580 buffer.readRegion(&fRegions->writableAt(i)); 587 buffer.readRegion(&fRegions->writableAt(i));
581 } 588 }
582 } break; 589 } break;
583 } 590 }
584 } 591 }
585 592
586 SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info, 593 SkPicturePlayback::SkPicturePlayback(SkStream* stream, const SkPictInfo& info,
587 SkPicture::InstallPixelRefProc proc) { 594 SkPicture::InstallPixelRefProc proc) {
588 this->init(); 595 this->init();
589 596 #if SK_RECORD_BOUNDS_IN_PICTURE
597 fHasRecordedBounds = SkToBool(info.fFlags & SkPictInfo::kHasRecordedBounds_F lag);
598 #else
599 // Can't handle skps with recorded bounds in a build that does support them.
600 SkASSERT(false == SkToBool(info.fFlags & SkPictInfo::kHasRecordedBounds_Flag ));
601 fHasRecordedBounds = false;
602 #endif
590 for (;;) { 603 for (;;) {
591 uint32_t tag = stream->readU32(); 604 uint32_t tag = stream->readU32();
592 if (PICT_EOF_TAG == tag) { 605 if (PICT_EOF_TAG == tag) {
593 break; 606 break;
594 } 607 }
595 608
596 uint32_t size = stream->readU32(); 609 uint32_t size = stream->readU32();
597 this->parseStreamTag(stream, info, tag, size, proc); 610 this->parseStreamTag(stream, info, tag, size, proc);
598 } 611 }
599 } 612 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 *size = 0; 656 *size = 0;
644 } else { 657 } else {
645 UNPACK_8_24(temp, op, *size); 658 UNPACK_8_24(temp, op, *size);
646 if (MASK_24 == *size) { 659 if (MASK_24 == *size) {
647 *size = reader->readInt(); 660 *size = reader->readInt();
648 } 661 }
649 } 662 }
650 return (DrawType) op; 663 return (DrawType) op;
651 } 664 }
652 665
666 // Sets 'bounds' to represent the clip bounds of the playback canvas,
667 // expressed in the recording device's coordinate space.
668 // returns true if the bounds are not empty.
669 static inline bool get_intial_clip_bounds(const SkCanvas& canvas, SkIRect* bound s) {
670 SkASSERT(NULL != bounds);
671 SkRect clipBounds;
672 if (canvas.getClipBounds(&clipBounds)) {
673 clipBounds.roundOut(bounds);
674 } else {
675 bounds->setEmpty();
676 return false;
677 }
678 return !bounds->isEmpty();
679 }
680
653 void SkPicturePlayback::draw(SkCanvas& canvas) { 681 void SkPicturePlayback::draw(SkCanvas& canvas) {
654 #ifdef ENABLE_TIME_DRAW 682 #ifdef ENABLE_TIME_DRAW
655 SkAutoTime at("SkPicture::draw", 50); 683 SkAutoTime at("SkPicture::draw", 50);
656 #endif 684 #endif
657 685
658 #ifdef SPEW_CLIP_SKIPPING 686 #ifdef SPEW_CLIP_SKIPPING
659 SkipClipRec skipRect, skipRRect, skipRegion, skipPath; 687 SkipClipRec skipRect, skipRRect, skipRegion, skipPath;
660 #endif 688 #endif
661 689
662 #ifdef SK_BUILD_FOR_ANDROID 690 #ifdef SK_BUILD_FOR_ANDROID
663 SkAutoMutexAcquire autoMutex(fDrawMutex); 691 SkAutoMutexAcquire autoMutex(fDrawMutex);
664 #endif 692 #endif
665 693
666 // kDrawComplete will be the signal that we have reached the end of 694 // kDrawComplete will be the signal that we have reached the end of
667 // the command stream 695 // the command stream
668 static const uint32_t kDrawComplete = SK_MaxU32; 696 static const uint32_t kDrawComplete = SK_MaxU32;
669 697
670 SkReader32 reader(fOpData->bytes(), fOpData->size()); 698 SkReader32 reader(fOpData->bytes(), fOpData->size());
671 TextContainer text; 699 TextContainer text;
672 SkTDArray<void*> results; 700 SkTDArray<void*> results;
673 701
702 bool initialClipBoundsSet = false;
703 SkIRect initialClipBounds; // only computed if needed
674 if (NULL != fStateTree && NULL != fBoundingHierarchy) { 704 if (NULL != fStateTree && NULL != fBoundingHierarchy) {
675 SkRect clipBounds; 705 if (!get_intial_clip_bounds(canvas, &initialClipBounds)) {
676 if (canvas.getClipBounds(&clipBounds)) { 706 return;
677 SkIRect query;
678 clipBounds.roundOut(&query);
679 fBoundingHierarchy->search(query, &results);
680 if (results.count() == 0) {
681 return;
682 }
683 SkTQSort<SkPictureStateTree::Draw>(
684 reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()),
685 reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1));
686 } 707 }
708 fBoundingHierarchy->search(initialClipBounds, &results);
709 if (results.count() == 0) {
710 return;
711 }
712 initialClipBoundsSet = true;
713 SkTQSort<SkPictureStateTree::Draw>(
714 reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()),
715 reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1));
687 } 716 }
688 717
718 #if SK_RECORD_BOUNDS_IN_PICTURE
719 if (fHasRecordedBounds) {
720 // TODO(junov): temporarily disable quickReject testing on 'canvas'
721 // because it is redundant with early bounds check.
722 if (!initialClipBoundsSet && !get_intial_clip_bounds(canvas, &initialCli pBounds)) {
723 return;
724 }
725 initialClipBoundsSet = true;
726 }
727 #endif
728
689 SkPictureStateTree::Iterator it = (NULL == fStateTree) ? 729 SkPictureStateTree::Iterator it = (NULL == fStateTree) ?
690 SkPictureStateTree::Iterator() : 730 SkPictureStateTree::Iterator() :
691 fStateTree->getIterator(results, &canvas); 731 fStateTree->getIterator(results, &canvas);
692 732
693 if (it.isValid()) { 733 if (it.isValid()) {
694 uint32_t skipTo = it.draw(); 734 uint32_t skipTo = it.draw();
695 if (kDrawComplete == skipTo) { 735 if (kDrawComplete == skipTo) {
696 return; 736 return;
697 } 737 }
698 reader.setOffset(skipTo); 738 reader.setOffset(skipTo);
699 } 739 }
700 740
701 // Record this, so we can concat w/ it if we encounter a setMatrix() 741 // Record this, so we can concat w/ it if we encounter a setMatrix()
702 SkMatrix initialMatrix = canvas.getTotalMatrix(); 742 SkMatrix initialMatrix = canvas.getTotalMatrix();
703 743
704 #ifdef SK_BUILD_FOR_ANDROID 744 #ifdef SK_BUILD_FOR_ANDROID
705 fAbortCurrentPlayback = false; 745 fAbortCurrentPlayback = false;
706 #endif 746 #endif
707 747
708 while (!reader.eof()) { 748 while (!reader.eof()) {
709 #ifdef SK_BUILD_FOR_ANDROID 749 #ifdef SK_BUILD_FOR_ANDROID
710 if (fAbortCurrentPlayback) { 750 if (fAbortCurrentPlayback) {
711 return; 751 return;
712 } 752 }
713 #endif 753 #endif
714 754
715 size_t curOffset = reader.offset(); 755 size_t curOffset = reader.offset();
716 uint32_t size; 756 uint32_t size;
717 DrawType op = read_op_and_size(&reader, &size); 757 DrawType op = read_op_and_size(&reader, &size);
718 if (NOOP == op) { 758 size_t skipTo = 0;
719 // NOOPs are to be ignored - do not propagate them any further 759 #ifdef SK_DEVELOPER
720 reader.setOffset(curOffset+size); 760 // TODO: once chunk sizes are in all .skps just use
721 continue; 761 // "curOffset + size"
762 skipTo = this->preDraw(curOffset, op);
763 #endif
764 if (0 == skipTo) {
765 if (NOOP == op) {
766 // NOOPs are to be ignored - do not propagate them any further
767 skipTo = curOffset + size;
768 }
769 #if SK_RECORD_BOUNDS_IN_PICTURE
770 else if (fHasRecordedBounds && SkPictureRecord::canRecordBounds(op)) {
771 const SkIRect& clippedBounds = reader.skipT<SkIRect>();
772 // recording canvas device bounds are in the same coordinate spa ce
773 // as local clip bounds at start of playback.
774 SkASSERT(initialClipBoundsSet);
775 if (!SkIRect::Intersects(clippedBounds, initialClipBounds)) {
776 skipTo = curOffset + size;
777 }
778 }
779 #endif
722 } 780 }
723 781
724 #ifdef SK_DEVELOPER
725 // TODO: once chunk sizes are in all .skps just use "curOffset + size"
726 size_t skipTo = this->preDraw(curOffset, op);
727 if (0 != skipTo) { 782 if (0 != skipTo) {
783 if (it.isValid()) {
784 // If using a bounding box hierarchy, advance the state tree
785 // iterator until at or after skipTo
786 uint32_t adjustedSkipTo;
787 do {
788 adjustedSkipTo = it.draw();
789 } while (adjustedSkipTo < skipTo);
790 skipTo = adjustedSkipTo;
791 }
728 if (kDrawComplete == skipTo) { 792 if (kDrawComplete == skipTo) {
729 break; 793 break;
730 } 794 }
731 reader.setOffset(skipTo); 795 reader.setOffset(skipTo);
732 continue; 796 continue;
733 } 797 }
734 #endif 798
735 switch (op) { 799 switch (op) {
736 case CLIP_PATH: { 800 case CLIP_PATH: {
737 const SkPath& path = getPath(reader); 801 const SkPath& path = getPath(reader);
738 uint32_t packed = reader.readInt(); 802 uint32_t packed = reader.readInt();
739 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 803 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
740 bool doAA = ClipParams_unpackDoAA(packed); 804 bool doAA = ClipParams_unpackDoAA(packed);
741 size_t offsetToRestore = reader.readInt(); 805 size_t offsetToRestore = reader.readInt();
742 SkASSERT(!offsetToRestore || \ 806 SkASSERT(!offsetToRestore || \
743 offsetToRestore >= reader.offset()); 807 offsetToRestore >= reader.offset());
744 if (!canvas.clipPath(path, regionOp, doAA) && offsetToRestore) { 808 if (!canvas.clipPath(path, regionOp, doAA) && offsetToRestore) {
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 for (index = 0; index < fRegionCount; index++) 1634 for (index = 0; index < fRegionCount; index++)
1571 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ), 1635 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ),
1572 "region%p, ", &fRegions[index]); 1636 "region%p, ", &fRegions[index]);
1573 if (fRegionCount > 0) 1637 if (fRegionCount > 0)
1574 SkDebugf("%s0};\n", pBuffer); 1638 SkDebugf("%s0};\n", pBuffer);
1575 1639
1576 const_cast<SkPicturePlayback*>(this)->dumpStream(); 1640 const_cast<SkPicturePlayback*>(this)->dumpStream();
1577 } 1641 }
1578 1642
1579 #endif 1643 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698