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 "SkPictureRecord.h" | 8 #include "SkPictureRecord.h" |
9 #include "SkTSearch.h" | 9 #include "SkTSearch.h" |
10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
11 #include "SkRRect.h" | 11 #include "SkRRect.h" |
12 #include "SkBBoxHierarchy.h" | 12 #include "SkBBoxHierarchy.h" |
13 #include "SkDevice.h" | 13 #include "SkDevice.h" |
14 #include "SkPictureStateTree.h" | 14 #include "SkPictureStateTree.h" |
15 | 15 |
16 #define HEAP_BLOCK_SIZE 4096 | 16 #define HEAP_BLOCK_SIZE 4096 |
17 | 17 |
18 enum { | 18 enum { |
19 // just need a value that save or getSaveCount would never return | 19 // just need a value that save or getSaveCount would never return |
20 kNoInitialSave = -1, | 20 kNoInitialSave = -1, |
21 }; | 21 }; |
22 | 22 |
23 // A lot of basic types get stored as a uint32_t: bools, ints, paint indices, et
c. | 23 // A lot of basic types get stored as a uint32_t: bools, ints, paint indices, et
c. |
24 static int const kUInt32Size = 4; | 24 static int const kUInt32Size = 4; |
25 | 25 |
26 static const uint32_t kSaveSize = 2 * kUInt32Size; | 26 static const uint32_t kSaveSize = 2 * kUInt32Size; |
27 static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size; | 27 static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size; |
28 static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect
); | 28 static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect
); |
29 | 29 |
30 SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device) : | 30 SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device) |
31 INHERITED(device), | 31 : INHERITED(device) |
32 fBoundingHierarchy(NULL), | 32 , fBoundingHierarchy(NULL) |
33 fStateTree(NULL), | 33 , fStateTree(NULL) |
34 fFlattenableHeap(HEAP_BLOCK_SIZE), | 34 , fFlattenableHeap(HEAP_BLOCK_SIZE) |
35 fPaints(&fFlattenableHeap), | 35 , fPaints(&fFlattenableHeap) |
36 fRecordFlags(flags) { | 36 , fRecordFlags(flags) { |
37 #ifdef SK_DEBUG_SIZE | 37 #ifdef SK_DEBUG_SIZE |
38 fPointBytes = fRectBytes = fTextBytes = 0; | 38 fPointBytes = fRectBytes = fTextBytes = 0; |
39 fPointWrites = fRectWrites = fTextWrites = 0; | 39 fPointWrites = fRectWrites = fTextWrites = 0; |
40 #endif | 40 #endif |
41 | 41 |
42 fBitmapHeap = SkNEW(SkBitmapHeap); | 42 fBitmapHeap = SkNEW(SkBitmapHeap); |
43 fFlattenableHeap.setBitmapStorage(fBitmapHeap); | 43 fFlattenableHeap.setBitmapStorage(fBitmapHeap); |
44 fPathHeap = NULL; // lazy allocate | 44 fPathHeap = NULL; // lazy allocate |
45 fFirstSavedLayerIndex = kNoSavedLayerIndex; | 45 fFirstSavedLayerIndex = kNoSavedLayerIndex; |
46 | 46 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 | 134 |
135 SkBaseDevice* SkPictureRecord::setDevice(SkBaseDevice* device) { | 135 SkBaseDevice* SkPictureRecord::setDevice(SkBaseDevice* device) { |
136 SkDEBUGFAIL("eeek, don't try to change the device on a recording canvas"); | 136 SkDEBUGFAIL("eeek, don't try to change the device on a recording canvas"); |
137 return this->INHERITED::setDevice(device); | 137 return this->INHERITED::setDevice(device); |
138 } | 138 } |
139 | 139 |
140 int SkPictureRecord::save(SaveFlags flags) { | 140 int SkPictureRecord::save(SaveFlags flags) { |
141 // record the offset to us, making it non-positive to distinguish a save | 141 // record the offset to us, making it non-positive to distinguish a save |
142 // from a clip entry. | 142 // from a clip entry. |
143 fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); | 143 fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); |
| 144 this->recordSave(flags); |
| 145 return this->INHERITED::save(flags); |
| 146 } |
144 | 147 |
| 148 void SkPictureRecord::recordSave(SaveFlags flags) { |
145 // op + flags | 149 // op + flags |
146 uint32_t size = kSaveSize; | 150 uint32_t size = kSaveSize; |
147 size_t initialOffset = this->addDraw(SAVE, &size); | 151 size_t initialOffset = this->addDraw(SAVE, &size); |
148 addInt(flags); | 152 addInt(flags); |
149 | 153 |
150 this->validate(initialOffset, size); | 154 this->validate(initialOffset, size); |
151 return this->INHERITED::save(flags); | |
152 } | 155 } |
153 | 156 |
154 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, | 157 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, |
155 SaveFlags flags) { | 158 SaveFlags flags) { |
156 // record the offset to us, making it non-positive to distinguish a save | 159 // record the offset to us, making it non-positive to distinguish a save |
157 // from a clip entry. | 160 // from a clip entry. |
158 fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); | 161 fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); |
| 162 this->recordSaveLayer(bounds, paint, flags); |
| 163 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { |
| 164 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); |
| 165 } |
159 | 166 |
| 167 /* Don't actually call INHERITED::saveLayer, because that will try to alloc
ate |
| 168 an offscreen device (potentially very big) which we don't actually need |
| 169 at this time (and may not be able to afford since during record our |
| 170 clip starts out the size of the picture, which is often much larger |
| 171 than the size of the actual device we'll use during playback). |
| 172 */ |
| 173 int count = this->INHERITED::save(flags); |
| 174 this->clipRectBounds(bounds, flags, NULL); |
| 175 return count; |
| 176 } |
| 177 |
| 178 void SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint
, |
| 179 SaveFlags flags) { |
160 // op + bool for 'bounds' | 180 // op + bool for 'bounds' |
161 uint32_t size = 2 * kUInt32Size; | 181 uint32_t size = 2 * kUInt32Size; |
162 if (NULL != bounds) { | 182 if (NULL != bounds) { |
163 size += sizeof(*bounds); // + rect | 183 size += sizeof(*bounds); // + rect |
164 } | 184 } |
165 // + paint index + flags | 185 // + paint index + flags |
166 size += 2 * kUInt32Size; | 186 size += 2 * kUInt32Size; |
167 | 187 |
168 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size)
; | 188 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size)
; |
169 | 189 |
170 size_t initialOffset = this->addDraw(SAVE_LAYER, &size); | 190 size_t initialOffset = this->addDraw(SAVE_LAYER, &size); |
171 addRectPtr(bounds); | 191 addRectPtr(bounds); |
172 SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.bytesWrit
ten()); | 192 SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.bytesWrit
ten()); |
173 addPaintPtr(paint); | 193 addPaintPtr(paint); |
174 addInt(flags); | 194 addInt(flags); |
175 | 195 |
176 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { | |
177 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); | |
178 } | |
179 | |
180 this->validate(initialOffset, size); | 196 this->validate(initialOffset, size); |
181 /* Don't actually call saveLayer, because that will try to allocate an | |
182 offscreen device (potentially very big) which we don't actually need | |
183 at this time (and may not be able to afford since during record our | |
184 clip starts out the size of the picture, which is often much larger | |
185 than the size of the actual device we'll use during playback). | |
186 */ | |
187 int count = this->INHERITED::save(flags); | |
188 this->clipRectBounds(bounds, flags, NULL); | |
189 return count; | |
190 } | 197 } |
191 | 198 |
192 bool SkPictureRecord::isDrawingToLayer() const { | 199 bool SkPictureRecord::isDrawingToLayer() const { |
193 return fFirstSavedLayerIndex != kNoSavedLayerIndex; | 200 return fFirstSavedLayerIndex != kNoSavedLayerIndex; |
194 } | 201 } |
195 | 202 |
196 /* | 203 /* |
197 * Read the op code from 'offset' in 'writer' and extract the size too. | 204 * Read the op code from 'offset' in 'writer' and extract the size too. |
198 */ | 205 */ |
199 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { | 206 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 | 321 |
315 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { | 322 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { |
316 return false; | 323 return false; |
317 } | 324 } |
318 | 325 |
319 if (kSaveLayerWithBoundsSize == result[0].fSize) { | 326 if (kSaveLayerWithBoundsSize == result[0].fSize) { |
320 // The saveLayer's bound can offset where the dbm is drawn | 327 // The saveLayer's bound can offset where the dbm is drawn |
321 return false; | 328 return false; |
322 } | 329 } |
323 | 330 |
324 | |
325 return merge_savelayer_paint_into_drawbitmp(writer, paintDict, | 331 return merge_savelayer_paint_into_drawbitmp(writer, paintDict, |
326 result[0], result[1]); | 332 result[0], result[1]); |
327 } | 333 } |
328 | 334 |
329 /* | 335 /* |
330 * Convert the command code located at 'offset' to a NOOP. Leave the size | 336 * Convert the command code located at 'offset' to a NOOP. Leave the size |
331 * field alone so the NOOP can be skipped later. | 337 * field alone so the NOOP can be skipped later. |
332 */ | 338 */ |
333 static void convert_command_to_noop(SkWriter32* writer, uint32_t offset) { | 339 static void convert_command_to_noop(SkWriter32* writer, uint32_t offset) { |
334 uint32_t command = writer->read32At(offset); | 340 uint32_t command = writer->read32At(offset); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 apply_optimization_to_bbh(gPictureRecordOpts[opt].fType, | 600 apply_optimization_to_bbh(gPictureRecordOpts[opt].fType, |
595 fStateTree, fBoundingHierarchy); | 601 fStateTree, fBoundingHierarchy); |
596 break; | 602 break; |
597 } | 603 } |
598 } | 604 } |
599 } | 605 } |
600 | 606 |
601 if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) || | 607 if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) || |
602 SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { | 608 SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { |
603 // No optimization fired so add the RESTORE | 609 // No optimization fired so add the RESTORE |
604 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.byte
sWritten()); | 610 this->recordRestore(); |
605 size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code | |
606 initialOffset = this->addDraw(RESTORE, &size); | |
607 } | 611 } |
608 | 612 |
609 fRestoreOffsetStack.pop(); | 613 fRestoreOffsetStack.pop(); |
610 | 614 |
| 615 return this->INHERITED::restore(); |
| 616 } |
| 617 |
| 618 void SkPictureRecord::recordRestore() { |
| 619 uint32_t initialOffset, size; |
| 620 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWri
tten()); |
| 621 size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code |
| 622 initialOffset = this->addDraw(RESTORE, &size); |
611 this->validate(initialOffset, size); | 623 this->validate(initialOffset, size); |
612 return this->INHERITED::restore(); | |
613 } | 624 } |
614 | 625 |
615 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { | 626 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { |
616 // op + dx + dy | 627 // op + dx + dy |
617 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 628 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
618 size_t initialOffset = this->addDraw(TRANSLATE, &size); | 629 size_t initialOffset = this->addDraw(TRANSLATE, &size); |
619 addScalar(dx); | 630 addScalar(dx); |
620 addScalar(dy); | 631 addScalar(dy); |
621 this->validate(initialOffset, size); | 632 this->validate(initialOffset, size); |
622 return this->INHERITED::translate(dx, dy); | 633 return this->INHERITED::translate(dx, dy); |
(...skipping 22 matching lines...) Expand all Loading... |
645 // op + sx + sy | 656 // op + sx + sy |
646 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 657 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
647 size_t initialOffset = this->addDraw(SKEW, &size); | 658 size_t initialOffset = this->addDraw(SKEW, &size); |
648 addScalar(sx); | 659 addScalar(sx); |
649 addScalar(sy); | 660 addScalar(sy); |
650 this->validate(initialOffset, size); | 661 this->validate(initialOffset, size); |
651 return this->INHERITED::skew(sx, sy); | 662 return this->INHERITED::skew(sx, sy); |
652 } | 663 } |
653 | 664 |
654 bool SkPictureRecord::concat(const SkMatrix& matrix) { | 665 bool SkPictureRecord::concat(const SkMatrix& matrix) { |
| 666 this->recordConcat(matrix); |
| 667 return this->INHERITED::concat(matrix); |
| 668 } |
| 669 |
| 670 void SkPictureRecord::recordConcat(const SkMatrix& matrix) { |
655 this->validate(fWriter.bytesWritten(), 0); | 671 this->validate(fWriter.bytesWritten(), 0); |
656 // op + matrix | 672 // op + matrix |
657 uint32_t size = kUInt32Size + matrix.writeToMemory(NULL); | 673 uint32_t size = kUInt32Size + matrix.writeToMemory(NULL); |
658 size_t initialOffset = this->addDraw(CONCAT, &size); | 674 size_t initialOffset = this->addDraw(CONCAT, &size); |
659 addMatrix(matrix); | 675 addMatrix(matrix); |
660 this->validate(initialOffset, size); | 676 this->validate(initialOffset, size); |
661 return this->INHERITED::concat(matrix); | |
662 } | 677 } |
663 | 678 |
664 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { | 679 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { |
665 this->validate(fWriter.bytesWritten(), 0); | 680 this->validate(fWriter.bytesWritten(), 0); |
666 // op + matrix | 681 // op + matrix |
667 uint32_t size = kUInt32Size + matrix.writeToMemory(NULL); | 682 uint32_t size = kUInt32Size + matrix.writeToMemory(NULL); |
668 size_t initialOffset = this->addDraw(SET_MATRIX, &size); | 683 size_t initialOffset = this->addDraw(SET_MATRIX, &size); |
669 addMatrix(matrix); | 684 addMatrix(matrix); |
670 this->validate(initialOffset, size); | 685 this->validate(initialOffset, size); |
671 this->INHERITED::setMatrix(matrix); | 686 this->INHERITED::setMatrix(matrix); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 // recorded. This is balanced by restoreToCount() call from endRecording, | 723 // recorded. This is balanced by restoreToCount() call from endRecording, |
709 // which in-turn calls our overridden restore(), so those get recorded too. | 724 // which in-turn calls our overridden restore(), so those get recorded too. |
710 fInitialSaveCount = this->save(kMatrixClip_SaveFlag); | 725 fInitialSaveCount = this->save(kMatrixClip_SaveFlag); |
711 } | 726 } |
712 | 727 |
713 void SkPictureRecord::endRecording() { | 728 void SkPictureRecord::endRecording() { |
714 SkASSERT(kNoInitialSave != fInitialSaveCount); | 729 SkASSERT(kNoInitialSave != fInitialSaveCount); |
715 this->restoreToCount(fInitialSaveCount); | 730 this->restoreToCount(fInitialSaveCount); |
716 } | 731 } |
717 | 732 |
718 void SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { | 733 int SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { |
719 if (fRestoreOffsetStack.isEmpty()) { | 734 if (fRestoreOffsetStack.isEmpty()) { |
720 return; | 735 return -1; |
721 } | 736 } |
722 | 737 |
723 // The RestoreOffset field is initially filled with a placeholder | 738 // The RestoreOffset field is initially filled with a placeholder |
724 // value that points to the offset of the previous RestoreOffset | 739 // value that points to the offset of the previous RestoreOffset |
725 // in the current stack level, thus forming a linked list so that | 740 // in the current stack level, thus forming a linked list so that |
726 // the restore offsets can be filled in when the corresponding | 741 // the restore offsets can be filled in when the corresponding |
727 // restore command is recorded. | 742 // restore command is recorded. |
728 int32_t prevOffset = fRestoreOffsetStack.top(); | 743 int32_t prevOffset = fRestoreOffsetStack.top(); |
729 | 744 |
730 if (regionOpExpands(op)) { | 745 if (regionOpExpands(op)) { |
731 // Run back through any previous clip ops, and mark their offset to | 746 // Run back through any previous clip ops, and mark their offset to |
732 // be 0, disabling their ability to trigger a jump-to-restore, otherwise | 747 // be 0, disabling their ability to trigger a jump-to-restore, otherwise |
733 // they could hide this clips ability to expand the clip (i.e. go from | 748 // they could hide this clips ability to expand the clip (i.e. go from |
734 // empty to non-empty). | 749 // empty to non-empty). |
735 fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); | 750 fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); |
736 | 751 |
737 // Reset the pointer back to the previous clip so that subsequent | 752 // Reset the pointer back to the previous clip so that subsequent |
738 // restores don't overwrite the offsets we just cleared. | 753 // restores don't overwrite the offsets we just cleared. |
739 prevOffset = 0; | 754 prevOffset = 0; |
740 } | 755 } |
741 | 756 |
742 size_t offset = fWriter.bytesWritten(); | 757 size_t offset = fWriter.bytesWritten(); |
743 addInt(prevOffset); | 758 addInt(prevOffset); |
744 fRestoreOffsetStack.top() = offset; | 759 fRestoreOffsetStack.top() = offset; |
| 760 return offset; |
745 } | 761 } |
746 | 762 |
747 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { | 763 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { |
| 764 this->recordClipRect(rect, op, doAA); |
| 765 return this->INHERITED::clipRect(rect, op, doAA); |
| 766 } |
| 767 |
| 768 int SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool do
AA) { |
| 769 |
748 // id + rect + clip params | 770 // id + rect + clip params |
749 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; | 771 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; |
750 // recordRestoreOffsetPlaceholder doesn't always write an offset | 772 // recordRestoreOffsetPlaceholder doesn't always write an offset |
751 if (!fRestoreOffsetStack.isEmpty()) { | 773 if (!fRestoreOffsetStack.isEmpty()) { |
752 // + restore offset | 774 // + restore offset |
753 size += kUInt32Size; | 775 size += kUInt32Size; |
754 } | 776 } |
| 777 |
755 size_t initialOffset = this->addDraw(CLIP_RECT, &size); | 778 size_t initialOffset = this->addDraw(CLIP_RECT, &size); |
756 addRect(rect); | 779 addRect(rect); |
757 addInt(ClipParams_pack(op, doAA)); | 780 addInt(ClipParams_pack(op, doAA)); |
758 recordRestoreOffsetPlaceholder(op); | 781 int offset = this->recordRestoreOffsetPlaceholder(op); |
759 | 782 |
760 this->validate(initialOffset, size); | 783 this->validate(initialOffset, size); |
761 return this->INHERITED::clipRect(rect, op, doAA); | 784 return offset; |
762 } | 785 } |
763 | 786 |
764 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA
) { | 787 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA
) { |
765 if (rrect.isRect()) { | 788 if (rrect.isRect()) { |
766 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); | 789 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); |
767 } | 790 } |
768 | 791 |
| 792 this->recordClipRRect(rrect, op, doAA); |
| 793 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
| 794 return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op,
false); |
| 795 } else { |
| 796 return this->INHERITED::clipRRect(rrect, op, doAA); |
| 797 } |
| 798 } |
| 799 |
| 800 int SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool
doAA) { |
| 801 |
769 // op + rrect + clip params | 802 // op + rrect + clip params |
770 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; | 803 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; |
771 // recordRestoreOffsetPlaceholder doesn't always write an offset | 804 // recordRestoreOffsetPlaceholder doesn't always write an offset |
772 if (!fRestoreOffsetStack.isEmpty()) { | 805 if (!fRestoreOffsetStack.isEmpty()) { |
773 // + restore offset | 806 // + restore offset |
774 size += kUInt32Size; | 807 size += kUInt32Size; |
775 } | 808 } |
776 size_t initialOffset = this->addDraw(CLIP_RRECT, &size); | 809 size_t initialOffset = this->addDraw(CLIP_RRECT, &size); |
777 addRRect(rrect); | 810 addRRect(rrect); |
778 addInt(ClipParams_pack(op, doAA)); | 811 addInt(ClipParams_pack(op, doAA)); |
779 recordRestoreOffsetPlaceholder(op); | 812 int offset = recordRestoreOffsetPlaceholder(op); |
780 | 813 |
781 this->validate(initialOffset, size); | 814 this->validate(initialOffset, size); |
782 | 815 return offset; |
783 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | |
784 return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op,
false); | |
785 } else { | |
786 return this->INHERITED::clipRRect(rrect, op, doAA); | |
787 } | |
788 } | 816 } |
789 | 817 |
790 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { | 818 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { |
791 | 819 |
792 SkRect r; | 820 SkRect r; |
793 if (!path.isInverseFillType() && path.isRect(&r)) { | 821 if (!path.isInverseFillType() && path.isRect(&r)) { |
794 return this->clipRect(r, op, doAA); | 822 return this->clipRect(r, op, doAA); |
795 } | 823 } |
796 | 824 |
| 825 int pathID = this->addPathToHeap(path); |
| 826 this->recordClipPath(pathID, op, doAA); |
| 827 |
| 828 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
| 829 return this->updateClipConservativelyUsingBounds(path.getBounds(), op, |
| 830 path.isInverseFillType(
)); |
| 831 } else { |
| 832 return this->INHERITED::clipPath(path, op, doAA); |
| 833 } |
| 834 } |
| 835 |
| 836 int SkPictureRecord::recordClipPath(int pathID, SkRegion::Op op, bool doAA) { |
| 837 |
797 // op + path index + clip params | 838 // op + path index + clip params |
798 uint32_t size = 3 * kUInt32Size; | 839 uint32_t size = 3 * kUInt32Size; |
799 // recordRestoreOffsetPlaceholder doesn't always write an offset | 840 // recordRestoreOffsetPlaceholder doesn't always write an offset |
800 if (!fRestoreOffsetStack.isEmpty()) { | 841 if (!fRestoreOffsetStack.isEmpty()) { |
801 // + restore offset | 842 // + restore offset |
802 size += kUInt32Size; | 843 size += kUInt32Size; |
803 } | 844 } |
804 size_t initialOffset = this->addDraw(CLIP_PATH, &size); | 845 size_t initialOffset = this->addDraw(CLIP_PATH, &size); |
805 addPath(path); | 846 addInt(pathID); |
806 addInt(ClipParams_pack(op, doAA)); | 847 addInt(ClipParams_pack(op, doAA)); |
807 recordRestoreOffsetPlaceholder(op); | 848 int offset = recordRestoreOffsetPlaceholder(op); |
808 | 849 |
809 this->validate(initialOffset, size); | 850 this->validate(initialOffset, size); |
810 | 851 return offset; |
811 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | |
812 return this->updateClipConservativelyUsingBounds(path.getBounds(), op, | |
813 path.isInverseFillType(
)); | |
814 } else { | |
815 return this->INHERITED::clipPath(path, op, doAA); | |
816 } | |
817 } | 852 } |
818 | 853 |
819 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { | 854 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { |
| 855 this->recordClipRegion(region, op); |
| 856 return this->INHERITED::clipRegion(region, op); |
| 857 } |
| 858 |
| 859 int SkPictureRecord::recordClipRegion(const SkRegion& region, SkRegion::Op op) { |
820 // op + clip params + region | 860 // op + clip params + region |
821 uint32_t size = 2 * kUInt32Size + region.writeToMemory(NULL); | 861 uint32_t size = 2 * kUInt32Size + region.writeToMemory(NULL); |
822 // recordRestoreOffsetPlaceholder doesn't always write an offset | 862 // recordRestoreOffsetPlaceholder doesn't always write an offset |
823 if (!fRestoreOffsetStack.isEmpty()) { | 863 if (!fRestoreOffsetStack.isEmpty()) { |
824 // + restore offset | 864 // + restore offset |
825 size += kUInt32Size; | 865 size += kUInt32Size; |
826 } | 866 } |
827 size_t initialOffset = this->addDraw(CLIP_REGION, &size); | 867 size_t initialOffset = this->addDraw(CLIP_REGION, &size); |
828 addRegion(region); | 868 addRegion(region); |
829 addInt(ClipParams_pack(op, false)); | 869 addInt(ClipParams_pack(op, false)); |
830 recordRestoreOffsetPlaceholder(op); | 870 int offset = recordRestoreOffsetPlaceholder(op); |
831 | 871 |
832 this->validate(initialOffset, size); | 872 this->validate(initialOffset, size); |
833 return this->INHERITED::clipRegion(region, op); | 873 return offset; |
834 } | 874 } |
835 | 875 |
836 void SkPictureRecord::clear(SkColor color) { | 876 void SkPictureRecord::clear(SkColor color) { |
837 // op + color | 877 // op + color |
838 uint32_t size = 2 * kUInt32Size; | 878 uint32_t size = 2 * kUInt32Size; |
839 size_t initialOffset = this->addDraw(DRAW_CLEAR, &size); | 879 size_t initialOffset = this->addDraw(DRAW_CLEAR, &size); |
840 addInt(color); | 880 addInt(color); |
841 this->validate(initialOffset, size); | 881 this->validate(initialOffset, size); |
842 } | 882 } |
843 | 883 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 const SkFlatData* data = paint ? getFlatPaintData(*paint) : NULL; | 1340 const SkFlatData* data = paint ? getFlatPaintData(*paint) : NULL; |
1301 this->addFlatPaint(data); | 1341 this->addFlatPaint(data); |
1302 return data; | 1342 return data; |
1303 } | 1343 } |
1304 | 1344 |
1305 void SkPictureRecord::addFlatPaint(const SkFlatData* flatPaint) { | 1345 void SkPictureRecord::addFlatPaint(const SkFlatData* flatPaint) { |
1306 int index = flatPaint ? flatPaint->index() : 0; | 1346 int index = flatPaint ? flatPaint->index() : 0; |
1307 this->addInt(index); | 1347 this->addInt(index); |
1308 } | 1348 } |
1309 | 1349 |
1310 void SkPictureRecord::addPath(const SkPath& path) { | 1350 int SkPictureRecord::addPathToHeap(const SkPath& path) { |
1311 if (NULL == fPathHeap) { | 1351 if (NULL == fPathHeap) { |
1312 fPathHeap = SkNEW(SkPathHeap); | 1352 fPathHeap = SkNEW(SkPathHeap); |
1313 } | 1353 } |
1314 addInt(fPathHeap->append(path)); | 1354 return fPathHeap->append(path); |
| 1355 } |
| 1356 |
| 1357 void SkPictureRecord::addPath(const SkPath& path) { |
| 1358 addInt(this->addPathToHeap(path)); |
1315 } | 1359 } |
1316 | 1360 |
1317 void SkPictureRecord::addPicture(SkPicture& picture) { | 1361 void SkPictureRecord::addPicture(SkPicture& picture) { |
1318 int index = fPictureRefs.find(&picture); | 1362 int index = fPictureRefs.find(&picture); |
1319 if (index < 0) { // not found | 1363 if (index < 0) { // not found |
1320 index = fPictureRefs.count(); | 1364 index = fPictureRefs.count(); |
1321 *fPictureRefs.append() = &picture; | 1365 *fPictureRefs.append() = &picture; |
1322 picture.ref(); | 1366 picture.ref(); |
1323 } | 1367 } |
1324 // follow the convention of recording a 1-based index | 1368 // follow the convention of recording a 1-based index |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 void SkPictureRecord::validateRegions() const { | 1561 void SkPictureRecord::validateRegions() const { |
1518 int count = fRegions.count(); | 1562 int count = fRegions.count(); |
1519 SkASSERT((unsigned) count < 0x1000); | 1563 SkASSERT((unsigned) count < 0x1000); |
1520 for (int index = 0; index < count; index++) { | 1564 for (int index = 0; index < count; index++) { |
1521 const SkFlatData* region = fRegions[index]; | 1565 const SkFlatData* region = fRegions[index]; |
1522 SkASSERT(region); | 1566 SkASSERT(region); |
1523 // region->validate(); | 1567 // region->validate(); |
1524 } | 1568 } |
1525 } | 1569 } |
1526 #endif | 1570 #endif |
OLD | NEW |