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