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

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 = true;
reed1 2013/03/08 20:23:23 do we want false here?
Justin Novosad 2013/03/08 22:35:42 Done.
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 fHasRecordedBounds = info.fFlags & SkPictInfo::kHasRecordedBounds_Flag;
reed1 2013/03/08 20:23:23 SkToBool(...)
Justin Novosad 2013/03/08 22:35:42 Done.
590 for (;;) { 597 for (;;) {
591 uint32_t tag = stream->readU32(); 598 uint32_t tag = stream->readU32();
592 if (PICT_EOF_TAG == tag) { 599 if (PICT_EOF_TAG == tag) {
593 break; 600 break;
594 } 601 }
595 602
596 uint32_t size = stream->readU32(); 603 uint32_t size = stream->readU32();
597 this->parseStreamTag(stream, info, tag, size, proc); 604 this->parseStreamTag(stream, info, tag, size, proc);
598 } 605 }
599 } 606 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 *size = 0; 650 *size = 0;
644 } else { 651 } else {
645 UNPACK_8_24(temp, op, *size); 652 UNPACK_8_24(temp, op, *size);
646 if (MASK_24 == *size) { 653 if (MASK_24 == *size) {
647 *size = reader->readInt(); 654 *size = reader->readInt();
648 } 655 }
649 } 656 }
650 return (DrawType) op; 657 return (DrawType) op;
651 } 658 }
652 659
660 static inline bool get_intial_clip_bounds(const SkCanvas& canvas, SkIRect* bound s, bool* isSet) {
reed1 2013/03/08 20:23:23 Maybe this is the best way, but this treats both i
Justin Novosad 2013/03/08 22:35:42 Done.
661 SkASSERT(NULL != bounds && NULL != isSet);
662 if (!(*isSet)) {
663 SkRect clipBounds;
664 *isSet = true;
665 if (canvas.getClipBounds(&clipBounds)) {
666 clipBounds.roundOut(bounds);
667 } else {
668 bounds->setEmpty();
669 return false;
670 }
671 }
672 return !bounds->isEmpty();
673 }
674
653 void SkPicturePlayback::draw(SkCanvas& canvas) { 675 void SkPicturePlayback::draw(SkCanvas& canvas) {
654 #ifdef ENABLE_TIME_DRAW 676 #ifdef ENABLE_TIME_DRAW
655 SkAutoTime at("SkPicture::draw", 50); 677 SkAutoTime at("SkPicture::draw", 50);
656 #endif 678 #endif
657 679
658 #ifdef SPEW_CLIP_SKIPPING 680 #ifdef SPEW_CLIP_SKIPPING
659 SkipClipRec skipRect, skipRRect, skipRegion, skipPath; 681 SkipClipRec skipRect, skipRRect, skipRegion, skipPath;
660 #endif 682 #endif
661 683
662 #ifdef SK_BUILD_FOR_ANDROID 684 #ifdef SK_BUILD_FOR_ANDROID
663 SkAutoMutexAcquire autoMutex(fDrawMutex); 685 SkAutoMutexAcquire autoMutex(fDrawMutex);
664 #endif 686 #endif
665 687
666 // kDrawComplete will be the signal that we have reached the end of 688 // kDrawComplete will be the signal that we have reached the end of
667 // the command stream 689 // the command stream
668 static const uint32_t kDrawComplete = SK_MaxU32; 690 static const uint32_t kDrawComplete = SK_MaxU32;
669 691
670 SkReader32 reader(fOpData->bytes(), fOpData->size()); 692 SkReader32 reader(fOpData->bytes(), fOpData->size());
671 TextContainer text; 693 TextContainer text;
672 SkTDArray<void*> results; 694 SkTDArray<void*> results;
673 695
696 bool initialClipBoundsSet = false;
697 SkIRect initialClipBounds; // only computed if needed
674 if (NULL != fStateTree && NULL != fBoundingHierarchy) { 698 if (NULL != fStateTree && NULL != fBoundingHierarchy) {
675 SkRect clipBounds; 699 if (get_intial_clip_bounds(canvas, &initialClipBounds, &initialClipBound sSet)) {
676 if (canvas.getClipBounds(&clipBounds)) { 700 fBoundingHierarchy->search(initialClipBounds, &results);
677 SkIRect query;
678 clipBounds.roundOut(&query);
679 fBoundingHierarchy->search(query, &results);
680 if (results.count() == 0) { 701 if (results.count() == 0) {
681 return; 702 return;
682 } 703 }
683 SkTQSort<SkPictureStateTree::Draw>( 704 SkTQSort<SkPictureStateTree::Draw>(
684 reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()), 705 reinterpret_cast<SkPictureStateTree::Draw**>(results.begin()),
685 reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1)); 706 reinterpret_cast<SkPictureStateTree::Draw**>(results.end()-1));
707 } else {
708 return;
709 }
710 }
711
712 if (fHasRecordedBounds) {
713 // TODO(junov): temporarily disable quickReject testing on 'canvas'
714 // because it is redundant with early bounds check.
715 if (!get_intial_clip_bounds(canvas, &initialClipBounds, &initialClipBoun dsSet)) {
716 return;
686 } 717 }
687 } 718 }
688 719
689 SkPictureStateTree::Iterator it = (NULL == fStateTree) ? 720 SkPictureStateTree::Iterator it = (NULL == fStateTree) ?
690 SkPictureStateTree::Iterator() : 721 SkPictureStateTree::Iterator() :
691 fStateTree->getIterator(results, &canvas); 722 fStateTree->getIterator(results, &canvas);
692 723
693 if (it.isValid()) { 724 if (it.isValid()) {
694 uint32_t skipTo = it.draw(); 725 uint32_t skipTo = it.draw();
695 if (kDrawComplete == skipTo) { 726 if (kDrawComplete == skipTo) {
(...skipping 12 matching lines...) Expand all
708 while (!reader.eof()) { 739 while (!reader.eof()) {
709 #ifdef SK_BUILD_FOR_ANDROID 740 #ifdef SK_BUILD_FOR_ANDROID
710 if (fAbortCurrentPlayback) { 741 if (fAbortCurrentPlayback) {
711 return; 742 return;
712 } 743 }
713 #endif 744 #endif
714 745
715 size_t curOffset = reader.offset(); 746 size_t curOffset = reader.offset();
716 uint32_t size; 747 uint32_t size;
717 DrawType op = read_op_and_size(&reader, &size); 748 DrawType op = read_op_and_size(&reader, &size);
718 if (NOOP == op) { 749 size_t skipTo = 0;
719 // NOOPs are to be ignored - do not propagate them any further 750 #ifdef SK_DEVELOPER
720 reader.setOffset(curOffset+size); 751 // TODO: once chunk sizes are in all .skps just use
721 continue; 752 // "curOffset + size"
753 skipTo = this->preDraw(curOffset, op);
754 #endif
755 if (0 == skipTo) {
756 if (NOOP == op) {
757 // NOOPs are to be ignored - do not propagate them any further
758 skipTo = curOffset + size;
759 } else if (fHasRecordedBounds && SkPictureRecord::canRecordBounds(op )) {
760 const SkIRect& clippedBounds = reader.skipT<SkIRect>();
761 // recording canvas device bounds are in the same coordinate spa ce
762 // as local clip bounds at start of playback.
763 SkASSERT(initialClipBoundsSet);
764 if (!SkIRect::Intersects(clippedBounds, initialClipBounds)) {
765 skipTo = curOffset + size;
766 }
767 }
722 } 768 }
723 769
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) { 770 if (0 != skipTo) {
771 if (it.isValid()) {
772 // If using a bounding box hierarchy, advance the state tree
773 // iterator until at or after skipTo
774 uint32_t adjustedSkipTo;
775 do {
776 adjustedSkipTo = it.draw();
777 } while (adjustedSkipTo < skipTo);
778 skipTo = adjustedSkipTo;
779 }
728 if (kDrawComplete == skipTo) { 780 if (kDrawComplete == skipTo) {
729 break; 781 break;
730 } 782 }
731 reader.setOffset(skipTo); 783 reader.setOffset(skipTo);
732 continue; 784 continue;
733 } 785 }
734 #endif 786
735 switch (op) { 787 switch (op) {
736 case CLIP_PATH: { 788 case CLIP_PATH: {
737 const SkPath& path = getPath(reader); 789 const SkPath& path = getPath(reader);
738 uint32_t packed = reader.readInt(); 790 uint32_t packed = reader.readInt();
739 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 791 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
740 bool doAA = ClipParams_unpackDoAA(packed); 792 bool doAA = ClipParams_unpackDoAA(packed);
741 size_t offsetToRestore = reader.readInt(); 793 size_t offsetToRestore = reader.readInt();
742 SkASSERT(!offsetToRestore || \ 794 SkASSERT(!offsetToRestore || \
743 offsetToRestore >= reader.offset()); 795 offsetToRestore >= reader.offset());
744 if (!canvas.clipPath(path, regionOp, doAA) && offsetToRestore) { 796 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++) 1622 for (index = 0; index < fRegionCount; index++)
1571 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ), 1623 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ),
1572 "region%p, ", &fRegions[index]); 1624 "region%p, ", &fRegions[index]);
1573 if (fRegionCount > 0) 1625 if (fRegionCount > 0)
1574 SkDebugf("%s0};\n", pBuffer); 1626 SkDebugf("%s0};\n", pBuffer);
1575 1627
1576 const_cast<SkPicturePlayback*>(this)->dumpStream(); 1628 const_cast<SkPicturePlayback*>(this)->dumpStream();
1577 } 1629 }
1578 1630
1579 #endif 1631 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698