OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkPictureRecord.h" | 8 #include "SkPictureRecord.h" |
9 #include "SkTSearch.h" | 9 #include "SkTSearch.h" |
10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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/07 18:37:40
Do you want to also make this one static inline?
reed1
2013/03/07 20:36:44
Maybe its time to create a static uint8_t array th
| |
65 bool SkPictureRecord::canRecordBounds(DrawType op) { | |
Justin Novosad
2013/03/07 20:25:47
It needs to be accessible from SkPictureBitmap.
| |
66 SkASSERT(op != DRAW_POS_TEXT_TOP_BOTTOM); // Should never be used when enco ding bounds | |
67 SkASSERT(op != DRAW_POS_TEXT_H_TOP_BOTTOM); | |
68 switch (op) { | |
69 case DRAW_BITMAP: | |
70 case DRAW_BITMAP_MATRIX: | |
71 case DRAW_BITMAP_NINE: | |
72 case DRAW_BITMAP_RECT_TO_RECT: | |
73 case DRAW_OVAL: | |
74 case DRAW_PATH: | |
75 case DRAW_POINTS: | |
76 case DRAW_POS_TEXT: | |
77 case DRAW_POS_TEXT_H: | |
78 case DRAW_RECT: | |
79 case DRAW_RRECT: | |
80 case DRAW_TEXT: | |
81 case DRAW_TEXT_ON_PATH: | |
82 case DRAW_VERTICES: | |
83 return true; | |
84 default: | |
85 return false; | |
86 } | |
87 } | |
88 | |
89 static inline bool modifiesState(DrawType op) { | |
90 switch (op) { | |
91 case CLIP_PATH: | |
92 case CLIP_REGION: | |
93 case CLIP_RECT: | |
94 case CLIP_RRECT: | |
95 case CONCAT: | |
96 case DRAW_PICTURE: | |
97 case RESTORE: | |
98 case ROTATE: | |
99 case SAVE: | |
100 case SAVE_LAYER: | |
101 case SCALE: | |
102 case SET_MATRIX: | |
103 case SKEW: | |
104 case TRANSLATE: | |
105 return true; | |
106 default: | |
107 return false; | |
108 } | |
109 } | |
110 | |
65 // Return the offset of the paint inside a given op's byte stream. A zero | 111 // 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 | 112 // return value means there is no paint (and you really shouldn't be calling |
67 // this method) | 113 // this method) |
68 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { | 114 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize, bool recordB ounds) { |
69 // These offsets are where the paint would be if the op size doesn't overflo w | 115 // 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] = { | 116 static const uint8_t gPaintOffsets[LAST_DRAWTYPE_ENUM + 1] = { |
71 0, // UNUSED - no paint | 117 0, // UNUSED - no paint |
72 0, // CLIP_PATH - no paint | 118 0, // CLIP_PATH - no paint |
73 0, // CLIP_REGION - no paint | 119 0, // CLIP_REGION - no paint |
74 0, // CLIP_RECT - no paint | 120 0, // CLIP_RECT - no paint |
75 0, // CLIP_RRECT - no paint | 121 0, // CLIP_RRECT - no paint |
76 0, // CONCAT - no paint | 122 0, // CONCAT - no paint |
77 1, // DRAW_BITMAP - right after op code | 123 1, // DRAW_BITMAP - right after op code |
78 1, // DRAW_BITMAP_MATRIX - right after op code | 124 1, // DRAW_BITMAP_MATRIX - right after op code |
(...skipping 30 matching lines...) Expand all Loading... | |
109 | 155 |
110 SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1); | 156 SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1); |
111 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); | 157 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); |
112 | 158 |
113 int overflow = 0; | 159 int overflow = 0; |
114 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { | 160 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { |
115 // This op's size overflows so an extra uint32_t will be written | 161 // This op's size overflows so an extra uint32_t will be written |
116 // after the op code | 162 // after the op code |
117 overflow = sizeof(uint32_t); | 163 overflow = sizeof(uint32_t); |
118 } | 164 } |
165 if (recordBounds && SkPictureRecord::canRecordBounds(op)) { | |
166 overflow += sizeof(SkIRect); | |
167 } | |
119 | 168 |
120 if (SAVE_LAYER == op) { | 169 if (SAVE_LAYER == op) { |
121 static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; | 170 static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; |
122 static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); | 171 static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); |
123 | 172 |
124 if (kSaveLayerNoBoundsSize == opSize) { | 173 if (kSaveLayerNoBoundsSize == opSize) { |
125 return kSaveLayerNoBoundsPaintOffset + overflow; | 174 return kSaveLayerNoBoundsPaintOffset + overflow; |
126 } else { | 175 } else { |
127 SkASSERT(kSaveLayerWithBoundsSize == opSize); | 176 SkASSERT(kSaveLayerWithBoundsSize == opSize); |
128 return kSaveLayerWithBoundsPaintOffset + overflow; | 177 return kSaveLayerWithBoundsPaintOffset + overflow; |
(...skipping 10 matching lines...) Expand all Loading... | |
139 } | 188 } |
140 | 189 |
141 int SkPictureRecord::save(SaveFlags flags) { | 190 int SkPictureRecord::save(SaveFlags flags) { |
142 // record the offset to us, making it non-positive to distinguish a save | 191 // record the offset to us, making it non-positive to distinguish a save |
143 // from a clip entry. | 192 // from a clip entry. |
144 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); | 193 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); |
145 | 194 |
146 // op + flags | 195 // op + flags |
147 uint32_t size = 2 * kUInt32Size; | 196 uint32_t size = 2 * kUInt32Size; |
148 uint32_t initialOffset = this->addDraw(SAVE, &size); | 197 uint32_t initialOffset = this->addDraw(SAVE, &size); |
198 SkASSERT(kInvalidOffset != initialOffset); | |
149 addInt(flags); | 199 addInt(flags); |
150 | 200 |
151 validate(initialOffset, size); | 201 validate(initialOffset, size); |
152 return this->INHERITED::save(flags); | 202 return this->INHERITED::save(flags); |
153 } | 203 } |
154 | 204 |
155 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, | 205 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, |
156 SaveFlags flags) { | 206 SaveFlags flags) { |
157 // record the offset to us, making it non-positive to distinguish a save | 207 // record the offset to us, making it non-positive to distinguish a save |
158 // from a clip entry. | 208 // from a clip entry. |
159 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); | 209 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); |
160 | 210 |
161 // op + bool for 'bounds' | 211 // op + bool for 'bounds' |
162 uint32_t size = 2 * kUInt32Size; | 212 uint32_t size = 2 * kUInt32Size; |
163 if (NULL != bounds) { | 213 if (NULL != bounds) { |
164 size += sizeof(*bounds); // + rect | 214 size += sizeof(*bounds); // + rect |
165 } | 215 } |
166 // + paint index + flags | 216 // + paint index + flags |
167 size += 2 * kUInt32Size; | 217 size += 2 * kUInt32Size; |
168 | 218 |
169 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; | 219 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; |
170 | 220 |
171 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); | 221 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); |
222 SkASSERT(kInvalidOffset != initialOffset); | |
172 addRectPtr(bounds); | 223 addRectPtr(bounds); |
173 SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.size()); | 224 SkASSERT(initialOffset + getPaintOffset(SAVE_LAYER, size, false) == fWriter. size()); |
174 addPaintPtr(paint); | 225 addPaintPtr(paint); |
175 addInt(flags); | 226 addInt(flags); |
176 | 227 |
177 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { | 228 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { |
178 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); | 229 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); |
179 } | 230 } |
180 | 231 |
181 validate(initialOffset, size); | 232 validate(initialOffset, size); |
182 /* Don't actually call saveLayer, because that will try to allocate an | 233 /* Don't actually call saveLayer, because that will try to allocate an |
183 offscreen device (potentially very big) which we don't actually need | 234 offscreen device (potentially very big) which we don't actually need |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 | 279 |
229 /* | 280 /* |
230 * Restore has just been called (but not recorded), look back at the | 281 * Restore has just been called (but not recorded), look back at the |
231 * matching save* and see if we are in the configuration: | 282 * matching save* and see if we are in the configuration: |
232 * SAVE_LAYER | 283 * SAVE_LAYER |
233 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC T | 284 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC T |
234 * RESTORE | 285 * RESTORE |
235 * where the saveLayer's color can be moved into the drawBitmap*'s paint | 286 * where the saveLayer's color can be moved into the drawBitmap*'s paint |
236 */ | 287 */ |
237 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, | 288 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, |
238 SkPaintDictionary* paintDict) { | 289 SkPaintDictionary* paintDict, bool recordBounds) { |
239 | 290 |
240 #ifdef SK_IGNORE_PICTURE_RECORD_SAVE_LAYER_OPT | 291 #ifdef SK_IGNORE_PICTURE_RECORD_SAVE_LAYER_OPT |
241 return false; | 292 return false; |
242 #endif | 293 #endif |
243 | 294 |
244 int32_t restoreOffset = (int32_t)writer->size(); | 295 int32_t restoreOffset = (int32_t)writer->size(); |
245 | 296 |
246 // back up to the save block | 297 // back up to the save block |
247 // TODO: add a stack to track save*/restore offsets rather than searching ba ckwards | 298 // TODO: add a stack to track save*/restore offsets rather than searching ba ckwards |
248 while (offset > 0) { | 299 while (offset > 0) { |
(...skipping 27 matching lines...) Expand all Loading... | |
276 if (DRAW_BITMAP != op && DRAW_BITMAP_MATRIX != op && | 327 if (DRAW_BITMAP != op && DRAW_BITMAP_MATRIX != op && |
277 DRAW_BITMAP_NINE != op && DRAW_BITMAP_RECT_TO_RECT != op) { | 328 DRAW_BITMAP_NINE != op && DRAW_BITMAP_RECT_TO_RECT != op) { |
278 return false; // not a match | 329 return false; // not a match |
279 } | 330 } |
280 | 331 |
281 offset = dbmOffset + dbmSize; | 332 offset = dbmOffset + dbmSize; |
282 if (offset < restoreOffset) { | 333 if (offset < restoreOffset) { |
283 return false; // something else between the dbm* and the restore | 334 return false; // something else between the dbm* and the restore |
284 } | 335 } |
285 | 336 |
286 uint32_t dbmPaintOffset = getPaintOffset(op, dbmSize); | 337 uint32_t dbmPaintOffset = getPaintOffset(op, dbmSize, recordBounds); |
287 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerSize); | 338 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerSize, false); |
288 | 339 |
289 // we have a match, now we need to get the paints involved | 340 // we have a match, now we need to get the paints involved |
290 int dbmPaintId = *((int32_t*)writer->peek32(dbmOffset+dbmPaintOffset)); | 341 int dbmPaintId = *((int32_t*)writer->peek32(dbmOffset+dbmPaintOffset)); |
291 int saveLayerPaintId = *((int32_t*)writer->peek32(saveLayerOffset+slPaintOff set)); | 342 int saveLayerPaintId = *((int32_t*)writer->peek32(saveLayerOffset+slPaintOff set)); |
292 | 343 |
293 if (0 == saveLayerPaintId) { | 344 if (0 == saveLayerPaintId) { |
294 // In this case the saveLayer/restore isn't needed at all - just kill th e saveLayer | 345 // In this case the saveLayer/restore isn't needed at all - just kill th e saveLayer |
295 // and signal the caller (by returning true) to not add the RESTORE op | 346 // and signal the caller (by returning true) to not add the RESTORE op |
296 uint32_t* ptr = writer->peek32(saveLayerOffset); | 347 uint32_t* ptr = writer->peek32(saveLayerOffset); |
297 *ptr = (*ptr & MASK_24) | (NOOP << 24); | 348 *ptr = (*ptr & MASK_24) | (NOOP << 24); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
411 if (fRestoreOffsetStack.count() == 0) { | 462 if (fRestoreOffsetStack.count() == 0) { |
412 return; | 463 return; |
413 } | 464 } |
414 | 465 |
415 if (fRestoreOffsetStack.count() == fFirstSavedLayerIndex) { | 466 if (fRestoreOffsetStack.count() == fFirstSavedLayerIndex) { |
416 fFirstSavedLayerIndex = kNoSavedLayerIndex; | 467 fFirstSavedLayerIndex = kNoSavedLayerIndex; |
417 } | 468 } |
418 | 469 |
419 uint32_t initialOffset, size; | 470 uint32_t initialOffset, size; |
420 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) && | 471 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) && |
421 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints)) { | 472 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints, |
473 this->recordBounds())) { | |
422 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); | 474 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); |
423 // op | 475 // op |
424 size = 1 * kUInt32Size; | 476 size = 1 * kUInt32Size; |
425 initialOffset = this->addDraw(RESTORE, &size); | 477 initialOffset = this->addDraw(RESTORE, &size); |
426 } else { | 478 } else { |
427 size = 0; | 479 size = 0; |
428 initialOffset = fWriter.size(); | 480 initialOffset = fWriter.size(); |
429 } | 481 } |
482 SkASSERT(kInvalidOffset != initialOffset); | |
430 | 483 |
431 fRestoreOffsetStack.pop(); | 484 fRestoreOffsetStack.pop(); |
432 | 485 |
433 validate(initialOffset, size); | 486 validate(initialOffset, size); |
434 return this->INHERITED::restore(); | 487 return this->INHERITED::restore(); |
435 } | 488 } |
436 | 489 |
490 uint32_t SkPictureRecord::addDraw(DrawType drawType, uint32_t* size, | |
491 const SkPaint* paint, const SkRect* localBound s) { | |
492 bool writeBounds = this->recordBounds() && canRecordBounds(drawType); | |
493 SkIRect clippedDevBounds; // Bounds of the clipped draw in device space | |
494 SkIRect devClipBounds; // Bounds of the current clip in device space | |
495 if (!modifiesState(drawType) && !this->getClipDeviceBounds(&devClipBounds)) { | |
496 // Optimize-out calls that are clipped-out. State modifying commands | |
497 // can not be optimized-out because they may have an impact on future ca lls | |
498 // if the clip is ever expanded. For example, with a union clip op. | |
499 return kInvalidOffset; | |
500 } | |
robertphillips
2013/03/07 18:37:40
mv clippedDevBounds down to here?
| |
501 if (writeBounds) { | |
502 SkASSERT(!modifiesState(drawType)); // Ensure devClipBounds is initializ ed | |
503 if (NULL == localBounds || (NULL != paint && !paint->canComputeFastBound s())) { | |
504 clippedDevBounds = devClipBounds; | |
505 } else { | |
506 SkRect paintBounds; | |
507 SkRect rectifiedBounds = *localBounds; | |
508 rectifiedBounds.sort(); | |
509 if (NULL != paint) { | |
510 if (drawType == DRAW_POINTS) { | |
511 paintBounds = paint->computeFastStrokeBounds(rectifiedBounds , &paintBounds); | |
512 } else { | |
513 paintBounds = paint->computeFastBounds(rectifiedBounds, &pai ntBounds); | |
514 } | |
515 } else { | |
516 paintBounds = *localBounds; | |
517 } | |
518 if (paintBounds.isEmpty()) { | |
519 // Area affected by draw op is empty even after accounting | |
520 // for stroke width. | |
521 return kInvalidOffset; | |
522 } | |
523 SkRect devBounds; | |
524 this->getTotalMatrix().mapRect(&devBounds, paintBounds); | |
525 devBounds.roundOut(&clippedDevBounds); | |
526 if (!clippedDevBounds.intersect(devClipBounds)) { | |
527 // Draw lies outside of clip. The clip can only get further | |
528 // restricted at playback time, so it is safe to reject during | |
529 // record stage. | |
530 return kInvalidOffset; | |
531 } | |
532 } | |
533 *size += sizeof(SkIRect); | |
534 } | |
535 | |
536 uint32_t offset = fWriter.size(); | |
537 | |
538 this->predrawNotify(); | |
539 | |
540 #ifdef SK_DEBUG_TRACE | |
541 SkDebugf("add %s\n", DrawTypeToString(drawType)); | |
542 #endif | |
543 SkASSERT(0 != *size); | |
544 SkASSERT(((uint8_t) drawType) == drawType); | |
545 if (0 != (*size & ~MASK_24) || *size == MASK_24) { | |
546 fWriter.writeInt(PACK_8_24(drawType, MASK_24)); | |
547 *size += 1; | |
548 fWriter.writeInt(*size); | |
549 } else { | |
550 fWriter.writeInt(PACK_8_24(drawType, *size)); | |
551 } | |
552 | |
553 if (writeBounds) { | |
554 fWriter.write(&clippedDevBounds, sizeof(clippedDevBounds)); | |
555 } | |
556 | |
557 return offset; | |
558 } | |
559 | |
437 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { | 560 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { |
438 // op + dx + dy | 561 // op + dx + dy |
439 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 562 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
440 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); | 563 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); |
564 SkASSERT(kInvalidOffset != initialOffset); | |
441 addScalar(dx); | 565 addScalar(dx); |
442 addScalar(dy); | 566 addScalar(dy); |
443 validate(initialOffset, size); | 567 validate(initialOffset, size); |
444 return this->INHERITED::translate(dx, dy); | 568 return this->INHERITED::translate(dx, dy); |
445 } | 569 } |
446 | 570 |
447 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { | 571 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { |
448 // op + sx + sy | 572 // op + sx + sy |
449 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 573 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
450 uint32_t initialOffset = this->addDraw(SCALE, &size); | 574 uint32_t initialOffset = this->addDraw(SCALE, &size); |
575 SkASSERT(kInvalidOffset != initialOffset); | |
451 addScalar(sx); | 576 addScalar(sx); |
452 addScalar(sy); | 577 addScalar(sy); |
453 validate(initialOffset, size); | 578 validate(initialOffset, size); |
454 return this->INHERITED::scale(sx, sy); | 579 return this->INHERITED::scale(sx, sy); |
455 } | 580 } |
456 | 581 |
457 bool SkPictureRecord::rotate(SkScalar degrees) { | 582 bool SkPictureRecord::rotate(SkScalar degrees) { |
458 // op + degrees | 583 // op + degrees |
459 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar); | 584 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar); |
460 uint32_t initialOffset = this->addDraw(ROTATE, &size); | 585 uint32_t initialOffset = this->addDraw(ROTATE, &size); |
586 SkASSERT(kInvalidOffset != initialOffset); | |
461 addScalar(degrees); | 587 addScalar(degrees); |
462 validate(initialOffset, size); | 588 validate(initialOffset, size); |
463 return this->INHERITED::rotate(degrees); | 589 return this->INHERITED::rotate(degrees); |
464 } | 590 } |
465 | 591 |
466 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { | 592 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { |
467 // op + sx + sy | 593 // op + sx + sy |
468 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 594 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
469 uint32_t initialOffset = this->addDraw(SKEW, &size); | 595 uint32_t initialOffset = this->addDraw(SKEW, &size); |
596 SkASSERT(kInvalidOffset != initialOffset); | |
470 addScalar(sx); | 597 addScalar(sx); |
471 addScalar(sy); | 598 addScalar(sy); |
472 validate(initialOffset, size); | 599 validate(initialOffset, size); |
473 return this->INHERITED::skew(sx, sy); | 600 return this->INHERITED::skew(sx, sy); |
474 } | 601 } |
475 | 602 |
476 bool SkPictureRecord::concat(const SkMatrix& matrix) { | 603 bool SkPictureRecord::concat(const SkMatrix& matrix) { |
477 validate(fWriter.size(), 0); | 604 validate(fWriter.size(), 0); |
478 // op + matrix index | 605 // op + matrix index |
479 uint32_t size = 2 * kUInt32Size; | 606 uint32_t size = 2 * kUInt32Size; |
480 uint32_t initialOffset = this->addDraw(CONCAT, &size); | 607 uint32_t initialOffset = this->addDraw(CONCAT, &size); |
608 SkASSERT(kInvalidOffset != initialOffset); | |
481 addMatrix(matrix); | 609 addMatrix(matrix); |
482 validate(initialOffset, size); | 610 validate(initialOffset, size); |
483 return this->INHERITED::concat(matrix); | 611 return this->INHERITED::concat(matrix); |
484 } | 612 } |
485 | 613 |
486 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { | 614 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { |
487 validate(fWriter.size(), 0); | 615 validate(fWriter.size(), 0); |
488 // op + matrix index | 616 // op + matrix index |
489 uint32_t size = 2 * kUInt32Size; | 617 uint32_t size = 2 * kUInt32Size; |
490 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size); | 618 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size); |
619 SkASSERT(kInvalidOffset != initialOffset); | |
491 addMatrix(matrix); | 620 addMatrix(matrix); |
492 validate(initialOffset, size); | 621 validate(initialOffset, size); |
493 this->INHERITED::setMatrix(matrix); | 622 this->INHERITED::setMatrix(matrix); |
494 } | 623 } |
495 | 624 |
496 static bool regionOpExpands(SkRegion::Op op) { | 625 static bool regionOpExpands(SkRegion::Op op) { |
497 switch (op) { | 626 switch (op) { |
498 case SkRegion::kUnion_Op: | 627 case SkRegion::kUnion_Op: |
499 case SkRegion::kXOR_Op: | 628 case SkRegion::kXOR_Op: |
500 case SkRegion::kReverseDifference_Op: | 629 case SkRegion::kReverseDifference_Op: |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
562 | 691 |
563 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { | 692 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { |
564 // id + rect + clip params | 693 // id + rect + clip params |
565 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; | 694 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; |
566 // recordRestoreOffsetPlaceholder doesn't always write an offset | 695 // recordRestoreOffsetPlaceholder doesn't always write an offset |
567 if (!fRestoreOffsetStack.isEmpty()) { | 696 if (!fRestoreOffsetStack.isEmpty()) { |
568 // + restore offset | 697 // + restore offset |
569 size += kUInt32Size; | 698 size += kUInt32Size; |
570 } | 699 } |
571 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size); | 700 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size); |
701 SkASSERT(kInvalidOffset != initialOffset); | |
572 addRect(rect); | 702 addRect(rect); |
573 addInt(ClipParams_pack(op, doAA)); | 703 addInt(ClipParams_pack(op, doAA)); |
574 recordRestoreOffsetPlaceholder(op); | 704 recordRestoreOffsetPlaceholder(op); |
575 | 705 |
576 validate(initialOffset, size); | 706 validate(initialOffset, size); |
577 return this->INHERITED::clipRect(rect, op, doAA); | 707 return this->INHERITED::clipRect(rect, op, doAA); |
578 } | 708 } |
579 | 709 |
580 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) { | 710 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) { |
581 if (rrect.isRect()) { | 711 if (rrect.isRect()) { |
582 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); | 712 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); |
583 } | 713 } |
584 | 714 |
585 // op + rrect + clip params | 715 // op + rrect + clip params |
586 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; | 716 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; |
587 // recordRestoreOffsetPlaceholder doesn't always write an offset | 717 // recordRestoreOffsetPlaceholder doesn't always write an offset |
588 if (!fRestoreOffsetStack.isEmpty()) { | 718 if (!fRestoreOffsetStack.isEmpty()) { |
589 // + restore offset | 719 // + restore offset |
590 size += kUInt32Size; | 720 size += kUInt32Size; |
591 } | 721 } |
592 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); | 722 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); |
723 SkASSERT(kInvalidOffset != initialOffset); | |
593 addRRect(rrect); | 724 addRRect(rrect); |
594 addInt(ClipParams_pack(op, doAA)); | 725 addInt(ClipParams_pack(op, doAA)); |
595 recordRestoreOffsetPlaceholder(op); | 726 recordRestoreOffsetPlaceholder(op); |
596 | 727 |
597 validate(initialOffset, size); | 728 validate(initialOffset, size); |
598 | 729 |
599 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | 730 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
600 return this->INHERITED::clipRect(rrect.getBounds(), op, doAA); | 731 return this->INHERITED::clipRect(rrect.getBounds(), op, doAA); |
601 } else { | 732 } else { |
602 return this->INHERITED::clipRRect(rrect, op, doAA); | 733 return this->INHERITED::clipRRect(rrect, op, doAA); |
603 } | 734 } |
604 } | 735 } |
605 | 736 |
606 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { | 737 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { |
607 | 738 |
608 SkRect r; | 739 SkRect r; |
609 if (!path.isInverseFillType() && path.isRect(&r)) { | 740 if (!path.isInverseFillType() && path.isRect(&r)) { |
610 return this->clipRect(r, op, doAA); | 741 return this->clipRect(r, op, doAA); |
611 } | 742 } |
612 | 743 |
613 // op + path index + clip params | 744 // op + path index + clip params |
614 uint32_t size = 3 * kUInt32Size; | 745 uint32_t size = 3 * kUInt32Size; |
615 // recordRestoreOffsetPlaceholder doesn't always write an offset | 746 // recordRestoreOffsetPlaceholder doesn't always write an offset |
616 if (!fRestoreOffsetStack.isEmpty()) { | 747 if (!fRestoreOffsetStack.isEmpty()) { |
617 // + restore offset | 748 // + restore offset |
618 size += kUInt32Size; | 749 size += kUInt32Size; |
619 } | 750 } |
620 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); | 751 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); |
752 SkASSERT(kInvalidOffset != initialOffset); | |
621 addPath(path); | 753 addPath(path); |
622 addInt(ClipParams_pack(op, doAA)); | 754 addInt(ClipParams_pack(op, doAA)); |
623 recordRestoreOffsetPlaceholder(op); | 755 recordRestoreOffsetPlaceholder(op); |
624 | 756 |
625 validate(initialOffset, size); | 757 validate(initialOffset, size); |
626 | 758 |
627 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | 759 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
628 return this->INHERITED::clipRect(path.getBounds(), op, doAA); | 760 return this->INHERITED::clipRect(path.getBounds(), op, doAA); |
629 } else { | 761 } else { |
630 return this->INHERITED::clipPath(path, op, doAA); | 762 return this->INHERITED::clipPath(path, op, doAA); |
631 } | 763 } |
632 } | 764 } |
633 | 765 |
634 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { | 766 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { |
635 // op + region index + clip params | 767 // op + region index + clip params |
636 uint32_t size = 3 * kUInt32Size; | 768 uint32_t size = 3 * kUInt32Size; |
637 // recordRestoreOffsetPlaceholder doesn't always write an offset | 769 // recordRestoreOffsetPlaceholder doesn't always write an offset |
638 if (!fRestoreOffsetStack.isEmpty()) { | 770 if (!fRestoreOffsetStack.isEmpty()) { |
639 // + restore offset | 771 // + restore offset |
640 size += kUInt32Size; | 772 size += kUInt32Size; |
641 } | 773 } |
642 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); | 774 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); |
775 SkASSERT(kInvalidOffset != initialOffset); | |
643 addRegion(region); | 776 addRegion(region); |
644 addInt(ClipParams_pack(op, false)); | 777 addInt(ClipParams_pack(op, false)); |
645 recordRestoreOffsetPlaceholder(op); | 778 recordRestoreOffsetPlaceholder(op); |
646 | 779 |
647 validate(initialOffset, size); | 780 validate(initialOffset, size); |
648 return this->INHERITED::clipRegion(region, op); | 781 return this->INHERITED::clipRegion(region, op); |
649 } | 782 } |
650 | 783 |
651 void SkPictureRecord::clear(SkColor color) { | 784 void SkPictureRecord::clear(SkColor color) { |
652 // op + color | 785 // op + color |
653 uint32_t size = 2 * kUInt32Size; | 786 uint32_t size = 2 * kUInt32Size; |
654 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); | 787 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); |
788 if (kInvalidOffset == initialOffset) { | |
789 return; | |
790 } | |
655 addInt(color); | 791 addInt(color); |
656 validate(initialOffset, size); | 792 validate(initialOffset, size); |
657 } | 793 } |
658 | 794 |
659 void SkPictureRecord::drawPaint(const SkPaint& paint) { | 795 void SkPictureRecord::drawPaint(const SkPaint& paint) { |
660 // op + paint index | 796 // op + paint index |
661 uint32_t size = 2 * kUInt32Size; | 797 uint32_t size = 2 * kUInt32Size; |
662 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); | 798 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); |
663 SkASSERT(initialOffset+getPaintOffset(DRAW_PAINT, size) == fWriter.size()); | 799 if (kInvalidOffset == initialOffset) { |
800 return; | |
801 } | |
802 SkASSERT(initialOffset + getPaintOffset(DRAW_PAINT, size, false) == fWriter. size()); | |
664 addPaint(paint); | 803 addPaint(paint); |
665 validate(initialOffset, size); | 804 validate(initialOffset, size); |
666 } | 805 } |
667 | 806 |
668 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], | 807 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], |
669 const SkPaint& paint) { | 808 const SkPaint& paint) { |
670 // op + paint index + mode + count + point data | 809 // op + paint index + mode + count + point data |
671 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); | 810 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); |
672 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size); | 811 uint32_t initialOffset; |
673 SkASSERT(initialOffset+getPaintOffset(DRAW_POINTS, size) == fWriter.size()); | 812 if (this->recordBounds()) { |
813 SkRect bbox; | |
814 bbox.set(pts, count); | |
815 initialOffset = this->addDraw(DRAW_POINTS, &size, &paint, &bbox); | |
816 } else { | |
817 initialOffset = this->addDraw(DRAW_POINTS, &size); | |
818 } | |
819 if (kInvalidOffset == initialOffset) { | |
820 return; | |
821 } | |
822 SkASSERT(initialOffset + getPaintOffset(DRAW_POINTS, size, this->recordBound s()) \ | |
823 == fWriter.size()); | |
674 addPaint(paint); | 824 addPaint(paint); |
675 addInt(mode); | 825 addInt(mode); |
676 addInt(count); | 826 addInt(count); |
677 fWriter.writeMul4(pts, count * sizeof(SkPoint)); | 827 fWriter.writeMul4(pts, count * sizeof(SkPoint)); |
678 validate(initialOffset, size); | 828 validate(initialOffset, size); |
679 } | 829 } |
680 | 830 |
681 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { | 831 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { |
682 // op + paint index + rect | 832 // op + paint index + rect |
683 uint32_t size = 2 * kUInt32Size + sizeof(oval); | 833 uint32_t size = 2 * kUInt32Size + sizeof(oval); |
684 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size); | 834 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size, &paint, &oval); |
685 SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size()); | 835 if (kInvalidOffset == initialOffset) { |
836 return; | |
837 } | |
838 SkASSERT(initialOffset + getPaintOffset(DRAW_OVAL, size, this->recordBounds( )) \ | |
839 == fWriter.size()); | |
686 addPaint(paint); | 840 addPaint(paint); |
687 addRect(oval); | 841 addRect(oval); |
688 validate(initialOffset, size); | 842 validate(initialOffset, size); |
689 } | 843 } |
690 | 844 |
691 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { | 845 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { |
692 // op + paint index + rect | 846 // op + paint index + rect |
693 uint32_t size = 2 * kUInt32Size + sizeof(rect); | 847 uint32_t size = 2 * kUInt32Size + sizeof(rect); |
694 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size); | 848 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size, &paint, &rect); |
695 SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size()); | 849 if (kInvalidOffset == initialOffset) { |
850 return; | |
851 } | |
852 SkASSERT(initialOffset + getPaintOffset(DRAW_RECT, size, this->recordBounds( )) \ | |
853 == fWriter.size()); | |
696 addPaint(paint); | 854 addPaint(paint); |
697 addRect(rect); | 855 addRect(rect); |
698 validate(initialOffset, size); | 856 validate(initialOffset, size); |
699 } | 857 } |
700 | 858 |
701 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { | 859 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { |
702 uint32_t initialOffset, size; | |
703 if (rrect.isRect()) { | 860 if (rrect.isRect()) { |
704 // op + paint index + rect | 861 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()) { | 862 } else if (rrect.isOval()) { |
711 // op + paint index + rect | 863 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 { | 864 } else { |
718 // op + paint index + rrect | 865 // op + paint index + rrect |
719 size = 2 * kUInt32Size + SkRRect::kSizeInMemory; | 866 uint32_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory; |
720 initialOffset = this->addDraw(DRAW_RRECT, &size); | 867 uint32_t initialOffset = this->addDraw(DRAW_RRECT, &size, &paint, &rrect .getBounds()); |
721 SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.size( )); | 868 if (kInvalidOffset == initialOffset) { |
869 return; | |
870 } | |
871 SkASSERT(initialOffset + getPaintOffset(DRAW_RRECT, size, this->recordBo unds()) \ | |
872 == fWriter.size()); | |
722 addPaint(paint); | 873 addPaint(paint); |
723 addRRect(rrect); | 874 addRRect(rrect); |
875 validate(initialOffset, size); | |
724 } | 876 } |
725 validate(initialOffset, size); | |
726 } | 877 } |
727 | 878 |
728 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { | 879 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { |
729 // op + paint index + path index | 880 // op + paint index + path index |
730 uint32_t size = 3 * kUInt32Size; | 881 uint32_t size = 3 * kUInt32Size; |
731 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size); | 882 const SkRect* bounds = path.isInverseFillType() ? NULL : &path.getBounds(); |
732 SkASSERT(initialOffset+getPaintOffset(DRAW_PATH, size) == fWriter.size()); | 883 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size, &paint, bounds); |
884 if (kInvalidOffset == initialOffset) { | |
885 return; | |
886 } | |
887 SkASSERT(initialOffset + getPaintOffset(DRAW_PATH, size, this->recordBounds( )) \ | |
888 == fWriter.size()); | |
733 addPaint(paint); | 889 addPaint(paint); |
734 addPath(path); | 890 addPath(path); |
735 validate(initialOffset, size); | 891 validate(initialOffset, size); |
736 } | 892 } |
737 | 893 |
738 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, | 894 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, |
739 const SkPaint* paint = NULL) { | 895 const SkPaint* paint = NULL) { |
740 // op + paint index + bitmap index + left + top | 896 // op + paint index + bitmap index + left + top |
741 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); | 897 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); |
742 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size); | 898 SkRect bounds = SkRect::MakeXYWH(left, top, bitmap.width(), bitmap.height()) ; |
743 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP, size) == fWriter.size()); | 899 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size, paint, &bounds); |
900 if (kInvalidOffset == initialOffset) { | |
901 return; | |
902 } | |
903 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP, size, this->recordBound s()) \ | |
904 == fWriter.size()); | |
744 addPaintPtr(paint); | 905 addPaintPtr(paint); |
745 addBitmap(bitmap); | 906 addBitmap(bitmap); |
746 addScalar(left); | 907 addScalar(left); |
747 addScalar(top); | 908 addScalar(top); |
748 validate(initialOffset, size); | 909 validate(initialOffset, size); |
749 } | 910 } |
750 | 911 |
751 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, | 912 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, |
752 const SkRect& dst, const SkPaint* paint) { | 913 const SkRect& dst, const SkPaint* paint) { |
753 // id + paint index + bitmap index + bool for 'src' | 914 // id + paint index + bitmap index + bool for 'src' |
754 uint32_t size = 4 * kUInt32Size; | 915 uint32_t size = 4 * kUInt32Size; |
755 if (NULL != src) { | 916 if (NULL != src) { |
756 size += sizeof(*src); // + rect | 917 size += sizeof(*src); // + rect |
757 } | 918 } |
758 size += sizeof(dst); // + rect | 919 size += sizeof(dst); // + rect |
759 | 920 |
760 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); | 921 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()); | 922 if (kInvalidOffset == initialOffset) { |
923 return; | |
924 } | |
925 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size, this ->recordBounds()) \ | |
926 == fWriter.size()); | |
762 addPaintPtr(paint); | 927 addPaintPtr(paint); |
763 addBitmap(bitmap); | 928 addBitmap(bitmap); |
764 addRectPtr(src); // may be null | 929 addRectPtr(src); // may be null |
765 addRect(dst); | 930 addRect(dst); |
766 validate(initialOffset, size); | 931 validate(initialOffset, size); |
767 } | 932 } |
768 | 933 |
769 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, | 934 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, |
770 const SkPaint* paint) { | 935 const SkPaint* paint) { |
771 // id + paint index + bitmap index + matrix index | 936 // id + paint index + bitmap index + matrix index |
772 uint32_t size = 4 * kUInt32Size; | 937 uint32_t size = 4 * kUInt32Size; |
773 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); | 938 uint32_t initialOffset; |
774 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.s ize()); | 939 if (this->recordBounds()) { |
940 SkRect bounds = SkRect::MakeWH(bitmap.width(), bitmap.height()); | |
941 matrix.mapRect(&bounds); | |
942 initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size, paint, &bounds) ; | |
943 } else { | |
944 initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); | |
945 } | |
946 if (kInvalidOffset == initialOffset) { | |
947 return; | |
948 } | |
949 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_MATRIX, size, this->reco rdBounds()) \ | |
950 == fWriter.size()); | |
775 addPaintPtr(paint); | 951 addPaintPtr(paint); |
776 addBitmap(bitmap); | 952 addBitmap(bitmap); |
777 addMatrix(matrix); | 953 addMatrix(matrix); |
778 validate(initialOffset, size); | 954 validate(initialOffset, size); |
779 } | 955 } |
780 | 956 |
781 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, | 957 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, |
782 const SkRect& dst, const SkPaint* paint) { | 958 const SkRect& dst, const SkPaint* paint) { |
783 // op + paint index + bitmap id + center + dst rect | 959 // op + paint index + bitmap id + center + dst rect |
784 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); | 960 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); |
785 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); | 961 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size, paint, &dst) ; |
786 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.siz e()); | 962 if (kInvalidOffset == initialOffset) { |
963 return; | |
964 } | |
965 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_NINE, size, this->record Bounds()) == \ | |
966 fWriter.size()); | |
787 addPaintPtr(paint); | 967 addPaintPtr(paint); |
788 addBitmap(bitmap); | 968 addBitmap(bitmap); |
789 addIRect(center); | 969 addIRect(center); |
790 addRect(dst); | 970 addRect(dst); |
791 validate(initialOffset, size); | 971 validate(initialOffset, size); |
792 } | 972 } |
793 | 973 |
794 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, | 974 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, |
795 const SkPaint* paint = NULL) { | 975 const SkPaint* paint) { |
796 // op + paint index + bitmap index + left + top | 976 // op + paint index + bitmap index + left + top |
797 uint32_t size = 5 * kUInt32Size; | 977 uint32_t size = 5 * kUInt32Size; |
798 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size); | 978 uint32_t initialOffset; |
robertphillips
2013/03/07 18:37:40
Could you expand on this with a "because ..."
| |
799 SkASSERT(initialOffset+getPaintOffset(DRAW_SPRITE, size) == fWriter.size()); | 979 // Note: Bounds encoding not supported. |
robertphillips
2013/03/07 18:37:40
Move uint32_t down to line 980?
| |
980 initialOffset = this->addDraw(DRAW_SPRITE, &size); | |
981 if (kInvalidOffset == initialOffset) { | |
982 return; | |
983 } | |
984 SkASSERT(initialOffset + getPaintOffset(DRAW_SPRITE, size, false) == fWriter .size()); | |
800 addPaintPtr(paint); | 985 addPaintPtr(paint); |
801 addBitmap(bitmap); | 986 addBitmap(bitmap); |
802 addInt(left); | 987 addInt(left); |
803 addInt(top); | 988 addInt(top); |
804 validate(initialOffset, size); | 989 validate(initialOffset, size); |
805 } | 990 } |
806 | 991 |
807 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been | 992 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been |
808 // tweaked by paint.computeFastBounds(). | 993 // tweaked by paint.computeFastBounds(). |
809 // | 994 // |
(...skipping 14 matching lines...) Expand all Loading... | |
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 } |
831 | 1016 |
832 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, | 1017 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, |
833 SkScalar y, const SkPaint& paint) { | 1018 SkScalar y, const SkPaint& paint) { |
834 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | 1019 // Note: The DRAW_TEXT_TOP_BOTTOM optimization is redundant if we are |
1020 // already recording full bounds. | |
1021 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds() && | |
robertphillips
2013/03/07 18:37:40
spaces
| |
1022 !this->recordBounds(); | |
835 | 1023 |
836 // op + paint index + length + 'length' worth of chars + x + y | 1024 // op + paint index + length + 'length' worth of chars + x + y |
837 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); | 1025 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); |
838 if (fast) { | 1026 if (fast) { |
839 size += 2 * sizeof(SkScalar); // + top & bottom | 1027 size += 2 * sizeof(SkScalar); // + top & bottom |
840 } | 1028 } |
841 | 1029 |
842 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; | 1030 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; |
843 uint32_t initialOffset = this->addDraw(op, &size); | 1031 uint32_t initialOffset; |
844 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); | 1032 if (this->recordBounds()) { |
1033 SkRect bbox; | |
1034 paint.measureText(text, byteLength, &bbox); | |
1035 SkPaint::FontMetrics metrics; | |
1036 paint.getFontMetrics(&metrics); | |
1037 | |
1038 // Vertical and aligned text need to be offset | |
1039 if (paint.isVerticalText()) { | |
1040 SkScalar h = bbox.fBottom - bbox.fTop; | |
1041 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
1042 bbox.fTop -= h / 2; | |
1043 bbox.fBottom -= h / 2; | |
1044 } | |
1045 // Pad top and bottom with max extents from FontMetrics | |
1046 bbox.fBottom += metrics.fBottom; | |
1047 bbox.fTop += metrics.fTop; | |
1048 } else { | |
1049 SkScalar w = bbox.fRight - bbox.fLeft; | |
1050 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
1051 bbox.fLeft -= w / 2; | |
1052 bbox.fRight -= w / 2; | |
1053 } else if (paint.getTextAlign() == SkPaint::kRight_Align) { | |
1054 bbox.fLeft -= w; | |
1055 bbox.fRight -= w; | |
1056 } | |
1057 // Set vertical bounds to max extents from font metrics | |
1058 bbox.fTop = metrics.fTop; | |
1059 bbox.fBottom = metrics.fBottom; | |
1060 } | |
1061 | |
1062 // Pad horizontal bounds on each side by half of max vertical extents (t his is sort of | |
reed1
2013/03/07 20:36:44
80-cols in this file
| |
1063 // arbitrary, but seems to produce reasonable results, if there were a w ay of getting max | |
1064 // glyph X-extents to pad by, that may be better here, but FontMetrics f XMin and fXMax seem | |
1065 // incorrect on most platforms (too small in Linux, never even set in Wi ndows). | |
reed1
2013/03/07 20:36:44
yikes! please file a bug!
Justin Novosad
2013/03/08 14:49:14
This was copy-pasted from SkBBoxRecord (r5423 by r
| |
1066 SkScalar pad = (metrics.fBottom - metrics.fTop) / 2; | |
1067 bbox.fLeft -= pad; | |
1068 bbox.fRight += pad; | |
1069 | |
1070 bbox.fLeft += x; | |
1071 bbox.fRight += x; | |
1072 bbox.fTop += y; | |
1073 bbox.fBottom += y; | |
1074 initialOffset = this->addDraw(op, &size, &paint, &bbox); | |
1075 } else { | |
1076 initialOffset = this->addDraw(op, &size); | |
1077 } | |
1078 if (kInvalidOffset == initialOffset) { | |
1079 return; | |
1080 } | |
1081 SkASSERT(initialOffset + getPaintOffset(op, size, this->recordBounds()) == f Writer.size()); | |
845 const SkFlatData* flatPaintData = addPaint(paint); | 1082 const SkFlatData* flatPaintData = addPaint(paint); |
846 SkASSERT(flatPaintData); | 1083 SkASSERT(flatPaintData); |
847 addText(text, byteLength); | 1084 addText(text, byteLength); |
848 addScalar(x); | 1085 addScalar(x); |
849 addScalar(y); | 1086 addScalar(y); |
850 if (fast) { | 1087 if (fast) { |
851 addFontMetricsTopBottom(paint, *flatPaintData, y, y); | 1088 addFontMetricsTopBottom(paint, *flatPaintData, y, y); |
852 } | 1089 } |
853 validate(initialOffset, size); | 1090 validate(initialOffset, size); |
854 } | 1091 } |
(...skipping 15 matching lines...) Expand all Loading... | |
870 canUseDrawH = false; | 1107 canUseDrawH = false; |
871 if (pos[index].fY < minY) { | 1108 if (pos[index].fY < minY) { |
872 minY = pos[index].fY; | 1109 minY = pos[index].fY; |
873 } else if (pos[index].fY > maxY) { | 1110 } else if (pos[index].fY > maxY) { |
874 maxY = pos[index].fY; | 1111 maxY = pos[index].fY; |
875 } | 1112 } |
876 } | 1113 } |
877 } | 1114 } |
878 } | 1115 } |
879 | 1116 |
880 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds(); | 1117 // Note: The DRAW_TEXT_[H_]TOP_BOTTOM optimization is redundant if we are |
1118 // already recording full bounds. | |
1119 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds() && | |
robertphillips
2013/03/07 18:37:40
spaces
| |
1120 !this->recordBounds(); | |
881 bool fast = canUseDrawH && fastBounds; | 1121 bool fast = canUseDrawH && fastBounds; |
882 | 1122 |
883 // op + paint index + length + 'length' worth of data + num points | 1123 // op + paint index + length + 'length' worth of data + num points |
884 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; | 1124 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; |
885 if (canUseDrawH) { | 1125 if (canUseDrawH) { |
886 if (fast) { | 1126 if (fast) { |
887 size += 2 * sizeof(SkScalar); // + top & bottom | 1127 size += 2 * sizeof(SkScalar); // + top & bottom |
888 } | 1128 } |
889 // + y-pos + actual x-point data | 1129 // + y-pos + actual x-point data |
890 size += sizeof(SkScalar) + points * sizeof(SkScalar); | 1130 size += sizeof(SkScalar) + points * sizeof(SkScalar); |
891 } else { | 1131 } else { |
892 // + x&y point data | 1132 // + x&y point data |
893 size += points * sizeof(SkPoint); | 1133 size += points * sizeof(SkPoint); |
894 if (fastBounds) { | 1134 if (fastBounds) { |
895 size += 2 * sizeof(SkScalar); // + top & bottom | 1135 size += 2 * sizeof(SkScalar); // + top & bottom |
896 } | 1136 } |
897 } | 1137 } |
898 | 1138 |
899 DrawType op; | 1139 DrawType op; |
900 if (fast) { | 1140 if (fast) { |
901 op = DRAW_POS_TEXT_H_TOP_BOTTOM; | 1141 op = DRAW_POS_TEXT_H_TOP_BOTTOM; |
902 } else if (canUseDrawH) { | 1142 } else if (canUseDrawH) { |
903 op = DRAW_POS_TEXT_H; | 1143 op = DRAW_POS_TEXT_H; |
904 } else if (fastBounds) { | 1144 } else if (fastBounds) { |
905 op = DRAW_POS_TEXT_TOP_BOTTOM; | 1145 op = DRAW_POS_TEXT_TOP_BOTTOM; |
906 } else { | 1146 } else { |
907 op = DRAW_POS_TEXT; | 1147 op = DRAW_POS_TEXT; |
908 } | 1148 } |
909 uint32_t initialOffset = this->addDraw(op, &size); | 1149 uint32_t initialOffset; |
910 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); | 1150 if (this->recordBounds()) { |
1151 SkRect bbox; | |
1152 bbox.set(pos, paint.countText(text, byteLength)); | |
1153 SkPaint::FontMetrics metrics; | |
1154 paint.getFontMetrics(&metrics); | |
1155 bbox.fTop += metrics.fTop; | |
1156 bbox.fBottom += metrics.fBottom; | |
1157 | |
1158 // pad on left and right by half of max vertical glyph extents | |
1159 SkScalar pad = (metrics.fTop - metrics.fBottom) / 2; | |
1160 bbox.fLeft += pad; | |
1161 bbox.fRight -= pad; | |
1162 initialOffset = addDraw(op, &size, &paint, &bbox); | |
1163 } else { | |
1164 initialOffset = this->addDraw(op, &size); | |
1165 } | |
1166 if (kInvalidOffset == initialOffset) { | |
1167 return; | |
1168 } | |
1169 SkASSERT(initialOffset + getPaintOffset(op, size, this->recordBounds()) == f Writer.size()); | |
911 const SkFlatData* flatPaintData = addPaint(paint); | 1170 const SkFlatData* flatPaintData = addPaint(paint); |
912 SkASSERT(flatPaintData); | 1171 SkASSERT(flatPaintData); |
913 addText(text, byteLength); | 1172 addText(text, byteLength); |
914 addInt(points); | 1173 addInt(points); |
915 | 1174 |
916 #ifdef SK_DEBUG_SIZE | 1175 #ifdef SK_DEBUG_SIZE |
917 size_t start = fWriter.size(); | 1176 size_t start = fWriter.size(); |
918 #endif | 1177 #endif |
919 if (canUseDrawH) { | 1178 if (canUseDrawH) { |
920 if (fast) { | 1179 if (fast) { |
(...skipping 16 matching lines...) Expand all Loading... | |
937 validate(initialOffset, size); | 1196 validate(initialOffset, size); |
938 } | 1197 } |
939 | 1198 |
940 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, | 1199 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, |
941 const SkScalar xpos[], SkScalar constY, | 1200 const SkScalar xpos[], SkScalar constY, |
942 const SkPaint& paint) { | 1201 const SkPaint& paint) { |
943 size_t points = paint.countText(text, byteLength); | 1202 size_t points = paint.countText(text, byteLength); |
944 if (0 == points) | 1203 if (0 == points) |
945 return; | 1204 return; |
946 | 1205 |
947 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | 1206 // Note: The DRAW_POS_TEXT_H_TOP_BOTTOM optimization is redundant if we are |
1207 // already recording full bounds. | |
1208 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds() && | |
robertphillips
2013/03/07 18:37:40
spaces
| |
1209 !this->recordBounds(); | |
948 | 1210 |
949 // op + paint index + length + 'length' worth of data + num points | 1211 // op + paint index + length + 'length' worth of data + num points |
950 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; | 1212 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; |
951 if (fast) { | 1213 if (fast) { |
952 size += 2 * sizeof(SkScalar); // + top & bottom | 1214 size += 2 * sizeof(SkScalar); // + top & bottom |
953 } | 1215 } |
954 // + y + the actual points | 1216 // + y + the actual points |
955 size += 1 * kUInt32Size + points * sizeof(SkScalar); | 1217 size += 1 * kUInt32Size + points * sizeof(SkScalar); |
956 | 1218 |
957 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H, | 1219 uint32_t initialOffset; |
958 &size); | 1220 if (this->recordBounds()) { |
1221 size_t numChars = paint.countText(text, byteLength); | |
robertphillips
2013/03/07 18:37:40
We should probably bail somewhere (or add an asser
Justin Novosad
2013/03/07 20:25:47
Actually, I just realized this is redundant with '
| |
1222 SkRect bbox; | |
1223 bbox.fLeft = xpos[0]; | |
robertphillips
2013/03/07 18:37:40
shouldn't this be 0 rather than numChars-1?
Justin Novosad
2013/03/07 20:25:47
For the algorithm to work, it actually does not ma
robertphillips
2013/03/07 20:57:37
Since we have no guarantee of monotonicity, what i
| |
1224 bbox.fRight = xpos[numChars - 1]; | |
1225 // if we had a guarantee that these will be monotonically increasing, th is could be sped up | |
1226 for (size_t i = 1; i < numChars; ++i) { | |
1227 if (xpos[i] < bbox.fLeft) { | |
1228 bbox.fLeft = xpos[i]; | |
1229 } | |
1230 if (xpos[i] > bbox.fRight) { | |
1231 bbox.fRight = xpos[i]; | |
1232 } | |
1233 } | |
1234 SkPaint::FontMetrics metrics; | |
reed1
2013/03/07 20:36:44
Some amount of this code looks awefully similar to
| |
1235 paint.getFontMetrics(&metrics); | |
1236 | |
1237 // pad horizontally by max glyph height | |
1238 SkScalar pad = (metrics.fTop - metrics.fBottom); | |
1239 bbox.fLeft += pad; | |
1240 bbox.fRight -= pad; | |
1241 | |
1242 bbox.fTop = metrics.fTop + constY; | |
1243 bbox.fBottom = metrics.fBottom + constY; | |
1244 initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size, &paint, &bbox); | |
1245 } else { | |
1246 initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_P OS_TEXT_H, | |
1247 &size); | |
1248 } | |
1249 if (kInvalidOffset == initialOffset) { | |
1250 return; | |
1251 } | |
1252 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size, this->recor dBounds()) \ | |
1253 == fWriter.size()); | |
959 const SkFlatData* flatPaintData = addPaint(paint); | 1254 const SkFlatData* flatPaintData = addPaint(paint); |
960 SkASSERT(flatPaintData); | 1255 SkASSERT(flatPaintData); |
961 addText(text, byteLength); | 1256 addText(text, byteLength); |
962 addInt(points); | 1257 addInt(points); |
963 | 1258 |
964 #ifdef SK_DEBUG_SIZE | 1259 #ifdef SK_DEBUG_SIZE |
965 size_t start = fWriter.size(); | 1260 size_t start = fWriter.size(); |
966 #endif | 1261 #endif |
967 if (fast) { | 1262 if (fast) { |
968 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); | 1263 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); |
969 } | 1264 } |
970 addScalar(constY); | 1265 addScalar(constY); |
971 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); | 1266 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); |
972 #ifdef SK_DEBUG_SIZE | 1267 #ifdef SK_DEBUG_SIZE |
973 fPointBytes += fWriter.size() - start; | 1268 fPointBytes += fWriter.size() - start; |
974 fPointWrites += points; | 1269 fPointWrites += points; |
975 #endif | 1270 #endif |
976 validate(initialOffset, size); | 1271 validate(initialOffset, size); |
977 } | 1272 } |
978 | 1273 |
979 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, | 1274 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, |
980 const SkPath& path, const SkMatrix* matrix, | 1275 const SkPath& path, const SkMatrix* matrix, |
981 const SkPaint& paint) { | 1276 const SkPaint& paint) { |
982 // op + paint index + length + 'length' worth of data + path index + matrix index | 1277 // op + paint index + length + 'length' worth of data + path index + matrix index |
983 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; | 1278 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; |
984 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); | 1279 uint32_t initialOffset; |
985 SkASSERT(initialOffset+getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter.si ze()); | 1280 if (this->recordBounds()) { |
1281 SkRect bbox = path.getBounds(); | |
1282 SkPaint::FontMetrics metrics; | |
1283 paint.getFontMetrics(&metrics); | |
1284 // pad out all sides by the max glyph height above baseline | |
1285 SkScalar pad = metrics.fTop; | |
1286 bbox.fLeft += pad; | |
1287 bbox.fRight -= pad; | |
1288 bbox.fTop += pad; | |
1289 bbox.fBottom -= pad; | |
1290 initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size, &paint, &bbox); | |
1291 } else { | |
1292 initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); | |
1293 } | |
1294 if (kInvalidOffset == initialOffset) { | |
1295 return; | |
1296 } | |
1297 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size, this->recor dBounds()) \ | |
1298 == fWriter.size()); | |
986 addPaint(paint); | 1299 addPaint(paint); |
987 addText(text, byteLength); | 1300 addText(text, byteLength); |
988 addPath(path); | 1301 addPath(path); |
989 addMatrixPtr(matrix); | 1302 addMatrixPtr(matrix); |
990 validate(initialOffset, size); | 1303 validate(initialOffset, size); |
991 } | 1304 } |
992 | 1305 |
993 void SkPictureRecord::drawPicture(SkPicture& picture) { | 1306 void SkPictureRecord::drawPicture(SkPicture& picture) { |
994 // op + picture index | 1307 // op + picture index |
995 uint32_t size = 2 * kUInt32Size; | 1308 uint32_t size = 2 * kUInt32Size; |
996 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size); | 1309 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size); |
1310 SkASSERT(kInvalidOffset != initialOffset); | |
997 addPicture(picture); | 1311 addPicture(picture); |
998 validate(initialOffset, size); | 1312 validate(initialOffset, size); |
999 } | 1313 } |
1000 | 1314 |
1001 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, | 1315 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, |
1002 const SkPoint vertices[], const SkPoint texs[], | 1316 const SkPoint vertices[], const SkPoint texs[], |
1003 const SkColor colors[], SkXfermode*, | 1317 const SkColor colors[], SkXfermode*, |
1004 const uint16_t indices[], int indexCount, | 1318 const uint16_t indices[], int indexCount, |
1005 const SkPaint& paint) { | 1319 const SkPaint& paint) { |
1006 uint32_t flags = 0; | 1320 uint32_t flags = 0; |
(...skipping 13 matching lines...) Expand all Loading... | |
1020 size += vertexCount * sizeof(SkPoint); // + uvs | 1334 size += vertexCount * sizeof(SkPoint); // + uvs |
1021 } | 1335 } |
1022 if (flags & DRAW_VERTICES_HAS_COLORS) { | 1336 if (flags & DRAW_VERTICES_HAS_COLORS) { |
1023 size += vertexCount * sizeof(SkColor); // + vert colors | 1337 size += vertexCount * sizeof(SkColor); // + vert colors |
1024 } | 1338 } |
1025 if (flags & DRAW_VERTICES_HAS_INDICES) { | 1339 if (flags & DRAW_VERTICES_HAS_INDICES) { |
1026 // + num indices + indices | 1340 // + num indices + indices |
1027 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); | 1341 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); |
1028 } | 1342 } |
1029 | 1343 |
1030 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size); | 1344 uint32_t initialOffset; |
1031 SkASSERT(initialOffset+getPaintOffset(DRAW_VERTICES, size) == fWriter.size() ); | 1345 if (this->recordBounds()) { |
1346 SkRect bbox; | |
1347 bbox.set(vertices, vertexCount); | |
1348 initialOffset = this->addDraw(DRAW_VERTICES, &size, &paint, &bbox); | |
1349 } else { | |
1350 initialOffset = this->addDraw(DRAW_VERTICES, &size); | |
1351 } | |
1352 if (kInvalidOffset == initialOffset) { | |
1353 return; | |
1354 } | |
1355 SkASSERT(initialOffset + getPaintOffset(DRAW_VERTICES, size, this->recordBou nds()) \ | |
1356 == fWriter.size()); | |
1032 addPaint(paint); | 1357 addPaint(paint); |
1033 addInt(flags); | 1358 addInt(flags); |
1034 addInt(vmode); | 1359 addInt(vmode); |
1035 addInt(vertexCount); | 1360 addInt(vertexCount); |
1036 addPoints(vertices, vertexCount); | 1361 addPoints(vertices, vertexCount); |
1037 if (flags & DRAW_VERTICES_HAS_TEXS) { | 1362 if (flags & DRAW_VERTICES_HAS_TEXS) { |
1038 addPoints(texs, vertexCount); | 1363 addPoints(texs, vertexCount); |
1039 } | 1364 } |
1040 if (flags & DRAW_VERTICES_HAS_COLORS) { | 1365 if (flags & DRAW_VERTICES_HAS_COLORS) { |
1041 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); | 1366 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); |
1042 } | 1367 } |
1043 if (flags & DRAW_VERTICES_HAS_INDICES) { | 1368 if (flags & DRAW_VERTICES_HAS_INDICES) { |
1044 addInt(indexCount); | 1369 addInt(indexCount); |
1045 fWriter.writePad(indices, indexCount * sizeof(uint16_t)); | 1370 fWriter.writePad(indices, indexCount * sizeof(uint16_t)); |
1046 } | 1371 } |
1047 validate(initialOffset, size); | 1372 validate(initialOffset, size); |
1048 } | 1373 } |
1049 | 1374 |
1050 void SkPictureRecord::drawData(const void* data, size_t length) { | 1375 void SkPictureRecord::drawData(const void* data, size_t length) { |
1051 // op + length + 'length' worth of data | 1376 // op + length + 'length' worth of data |
1052 uint32_t size = 2 * kUInt32Size + SkAlign4(length); | 1377 uint32_t size = 2 * kUInt32Size + SkAlign4(length); |
1053 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size); | 1378 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size); |
1379 SkASSERT(kInvalidOffset != initialOffset); | |
1054 addInt(length); | 1380 addInt(length); |
1055 fWriter.writePad(data, length); | 1381 fWriter.writePad(data, length); |
1056 validate(initialOffset, size); | 1382 validate(initialOffset, size); |
1057 } | 1383 } |
1058 | 1384 |
1059 /////////////////////////////////////////////////////////////////////////////// | 1385 /////////////////////////////////////////////////////////////////////////////// |
1060 | 1386 |
1061 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { | 1387 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { |
1062 const int index = fBitmapHeap->insert(bitmap); | 1388 const int index = fBitmapHeap->insert(bitmap); |
1063 // In debug builds, a bad return value from insert() will crash, allowing fo r debugging. In | 1389 // 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 Loading... | |
1292 void SkPictureRecord::validateRegions() const { | 1618 void SkPictureRecord::validateRegions() const { |
1293 int count = fRegions.count(); | 1619 int count = fRegions.count(); |
1294 SkASSERT((unsigned) count < 0x1000); | 1620 SkASSERT((unsigned) count < 0x1000); |
1295 for (int index = 0; index < count; index++) { | 1621 for (int index = 0; index < count; index++) { |
1296 const SkFlatData* region = fRegions[index]; | 1622 const SkFlatData* region = fRegions[index]; |
1297 SkASSERT(region); | 1623 SkASSERT(region); |
1298 // region->validate(); | 1624 // region->validate(); |
1299 } | 1625 } |
1300 } | 1626 } |
1301 #endif | 1627 #endif |
OLD | NEW |