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

Side by Side Diff: src/core/SkPictureRecord.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, 7 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 "SkPictureRecord.h" 8 #include "SkPictureRecord.h"
9 #include "SkTSearch.h" 9 #include "SkTSearch.h"
10 #include "SkPixelRef.h" 10 #include "SkPixelRef.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 SkSafeUnref(fBitmapHeap); 56 SkSafeUnref(fBitmapHeap);
57 SkSafeUnref(fPathHeap); 57 SkSafeUnref(fPathHeap);
58 SkSafeUnref(fBoundingHierarchy); 58 SkSafeUnref(fBoundingHierarchy);
59 SkSafeUnref(fStateTree); 59 SkSafeUnref(fStateTree);
60 fFlattenableHeap.setBitmapStorage(NULL); 60 fFlattenableHeap.setBitmapStorage(NULL);
61 fPictureRefs.unrefAll(); 61 fPictureRefs.unrefAll();
62 } 62 }
63 63
64 /////////////////////////////////////////////////////////////////////////////// 64 ///////////////////////////////////////////////////////////////////////////////
65 65
66 enum DrawTypeFlags {
67 kHasPaint_DrawTypeFlag = 1 << 0,
68 kModifiesState_DrawTypeFlag = 1 << 1, // modifes clip or matrix state
69 kCanRecordBounds_DrawTypeFlag = 1 << 2,
70 };
71
72 static const uint8_t gDrawTypeFlags[LAST_DRAWTYPE_ENUM + 1] = {
73 0, // UNUSED
74 kModifiesState_DrawTypeFlag, // CLIP_PATH
75 kModifiesState_DrawTypeFlag, // CLIP_REGION
76 kModifiesState_DrawTypeFlag, // CLIP_RECT
77 kModifiesState_DrawTypeFlag, // CLIP_RRECT
78 kModifiesState_DrawTypeFlag, // CONCAT
79 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP
80 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_MATR IX
81 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_NINE
82 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_RECT _TO_RECT
83 0, // DRAW_CLEAR
84 0, // DRAW_DATA
85 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_OVAL
86 kHasPaint_DrawTypeFlag, // DRAW_PAINT
87 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_PATH
88 kModifiesState_DrawTypeFlag, // DRAW_PICTURE
89 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POINTS
90 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POS_TEXT
91 kHasPaint_DrawTypeFlag, // DRAW_POS_TEXT_TO P_BOTTOM
92 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POS_TEXT_H
93 kHasPaint_DrawTypeFlag, // DRAW_POS_TEXT_H_ TOP_BOTTOM
94 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_RECT
95 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_RRECT
96 kHasPaint_DrawTypeFlag, // DRAW_SPRITE
97 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_TEXT
98 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_TEXT_ON_PAT H
99 kHasPaint_DrawTypeFlag, // DRAW_TEXT_TOP_BO TTOM
100 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_VERTICES
101 kModifiesState_DrawTypeFlag, // RESTORE
102 kModifiesState_DrawTypeFlag, // ROTATE
103 kModifiesState_DrawTypeFlag, // SAVE
104 kHasPaint_DrawTypeFlag | kModifiesState_DrawTypeFlag, // SAVE_LAYER
105 kModifiesState_DrawTypeFlag, // SCALE
106 kModifiesState_DrawTypeFlag, // SET_MATRIX
107 kModifiesState_DrawTypeFlag, // SKEW
108 kModifiesState_DrawTypeFlag, // TRANSLATE
109 0, // NOOP
110 };
111
112 bool SkPictureRecord::canRecordBounds(DrawType op) {
113 #if SK_RECORD_BOUNDS_IN_PICTURE
114 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM);
115 return SkToBool(gDrawTypeFlags[op] & kCanRecordBounds_DrawTypeFlag);
116 #else
117 return false;
118 #endif
119 }
120
121 static inline bool modifies_state(DrawType op) {
122 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM);
123 return SkToBool(gDrawTypeFlags[op] & kModifiesState_DrawTypeFlag);
124 }
125
66 // Return the offset of the paint inside a given op's byte stream. A zero 126 // Return the offset of the paint inside a given op's byte stream. A zero
67 // return value means there is no paint (and you really shouldn't be calling 127 // return value means there is no paint (and you really shouldn't be calling
68 // this method) 128 // this method)
69 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { 129 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) {
70 // These offsets are where the paint would be if the op size doesn't overflo w 130 // These offsets are where the paint would be if the op size doesn't overflo w
71 static const uint8_t gPaintOffsets[LAST_DRAWTYPE_ENUM + 1] = {
72 0, // UNUSED - no paint
73 0, // CLIP_PATH - no paint
74 0, // CLIP_REGION - no paint
75 0, // CLIP_RECT - no paint
76 0, // CLIP_RRECT - no paint
77 0, // CONCAT - no paint
78 1, // DRAW_BITMAP - right after op code
79 1, // DRAW_BITMAP_MATRIX - right after op code
80 1, // DRAW_BITMAP_NINE - right after op code
81 1, // DRAW_BITMAP_RECT_TO_RECT - right after op code
82 0, // DRAW_CLEAR - no paint
83 0, // DRAW_DATA - no paint
84 1, // DRAW_OVAL - right after op code
85 1, // DRAW_PAINT - right after op code
86 1, // DRAW_PATH - right after op code
87 0, // DRAW_PICTURE - no paint
88 1, // DRAW_POINTS - right after op code
89 1, // DRAW_POS_TEXT - right after op code
90 1, // DRAW_POS_TEXT_TOP_BOTTOM - right after op code
91 1, // DRAW_POS_TEXT_H - right after op code
92 1, // DRAW_POS_TEXT_H_TOP_BOTTOM - right after op code
93 1, // DRAW_RECT - right after op code
94 1, // DRAW_RRECT - right after op code
95 1, // DRAW_SPRITE - right after op code
96 1, // DRAW_TEXT - right after op code
97 1, // DRAW_TEXT_ON_PATH - right after op code
98 1, // DRAW_TEXT_TOP_BOTTOM - right after op code
99 1, // DRAW_VERTICES - right after op code
100 0, // RESTORE - no paint
101 0, // ROTATE - no paint
102 0, // SAVE - no paint
103 0, // SAVE_LAYER - see below - this paint's location varies
104 0, // SCALE - no paint
105 0, // SET_MATRIX - no paint
106 0, // SKEW - no paint
107 0, // TRANSLATE - no paint
108 0, // NOOP - no paint
109 };
110
111 SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1);
112 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); 131 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM);
113 132
114 int overflow = 0; 133 int offset = sizeof(uint32_t); // storage for op and 24-bit size
115 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { 134 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) {
116 // This op's size overflows so an extra uint32_t will be written 135 // This op's size overflows so an extra uint32_t will be written
117 // after the op code 136 // after the op code
118 overflow = sizeof(uint32_t); 137 offset += sizeof(uint32_t);
138 }
139 if (SkPictureRecord::canRecordBounds(op)) {
140 offset += sizeof(SkIRect);
119 } 141 }
120 142
121 if (SAVE_LAYER == op) { 143 if (SAVE_LAYER == op) {
122 static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; 144 static const uint32_t kSaveLayerNoBoundsPaintOffset = kUInt32Size;
123 static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); 145 static const uint32_t kSaveLayerWithBoundsPaintOffset = kUInt32Size + si zeof(SkRect);
124 146
125 if (kSaveLayerNoBoundsSize == opSize) { 147 if (kSaveLayerNoBoundsSize == opSize) {
126 return kSaveLayerNoBoundsPaintOffset + overflow; 148 offset += kSaveLayerNoBoundsPaintOffset;
127 } else { 149 } else {
128 SkASSERT(kSaveLayerWithBoundsSize == opSize); 150 SkASSERT(kSaveLayerWithBoundsSize == opSize);
129 return kSaveLayerWithBoundsPaintOffset + overflow; 151 offset += kSaveLayerWithBoundsPaintOffset;
130 } 152 }
131 } 153 }
132 154
133 SkASSERT(0 != gPaintOffsets[op]); // really shouldn't be calling this meth od 155 SkASSERT(kHasPaint_DrawTypeFlag & gDrawTypeFlags[op]); // Shouldn't be call ing this method
134 return gPaintOffsets[op] * sizeof(uint32_t) + overflow; 156 return offset;
135 } 157 }
136 158
137 SkDevice* SkPictureRecord::setDevice(SkDevice* device) { 159 SkDevice* SkPictureRecord::setDevice(SkDevice* device) {
138 SkASSERT(!"eeek, don't try to change the device on a recording canvas"); 160 SkASSERT(!"eeek, don't try to change the device on a recording canvas");
139 return this->INHERITED::setDevice(device); 161 return this->INHERITED::setDevice(device);
140 } 162 }
141 163
142 int SkPictureRecord::save(SaveFlags flags) { 164 int SkPictureRecord::save(SaveFlags flags) {
143 // record the offset to us, making it non-positive to distinguish a save 165 // record the offset to us, making it non-positive to distinguish a save
144 // from a clip entry. 166 // from a clip entry.
145 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); 167 fRestoreOffsetStack.push(-(int32_t)fWriter.size());
146 168
147 // op + flags 169 // op + flags
148 uint32_t size = 2 * kUInt32Size; 170 uint32_t size = 2 * kUInt32Size;
149 uint32_t initialOffset = this->addDraw(SAVE, &size); 171 uint32_t initialOffset = this->addDraw(SAVE, &size);
172 SkASSERT(kInvalidOffset != initialOffset);
150 addInt(flags); 173 addInt(flags);
151 174
152 validate(initialOffset, size); 175 validate(initialOffset, size);
153 return this->INHERITED::save(flags); 176 return this->INHERITED::save(flags);
154 } 177 }
155 178
156 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, 179 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint,
157 SaveFlags flags) { 180 SaveFlags flags) {
158 // record the offset to us, making it non-positive to distinguish a save 181 // record the offset to us, making it non-positive to distinguish a save
159 // from a clip entry. 182 // from a clip entry.
160 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); 183 fRestoreOffsetStack.push(-(int32_t)fWriter.size());
161 184
162 // op + bool for 'bounds' 185 // op + bool for 'bounds'
163 uint32_t size = 2 * kUInt32Size; 186 uint32_t size = 2 * kUInt32Size;
164 if (NULL != bounds) { 187 if (NULL != bounds) {
165 size += sizeof(*bounds); // + rect 188 size += sizeof(*bounds); // + rect
166 } 189 }
167 // + paint index + flags 190 // + paint index + flags
168 size += 2 * kUInt32Size; 191 size += 2 * kUInt32Size;
169 192
170 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; 193 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ;
171 194
172 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); 195 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size);
196 SkASSERT(kInvalidOffset != initialOffset);
173 addRectPtr(bounds); 197 addRectPtr(bounds);
174 SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.size()); 198 SkASSERT(initialOffset + getPaintOffset(SAVE_LAYER, size) == fWriter.size()) ;
175 addPaintPtr(paint); 199 addPaintPtr(paint);
176 addInt(flags); 200 addInt(flags);
177 201
178 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { 202 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) {
179 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); 203 fFirstSavedLayerIndex = fRestoreOffsetStack.count();
180 } 204 }
181 205
182 validate(initialOffset, size); 206 validate(initialOffset, size);
183 /* Don't actually call saveLayer, because that will try to allocate an 207 /* Don't actually call saveLayer, because that will try to allocate an
184 offscreen device (potentially very big) which we don't actually need 208 offscreen device (potentially very big) which we don't actually need
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 } 603 }
580 } 604 }
581 605
582 if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) || 606 if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) ||
583 SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { 607 SK_ARRAY_COUNT(gPictureRecordOpts) == opt) {
584 // No optimization fired so add the RESTORE 608 // No optimization fired so add the RESTORE
585 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); 609 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ());
586 size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code 610 size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code
587 initialOffset = this->addDraw(RESTORE, &size); 611 initialOffset = this->addDraw(RESTORE, &size);
588 } 612 }
613 SkASSERT(kInvalidOffset != initialOffset);
589 614
590 fRestoreOffsetStack.pop(); 615 fRestoreOffsetStack.pop();
591 616
592 validate(initialOffset, size); 617 validate(initialOffset, size);
593 return this->INHERITED::restore(); 618 return this->INHERITED::restore();
594 } 619 }
595 620
621 uint32_t SkPictureRecord::addDraw(DrawType drawType, uint32_t* size,
622 const SkPaint* paint, const SkRect* localBound s) {
623 SkIRect devClipBounds; // Bounds of the current clip in device space
624 if (!this->getClipDeviceBounds(&devClipBounds) && !modifies_state(drawType)) {
625 // Optimize-out calls that are clipped-out. State modifying commands
626 // can not be optimized-out because they may have an impact on future ca lls
627 // if the clip is ever expanded. For example, with a union clip op.
628 return kInvalidOffset;
629 }
630 #if SK_RECORD_BOUNDS_IN_PICTURE
631 bool writeBounds = canRecordBounds(drawType);
632 SkIRect clippedDevBounds; // Bounds of the clipped draw in device space
Tom Hudson 2013/05/14 17:00:49 Nit: clippedDevBounds and devClipBounds are a bit
633 if (writeBounds) {
634 SkASSERT(!modifies_state(drawType)); // Ensure devClipBounds is initial ized
Tom Hudson 2013/05/14 17:00:49 Not obvious how the comment follows from the asser
635 if (NULL == localBounds || (NULL != paint && !paint->canComputeFastBound s())) {
636 clippedDevBounds = devClipBounds;
637 } else {
638 SkRect paintBounds;
639 SkRect rectifiedBounds = *localBounds;
640 rectifiedBounds.sort();
641 if (NULL != paint) {
642 if (drawType == DRAW_POINTS) {
643 paintBounds = paint->computeFastStrokeBounds(rectifiedBounds , &paintBounds);
644 } else {
645 paintBounds = paint->computeFastBounds(rectifiedBounds, &pai ntBounds);
646 }
647 } else {
648 paintBounds = *localBounds;
649 }
650 if (paintBounds.isEmpty()) {
651 // Area affected by draw op is empty even after accounting
652 // for stroke width.
653 return kInvalidOffset;
654 }
655 SkRect devBounds;
656 this->getTotalMatrix().mapRect(&devBounds, paintBounds);
657 devBounds.roundOut(&clippedDevBounds);
658 if (!clippedDevBounds.intersect(devClipBounds)) {
659 // Draw lies outside of clip. The clip can only get further
660 // restricted at playback time, so it is safe to reject during
661 // record stage.
662 return kInvalidOffset;
663 }
664 }
665 *size += sizeof(SkIRect);
666 }
667 #else
668 sk_ignore_unused_variable(paint);
669 sk_ignore_unused_variable(localBounds);
670 #endif
671
672 uint32_t offset = fWriter.size();
673
674 this->predrawNotify();
675
676 #ifdef SK_DEBUG_TRACE
677 SkDebugf("add %s\n", DrawTypeToString(drawType));
678 #endif
679 SkASSERT(0 != *size);
680 SkASSERT(((uint8_t) drawType) == drawType);
681 if (0 != (*size & ~MASK_24) || *size == MASK_24) {
682 fWriter.writeInt(PACK_8_24(drawType, MASK_24));
683 *size += 1;
684 fWriter.writeInt(*size);
685 } else {
686 fWriter.writeInt(PACK_8_24(drawType, *size));
687 }
688
689 #if SK_RECORD_BOUNDS_IN_PICTURE
690 if (writeBounds) {
691 fWriter.write(&clippedDevBounds, sizeof(clippedDevBounds));
692 fLastDrawBounds = clippedDevBounds;
693 } else {
694 fLastDrawBounds = devClipBounds;
695 }
696 #endif
697
698 return offset;
699 }
700
596 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { 701 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) {
597 // op + dx + dy 702 // op + dx + dy
598 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 703 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
599 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); 704 uint32_t initialOffset = this->addDraw(TRANSLATE, &size);
705 SkASSERT(kInvalidOffset != initialOffset);
600 addScalar(dx); 706 addScalar(dx);
601 addScalar(dy); 707 addScalar(dy);
602 validate(initialOffset, size); 708 validate(initialOffset, size);
603 return this->INHERITED::translate(dx, dy); 709 return this->INHERITED::translate(dx, dy);
604 } 710 }
605 711
606 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { 712 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) {
607 // op + sx + sy 713 // op + sx + sy
608 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 714 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
609 uint32_t initialOffset = this->addDraw(SCALE, &size); 715 uint32_t initialOffset = this->addDraw(SCALE, &size);
716 SkASSERT(kInvalidOffset != initialOffset);
610 addScalar(sx); 717 addScalar(sx);
611 addScalar(sy); 718 addScalar(sy);
612 validate(initialOffset, size); 719 validate(initialOffset, size);
613 return this->INHERITED::scale(sx, sy); 720 return this->INHERITED::scale(sx, sy);
614 } 721 }
615 722
616 bool SkPictureRecord::rotate(SkScalar degrees) { 723 bool SkPictureRecord::rotate(SkScalar degrees) {
617 // op + degrees 724 // op + degrees
618 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar); 725 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar);
619 uint32_t initialOffset = this->addDraw(ROTATE, &size); 726 uint32_t initialOffset = this->addDraw(ROTATE, &size);
727 SkASSERT(kInvalidOffset != initialOffset);
620 addScalar(degrees); 728 addScalar(degrees);
621 validate(initialOffset, size); 729 validate(initialOffset, size);
622 return this->INHERITED::rotate(degrees); 730 return this->INHERITED::rotate(degrees);
623 } 731 }
624 732
625 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { 733 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) {
626 // op + sx + sy 734 // op + sx + sy
627 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 735 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
628 uint32_t initialOffset = this->addDraw(SKEW, &size); 736 uint32_t initialOffset = this->addDraw(SKEW, &size);
737 SkASSERT(kInvalidOffset != initialOffset);
629 addScalar(sx); 738 addScalar(sx);
630 addScalar(sy); 739 addScalar(sy);
631 validate(initialOffset, size); 740 validate(initialOffset, size);
632 return this->INHERITED::skew(sx, sy); 741 return this->INHERITED::skew(sx, sy);
633 } 742 }
634 743
635 bool SkPictureRecord::concat(const SkMatrix& matrix) { 744 bool SkPictureRecord::concat(const SkMatrix& matrix) {
636 validate(fWriter.size(), 0); 745 validate(fWriter.size(), 0);
637 // op + matrix index 746 // op + matrix index
638 uint32_t size = 2 * kUInt32Size; 747 uint32_t size = 2 * kUInt32Size;
639 uint32_t initialOffset = this->addDraw(CONCAT, &size); 748 uint32_t initialOffset = this->addDraw(CONCAT, &size);
749 SkASSERT(kInvalidOffset != initialOffset);
640 addMatrix(matrix); 750 addMatrix(matrix);
641 validate(initialOffset, size); 751 validate(initialOffset, size);
642 return this->INHERITED::concat(matrix); 752 return this->INHERITED::concat(matrix);
643 } 753 }
644 754
645 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { 755 void SkPictureRecord::setMatrix(const SkMatrix& matrix) {
646 validate(fWriter.size(), 0); 756 validate(fWriter.size(), 0);
647 // op + matrix index 757 // op + matrix index
648 uint32_t size = 2 * kUInt32Size; 758 uint32_t size = 2 * kUInt32Size;
649 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size); 759 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size);
760 SkASSERT(kInvalidOffset != initialOffset);
650 addMatrix(matrix); 761 addMatrix(matrix);
651 validate(initialOffset, size); 762 validate(initialOffset, size);
652 this->INHERITED::setMatrix(matrix); 763 this->INHERITED::setMatrix(matrix);
653 } 764 }
654 765
655 static bool regionOpExpands(SkRegion::Op op) { 766 static bool regionOpExpands(SkRegion::Op op) {
656 switch (op) { 767 switch (op) {
657 case SkRegion::kUnion_Op: 768 case SkRegion::kUnion_Op:
658 case SkRegion::kXOR_Op: 769 case SkRegion::kXOR_Op:
659 case SkRegion::kReverseDifference_Op: 770 case SkRegion::kReverseDifference_Op:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 832
722 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 833 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
723 // id + rect + clip params 834 // id + rect + clip params
724 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; 835 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size;
725 // recordRestoreOffsetPlaceholder doesn't always write an offset 836 // recordRestoreOffsetPlaceholder doesn't always write an offset
726 if (!fRestoreOffsetStack.isEmpty()) { 837 if (!fRestoreOffsetStack.isEmpty()) {
727 // + restore offset 838 // + restore offset
728 size += kUInt32Size; 839 size += kUInt32Size;
729 } 840 }
730 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size); 841 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size);
842 SkASSERT(kInvalidOffset != initialOffset);
731 addRect(rect); 843 addRect(rect);
732 addInt(ClipParams_pack(op, doAA)); 844 addInt(ClipParams_pack(op, doAA));
733 recordRestoreOffsetPlaceholder(op); 845 recordRestoreOffsetPlaceholder(op);
734 846
735 validate(initialOffset, size); 847 validate(initialOffset, size);
736 return this->INHERITED::clipRect(rect, op, doAA); 848 return this->INHERITED::clipRect(rect, op, doAA);
737 } 849 }
738 850
739 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) { 851 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) {
740 if (rrect.isRect()) { 852 if (rrect.isRect()) {
741 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); 853 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA);
742 } 854 }
743 855
744 // op + rrect + clip params 856 // op + rrect + clip params
745 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; 857 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size;
746 // recordRestoreOffsetPlaceholder doesn't always write an offset 858 // recordRestoreOffsetPlaceholder doesn't always write an offset
747 if (!fRestoreOffsetStack.isEmpty()) { 859 if (!fRestoreOffsetStack.isEmpty()) {
748 // + restore offset 860 // + restore offset
749 size += kUInt32Size; 861 size += kUInt32Size;
750 } 862 }
751 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); 863 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size);
864 SkASSERT(kInvalidOffset != initialOffset);
752 addRRect(rrect); 865 addRRect(rrect);
753 addInt(ClipParams_pack(op, doAA)); 866 addInt(ClipParams_pack(op, doAA));
754 recordRestoreOffsetPlaceholder(op); 867 recordRestoreOffsetPlaceholder(op);
755 868
756 validate(initialOffset, size); 869 validate(initialOffset, size);
757 870
758 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { 871 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
759 return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, doAA, false); 872 return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, doAA, false);
760 } else { 873 } else {
761 return this->INHERITED::clipRRect(rrect, op, doAA); 874 return this->INHERITED::clipRRect(rrect, op, doAA);
762 } 875 }
763 } 876 }
764 877
765 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 878 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
766 879
767 SkRect r; 880 SkRect r;
768 if (!path.isInverseFillType() && path.isRect(&r)) { 881 if (!path.isInverseFillType() && path.isRect(&r)) {
769 return this->clipRect(r, op, doAA); 882 return this->clipRect(r, op, doAA);
770 } 883 }
771 884
772 // op + path index + clip params 885 // op + path index + clip params
773 uint32_t size = 3 * kUInt32Size; 886 uint32_t size = 3 * kUInt32Size;
774 // recordRestoreOffsetPlaceholder doesn't always write an offset 887 // recordRestoreOffsetPlaceholder doesn't always write an offset
775 if (!fRestoreOffsetStack.isEmpty()) { 888 if (!fRestoreOffsetStack.isEmpty()) {
776 // + restore offset 889 // + restore offset
777 size += kUInt32Size; 890 size += kUInt32Size;
778 } 891 }
779 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); 892 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size);
893 SkASSERT(kInvalidOffset != initialOffset);
780 addPath(path); 894 addPath(path);
781 addInt(ClipParams_pack(op, doAA)); 895 addInt(ClipParams_pack(op, doAA));
782 recordRestoreOffsetPlaceholder(op); 896 recordRestoreOffsetPlaceholder(op);
783 897
784 validate(initialOffset, size); 898 validate(initialOffset, size);
785 899
786 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { 900 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
787 return this->updateClipConservativelyUsingBounds(path.getBounds(), op, d oAA, 901 return this->updateClipConservativelyUsingBounds(path.getBounds(), op, d oAA,
788 path.isInverseFillType( )); 902 path.isInverseFillType( ));
789 } else { 903 } else {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 977
864 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { 978 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
865 // op + region index + clip params 979 // op + region index + clip params
866 uint32_t size = 3 * kUInt32Size; 980 uint32_t size = 3 * kUInt32Size;
867 // recordRestoreOffsetPlaceholder doesn't always write an offset 981 // recordRestoreOffsetPlaceholder doesn't always write an offset
868 if (!fRestoreOffsetStack.isEmpty()) { 982 if (!fRestoreOffsetStack.isEmpty()) {
869 // + restore offset 983 // + restore offset
870 size += kUInt32Size; 984 size += kUInt32Size;
871 } 985 }
872 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); 986 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size);
987 SkASSERT(kInvalidOffset != initialOffset);
873 addRegion(region); 988 addRegion(region);
874 addInt(ClipParams_pack(op, false)); 989 addInt(ClipParams_pack(op, false));
875 recordRestoreOffsetPlaceholder(op); 990 recordRestoreOffsetPlaceholder(op);
876 991
877 validate(initialOffset, size); 992 validate(initialOffset, size);
878 return this->INHERITED::clipRegion(region, op); 993 return this->INHERITED::clipRegion(region, op);
879 } 994 }
880 995
881 void SkPictureRecord::clear(SkColor color) { 996 void SkPictureRecord::clear(SkColor color) {
882 // op + color 997 // op + color
883 uint32_t size = 2 * kUInt32Size; 998 uint32_t size = 2 * kUInt32Size;
884 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); 999 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size);
1000 if (kInvalidOffset == initialOffset) {
Tom Hudson 2013/05/14 17:00:49 Why not asserts here as above?
1001 return;
1002 }
885 addInt(color); 1003 addInt(color);
886 validate(initialOffset, size); 1004 validate(initialOffset, size);
887 } 1005 }
888 1006
889 void SkPictureRecord::drawPaint(const SkPaint& paint) { 1007 void SkPictureRecord::drawPaint(const SkPaint& paint) {
890 // op + paint index 1008 // op + paint index
891 uint32_t size = 2 * kUInt32Size; 1009 uint32_t size = 2 * kUInt32Size;
892 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); 1010 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size);
893 SkASSERT(initialOffset+getPaintOffset(DRAW_PAINT, size) == fWriter.size()); 1011 if (kInvalidOffset == initialOffset) {
1012 return;
1013 }
1014 SkASSERT(initialOffset + getPaintOffset(DRAW_PAINT, size) == fWriter.size()) ;
894 addPaint(paint); 1015 addPaint(paint);
895 validate(initialOffset, size); 1016 validate(initialOffset, size);
896 } 1017 }
897 1018
898 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], 1019 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [],
899 const SkPaint& paint) { 1020 const SkPaint& paint) {
900 // op + paint index + mode + count + point data 1021 // op + paint index + mode + count + point data
901 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); 1022 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint);
1023 #if SK_RECORD_BOUNDS_IN_PICTURE
1024 SkRect bbox;
1025 bbox.set(pts, count);
1026 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size, &paint, &bbox);
1027 #else
902 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size); 1028 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size);
903 SkASSERT(initialOffset+getPaintOffset(DRAW_POINTS, size) == fWriter.size()); 1029 #endif
1030 if (kInvalidOffset == initialOffset) {
1031 return;
1032 }
1033 SkASSERT(initialOffset + getPaintOffset(DRAW_POINTS, size) == fWriter.size() );
904 addPaint(paint); 1034 addPaint(paint);
905 addInt(mode); 1035 addInt(mode);
906 addInt(count); 1036 addInt(count);
907 fWriter.writeMul4(pts, count * sizeof(SkPoint)); 1037 fWriter.writeMul4(pts, count * sizeof(SkPoint));
908 validate(initialOffset, size); 1038 validate(initialOffset, size);
909 } 1039 }
910 1040
911 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { 1041 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) {
912 // op + paint index + rect 1042 // op + paint index + rect
913 uint32_t size = 2 * kUInt32Size + sizeof(oval); 1043 uint32_t size = 2 * kUInt32Size + sizeof(oval);
1044 #if SK_RECORD_BOUNDS_IN_PICTURE
1045 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size, &paint, &oval);
1046 #else
914 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size); 1047 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size);
915 SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size()); 1048 #endif
1049 if (kInvalidOffset == initialOffset) {
1050 return;
1051 }
1052 SkASSERT(initialOffset + getPaintOffset(DRAW_OVAL, size) == fWriter.size());
916 addPaint(paint); 1053 addPaint(paint);
917 addRect(oval); 1054 addRect(oval);
918 validate(initialOffset, size); 1055 validate(initialOffset, size);
919 } 1056 }
920 1057
921 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { 1058 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
922 // op + paint index + rect 1059 // op + paint index + rect
923 uint32_t size = 2 * kUInt32Size + sizeof(rect); 1060 uint32_t size = 2 * kUInt32Size + sizeof(rect);
1061 #if SK_RECORD_BOUNDS_IN_PICTURE
1062 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size, &paint, &rect);
1063 #else
924 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size); 1064 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size);
925 SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size()); 1065 #endif
1066 if (kInvalidOffset == initialOffset) {
1067 return;
1068 }
1069 SkASSERT(initialOffset + getPaintOffset(DRAW_RECT, size) == fWriter.size());
926 addPaint(paint); 1070 addPaint(paint);
927 addRect(rect); 1071 addRect(rect);
928 validate(initialOffset, size); 1072 validate(initialOffset, size);
929 } 1073 }
930 1074
931 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 1075 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
932 if (rrect.isRect()) { 1076 if (rrect.isRect()) {
933 this->SkPictureRecord::drawRect(rrect.getBounds(), paint); 1077 this->SkPictureRecord::drawRect(rrect.getBounds(), paint);
934 } else if (rrect.isOval()) { 1078 } else if (rrect.isOval()) {
935 this->SkPictureRecord::drawOval(rrect.getBounds(), paint); 1079 this->SkPictureRecord::drawOval(rrect.getBounds(), paint);
936 } else { 1080 } else {
937 // op + paint index + rrect 1081 // op + paint index + rrect
938 uint32_t initialOffset, size; 1082 uint32_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory;
939 size = 2 * kUInt32Size + SkRRect::kSizeInMemory; 1083 #if SK_RECORD_BOUNDS_IN_PICTURE
940 initialOffset = this->addDraw(DRAW_RRECT, &size); 1084 uint32_t initialOffset = this->addDraw(DRAW_RRECT, &size, &paint, &rrect .getBounds());
941 SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.size( )); 1085 #else
1086 uint32_t initialOffset = this->addDraw(DRAW_RRECT, &size);
1087 #endif
1088 if (kInvalidOffset == initialOffset) {
1089 return;
1090 }
1091 SkASSERT(initialOffset + getPaintOffset(DRAW_RRECT, size) == fWriter.siz e());
942 addPaint(paint); 1092 addPaint(paint);
943 addRRect(rrect); 1093 addRRect(rrect);
944 validate(initialOffset, size); 1094 validate(initialOffset, size);
945 } 1095 }
946 } 1096 }
947 1097
948 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { 1098 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
949 // op + paint index + path index 1099 // op + paint index + path index
950 uint32_t size = 3 * kUInt32Size; 1100 uint32_t size = 3 * kUInt32Size;
1101 #if SK_RECORD_BOUNDS_IN_PICTURE
1102 const SkRect* bounds = path.isInverseFillType() ? NULL : &path.getBounds();
1103 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size, &paint, bounds);
1104 #else
951 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size); 1105 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size);
952 SkASSERT(initialOffset+getPaintOffset(DRAW_PATH, size) == fWriter.size()); 1106 #endif
1107 if (kInvalidOffset == initialOffset) {
1108 return;
1109 }
1110 SkASSERT(initialOffset + getPaintOffset(DRAW_PATH, size) == fWriter.size());
953 addPaint(paint); 1111 addPaint(paint);
954 addPath(path); 1112 addPath(path);
955 validate(initialOffset, size); 1113 validate(initialOffset, size);
956 } 1114 }
957 1115
958 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 1116 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
959 const SkPaint* paint = NULL) { 1117 const SkPaint* paint = NULL) {
960 // op + paint index + bitmap index + left + top 1118 // op + paint index + bitmap index + left + top
961 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 1119 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
1120 #if SK_RECORD_BOUNDS_IN_PICTURE
1121 SkRect bounds = SkRect::MakeXYWH(left, top, bitmap.width(), bitmap.height()) ;
1122 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size, paint, &bounds);
1123 #else
962 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size); 1124 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size);
963 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP, size) == fWriter.size()); 1125 #endif
1126 if (kInvalidOffset == initialOffset) {
1127 return;
1128 }
1129 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP, size) == fWriter.size() );
964 addPaintPtr(paint); 1130 addPaintPtr(paint);
965 addBitmap(bitmap); 1131 addBitmap(bitmap);
966 addScalar(left); 1132 addScalar(left);
967 addScalar(top); 1133 addScalar(top);
968 validate(initialOffset, size); 1134 validate(initialOffset, size);
969 } 1135 }
970 1136
971 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 1137 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
972 const SkRect& dst, const SkPaint* paint) { 1138 const SkRect& dst, const SkPaint* paint) {
973 // id + paint index + bitmap index + bool for 'src' 1139 // id + paint index + bitmap index + bool for 'src'
974 uint32_t size = 4 * kUInt32Size; 1140 uint32_t size = 4 * kUInt32Size;
975 if (NULL != src) { 1141 if (NULL != src) {
976 size += sizeof(*src); // + rect 1142 size += sizeof(*src); // + rect
977 } 1143 }
978 size += sizeof(dst); // + rect 1144 size += sizeof(dst); // + rect
979 1145
1146 #if SK_RECORD_BOUNDS_IN_PICTURE
1147 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size, pain t, &dst);
1148 #else
980 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); 1149 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size);
981 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == fWr iter.size()); 1150 #endif
1151 if (kInvalidOffset == initialOffset) {
1152 return;
1153 }
1154 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == f Writer.size());
982 addPaintPtr(paint); 1155 addPaintPtr(paint);
983 addBitmap(bitmap); 1156 addBitmap(bitmap);
984 addRectPtr(src); // may be null 1157 addRectPtr(src); // may be null
985 addRect(dst); 1158 addRect(dst);
986 validate(initialOffset, size); 1159 validate(initialOffset, size);
987 } 1160 }
988 1161
989 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, 1162 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix,
990 const SkPaint* paint) { 1163 const SkPaint* paint) {
991 // id + paint index + bitmap index + matrix index 1164 // id + paint index + bitmap index + matrix index
992 uint32_t size = 4 * kUInt32Size; 1165 uint32_t size = 4 * kUInt32Size;
1166 #if SK_RECORD_BOUNDS_IN_PICTURE
1167 SkRect bounds = SkRect::MakeWH(bitmap.width(), bitmap.height());
1168 matrix.mapRect(&bounds);
1169 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size, paint, &bo unds);
1170 #else
993 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); 1171 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size);
994 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.s ize()); 1172 #endif
1173 if (kInvalidOffset == initialOffset) {
1174 return;
1175 }
1176 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter .size());
995 addPaintPtr(paint); 1177 addPaintPtr(paint);
996 addBitmap(bitmap); 1178 addBitmap(bitmap);
997 addMatrix(matrix); 1179 addMatrix(matrix);
998 validate(initialOffset, size); 1180 validate(initialOffset, size);
999 } 1181 }
1000 1182
1001 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, 1183 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er,
1002 const SkRect& dst, const SkPaint* paint) { 1184 const SkRect& dst, const SkPaint* paint) {
1003 // op + paint index + bitmap id + center + dst rect 1185 // op + paint index + bitmap id + center + dst rect
1004 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); 1186 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst);
1187 #if SK_RECORD_BOUNDS_IN_PICTURE
1188 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size, paint, &dst) ;
1189 #else
1005 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); 1190 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size);
1006 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.siz e()); 1191 #endif
1192 if (kInvalidOffset == initialOffset) {
1193 return;
1194 }
1195 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.s ize());
1007 addPaintPtr(paint); 1196 addPaintPtr(paint);
1008 addBitmap(bitmap); 1197 addBitmap(bitmap);
1009 addIRect(center); 1198 addIRect(center);
1010 addRect(dst); 1199 addRect(dst);
1011 validate(initialOffset, size); 1200 validate(initialOffset, size);
1012 } 1201 }
1013 1202
1014 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, 1203 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
1015 const SkPaint* paint = NULL) { 1204 const SkPaint* paint) {
1016 // op + paint index + bitmap index + left + top 1205 // op + paint index + bitmap index + left + top
1017 uint32_t size = 5 * kUInt32Size; 1206 uint32_t size = 5 * kUInt32Size;
1207 // Note: Bounds encoding not supported on drawSprite. Because drawSprite
1208 // ignores the current transform matrix, the bounds will not follow the
1209 // playback canvas's initial tranform matrix at playback time, and
1210 // recorded bounds are assumed to be in the playback canvas' initial
1211 // local frame of reference.
1018 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size); 1212 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size);
1019 SkASSERT(initialOffset+getPaintOffset(DRAW_SPRITE, size) == fWriter.size()); 1213 if (kInvalidOffset == initialOffset) {
1214 return;
1215 }
1216 SkASSERT(initialOffset + getPaintOffset(DRAW_SPRITE, size) == fWriter.size() );
1020 addPaintPtr(paint); 1217 addPaintPtr(paint);
1021 addBitmap(bitmap); 1218 addBitmap(bitmap);
1022 addInt(left); 1219 addInt(left);
1023 addInt(top); 1220 addInt(top);
1024 validate(initialOffset, size); 1221 validate(initialOffset, size);
1025 } 1222 }
1026 1223
1224 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
1027 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been 1225 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been
1028 // tweaked by paint.computeFastBounds(). 1226 // tweaked by paint.computeFastBounds().
1029 // 1227 //
1030 static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2] ) { 1228 static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2] ) {
1031 SkPaint::FontMetrics metrics; 1229 SkPaint::FontMetrics metrics;
1032 paint.getFontMetrics(&metrics); 1230 paint.getFontMetrics(&metrics);
1033 SkRect bounds; 1231 SkRect bounds;
1034 // construct a rect so we can see any adjustments from the paint. 1232 // construct a rect so we can see any adjustments from the paint.
1035 // we use 0,1 for left,right, just so the rect isn't empty 1233 // we use 0,1 for left,right, just so the rect isn't empty
1036 bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom); 1234 bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom);
1037 (void)paint.computeFastBounds(bounds, &bounds); 1235 (void)paint.computeFastBounds(bounds, &bounds);
1038 topbot[0] = bounds.fTop; 1236 topbot[0] = bounds.fTop;
1039 topbot[1] = bounds.fBottom; 1237 topbot[1] = bounds.fBottom;
1040 } 1238 }
1041 1239
1042 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlat Data& flat, 1240 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlat Data& flat,
1043 SkScalar minY, SkScalar maxY) { 1241 SkScalar minY, SkScalar maxY) {
1044 if (!flat.isTopBotWritten()) { 1242 if (!flat.isTopBotWritten()) {
1045 computeFontMetricsTopBottom(paint, flat.writableTopBot()); 1243 computeFontMetricsTopBottom(paint, flat.writableTopBot());
1046 SkASSERT(flat.isTopBotWritten()); 1244 SkASSERT(flat.isTopBotWritten());
1047 } 1245 }
1048 addScalar(flat.topBot()[0] + minY); 1246 addScalar(flat.topBot()[0] + minY);
1049 addScalar(flat.topBot()[1] + maxY); 1247 addScalar(flat.topBot()[1] + maxY);
1050 } 1248 }
1249 #endif
1250
1251 #if SK_RECORD_BOUNDS_IN_PICTURE
1252 static void pad_text_bbox_horizontally(const SkPaint::FontMetrics& metrics, SkRe ct* bbox) {
1253 // Pad horizontal bounds on each side by max vertical extents.
1254 // This is sort of arbitrary, but seems to produce reasonable results.
1255 // If there were a way of getting max glyph X-extents to pad by, that
1256 // may be better here, but FontMetrics fXMin and fXMax seem incorrect
1257 // on most platforms (too small in Linux, never even set in Windows).
1258 SkScalar pad = (metrics.fBottom - metrics.fTop);
1259 SkASSERT(pad > 0);
1260 bbox->fLeft -= pad;
1261 bbox->fRight += pad;
1262 }
1263 #endif
1051 1264
1052 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, 1265 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x,
1053 SkScalar y, const SkPaint& paint) { 1266 SkScalar y, const SkPaint& paint) {
1054 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); 1267 // Note: The DRAW_TEXT_TOP_BOTTOM optimization is redundant if we are
1268 // already recording full bounds.
1055 1269
1056 // op + paint index + length + 'length' worth of chars + x + y 1270 // op + paint index + length + 'length' worth of chars + x + y
1057 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); 1271 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar );
1272
1273 #if SK_RECORD_BOUNDS_IN_PICTURE
1274 SkRect bbox;
1275 paint.measureText(text, byteLength, &bbox);
1276 SkPaint::FontMetrics metrics;
1277 paint.getFontMetrics(&metrics);
1278
1279 // Vertical and aligned text need to be offset
1280 if (paint.isVerticalText()) {
1281 SkScalar h = bbox.fBottom - bbox.fTop;
1282 if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1283 bbox.fTop -= h / 2;
1284 bbox.fBottom -= h / 2;
1285 }
1286 // Pad top and bottom with max extents from FontMetrics
1287 bbox.fBottom += metrics.fBottom;
1288 bbox.fTop += metrics.fTop;
1289 } else {
1290 SkScalar w = bbox.fRight - bbox.fLeft;
1291 if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1292 bbox.fLeft -= w / 2;
1293 bbox.fRight -= w / 2;
1294 } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
1295 bbox.fLeft -= w;
1296 bbox.fRight -= w;
1297 }
1298 // Set vertical bounds to max extents from font metrics
1299 bbox.fTop = metrics.fTop;
1300 bbox.fBottom = metrics.fBottom;
1301 }
1302 pad_text_bbox_horizontally(metrics, &bbox);
1303 bbox.fLeft += x;
1304 bbox.fRight += x;
1305 bbox.fTop += y;
1306 bbox.fBottom += y;
1307 uint32_t initialOffset = this->addDraw(DRAW_TEXT, &size, &paint, &bbox);
1308 #else
1309 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds();
1310
1058 if (fast) { 1311 if (fast) {
1059 size += 2 * sizeof(SkScalar); // + top & bottom 1312 size += 2 * sizeof(SkScalar); // + top & bottom
1060 } 1313 }
1061
1062 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; 1314 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT;
1063 uint32_t initialOffset = this->addDraw(op, &size); 1315 uint32_t initialOffset = this->addDraw(op, &size);
1064 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); 1316 #endif
1317 if (kInvalidOffset == initialOffset) {
1318 return;
1319 }
1320 #if SK_RECORD_BOUNDS_IN_PICTURE
1321 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT, size) == fWriter.size());
1322 #else
1323 SkASSERT(initialOffset + getPaintOffset(op, size) == fWriter.size());
1324 #endif
1065 const SkFlatData* flatPaintData = addPaint(paint); 1325 const SkFlatData* flatPaintData = addPaint(paint);
1066 SkASSERT(flatPaintData);
1067 addText(text, byteLength); 1326 addText(text, byteLength);
1068 addScalar(x); 1327 addScalar(x);
1069 addScalar(y); 1328 addScalar(y);
1329 #if SK_RECORD_BOUNDS_IN_PICTURE
1330 // We still need to call addPaint even if we don't use flatPaintData
1331 sk_ignore_unused_variable(flatPaintData);
1332 #else
1333 SkASSERT(flatPaintData);
1070 if (fast) { 1334 if (fast) {
1071 addFontMetricsTopBottom(paint, *flatPaintData, y, y); 1335 addFontMetricsTopBottom(paint, *flatPaintData, y, y);
1072 } 1336 }
1337 #endif
1073 validate(initialOffset, size); 1338 validate(initialOffset, size);
1074 } 1339 }
1075 1340
1076 void SkPictureRecord::drawPosText(const void* text, size_t byteLength, 1341 void SkPictureRecord::drawPosText(const void* text, size_t byteLength,
1077 const SkPoint pos[], const SkPaint& paint) { 1342 const SkPoint pos[], const SkPaint& paint) {
1078 size_t points = paint.countText(text, byteLength); 1343 size_t points = paint.countText(text, byteLength);
1079 if (0 == points) 1344 if (0 == points)
1080 return; 1345 return;
1081 1346
1082 bool canUseDrawH = true; 1347 bool canUseDrawH = true;
1083 SkScalar minY = pos[0].fY; 1348 SkScalar minY = pos[0].fY;
1084 SkScalar maxY = pos[0].fY; 1349 SkScalar maxY = pos[0].fY;
1085 // check if the caller really should have used drawPosTextH() 1350 // check if the caller really should have used drawPosTextH()
1086 { 1351 {
1087 const SkScalar firstY = pos[0].fY; 1352 const SkScalar firstY = pos[0].fY;
1088 for (size_t index = 1; index < points; index++) { 1353 for (size_t index = 1; index < points; index++) {
1089 if (pos[index].fY != firstY) { 1354 if (pos[index].fY != firstY) {
1090 canUseDrawH = false; 1355 canUseDrawH = false;
1091 if (pos[index].fY < minY) { 1356 if (pos[index].fY < minY) {
1092 minY = pos[index].fY; 1357 minY = pos[index].fY;
1093 } else if (pos[index].fY > maxY) { 1358 } else if (pos[index].fY > maxY) {
1094 maxY = pos[index].fY; 1359 maxY = pos[index].fY;
1095 } 1360 }
1096 } 1361 }
1097 } 1362 }
1098 } 1363 }
1099 1364
1365 // Note: The DRAW_TEXT_[H_]TOP_BOTTOM optimization is redundant if we are
1366 // already recording full bounds.
1367 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
1100 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds(); 1368 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds();
1101 bool fast = canUseDrawH && fastBounds; 1369 bool fast = canUseDrawH && fastBounds;
1370 #endif
1102 1371
1103 // op + paint index + length + 'length' worth of data + num points 1372 // op + paint index + length + 'length' worth of data + num points
1104 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; 1373 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size;
1105 if (canUseDrawH) { 1374 if (canUseDrawH) {
1375 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
1106 if (fast) { 1376 if (fast) {
1107 size += 2 * sizeof(SkScalar); // + top & bottom 1377 size += 2 * sizeof(SkScalar); // + top & bottom
1108 } 1378 }
1379 #endif
1109 // + y-pos + actual x-point data 1380 // + y-pos + actual x-point data
1110 size += sizeof(SkScalar) + points * sizeof(SkScalar); 1381 size += sizeof(SkScalar) + points * sizeof(SkScalar);
1111 } else { 1382 } else {
1112 // + x&y point data 1383 // + x&y point data
1113 size += points * sizeof(SkPoint); 1384 size += points * sizeof(SkPoint);
1385 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
1114 if (fastBounds) { 1386 if (fastBounds) {
1115 size += 2 * sizeof(SkScalar); // + top & bottom 1387 size += 2 * sizeof(SkScalar); // + top & bottom
1116 } 1388 }
1389 #endif
1117 } 1390 }
1118 1391
1119 DrawType op; 1392 DrawType op;
1393 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
1120 if (fast) { 1394 if (fast) {
1121 op = DRAW_POS_TEXT_H_TOP_BOTTOM; 1395 op = DRAW_POS_TEXT_H_TOP_BOTTOM;
1122 } else if (canUseDrawH) { 1396 } else
1397 #endif
1398 if (canUseDrawH) {
1123 op = DRAW_POS_TEXT_H; 1399 op = DRAW_POS_TEXT_H;
1400 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
1124 } else if (fastBounds) { 1401 } else if (fastBounds) {
1125 op = DRAW_POS_TEXT_TOP_BOTTOM; 1402 op = DRAW_POS_TEXT_TOP_BOTTOM;
1403 #endif
1126 } else { 1404 } else {
1127 op = DRAW_POS_TEXT; 1405 op = DRAW_POS_TEXT;
1128 } 1406 }
1407 #if SK_RECORD_BOUNDS_IN_PICTURE
1408 SkRect bbox;
1409 bbox.set(pos, paint.countText(text, byteLength));
1410 SkPaint::FontMetrics metrics;
1411 paint.getFontMetrics(&metrics);
1412 bbox.fTop += metrics.fTop;
1413 bbox.fBottom += metrics.fBottom;
1414
1415 // pad on left and right by half of max vertical glyph extents
1416 pad_text_bbox_horizontally(metrics, &bbox);
1417 uint32_t initialOffset = this->addDraw(op, &size, &paint, &bbox);
1418 #else
1129 uint32_t initialOffset = this->addDraw(op, &size); 1419 uint32_t initialOffset = this->addDraw(op, &size);
1130 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); 1420 #endif
1421 if (kInvalidOffset == initialOffset) {
1422 return;
1423 }
1424 SkASSERT(initialOffset + getPaintOffset(op, size) == fWriter.size());
1131 const SkFlatData* flatPaintData = addPaint(paint); 1425 const SkFlatData* flatPaintData = addPaint(paint);
1132 SkASSERT(flatPaintData); 1426 SkASSERT(flatPaintData);
1133 addText(text, byteLength); 1427 addText(text, byteLength);
1134 addInt(points); 1428 addInt(points);
1135 1429
1136 #ifdef SK_DEBUG_SIZE 1430 #ifdef SK_DEBUG_SIZE
1137 size_t start = fWriter.size(); 1431 size_t start = fWriter.size();
1138 #endif 1432 #endif
1139 if (canUseDrawH) { 1433 if (canUseDrawH) {
1434 #if SK_RECORD_BOUNDS_IN_PICTURE
1435 // We still need to call addPaint even if we don't use flatPaintData
1436 sk_ignore_unused_variable(flatPaintData);
1437 #else
1140 if (fast) { 1438 if (fast) {
1141 addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY) ; 1439 addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY) ;
1142 } 1440 }
1441 #endif
1143 addScalar(pos[0].fY); 1442 addScalar(pos[0].fY);
1144 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); 1443 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar));
1145 for (size_t index = 0; index < points; index++) 1444 for (size_t index = 0; index < points; index++)
1146 *xptr++ = pos[index].fX; 1445 *xptr++ = pos[index].fX;
1147 } else { 1446 } else {
1148 fWriter.writeMul4(pos, points * sizeof(SkPoint)); 1447 fWriter.writeMul4(pos, points * sizeof(SkPoint));
1448 #if SK_RECORD_BOUNDS_IN_PICTURE
1449 // We still need to call addPaint even if we don't use flatPaintData
1450 sk_ignore_unused_variable(flatPaintData);
1451 #else
1149 if (fastBounds) { 1452 if (fastBounds) {
1150 addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY); 1453 addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY);
1151 } 1454 }
1455 #endif
1152 } 1456 }
1153 #ifdef SK_DEBUG_SIZE 1457 #ifdef SK_DEBUG_SIZE
1154 fPointBytes += fWriter.size() - start; 1458 fPointBytes += fWriter.size() - start;
1155 fPointWrites += points; 1459 fPointWrites += points;
1156 #endif 1460 #endif
1157 validate(initialOffset, size); 1461 validate(initialOffset, size);
1158 } 1462 }
1159 1463
1160 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, 1464 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength,
1161 const SkScalar xpos[], SkScalar constY, 1465 const SkScalar xpos[], SkScalar constY,
1162 const SkPaint& paint) { 1466 const SkPaint& paint) {
1163 size_t points = paint.countText(text, byteLength); 1467 size_t numChars = paint.countText(text, byteLength);
1164 if (0 == points) 1468 if (0 == numChars)
1165 return; 1469 return;
1166 1470
1167 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds();
1168
1169 // op + paint index + length + 'length' worth of data + num points 1471 // op + paint index + length + 'length' worth of data + num points
1170 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; 1472 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size;
1473
1474 // Note: The DRAW_POS_TEXT_H_TOP_BOTTOM optimization is redundant if we are
1475 // already recording full bounds.
1476 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
1477 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds();
1171 if (fast) { 1478 if (fast) {
1172 size += 2 * sizeof(SkScalar); // + top & bottom 1479 size += 2 * sizeof(SkScalar); // + top & bottom
1173 } 1480 }
1481 #endif
1482
1174 // + y + the actual points 1483 // + y + the actual points
1175 size += 1 * kUInt32Size + points * sizeof(SkScalar); 1484 size += 1 * kUInt32Size + numChars * sizeof(SkScalar);
1176 1485
1486 #if SK_RECORD_BOUNDS_IN_PICTURE
1487 SkRect bbox;
1488 bbox.fLeft = xpos[0];
1489 bbox.fRight = xpos[numChars - 1];
1490 // if we had a guarantee that these will be monotonically increasing, this c ould be sped up
Tom Hudson 2013/05/14 17:00:49 Would this break on RTL? Do we have a guarantee th
1491 for (size_t i = 0; i < numChars; ++i) {
1492 if (xpos[i] < bbox.fLeft) {
1493 bbox.fLeft = xpos[i];
1494 }
1495 if (xpos[i] > bbox.fRight) {
1496 bbox.fRight = xpos[i];
1497 }
1498 }
1499 SkPaint::FontMetrics metrics;
1500 paint.getFontMetrics(&metrics);
1501 pad_text_bbox_horizontally(metrics, &bbox);
1502 bbox.fTop = metrics.fTop + constY;
1503 bbox.fBottom = metrics.fBottom + constY;
1504 uint32_t initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size, &paint, &bbox );
1505 #else
1177 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H, 1506 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H,
1178 &size); 1507 &size);
1508 #endif
1509 if (kInvalidOffset == initialOffset) {
1510 return;
1511 }
1512 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter. size());
1179 const SkFlatData* flatPaintData = addPaint(paint); 1513 const SkFlatData* flatPaintData = addPaint(paint);
1180 SkASSERT(flatPaintData); 1514 SkASSERT(flatPaintData);
1181 addText(text, byteLength); 1515 addText(text, byteLength);
1182 addInt(points); 1516 addInt(numChars);
1183 1517
1184 #ifdef SK_DEBUG_SIZE 1518 #ifdef SK_DEBUG_SIZE
1185 size_t start = fWriter.size(); 1519 size_t start = fWriter.size();
1186 #endif 1520 #endif
1521 #if SK_RECORD_BOUNDS_IN_PICTURE
1522 // We still need to call addPaint even if we don't use flatPaintData
1523 sk_ignore_unused_variable(flatPaintData);
1524 #else
1187 if (fast) { 1525 if (fast) {
1188 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); 1526 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY);
1189 } 1527 }
1528 #endif
1190 addScalar(constY); 1529 addScalar(constY);
1191 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); 1530 fWriter.writeMul4(xpos, numChars * sizeof(SkScalar));
1192 #ifdef SK_DEBUG_SIZE 1531 #ifdef SK_DEBUG_SIZE
1193 fPointBytes += fWriter.size() - start; 1532 fPointBytes += fWriter.size() - start;
1194 fPointWrites += points; 1533 fPointWrites += points;
1195 #endif 1534 #endif
1196 validate(initialOffset, size); 1535 validate(initialOffset, size);
1197 } 1536 }
1198 1537
1199 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, 1538 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength,
1200 const SkPath& path, const SkMatrix* matrix, 1539 const SkPath& path, const SkMatrix* matrix,
1201 const SkPaint& paint) { 1540 const SkPaint& paint) {
1202 // op + paint index + length + 'length' worth of data + path index + matrix index 1541 // op + paint index + length + 'length' worth of data + path index + matrix index
1203 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; 1542 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size;
1543 #if SK_RECORD_BOUNDS_IN_PICTURE
1544 SkRect bbox = path.getBounds();
1545 SkPaint::FontMetrics metrics;
1546 paint.getFontMetrics(&metrics);
1547 // pad out all sides by the max glyph height above baseline
1548 SkScalar pad = metrics.fTop;
1549 bbox.fLeft += pad;
1550 bbox.fRight -= pad;
1551 bbox.fTop += pad;
1552 bbox.fBottom -= pad;
1553 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size, &paint, &bb ox);
1554 #else
1204 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); 1555 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size);
1205 SkASSERT(initialOffset+getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter.si ze()); 1556 #endif
1557 if (kInvalidOffset == initialOffset) {
1558 return;
1559 }
1560 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter. size());
1206 addPaint(paint); 1561 addPaint(paint);
1207 addText(text, byteLength); 1562 addText(text, byteLength);
1208 addPath(path); 1563 addPath(path);
1209 addMatrixPtr(matrix); 1564 addMatrixPtr(matrix);
1210 validate(initialOffset, size); 1565 validate(initialOffset, size);
1211 } 1566 }
1212 1567
1213 void SkPictureRecord::drawPicture(SkPicture& picture) { 1568 void SkPictureRecord::drawPicture(SkPicture& picture) {
1214 // op + picture index 1569 // op + picture index
1215 uint32_t size = 2 * kUInt32Size; 1570 uint32_t size = 2 * kUInt32Size;
1216 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size); 1571 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size);
1572 SkASSERT(kInvalidOffset != initialOffset);
1217 addPicture(picture); 1573 addPicture(picture);
1218 validate(initialOffset, size); 1574 validate(initialOffset, size);
1219 } 1575 }
1220 1576
1221 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, 1577 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount,
1222 const SkPoint vertices[], const SkPoint texs[], 1578 const SkPoint vertices[], const SkPoint texs[],
1223 const SkColor colors[], SkXfermode*, 1579 const SkColor colors[], SkXfermode*,
1224 const uint16_t indices[], int indexCount, 1580 const uint16_t indices[], int indexCount,
1225 const SkPaint& paint) { 1581 const SkPaint& paint) {
1226 uint32_t flags = 0; 1582 uint32_t flags = 0;
(...skipping 12 matching lines...) Expand all
1239 if (flags & DRAW_VERTICES_HAS_TEXS) { 1595 if (flags & DRAW_VERTICES_HAS_TEXS) {
1240 size += vertexCount * sizeof(SkPoint); // + uvs 1596 size += vertexCount * sizeof(SkPoint); // + uvs
1241 } 1597 }
1242 if (flags & DRAW_VERTICES_HAS_COLORS) { 1598 if (flags & DRAW_VERTICES_HAS_COLORS) {
1243 size += vertexCount * sizeof(SkColor); // + vert colors 1599 size += vertexCount * sizeof(SkColor); // + vert colors
1244 } 1600 }
1245 if (flags & DRAW_VERTICES_HAS_INDICES) { 1601 if (flags & DRAW_VERTICES_HAS_INDICES) {
1246 // + num indices + indices 1602 // + num indices + indices
1247 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); 1603 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t));
1248 } 1604 }
1249 1605 #if SK_RECORD_BOUNDS_IN_PICTURE
1606 SkRect bbox;
1607 bbox.set(vertices, vertexCount);
1608 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size, &paint, &bbox);
1609 #else
1250 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size); 1610 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size);
1251 SkASSERT(initialOffset+getPaintOffset(DRAW_VERTICES, size) == fWriter.size() ); 1611 #endif
1612 if (kInvalidOffset == initialOffset) {
1613 return;
1614 }
1615 SkASSERT(initialOffset + getPaintOffset(DRAW_VERTICES, size) == fWriter.size ());
1252 addPaint(paint); 1616 addPaint(paint);
1253 addInt(flags); 1617 addInt(flags);
1254 addInt(vmode); 1618 addInt(vmode);
1255 addInt(vertexCount); 1619 addInt(vertexCount);
1256 addPoints(vertices, vertexCount); 1620 addPoints(vertices, vertexCount);
1257 if (flags & DRAW_VERTICES_HAS_TEXS) { 1621 if (flags & DRAW_VERTICES_HAS_TEXS) {
1258 addPoints(texs, vertexCount); 1622 addPoints(texs, vertexCount);
1259 } 1623 }
1260 if (flags & DRAW_VERTICES_HAS_COLORS) { 1624 if (flags & DRAW_VERTICES_HAS_COLORS) {
1261 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); 1625 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor));
1262 } 1626 }
1263 if (flags & DRAW_VERTICES_HAS_INDICES) { 1627 if (flags & DRAW_VERTICES_HAS_INDICES) {
1264 addInt(indexCount); 1628 addInt(indexCount);
1265 fWriter.writePad(indices, indexCount * sizeof(uint16_t)); 1629 fWriter.writePad(indices, indexCount * sizeof(uint16_t));
1266 } 1630 }
1267 validate(initialOffset, size); 1631 validate(initialOffset, size);
1268 } 1632 }
1269 1633
1270 void SkPictureRecord::drawData(const void* data, size_t length) { 1634 void SkPictureRecord::drawData(const void* data, size_t length) {
1271 // op + length + 'length' worth of data 1635 // op + length + 'length' worth of data
1272 uint32_t size = 2 * kUInt32Size + SkAlign4(length); 1636 uint32_t size = 2 * kUInt32Size + SkAlign4(length);
1273 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size); 1637 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size);
1638 SkASSERT(kInvalidOffset != initialOffset);
1274 addInt(length); 1639 addInt(length);
1275 fWriter.writePad(data, length); 1640 fWriter.writePad(data, length);
1276 validate(initialOffset, size); 1641 validate(initialOffset, size);
1277 } 1642 }
1278 1643
1279 /////////////////////////////////////////////////////////////////////////////// 1644 ///////////////////////////////////////////////////////////////////////////////
1280 1645
1281 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { 1646 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
1282 const int index = fBitmapHeap->insert(bitmap); 1647 const int index = fBitmapHeap->insert(bitmap);
1283 // In debug builds, a bad return value from insert() will crash, allowing fo r debugging. In 1648 // In debug builds, a bad return value from insert() will crash, allowing fo r debugging. In
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 void SkPictureRecord::validateRegions() const { 1877 void SkPictureRecord::validateRegions() const {
1513 int count = fRegions.count(); 1878 int count = fRegions.count();
1514 SkASSERT((unsigned) count < 0x1000); 1879 SkASSERT((unsigned) count < 0x1000);
1515 for (int index = 0; index < count; index++) { 1880 for (int index = 0; index < count; index++) {
1516 const SkFlatData* region = fRegions[index]; 1881 const SkFlatData* region = fRegions[index];
1517 SkASSERT(region); 1882 SkASSERT(region);
1518 // region->validate(); 1883 // region->validate();
1519 } 1884 }
1520 } 1885 }
1521 #endif 1886 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698