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

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

Powered by Google App Engine
This is Rietveld 408576698