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

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, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/core/SkPictureRecord.h ('K') | « src/core/SkPictureRecord.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 SkPictureRecord::~SkPictureRecord() { 54 SkPictureRecord::~SkPictureRecord() {
55 SkSafeUnref(fBitmapHeap); 55 SkSafeUnref(fBitmapHeap);
56 SkSafeUnref(fPathHeap); 56 SkSafeUnref(fPathHeap);
57 SkSafeUnref(fBoundingHierarchy); 57 SkSafeUnref(fBoundingHierarchy);
58 SkSafeUnref(fStateTree); 58 SkSafeUnref(fStateTree);
59 fFlattenableHeap.setBitmapStorage(NULL); 59 fFlattenableHeap.setBitmapStorage(NULL);
60 fPictureRefs.unrefAll(); 60 fPictureRefs.unrefAll();
61 } 61 }
62 62
63 /////////////////////////////////////////////////////////////////////////////// 63 ///////////////////////////////////////////////////////////////////////////////
64 64
robertphillips 2013/03/08 20:40:04 comment - esp w.r.t. modifies state
Justin Novosad 2013/03/08 22:35:42 Done.
65 enum DrawTypeFlags {
66 kHasPaint_DrawTypeFlag = 1 << 0,
67 kModifiesState_DrawTypeFlag = 1 << 1,
68 kCanRecordBounds_DrawTypeFlag = 1 << 2,
69 };
70
71 static const uint8_t gDrawTypeInfo[LAST_DRAWTYPE_ENUM + 1] = {
72 0, // UNUSED
73 kModifiesState_DrawTypeFlag, // CLIP_PATH
74 kModifiesState_DrawTypeFlag, // CLIP_REGION
75 kModifiesState_DrawTypeFlag, // CLIP_RECT
76 kModifiesState_DrawTypeFlag, // CLIP_RRECT
77 kModifiesState_DrawTypeFlag, // CONCAT
78 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP
79 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_MATR IX
80 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_NINE
81 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_RECT _TO_RECT
82 0, // DRAW_CLEAR
83 0, // DRAW_DATA
84 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_OVAL
85 kHasPaint_DrawTypeFlag, // DRAW_PAINT
86 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_PATH
87 kModifiesState_DrawTypeFlag, // DRAW_PICTURE
88 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POINTS
89 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POS_TEXT
90 kHasPaint_DrawTypeFlag, // DRAW_POS_TEXT_TO P_BOTTOM
91 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POS_TEXT_H
92 kHasPaint_DrawTypeFlag, // DRAW_POS_TEXT_H_ TOP_BOTTOM
93 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_RECT
94 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_RRECT
95 kHasPaint_DrawTypeFlag, // DRAW_SPRITE
96 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_TEXT
97 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_TEXT_ON_PAT H
98 kHasPaint_DrawTypeFlag, // DRAW_TEXT_TOP_BO TTOM
99 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_VERTICES
100 kModifiesState_DrawTypeFlag, // RESTORE
101 kModifiesState_DrawTypeFlag, // ROTATE
102 kModifiesState_DrawTypeFlag, // SAVE
103 kHasPaint_DrawTypeFlag | kModifiesState_DrawTypeFlag, // SAVE_LAYER
104 kModifiesState_DrawTypeFlag, // SCALE
105 kModifiesState_DrawTypeFlag, // SET_MATRIX
106 kModifiesState_DrawTypeFlag, // SKEW
107 kModifiesState_DrawTypeFlag, // TRANSLATE
108 0, // NOOP
109 };
110
111 bool SkPictureRecord::canRecordBounds(DrawType op) {
112 #if SK_RECORD_BOUNDS_IN_PICTURE
113 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM);
114 return SkToBool(gDrawTypeInfo[op] & kCanRecordBounds_DrawTypeFlag);
115 #else
116 return false;
117 #endif
118 }
119
robertphillips 2013/03/08 20:40:04 modifies_state
Justin Novosad 2013/03/08 22:35:42 Done.
120 static inline bool modifiesState(DrawType op) {
121 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM);
122 return SkToBool(gDrawTypeInfo[op] & kModifiesState_DrawTypeFlag);
123 }
124
65 // Return the offset of the paint inside a given op's byte stream. A zero 125 // Return the offset of the paint inside a given op's byte stream. A zero
66 // return value means there is no paint (and you really shouldn't be calling 126 // return value means there is no paint (and you really shouldn't be calling
67 // this method) 127 // this method)
68 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { 128 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) {
69 // These offsets are where the paint would be if the op size doesn't overflo w 129 // These offsets are where the paint would be if the op size doesn't overflo w
70 static const uint8_t gPaintOffsets[LAST_DRAWTYPE_ENUM + 1] = {
71 0, // UNUSED - no paint
72 0, // CLIP_PATH - no paint
73 0, // CLIP_REGION - no paint
74 0, // CLIP_RECT - no paint
75 0, // CLIP_RRECT - no paint
76 0, // CONCAT - no paint
77 1, // DRAW_BITMAP - right after op code
78 1, // DRAW_BITMAP_MATRIX - right after op code
79 1, // DRAW_BITMAP_NINE - right after op code
80 1, // DRAW_BITMAP_RECT_TO_RECT - right after op code
81 0, // DRAW_CLEAR - no paint
82 0, // DRAW_DATA - no paint
83 1, // DRAW_OVAL - right after op code
84 1, // DRAW_PAINT - right after op code
85 1, // DRAW_PATH - right after op code
86 0, // DRAW_PICTURE - no paint
87 1, // DRAW_POINTS - right after op code
88 1, // DRAW_POS_TEXT - right after op code
89 1, // DRAW_POS_TEXT_TOP_BOTTOM - right after op code
90 1, // DRAW_POS_TEXT_H - right after op code
91 1, // DRAW_POS_TEXT_H_TOP_BOTTOM - right after op code
92 1, // DRAW_RECT - right after op code
93 1, // DRAW_RRECT - right after op code
94 1, // DRAW_SPRITE - right after op code
95 1, // DRAW_TEXT - right after op code
96 1, // DRAW_TEXT_ON_PATH - right after op code
97 1, // DRAW_TEXT_TOP_BOTTOM - right after op code
98 1, // DRAW_VERTICES - right after op code
99 0, // RESTORE - no paint
100 0, // ROTATE - no paint
101 0, // SAVE - no paint
102 0, // SAVE_LAYER - see below - this paint's location varies
103 0, // SCALE - no paint
104 0, // SET_MATRIX - no paint
105 0, // SKEW - no paint
106 0, // TRANSLATE - no paint
107 0, // NOOP - no paint
108 };
109
110 SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1);
111 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); 130 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM);
112 131
robertphillips 2013/03/08 20:40:04 op and 24bit size
Justin Novosad 2013/03/08 22:35:42 Done.
113 int overflow = 0; 132 int offset = sizeof(uint32_t); // storage for op
114 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { 133 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) {
115 // This op's size overflows so an extra uint32_t will be written 134 // This op's size overflows so an extra uint32_t will be written
116 // after the op code 135 // after the op code
117 overflow = sizeof(uint32_t); 136 offset += sizeof(uint32_t);
137 }
138 if (SkPictureRecord::canRecordBounds(op)) {
139 offset += sizeof(SkIRect);
118 } 140 }
119 141
120 if (SAVE_LAYER == op) { 142 if (SAVE_LAYER == op) {
121 static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; 143 static const uint32_t kSaveLayerNoBoundsPaintOffset = kUInt32Size;
122 static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); 144 static const uint32_t kSaveLayerWithBoundsPaintOffset = kUInt32Size + si zeof(SkRect);
123 145
124 if (kSaveLayerNoBoundsSize == opSize) { 146 if (kSaveLayerNoBoundsSize == opSize) {
125 return kSaveLayerNoBoundsPaintOffset + overflow; 147 offset += kSaveLayerNoBoundsPaintOffset;
126 } else { 148 } else {
127 SkASSERT(kSaveLayerWithBoundsSize == opSize); 149 SkASSERT(kSaveLayerWithBoundsSize == opSize);
128 return kSaveLayerWithBoundsPaintOffset + overflow; 150 offset += kSaveLayerWithBoundsPaintOffset;
129 } 151 }
130 } 152 }
131 153
robertphillips 2013/03/08 20:40:04 overlength line
Justin Novosad 2013/03/08 22:35:42 Done.
132 SkASSERT(0 != gPaintOffsets[op]); // really shouldn't be calling this meth od 154 SkASSERT(kHasPaint_DrawTypeFlag & gDrawTypeInfo[op]); // really shouldn't be calling this method
robertphillips 2013/03/08 20:40:04 What's up with this comment
Justin Novosad 2013/03/08 22:35:42 Done.
133 return gPaintOffsets[op] * sizeof(uint32_t) + overflow; 155 // Built-in assumption that the paint
156 return offset;
134 } 157 }
135 158
136 SkDevice* SkPictureRecord::setDevice(SkDevice* device) { 159 SkDevice* SkPictureRecord::setDevice(SkDevice* device) {
137 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");
138 return this->INHERITED::setDevice(device); 161 return this->INHERITED::setDevice(device);
139 } 162 }
140 163
141 int SkPictureRecord::save(SaveFlags flags) { 164 int SkPictureRecord::save(SaveFlags flags) {
142 // 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
143 // from a clip entry. 166 // from a clip entry.
144 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); 167 fRestoreOffsetStack.push(-(int32_t)fWriter.size());
145 168
146 // op + flags 169 // op + flags
147 uint32_t size = 2 * kUInt32Size; 170 uint32_t size = 2 * kUInt32Size;
148 uint32_t initialOffset = this->addDraw(SAVE, &size); 171 uint32_t initialOffset = this->addDraw(SAVE, &size);
172 SkASSERT(kInvalidOffset != initialOffset);
149 addInt(flags); 173 addInt(flags);
150 174
151 validate(initialOffset, size); 175 validate(initialOffset, size);
152 return this->INHERITED::save(flags); 176 return this->INHERITED::save(flags);
153 } 177 }
154 178
155 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, 179 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint,
156 SaveFlags flags) { 180 SaveFlags flags) {
157 // 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
158 // from a clip entry. 182 // from a clip entry.
159 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); 183 fRestoreOffsetStack.push(-(int32_t)fWriter.size());
160 184
161 // op + bool for 'bounds' 185 // op + bool for 'bounds'
162 uint32_t size = 2 * kUInt32Size; 186 uint32_t size = 2 * kUInt32Size;
163 if (NULL != bounds) { 187 if (NULL != bounds) {
164 size += sizeof(*bounds); // + rect 188 size += sizeof(*bounds); // + rect
165 } 189 }
166 // + paint index + flags 190 // + paint index + flags
167 size += 2 * kUInt32Size; 191 size += 2 * kUInt32Size;
168 192
169 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; 193 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ;
170 194
171 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); 195 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size);
196 SkASSERT(kInvalidOffset != initialOffset);
172 addRectPtr(bounds); 197 addRectPtr(bounds);
173 SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.size()); 198 SkASSERT(initialOffset + getPaintOffset(SAVE_LAYER, size) == fWriter.size()) ;
174 addPaintPtr(paint); 199 addPaintPtr(paint);
175 addInt(flags); 200 addInt(flags);
176 201
177 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { 202 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) {
178 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); 203 fFirstSavedLayerIndex = fRestoreOffsetStack.count();
179 } 204 }
180 205
181 validate(initialOffset, size); 206 validate(initialOffset, size);
182 /* 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
183 offscreen device (potentially very big) which we don't actually need 208 offscreen device (potentially very big) which we don't actually need
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) && 445 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) &&
421 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints)) { 446 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints)) {
422 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); 447 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ());
423 // op 448 // op
424 size = 1 * kUInt32Size; 449 size = 1 * kUInt32Size;
425 initialOffset = this->addDraw(RESTORE, &size); 450 initialOffset = this->addDraw(RESTORE, &size);
426 } else { 451 } else {
427 size = 0; 452 size = 0;
428 initialOffset = fWriter.size(); 453 initialOffset = fWriter.size();
429 } 454 }
455 SkASSERT(kInvalidOffset != initialOffset);
430 456
431 fRestoreOffsetStack.pop(); 457 fRestoreOffsetStack.pop();
432 458
433 validate(initialOffset, size); 459 validate(initialOffset, size);
434 return this->INHERITED::restore(); 460 return this->INHERITED::restore();
435 } 461 }
436 462
463 uint32_t SkPictureRecord::addDraw(DrawType drawType, uint32_t* size,
464 const SkPaint* paint, const SkRect* localBound s) {
465 SkIRect devClipBounds; // Bounds of the current clip in device space
466 if (!modifiesState(drawType) && !this->getClipDeviceBounds(&devClipBounds)) {
467 // Optimize-out calls that are clipped-out. State modifying commands
468 // can not be optimized-out because they may have an impact on future ca lls
469 // if the clip is ever expanded. For example, with a union clip op.
470 return kInvalidOffset;
471 }
472 #if SK_RECORD_BOUNDS_IN_PICTURE
473 bool writeBounds = canRecordBounds(drawType);
474 SkIRect clippedDevBounds; // Bounds of the clipped draw in device space
475 if (writeBounds) {
476 SkASSERT(!modifiesState(drawType)); // Ensure devClipBounds is initiali zed
477 if (NULL == localBounds || (NULL != paint && !paint->canComputeFastBound s())) {
478 clippedDevBounds = devClipBounds;
479 } else {
480 SkRect paintBounds;
481 SkRect rectifiedBounds = *localBounds;
482 rectifiedBounds.sort();
483 if (NULL != paint) {
484 if (drawType == DRAW_POINTS) {
485 paintBounds = paint->computeFastStrokeBounds(rectifiedBounds , &paintBounds);
486 } else {
487 paintBounds = paint->computeFastBounds(rectifiedBounds, &pai ntBounds);
488 }
489 } else {
490 paintBounds = *localBounds;
491 }
492 if (paintBounds.isEmpty()) {
493 // Area affected by draw op is empty even after accounting
494 // for stroke width.
495 return kInvalidOffset;
496 }
497 SkRect devBounds;
498 this->getTotalMatrix().mapRect(&devBounds, paintBounds);
499 devBounds.roundOut(&clippedDevBounds);
500 if (!clippedDevBounds.intersect(devClipBounds)) {
501 // Draw lies outside of clip. The clip can only get further
502 // restricted at playback time, so it is safe to reject during
503 // record stage.
504 return kInvalidOffset;
505 }
506 }
507 *size += sizeof(SkIRect);
508 }
509 #endif
510
511 uint32_t offset = fWriter.size();
512
513 this->predrawNotify();
514
515 #ifdef SK_DEBUG_TRACE
516 SkDebugf("add %s\n", DrawTypeToString(drawType));
517 #endif
518 SkASSERT(0 != *size);
519 SkASSERT(((uint8_t) drawType) == drawType);
520 if (0 != (*size & ~MASK_24) || *size == MASK_24) {
521 fWriter.writeInt(PACK_8_24(drawType, MASK_24));
522 *size += 1;
523 fWriter.writeInt(*size);
524 } else {
525 fWriter.writeInt(PACK_8_24(drawType, *size));
526 }
527
528 #if SK_RECORD_BOUNDS_IN_PICTURE
529 if (writeBounds) {
530 fWriter.write(&clippedDevBounds, sizeof(clippedDevBounds));
531 }
532 #endif
533
534 return offset;
535 }
536
437 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { 537 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) {
438 // op + dx + dy 538 // op + dx + dy
439 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 539 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
440 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); 540 uint32_t initialOffset = this->addDraw(TRANSLATE, &size);
541 SkASSERT(kInvalidOffset != initialOffset);
441 addScalar(dx); 542 addScalar(dx);
442 addScalar(dy); 543 addScalar(dy);
443 validate(initialOffset, size); 544 validate(initialOffset, size);
444 return this->INHERITED::translate(dx, dy); 545 return this->INHERITED::translate(dx, dy);
445 } 546 }
446 547
447 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { 548 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) {
448 // op + sx + sy 549 // op + sx + sy
449 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 550 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
450 uint32_t initialOffset = this->addDraw(SCALE, &size); 551 uint32_t initialOffset = this->addDraw(SCALE, &size);
552 SkASSERT(kInvalidOffset != initialOffset);
451 addScalar(sx); 553 addScalar(sx);
452 addScalar(sy); 554 addScalar(sy);
453 validate(initialOffset, size); 555 validate(initialOffset, size);
454 return this->INHERITED::scale(sx, sy); 556 return this->INHERITED::scale(sx, sy);
455 } 557 }
456 558
457 bool SkPictureRecord::rotate(SkScalar degrees) { 559 bool SkPictureRecord::rotate(SkScalar degrees) {
458 // op + degrees 560 // op + degrees
459 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar); 561 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar);
460 uint32_t initialOffset = this->addDraw(ROTATE, &size); 562 uint32_t initialOffset = this->addDraw(ROTATE, &size);
563 SkASSERT(kInvalidOffset != initialOffset);
461 addScalar(degrees); 564 addScalar(degrees);
462 validate(initialOffset, size); 565 validate(initialOffset, size);
463 return this->INHERITED::rotate(degrees); 566 return this->INHERITED::rotate(degrees);
464 } 567 }
465 568
466 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { 569 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) {
467 // op + sx + sy 570 // op + sx + sy
468 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 571 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
469 uint32_t initialOffset = this->addDraw(SKEW, &size); 572 uint32_t initialOffset = this->addDraw(SKEW, &size);
573 SkASSERT(kInvalidOffset != initialOffset);
470 addScalar(sx); 574 addScalar(sx);
471 addScalar(sy); 575 addScalar(sy);
472 validate(initialOffset, size); 576 validate(initialOffset, size);
473 return this->INHERITED::skew(sx, sy); 577 return this->INHERITED::skew(sx, sy);
474 } 578 }
475 579
476 bool SkPictureRecord::concat(const SkMatrix& matrix) { 580 bool SkPictureRecord::concat(const SkMatrix& matrix) {
477 validate(fWriter.size(), 0); 581 validate(fWriter.size(), 0);
478 // op + matrix index 582 // op + matrix index
479 uint32_t size = 2 * kUInt32Size; 583 uint32_t size = 2 * kUInt32Size;
480 uint32_t initialOffset = this->addDraw(CONCAT, &size); 584 uint32_t initialOffset = this->addDraw(CONCAT, &size);
585 SkASSERT(kInvalidOffset != initialOffset);
481 addMatrix(matrix); 586 addMatrix(matrix);
482 validate(initialOffset, size); 587 validate(initialOffset, size);
483 return this->INHERITED::concat(matrix); 588 return this->INHERITED::concat(matrix);
484 } 589 }
485 590
486 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { 591 void SkPictureRecord::setMatrix(const SkMatrix& matrix) {
487 validate(fWriter.size(), 0); 592 validate(fWriter.size(), 0);
488 // op + matrix index 593 // op + matrix index
489 uint32_t size = 2 * kUInt32Size; 594 uint32_t size = 2 * kUInt32Size;
490 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size); 595 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size);
596 SkASSERT(kInvalidOffset != initialOffset);
491 addMatrix(matrix); 597 addMatrix(matrix);
492 validate(initialOffset, size); 598 validate(initialOffset, size);
493 this->INHERITED::setMatrix(matrix); 599 this->INHERITED::setMatrix(matrix);
494 } 600 }
495 601
496 static bool regionOpExpands(SkRegion::Op op) { 602 static bool regionOpExpands(SkRegion::Op op) {
497 switch (op) { 603 switch (op) {
498 case SkRegion::kUnion_Op: 604 case SkRegion::kUnion_Op:
499 case SkRegion::kXOR_Op: 605 case SkRegion::kXOR_Op:
500 case SkRegion::kReverseDifference_Op: 606 case SkRegion::kReverseDifference_Op:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 668
563 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 669 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
564 // id + rect + clip params 670 // id + rect + clip params
565 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; 671 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size;
566 // recordRestoreOffsetPlaceholder doesn't always write an offset 672 // recordRestoreOffsetPlaceholder doesn't always write an offset
567 if (!fRestoreOffsetStack.isEmpty()) { 673 if (!fRestoreOffsetStack.isEmpty()) {
568 // + restore offset 674 // + restore offset
569 size += kUInt32Size; 675 size += kUInt32Size;
570 } 676 }
571 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size); 677 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size);
678 SkASSERT(kInvalidOffset != initialOffset);
572 addRect(rect); 679 addRect(rect);
573 addInt(ClipParams_pack(op, doAA)); 680 addInt(ClipParams_pack(op, doAA));
574 recordRestoreOffsetPlaceholder(op); 681 recordRestoreOffsetPlaceholder(op);
575 682
576 validate(initialOffset, size); 683 validate(initialOffset, size);
577 return this->INHERITED::clipRect(rect, op, doAA); 684 return this->INHERITED::clipRect(rect, op, doAA);
578 } 685 }
579 686
580 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) { 687 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) {
581 if (rrect.isRect()) { 688 if (rrect.isRect()) {
582 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); 689 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA);
583 } 690 }
584 691
585 // op + rrect + clip params 692 // op + rrect + clip params
586 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; 693 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size;
587 // recordRestoreOffsetPlaceholder doesn't always write an offset 694 // recordRestoreOffsetPlaceholder doesn't always write an offset
588 if (!fRestoreOffsetStack.isEmpty()) { 695 if (!fRestoreOffsetStack.isEmpty()) {
589 // + restore offset 696 // + restore offset
590 size += kUInt32Size; 697 size += kUInt32Size;
591 } 698 }
592 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); 699 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size);
700 SkASSERT(kInvalidOffset != initialOffset);
593 addRRect(rrect); 701 addRRect(rrect);
594 addInt(ClipParams_pack(op, doAA)); 702 addInt(ClipParams_pack(op, doAA));
595 recordRestoreOffsetPlaceholder(op); 703 recordRestoreOffsetPlaceholder(op);
596 704
597 validate(initialOffset, size); 705 validate(initialOffset, size);
598 706
599 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { 707 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
600 return this->INHERITED::clipRect(rrect.getBounds(), op, doAA); 708 return this->INHERITED::clipRect(rrect.getBounds(), op, doAA);
601 } else { 709 } else {
602 return this->INHERITED::clipRRect(rrect, op, doAA); 710 return this->INHERITED::clipRRect(rrect, op, doAA);
603 } 711 }
604 } 712 }
605 713
606 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 714 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
607 715
608 SkRect r; 716 SkRect r;
609 if (!path.isInverseFillType() && path.isRect(&r)) { 717 if (!path.isInverseFillType() && path.isRect(&r)) {
610 return this->clipRect(r, op, doAA); 718 return this->clipRect(r, op, doAA);
611 } 719 }
612 720
613 // op + path index + clip params 721 // op + path index + clip params
614 uint32_t size = 3 * kUInt32Size; 722 uint32_t size = 3 * kUInt32Size;
615 // recordRestoreOffsetPlaceholder doesn't always write an offset 723 // recordRestoreOffsetPlaceholder doesn't always write an offset
616 if (!fRestoreOffsetStack.isEmpty()) { 724 if (!fRestoreOffsetStack.isEmpty()) {
617 // + restore offset 725 // + restore offset
618 size += kUInt32Size; 726 size += kUInt32Size;
619 } 727 }
620 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); 728 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size);
729 SkASSERT(kInvalidOffset != initialOffset);
621 addPath(path); 730 addPath(path);
622 addInt(ClipParams_pack(op, doAA)); 731 addInt(ClipParams_pack(op, doAA));
623 recordRestoreOffsetPlaceholder(op); 732 recordRestoreOffsetPlaceholder(op);
624 733
625 validate(initialOffset, size); 734 validate(initialOffset, size);
626 735
627 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { 736 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
628 return this->INHERITED::clipRect(path.getBounds(), op, doAA); 737 return this->INHERITED::clipRect(path.getBounds(), op, doAA);
629 } else { 738 } else {
630 return this->INHERITED::clipPath(path, op, doAA); 739 return this->INHERITED::clipPath(path, op, doAA);
631 } 740 }
632 } 741 }
633 742
634 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { 743 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
635 // op + region index + clip params 744 // op + region index + clip params
636 uint32_t size = 3 * kUInt32Size; 745 uint32_t size = 3 * kUInt32Size;
637 // recordRestoreOffsetPlaceholder doesn't always write an offset 746 // recordRestoreOffsetPlaceholder doesn't always write an offset
638 if (!fRestoreOffsetStack.isEmpty()) { 747 if (!fRestoreOffsetStack.isEmpty()) {
639 // + restore offset 748 // + restore offset
640 size += kUInt32Size; 749 size += kUInt32Size;
641 } 750 }
642 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); 751 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size);
752 SkASSERT(kInvalidOffset != initialOffset);
643 addRegion(region); 753 addRegion(region);
644 addInt(ClipParams_pack(op, false)); 754 addInt(ClipParams_pack(op, false));
645 recordRestoreOffsetPlaceholder(op); 755 recordRestoreOffsetPlaceholder(op);
646 756
647 validate(initialOffset, size); 757 validate(initialOffset, size);
648 return this->INHERITED::clipRegion(region, op); 758 return this->INHERITED::clipRegion(region, op);
649 } 759 }
650 760
651 void SkPictureRecord::clear(SkColor color) { 761 void SkPictureRecord::clear(SkColor color) {
652 // op + color 762 // op + color
653 uint32_t size = 2 * kUInt32Size; 763 uint32_t size = 2 * kUInt32Size;
654 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); 764 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size);
765 if (kInvalidOffset == initialOffset) {
766 return;
767 }
655 addInt(color); 768 addInt(color);
656 validate(initialOffset, size); 769 validate(initialOffset, size);
657 } 770 }
658 771
659 void SkPictureRecord::drawPaint(const SkPaint& paint) { 772 void SkPictureRecord::drawPaint(const SkPaint& paint) {
660 // op + paint index 773 // op + paint index
661 uint32_t size = 2 * kUInt32Size; 774 uint32_t size = 2 * kUInt32Size;
662 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); 775 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size);
663 SkASSERT(initialOffset+getPaintOffset(DRAW_PAINT, size) == fWriter.size()); 776 if (kInvalidOffset == initialOffset) {
777 return;
778 }
779 SkASSERT(initialOffset + getPaintOffset(DRAW_PAINT, size) == fWriter.size()) ;
664 addPaint(paint); 780 addPaint(paint);
665 validate(initialOffset, size); 781 validate(initialOffset, size);
666 } 782 }
667 783
668 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], 784 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [],
669 const SkPaint& paint) { 785 const SkPaint& paint) {
670 // op + paint index + mode + count + point data 786 // op + paint index + mode + count + point data
671 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); 787 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint);
788 #if SK_RECORD_BOUNDS_IN_PICTURE
789 SkRect bbox;
790 bbox.set(pts, count);
791 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size, &paint, &bbox);
792 #else
672 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size); 793 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size);
673 SkASSERT(initialOffset+getPaintOffset(DRAW_POINTS, size) == fWriter.size()); 794 #endif
795 if (kInvalidOffset == initialOffset) {
796 return;
797 }
798 SkASSERT(initialOffset + getPaintOffset(DRAW_POINTS, size) == fWriter.size() );
674 addPaint(paint); 799 addPaint(paint);
675 addInt(mode); 800 addInt(mode);
676 addInt(count); 801 addInt(count);
677 fWriter.writeMul4(pts, count * sizeof(SkPoint)); 802 fWriter.writeMul4(pts, count * sizeof(SkPoint));
678 validate(initialOffset, size); 803 validate(initialOffset, size);
679 } 804 }
680 805
681 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { 806 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) {
682 // op + paint index + rect 807 // op + paint index + rect
683 uint32_t size = 2 * kUInt32Size + sizeof(oval); 808 uint32_t size = 2 * kUInt32Size + sizeof(oval);
684 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size); 809 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size, &paint, &oval);
685 SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size()); 810 if (kInvalidOffset == initialOffset) {
811 return;
812 }
813 SkASSERT(initialOffset + getPaintOffset(DRAW_OVAL, size) == fWriter.size());
686 addPaint(paint); 814 addPaint(paint);
687 addRect(oval); 815 addRect(oval);
688 validate(initialOffset, size); 816 validate(initialOffset, size);
689 } 817 }
690 818
691 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { 819 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
692 // op + paint index + rect 820 // op + paint index + rect
693 uint32_t size = 2 * kUInt32Size + sizeof(rect); 821 uint32_t size = 2 * kUInt32Size + sizeof(rect);
694 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size); 822 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size, &paint, &rect);
695 SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size()); 823 if (kInvalidOffset == initialOffset) {
824 return;
825 }
826 SkASSERT(initialOffset + getPaintOffset(DRAW_RECT, size) == fWriter.size());
696 addPaint(paint); 827 addPaint(paint);
697 addRect(rect); 828 addRect(rect);
698 validate(initialOffset, size); 829 validate(initialOffset, size);
699 } 830 }
700 831
701 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 832 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
702 uint32_t initialOffset, size;
703 if (rrect.isRect()) { 833 if (rrect.isRect()) {
704 // op + paint index + rect 834 this->drawRect(rrect.getBounds(), paint);
705 size = 2 * kUInt32Size + sizeof(SkRect);
706 initialOffset = this->addDraw(DRAW_RECT, &size);
707 SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size() );
708 addPaint(paint);
709 addRect(rrect.getBounds());
710 } else if (rrect.isOval()) { 835 } else if (rrect.isOval()) {
711 // op + paint index + rect 836 this->drawOval(rrect.getBounds(), paint);
712 size = 2 * kUInt32Size + sizeof(SkRect);
713 initialOffset = this->addDraw(DRAW_OVAL, &size);
714 SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size() );
715 addPaint(paint);
716 addRect(rrect.getBounds());
717 } else { 837 } else {
718 // op + paint index + rrect 838 // op + paint index + rrect
719 size = 2 * kUInt32Size + SkRRect::kSizeInMemory; 839 uint32_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory;
720 initialOffset = this->addDraw(DRAW_RRECT, &size); 840 uint32_t initialOffset = this->addDraw(DRAW_RRECT, &size, &paint, &rrect .getBounds());
721 SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.size( )); 841 if (kInvalidOffset == initialOffset) {
842 return;
843 }
844 SkASSERT(initialOffset + getPaintOffset(DRAW_RRECT, size) == fWriter.siz e());
722 addPaint(paint); 845 addPaint(paint);
723 addRRect(rrect); 846 addRRect(rrect);
847 validate(initialOffset, size);
724 } 848 }
725 validate(initialOffset, size);
726 } 849 }
727 850
728 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { 851 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) {
729 // op + paint index + path index 852 // op + paint index + path index
730 uint32_t size = 3 * kUInt32Size; 853 uint32_t size = 3 * kUInt32Size;
731 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size); 854 const SkRect* bounds = path.isInverseFillType() ? NULL : &path.getBounds();
732 SkASSERT(initialOffset+getPaintOffset(DRAW_PATH, size) == fWriter.size()); 855 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size, &paint, bounds);
856 if (kInvalidOffset == initialOffset) {
857 return;
858 }
859 SkASSERT(initialOffset + getPaintOffset(DRAW_PATH, size) == fWriter.size());
733 addPaint(paint); 860 addPaint(paint);
734 addPath(path); 861 addPath(path);
735 validate(initialOffset, size); 862 validate(initialOffset, size);
736 } 863 }
737 864
738 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 865 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
739 const SkPaint* paint = NULL) { 866 const SkPaint* paint = NULL) {
740 // op + paint index + bitmap index + left + top 867 // op + paint index + bitmap index + left + top
741 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 868 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
742 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size); 869 SkRect bounds = SkRect::MakeXYWH(left, top, bitmap.width(), bitmap.height()) ;
743 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP, size) == fWriter.size()); 870 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size, paint, &bounds);
871 if (kInvalidOffset == initialOffset) {
872 return;
873 }
874 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP, size) == fWriter.size() );
744 addPaintPtr(paint); 875 addPaintPtr(paint);
745 addBitmap(bitmap); 876 addBitmap(bitmap);
746 addScalar(left); 877 addScalar(left);
747 addScalar(top); 878 addScalar(top);
748 validate(initialOffset, size); 879 validate(initialOffset, size);
749 } 880 }
750 881
751 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 882 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
752 const SkRect& dst, const SkPaint* paint) { 883 const SkRect& dst, const SkPaint* paint) {
753 // id + paint index + bitmap index + bool for 'src' 884 // id + paint index + bitmap index + bool for 'src'
754 uint32_t size = 4 * kUInt32Size; 885 uint32_t size = 4 * kUInt32Size;
755 if (NULL != src) { 886 if (NULL != src) {
756 size += sizeof(*src); // + rect 887 size += sizeof(*src); // + rect
757 } 888 }
758 size += sizeof(dst); // + rect 889 size += sizeof(dst); // + rect
759 890
760 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); 891 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size, pain t, &dst);
761 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == fWr iter.size()); 892 if (kInvalidOffset == initialOffset) {
893 return;
894 }
895 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == f Writer.size());
762 addPaintPtr(paint); 896 addPaintPtr(paint);
763 addBitmap(bitmap); 897 addBitmap(bitmap);
764 addRectPtr(src); // may be null 898 addRectPtr(src); // may be null
765 addRect(dst); 899 addRect(dst);
766 validate(initialOffset, size); 900 validate(initialOffset, size);
767 } 901 }
768 902
769 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, 903 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix,
770 const SkPaint* paint) { 904 const SkPaint* paint) {
771 // id + paint index + bitmap index + matrix index 905 // id + paint index + bitmap index + matrix index
772 uint32_t size = 4 * kUInt32Size; 906 uint32_t size = 4 * kUInt32Size;
907 #if SK_RECORD_BOUNDS_IN_PICTURE
908 SkRect bounds = SkRect::MakeWH(bitmap.width(), bitmap.height());
909 matrix.mapRect(&bounds);
910 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size, paint, &bo unds);
911 #else
773 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); 912 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size);
774 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.s ize()); 913 #endif
914 if (kInvalidOffset == initialOffset) {
915 return;
916 }
917 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter .size());
775 addPaintPtr(paint); 918 addPaintPtr(paint);
776 addBitmap(bitmap); 919 addBitmap(bitmap);
777 addMatrix(matrix); 920 addMatrix(matrix);
778 validate(initialOffset, size); 921 validate(initialOffset, size);
779 } 922 }
780 923
781 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, 924 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er,
782 const SkRect& dst, const SkPaint* paint) { 925 const SkRect& dst, const SkPaint* paint) {
783 // op + paint index + bitmap id + center + dst rect 926 // op + paint index + bitmap id + center + dst rect
784 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); 927 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst);
785 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); 928 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size, paint, &dst) ;
786 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.siz e()); 929 if (kInvalidOffset == initialOffset) {
930 return;
931 }
932 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.s ize());
787 addPaintPtr(paint); 933 addPaintPtr(paint);
788 addBitmap(bitmap); 934 addBitmap(bitmap);
789 addIRect(center); 935 addIRect(center);
790 addRect(dst); 936 addRect(dst);
791 validate(initialOffset, size); 937 validate(initialOffset, size);
792 } 938 }
793 939
794 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, 940 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
795 const SkPaint* paint = NULL) { 941 const SkPaint* paint) {
796 // op + paint index + bitmap index + left + top 942 // op + paint index + bitmap index + left + top
797 uint32_t size = 5 * kUInt32Size; 943 uint32_t size = 5 * kUInt32Size;
robertphillips 2013/03/08 20:40:04 Bacause -> Because
Justin Novosad 2013/03/08 22:35:42 Done.
944 // Note: Bounds encoding not supported on drawSprite. Bacause drawSprite ign ores
945 // the current transform matrix, the bounds will not follow the playback
946 // canvas's initial tranform matrix at playback time, and recorded bounds
robertphillips 2013/03/08 20:40:04 initial
Justin Novosad 2013/03/08 22:35:42 Done.
947 // are assumed to be in the playback canvas' intial local frame of reference .
798 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size); 948 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size);
799 SkASSERT(initialOffset+getPaintOffset(DRAW_SPRITE, size) == fWriter.size()); 949 if (kInvalidOffset == initialOffset) {
950 return;
951 }
952 SkASSERT(initialOffset + getPaintOffset(DRAW_SPRITE, size) == fWriter.size() );
800 addPaintPtr(paint); 953 addPaintPtr(paint);
801 addBitmap(bitmap); 954 addBitmap(bitmap);
802 addInt(left); 955 addInt(left);
803 addInt(top); 956 addInt(top);
804 validate(initialOffset, size); 957 validate(initialOffset, size);
805 } 958 }
806 959
807 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been 960 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been
808 // tweaked by paint.computeFastBounds(). 961 // tweaked by paint.computeFastBounds().
809 // 962 //
810 static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2] ) { 963 static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2] ) {
811 SkPaint::FontMetrics metrics; 964 SkPaint::FontMetrics metrics;
812 paint.getFontMetrics(&metrics); 965 paint.getFontMetrics(&metrics);
813 SkRect bounds; 966 SkRect bounds;
814 // construct a rect so we can see any adjustments from the paint. 967 // construct a rect so we can see any adjustments from the paint.
815 // we use 0,1 for left,right, just so the rect isn't empty 968 // we use 0,1 for left,right, just so the rect isn't empty
816 bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom); 969 bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom);
817 (void)paint.computeFastBounds(bounds, &bounds); 970 (void)paint.computeFastBounds(bounds, &bounds);
818 topbot[0] = bounds.fTop; 971 topbot[0] = bounds.fTop;
819 topbot[1] = bounds.fBottom; 972 topbot[1] = bounds.fBottom;
820 } 973 }
821 974
975 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
822 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlat Data& flat, 976 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlat Data& flat,
823 SkScalar minY, SkScalar maxY) { 977 SkScalar minY, SkScalar maxY) {
824 if (!flat.isTopBotWritten()) { 978 if (!flat.isTopBotWritten()) {
825 computeFontMetricsTopBottom(paint, flat.writableTopBot()); 979 computeFontMetricsTopBottom(paint, flat.writableTopBot());
826 SkASSERT(flat.isTopBotWritten()); 980 SkASSERT(flat.isTopBotWritten());
827 } 981 }
828 addScalar(flat.topBot()[0] + minY); 982 addScalar(flat.topBot()[0] + minY);
829 addScalar(flat.topBot()[1] + maxY); 983 addScalar(flat.topBot()[1] + maxY);
830 } 984 }
985 #endif
986
987 static void pad_text_bbox_horizontally(const SkPaint::FontMetrics& metrics, SkRe ct* bbox) {
988 // Pad horizontal bounds on each side by max vertical extents.
989 // This is sort of arbitrary, but seems to produce reasonable results.
990 // If there were a way of getting max glyph X-extents to pad by, that
991 // may be better here, but FontMetrics fXMin and fXMax seem incorrect
992 // on most platforms (too small in Linux, never even set in Windows).
993 SkScalar pad = (metrics.fBottom - metrics.fTop);
994 SkASSERT(pad > 0);
995 bbox->fLeft -= pad;
996 bbox->fRight += pad;
997 }
831 998
832 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, 999 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x,
833 SkScalar y, const SkPaint& paint) { 1000 SkScalar y, const SkPaint& paint) {
834 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); 1001 // Note: The DRAW_TEXT_TOP_BOTTOM optimization is redundant if we are
1002 // already recording full bounds.
835 1003
836 // op + paint index + length + 'length' worth of chars + x + y 1004 // op + paint index + length + 'length' worth of chars + x + y
837 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); 1005 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar );
1006
1007 #if SK_RECORD_BOUNDS_IN_PICTURE
1008 SkRect bbox;
1009 paint.measureText(text, byteLength, &bbox);
1010 SkPaint::FontMetrics metrics;
1011 paint.getFontMetrics(&metrics);
1012
1013 // Vertical and aligned text need to be offset
1014 if (paint.isVerticalText()) {
1015 SkScalar h = bbox.fBottom - bbox.fTop;
1016 if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1017 bbox.fTop -= h / 2;
1018 bbox.fBottom -= h / 2;
1019 }
1020 // Pad top and bottom with max extents from FontMetrics
1021 bbox.fBottom += metrics.fBottom;
1022 bbox.fTop += metrics.fTop;
1023 } else {
1024 SkScalar w = bbox.fRight - bbox.fLeft;
1025 if (paint.getTextAlign() == SkPaint::kCenter_Align) {
1026 bbox.fLeft -= w / 2;
1027 bbox.fRight -= w / 2;
1028 } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
1029 bbox.fLeft -= w;
1030 bbox.fRight -= w;
1031 }
1032 // Set vertical bounds to max extents from font metrics
1033 bbox.fTop = metrics.fTop;
1034 bbox.fBottom = metrics.fBottom;
1035 }
1036 pad_text_bbox_horizontally(metrics, &bbox);
1037 bbox.fLeft += x;
1038 bbox.fRight += x;
1039 bbox.fTop += y;
1040 bbox.fBottom += y;
1041 uint32_t initialOffset = this->addDraw(DRAW_TEXT, &size, &paint, &bbox);
1042 #else
1043 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds();
1044
838 if (fast) { 1045 if (fast) {
839 size += 2 * sizeof(SkScalar); // + top & bottom 1046 size += 2 * sizeof(SkScalar); // + top & bottom
840 } 1047 }
841
842 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; 1048 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT;
843 uint32_t initialOffset = this->addDraw(op, &size); 1049 uint32_t initialOffset = this->addDraw(op, &size);
844 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); 1050 #endif
1051 if (kInvalidOffset == initialOffset) {
1052 return;
1053 }
1054 #if SK_RECORD_BOUNDS_IN_PICTURE
1055 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT, size) == fWriter.size());
1056 #else
1057 SkASSERT(initialOffset + getPaintOffset(op, size) == fWriter.size());
1058 #endif
845 const SkFlatData* flatPaintData = addPaint(paint); 1059 const SkFlatData* flatPaintData = addPaint(paint);
846 SkASSERT(flatPaintData); 1060 SkASSERT(flatPaintData);
847 addText(text, byteLength); 1061 addText(text, byteLength);
848 addScalar(x); 1062 addScalar(x);
849 addScalar(y); 1063 addScalar(y);
1064 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
850 if (fast) { 1065 if (fast) {
851 addFontMetricsTopBottom(paint, *flatPaintData, y, y); 1066 addFontMetricsTopBottom(paint, *flatPaintData, y, y);
852 } 1067 }
1068 #endif
853 validate(initialOffset, size); 1069 validate(initialOffset, size);
854 } 1070 }
855 1071
856 void SkPictureRecord::drawPosText(const void* text, size_t byteLength, 1072 void SkPictureRecord::drawPosText(const void* text, size_t byteLength,
857 const SkPoint pos[], const SkPaint& paint) { 1073 const SkPoint pos[], const SkPaint& paint) {
858 size_t points = paint.countText(text, byteLength); 1074 size_t points = paint.countText(text, byteLength);
859 if (0 == points) 1075 if (0 == points)
860 return; 1076 return;
861 1077
862 bool canUseDrawH = true; 1078 bool canUseDrawH = true;
863 SkScalar minY = pos[0].fY; 1079 SkScalar minY = pos[0].fY;
864 SkScalar maxY = pos[0].fY; 1080 SkScalar maxY = pos[0].fY;
865 // check if the caller really should have used drawPosTextH() 1081 // check if the caller really should have used drawPosTextH()
866 { 1082 {
867 const SkScalar firstY = pos[0].fY; 1083 const SkScalar firstY = pos[0].fY;
868 for (size_t index = 1; index < points; index++) { 1084 for (size_t index = 1; index < points; index++) {
869 if (pos[index].fY != firstY) { 1085 if (pos[index].fY != firstY) {
870 canUseDrawH = false; 1086 canUseDrawH = false;
871 if (pos[index].fY < minY) { 1087 if (pos[index].fY < minY) {
872 minY = pos[index].fY; 1088 minY = pos[index].fY;
873 } else if (pos[index].fY > maxY) { 1089 } else if (pos[index].fY > maxY) {
874 maxY = pos[index].fY; 1090 maxY = pos[index].fY;
875 } 1091 }
876 } 1092 }
877 } 1093 }
878 } 1094 }
879 1095
1096 // Note: The DRAW_TEXT_[H_]TOP_BOTTOM optimization is redundant if we are
1097 // already recording full bounds.
robertphillips 2013/03/08 20:40:04 How about just setting these to false for RECORD_B
Justin Novosad 2013/03/08 22:35:42 I like it this way. The day I revisit to get rid o
1098 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
880 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds(); 1099 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds();
881 bool fast = canUseDrawH && fastBounds; 1100 bool fast = canUseDrawH && fastBounds;
1101 #endif
882 1102
883 // op + paint index + length + 'length' worth of data + num points 1103 // op + paint index + length + 'length' worth of data + num points
884 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; 1104 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size;
885 if (canUseDrawH) { 1105 if (canUseDrawH) {
1106 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
886 if (fast) { 1107 if (fast) {
887 size += 2 * sizeof(SkScalar); // + top & bottom 1108 size += 2 * sizeof(SkScalar); // + top & bottom
888 } 1109 }
1110 #endif
889 // + y-pos + actual x-point data 1111 // + y-pos + actual x-point data
890 size += sizeof(SkScalar) + points * sizeof(SkScalar); 1112 size += sizeof(SkScalar) + points * sizeof(SkScalar);
891 } else { 1113 } else {
892 // + x&y point data 1114 // + x&y point data
893 size += points * sizeof(SkPoint); 1115 size += points * sizeof(SkPoint);
1116 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
894 if (fastBounds) { 1117 if (fastBounds) {
895 size += 2 * sizeof(SkScalar); // + top & bottom 1118 size += 2 * sizeof(SkScalar); // + top & bottom
896 } 1119 }
1120 #endif
897 } 1121 }
898 1122
899 DrawType op; 1123 DrawType op;
1124 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
900 if (fast) { 1125 if (fast) {
901 op = DRAW_POS_TEXT_H_TOP_BOTTOM; 1126 op = DRAW_POS_TEXT_H_TOP_BOTTOM;
902 } else if (canUseDrawH) { 1127 } else
1128 #endif
1129 if (canUseDrawH) {
903 op = DRAW_POS_TEXT_H; 1130 op = DRAW_POS_TEXT_H;
1131 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
904 } else if (fastBounds) { 1132 } else if (fastBounds) {
905 op = DRAW_POS_TEXT_TOP_BOTTOM; 1133 op = DRAW_POS_TEXT_TOP_BOTTOM;
1134 #endif
906 } else { 1135 } else {
907 op = DRAW_POS_TEXT; 1136 op = DRAW_POS_TEXT;
908 } 1137 }
1138 #if SK_RECORD_BOUNDS_IN_PICTURE
1139 SkRect bbox;
1140 bbox.set(pos, paint.countText(text, byteLength));
1141 SkPaint::FontMetrics metrics;
1142 paint.getFontMetrics(&metrics);
1143 bbox.fTop += metrics.fTop;
1144 bbox.fBottom += metrics.fBottom;
1145
1146 // pad on left and right by half of max vertical glyph extents
1147 pad_text_bbox_horizontally(metrics, &bbox);
1148 uint32_t initialOffset = this->addDraw(op, &size, &paint, &bbox);
1149 #else
909 uint32_t initialOffset = this->addDraw(op, &size); 1150 uint32_t initialOffset = this->addDraw(op, &size);
910 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); 1151 #endif
1152 if (kInvalidOffset == initialOffset) {
1153 return;
1154 }
1155 SkASSERT(initialOffset + getPaintOffset(op, size) == fWriter.size());
911 const SkFlatData* flatPaintData = addPaint(paint); 1156 const SkFlatData* flatPaintData = addPaint(paint);
912 SkASSERT(flatPaintData); 1157 SkASSERT(flatPaintData);
913 addText(text, byteLength); 1158 addText(text, byteLength);
914 addInt(points); 1159 addInt(points);
915 1160
916 #ifdef SK_DEBUG_SIZE 1161 #ifdef SK_DEBUG_SIZE
917 size_t start = fWriter.size(); 1162 size_t start = fWriter.size();
918 #endif 1163 #endif
919 if (canUseDrawH) { 1164 if (canUseDrawH) {
1165 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
920 if (fast) { 1166 if (fast) {
921 addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY) ; 1167 addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY) ;
922 } 1168 }
1169 #endif
923 addScalar(pos[0].fY); 1170 addScalar(pos[0].fY);
924 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); 1171 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar));
925 for (size_t index = 0; index < points; index++) 1172 for (size_t index = 0; index < points; index++)
926 *xptr++ = pos[index].fX; 1173 *xptr++ = pos[index].fX;
927 } else { 1174 } else {
928 fWriter.writeMul4(pos, points * sizeof(SkPoint)); 1175 fWriter.writeMul4(pos, points * sizeof(SkPoint));
1176 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
929 if (fastBounds) { 1177 if (fastBounds) {
930 addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY); 1178 addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY);
931 } 1179 }
1180 #endif
932 } 1181 }
933 #ifdef SK_DEBUG_SIZE 1182 #ifdef SK_DEBUG_SIZE
934 fPointBytes += fWriter.size() - start; 1183 fPointBytes += fWriter.size() - start;
935 fPointWrites += points; 1184 fPointWrites += points;
936 #endif 1185 #endif
937 validate(initialOffset, size); 1186 validate(initialOffset, size);
938 } 1187 }
939 1188
940 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, 1189 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength,
941 const SkScalar xpos[], SkScalar constY, 1190 const SkScalar xpos[], SkScalar constY,
942 const SkPaint& paint) { 1191 const SkPaint& paint) {
943 size_t points = paint.countText(text, byteLength); 1192 size_t numChars = paint.countText(text, byteLength);
944 if (0 == points) 1193 if (0 == numChars)
945 return; 1194 return;
946 1195
robertphillips 2013/03/08 20:40:04 the "op + ..." comment should move up here too
Justin Novosad 2013/03/08 22:35:42 Done.
1196 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size;
1197
1198 // Note: The DRAW_POS_TEXT_H_TOP_BOTTOM optimization is redundant if we are
1199 // already recording full bounds.
1200 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
947 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); 1201 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds();
948
949 // op + paint index + length + 'length' worth of data + num points 1202 // op + paint index + length + 'length' worth of data + num points
950 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size;
951 if (fast) { 1203 if (fast) {
952 size += 2 * sizeof(SkScalar); // + top & bottom 1204 size += 2 * sizeof(SkScalar); // + top & bottom
953 } 1205 }
1206 #endif
1207
954 // + y + the actual points 1208 // + y + the actual points
955 size += 1 * kUInt32Size + points * sizeof(SkScalar); 1209 size += 1 * kUInt32Size + numChars * sizeof(SkScalar);
956 1210
1211 #if SK_RECORD_BOUNDS_IN_PICTURE
1212 SkRect bbox;
1213 bbox.fLeft = xpos[0];
robertphillips 2013/03/08 20:40:04 fix this?
Justin Novosad 2013/03/08 22:35:42 It was fixed. The loop below now starts at 0 inste
1214 bbox.fRight = xpos[numChars - 1];
1215 // if we had a guarantee that these will be monotonically increasing, this c ould be sped up
1216 for (size_t i = 0; i < numChars; ++i) {
1217 if (xpos[i] < bbox.fLeft) {
1218 bbox.fLeft = xpos[i];
1219 }
1220 if (xpos[i] > bbox.fRight) {
1221 bbox.fRight = xpos[i];
1222 }
1223 }
1224 SkPaint::FontMetrics metrics;
1225 paint.getFontMetrics(&metrics);
1226 pad_text_bbox_horizontally(metrics, &bbox);
1227 bbox.fTop = metrics.fTop + constY;
1228 bbox.fBottom = metrics.fBottom + constY;
1229 uint32_t initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size, &paint, &bbox );
1230 #else
957 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H, 1231 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H,
958 &size); 1232 &size);
1233 #endif
1234 if (kInvalidOffset == initialOffset) {
1235 return;
1236 }
1237 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter. size());
959 const SkFlatData* flatPaintData = addPaint(paint); 1238 const SkFlatData* flatPaintData = addPaint(paint);
960 SkASSERT(flatPaintData); 1239 SkASSERT(flatPaintData);
961 addText(text, byteLength); 1240 addText(text, byteLength);
962 addInt(points); 1241 addInt(numChars);
963 1242
964 #ifdef SK_DEBUG_SIZE 1243 #ifdef SK_DEBUG_SIZE
965 size_t start = fWriter.size(); 1244 size_t start = fWriter.size();
966 #endif 1245 #endif
1246 #if !(SK_RECORD_BOUNDS_IN_PICTURE)
967 if (fast) { 1247 if (fast) {
968 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); 1248 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY);
969 } 1249 }
1250 #endif
970 addScalar(constY); 1251 addScalar(constY);
971 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); 1252 fWriter.writeMul4(xpos, numChars * sizeof(SkScalar));
972 #ifdef SK_DEBUG_SIZE 1253 #ifdef SK_DEBUG_SIZE
973 fPointBytes += fWriter.size() - start; 1254 fPointBytes += fWriter.size() - start;
974 fPointWrites += points; 1255 fPointWrites += points;
975 #endif 1256 #endif
976 validate(initialOffset, size); 1257 validate(initialOffset, size);
977 } 1258 }
978 1259
979 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, 1260 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength,
980 const SkPath& path, const SkMatrix* matrix, 1261 const SkPath& path, const SkMatrix* matrix,
981 const SkPaint& paint) { 1262 const SkPaint& paint) {
982 // op + paint index + length + 'length' worth of data + path index + matrix index 1263 // op + paint index + length + 'length' worth of data + path index + matrix index
983 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; 1264 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size;
1265 #if SK_RECORD_BOUNDS_IN_PICTURE
1266 SkRect bbox = path.getBounds();
1267 SkPaint::FontMetrics metrics;
1268 paint.getFontMetrics(&metrics);
1269 // pad out all sides by the max glyph height above baseline
1270 SkScalar pad = metrics.fTop;
1271 bbox.fLeft += pad;
1272 bbox.fRight -= pad;
1273 bbox.fTop += pad;
1274 bbox.fBottom -= pad;
1275 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size, &paint, &bb ox);
1276 #else
984 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); 1277 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size);
985 SkASSERT(initialOffset+getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter.si ze()); 1278 #endif
1279 if (kInvalidOffset == initialOffset) {
1280 return;
1281 }
1282 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter. size());
986 addPaint(paint); 1283 addPaint(paint);
987 addText(text, byteLength); 1284 addText(text, byteLength);
988 addPath(path); 1285 addPath(path);
989 addMatrixPtr(matrix); 1286 addMatrixPtr(matrix);
990 validate(initialOffset, size); 1287 validate(initialOffset, size);
991 } 1288 }
992 1289
993 void SkPictureRecord::drawPicture(SkPicture& picture) { 1290 void SkPictureRecord::drawPicture(SkPicture& picture) {
994 // op + picture index 1291 // op + picture index
995 uint32_t size = 2 * kUInt32Size; 1292 uint32_t size = 2 * kUInt32Size;
996 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size); 1293 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size);
1294 SkASSERT(kInvalidOffset != initialOffset);
997 addPicture(picture); 1295 addPicture(picture);
998 validate(initialOffset, size); 1296 validate(initialOffset, size);
999 } 1297 }
1000 1298
1001 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, 1299 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount,
1002 const SkPoint vertices[], const SkPoint texs[], 1300 const SkPoint vertices[], const SkPoint texs[],
1003 const SkColor colors[], SkXfermode*, 1301 const SkColor colors[], SkXfermode*,
1004 const uint16_t indices[], int indexCount, 1302 const uint16_t indices[], int indexCount,
1005 const SkPaint& paint) { 1303 const SkPaint& paint) {
1006 uint32_t flags = 0; 1304 uint32_t flags = 0;
(...skipping 12 matching lines...) Expand all
1019 if (flags & DRAW_VERTICES_HAS_TEXS) { 1317 if (flags & DRAW_VERTICES_HAS_TEXS) {
1020 size += vertexCount * sizeof(SkPoint); // + uvs 1318 size += vertexCount * sizeof(SkPoint); // + uvs
1021 } 1319 }
1022 if (flags & DRAW_VERTICES_HAS_COLORS) { 1320 if (flags & DRAW_VERTICES_HAS_COLORS) {
1023 size += vertexCount * sizeof(SkColor); // + vert colors 1321 size += vertexCount * sizeof(SkColor); // + vert colors
1024 } 1322 }
1025 if (flags & DRAW_VERTICES_HAS_INDICES) { 1323 if (flags & DRAW_VERTICES_HAS_INDICES) {
1026 // + num indices + indices 1324 // + num indices + indices
1027 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); 1325 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t));
1028 } 1326 }
1029 1327 #if SK_RECORD_BOUNDS_IN_PICTURE
1328 SkRect bbox;
1329 bbox.set(vertices, vertexCount);
1330 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size, &paint, &bbox);
1331 #else
1030 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size); 1332 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size);
1031 SkASSERT(initialOffset+getPaintOffset(DRAW_VERTICES, size) == fWriter.size() ); 1333 #endif
1334 if (kInvalidOffset == initialOffset) {
1335 return;
1336 }
1337 SkASSERT(initialOffset + getPaintOffset(DRAW_VERTICES, size) == fWriter.size ());
1032 addPaint(paint); 1338 addPaint(paint);
1033 addInt(flags); 1339 addInt(flags);
1034 addInt(vmode); 1340 addInt(vmode);
1035 addInt(vertexCount); 1341 addInt(vertexCount);
1036 addPoints(vertices, vertexCount); 1342 addPoints(vertices, vertexCount);
1037 if (flags & DRAW_VERTICES_HAS_TEXS) { 1343 if (flags & DRAW_VERTICES_HAS_TEXS) {
1038 addPoints(texs, vertexCount); 1344 addPoints(texs, vertexCount);
1039 } 1345 }
1040 if (flags & DRAW_VERTICES_HAS_COLORS) { 1346 if (flags & DRAW_VERTICES_HAS_COLORS) {
1041 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); 1347 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor));
1042 } 1348 }
1043 if (flags & DRAW_VERTICES_HAS_INDICES) { 1349 if (flags & DRAW_VERTICES_HAS_INDICES) {
1044 addInt(indexCount); 1350 addInt(indexCount);
1045 fWriter.writePad(indices, indexCount * sizeof(uint16_t)); 1351 fWriter.writePad(indices, indexCount * sizeof(uint16_t));
1046 } 1352 }
1047 validate(initialOffset, size); 1353 validate(initialOffset, size);
1048 } 1354 }
1049 1355
1050 void SkPictureRecord::drawData(const void* data, size_t length) { 1356 void SkPictureRecord::drawData(const void* data, size_t length) {
1051 // op + length + 'length' worth of data 1357 // op + length + 'length' worth of data
1052 uint32_t size = 2 * kUInt32Size + SkAlign4(length); 1358 uint32_t size = 2 * kUInt32Size + SkAlign4(length);
1053 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size); 1359 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size);
1360 SkASSERT(kInvalidOffset != initialOffset);
1054 addInt(length); 1361 addInt(length);
1055 fWriter.writePad(data, length); 1362 fWriter.writePad(data, length);
1056 validate(initialOffset, size); 1363 validate(initialOffset, size);
1057 } 1364 }
1058 1365
1059 /////////////////////////////////////////////////////////////////////////////// 1366 ///////////////////////////////////////////////////////////////////////////////
1060 1367
1061 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { 1368 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
1062 const int index = fBitmapHeap->insert(bitmap); 1369 const int index = fBitmapHeap->insert(bitmap);
1063 // In debug builds, a bad return value from insert() will crash, allowing fo r debugging. In 1370 // 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
1292 void SkPictureRecord::validateRegions() const { 1599 void SkPictureRecord::validateRegions() const {
1293 int count = fRegions.count(); 1600 int count = fRegions.count();
1294 SkASSERT((unsigned) count < 0x1000); 1601 SkASSERT((unsigned) count < 0x1000);
1295 for (int index = 0; index < count; index++) { 1602 for (int index = 0; index < count; index++) {
1296 const SkFlatData* region = fRegions[index]; 1603 const SkFlatData* region = fRegions[index];
1297 SkASSERT(region); 1604 SkASSERT(region);
1298 // region->validate(); 1605 // region->validate();
1299 } 1606 }
1300 } 1607 }
1301 #endif 1608 #endif
OLDNEW
« src/core/SkPictureRecord.h ('K') | « src/core/SkPictureRecord.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698