OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 0, // SAVE_LAYER - see below - this paint's location varies | 105 0, // SAVE_LAYER - see below - this paint's location varies |
106 0, // SCALE - no paint | 106 0, // SCALE - no paint |
107 0, // SET_MATRIX - no paint | 107 0, // SET_MATRIX - no paint |
108 0, // SKEW - no paint | 108 0, // SKEW - no paint |
109 0, // TRANSLATE - no paint | 109 0, // TRANSLATE - no paint |
110 0, // NOOP - no paint | 110 0, // NOOP - no paint |
111 0, // BEGIN_GROUP - no paint | 111 0, // BEGIN_GROUP - no paint |
112 0, // COMMENT - no paint | 112 0, // COMMENT - no paint |
113 0, // END_GROUP - no paint | 113 0, // END_GROUP - no paint |
114 1, // DRAWDRRECT - right after op code | 114 1, // DRAWDRRECT - right after op code |
| 115 0, // PUSH_CULL - no paint |
| 116 0, // POP_CULL - no paint |
115 }; | 117 }; |
116 | 118 |
117 SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1, | 119 SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1, |
118 need_to_be_in_sync); | 120 need_to_be_in_sync); |
119 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); | 121 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); |
120 | 122 |
121 int overflow = 0; | 123 int overflow = 0; |
122 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { | 124 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { |
123 // This op's size overflows so an extra uint32_t will be written | 125 // This op's size overflows so an extra uint32_t will be written |
124 // after the op code | 126 // after the op code |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 | 215 |
214 bool SkPictureRecord::isDrawingToLayer() const { | 216 bool SkPictureRecord::isDrawingToLayer() const { |
215 #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE | 217 #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE |
216 return fMCMgr.isDrawingToLayer(); | 218 return fMCMgr.isDrawingToLayer(); |
217 #else | 219 #else |
218 return fFirstSavedLayerIndex != kNoSavedLayerIndex; | 220 return fFirstSavedLayerIndex != kNoSavedLayerIndex; |
219 #endif | 221 #endif |
220 } | 222 } |
221 | 223 |
222 /* | 224 /* |
| 225 * Read the op code from 'offset' in 'writer'. |
| 226 */ |
| 227 #ifdef SK_DEBUG |
| 228 static DrawType peek_op(SkWriter32* writer, int32_t offset) { |
| 229 return (DrawType)(writer->readTAt<uint32_t>(offset) >> 24); |
| 230 } |
| 231 #endif |
| 232 |
| 233 /* |
223 * Read the op code from 'offset' in 'writer' and extract the size too. | 234 * Read the op code from 'offset' in 'writer' and extract the size too. |
224 */ | 235 */ |
225 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { | 236 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { |
226 uint32_t peek = writer->readTAt<uint32_t>(offset); | 237 uint32_t peek = writer->readTAt<uint32_t>(offset); |
227 | 238 |
228 uint32_t op; | 239 uint32_t op; |
229 UNPACK_8_24(peek, op, *size); | 240 UNPACK_8_24(peek, op, *size); |
230 if (MASK_24 == *size) { | 241 if (MASK_24 == *size) { |
231 // size required its own slot right after the op code | 242 // size required its own slot right after the op code |
232 *size = writer->readTAt<uint32_t>(offset + kUInt32Size); | 243 *size = writer->readTAt<uint32_t>(offset + kUInt32Size); |
(...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 this->validate(initialOffset, size); | 1552 this->validate(initialOffset, size); |
1542 } | 1553 } |
1543 | 1554 |
1544 void SkPictureRecord::endCommentGroup() { | 1555 void SkPictureRecord::endCommentGroup() { |
1545 // op/size | 1556 // op/size |
1546 uint32_t size = 1 * kUInt32Size; | 1557 uint32_t size = 1 * kUInt32Size; |
1547 size_t initialOffset = this->addDraw(END_COMMENT_GROUP, &size); | 1558 size_t initialOffset = this->addDraw(END_COMMENT_GROUP, &size); |
1548 this->validate(initialOffset, size); | 1559 this->validate(initialOffset, size); |
1549 } | 1560 } |
1550 | 1561 |
| 1562 // [op/size] [rect] [skip offset] |
| 1563 static const uint32_t kPushCullOpSize = 2 * kUInt32Size + sizeof(SkRect); |
| 1564 void SkPictureRecord::onPushCull(const SkRect& cullRect) { |
| 1565 // Skip identical cull rects. |
| 1566 if (!fCullOffsetStack.isEmpty()) { |
| 1567 const SkRect& prevCull = fWriter.readTAt<SkRect>(fCullOffsetStack.top()
- sizeof(SkRect)); |
| 1568 if (prevCull == cullRect) { |
| 1569 // Skipped culls are tracked on the stack, but they point to the pre
vious offset. |
| 1570 fCullOffsetStack.push(fCullOffsetStack.top()); |
| 1571 return; |
| 1572 } |
| 1573 |
| 1574 SkASSERT(prevCull.contains(cullRect)); |
| 1575 } |
| 1576 |
| 1577 uint32_t size = kPushCullOpSize; |
| 1578 size_t initialOffset = this->addDraw(PUSH_CULL, &size); |
| 1579 // PUSH_CULL's size should stay constant (used to rewind). |
| 1580 SkASSERT(size == kPushCullOpSize); |
| 1581 |
| 1582 this->addRect(cullRect); |
| 1583 fCullOffsetStack.push(fWriter.bytesWritten()); |
| 1584 this->addInt(0); |
| 1585 this->validate(initialOffset, size); |
| 1586 } |
| 1587 |
| 1588 void SkPictureRecord::onPopCull() { |
| 1589 SkASSERT(!fCullOffsetStack.isEmpty()); |
| 1590 |
| 1591 uint32_t cullSkipOffset = fCullOffsetStack.top(); |
| 1592 fCullOffsetStack.pop(); |
| 1593 |
| 1594 // Skipped push, do the same for pop. |
| 1595 if (!fCullOffsetStack.isEmpty() && cullSkipOffset == fCullOffsetStack.top())
{ |
| 1596 return; |
| 1597 } |
| 1598 |
| 1599 // Collapse empty push/pop pairs. |
| 1600 if ((size_t)(cullSkipOffset + kUInt32Size) == fWriter.bytesWritten()) { |
| 1601 SkASSERT(fWriter.bytesWritten() >= kPushCullOpSize); |
| 1602 SkASSERT(PUSH_CULL == peek_op(&fWriter, fWriter.bytesWritten() - kPushCu
llOpSize)); |
| 1603 fWriter.rewindToOffset(fWriter.bytesWritten() - kPushCullOpSize); |
| 1604 return; |
| 1605 } |
| 1606 |
| 1607 // op only |
| 1608 uint32_t size = kUInt32Size; |
| 1609 size_t initialOffset = this->addDraw(POP_CULL, &size); |
| 1610 |
| 1611 // update the cull skip offset to point past this op. |
| 1612 fWriter.overwriteTAt<uint32_t>(cullSkipOffset, fWriter.bytesWritten()); |
| 1613 |
| 1614 this->validate(initialOffset, size); |
| 1615 } |
| 1616 |
1551 /////////////////////////////////////////////////////////////////////////////// | 1617 /////////////////////////////////////////////////////////////////////////////// |
1552 | 1618 |
1553 SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info) { | 1619 SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info) { |
1554 return SkSurface::NewPicture(info.fWidth, info.fHeight); | 1620 return SkSurface::NewPicture(info.fWidth, info.fHeight); |
1555 } | 1621 } |
1556 | 1622 |
1557 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { | 1623 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { |
1558 const int index = fBitmapHeap->insert(bitmap); | 1624 const int index = fBitmapHeap->insert(bitmap); |
1559 // In debug builds, a bad return value from insert() will crash, allowing fo
r debugging. In | 1625 // In debug builds, a bad return value from insert() will crash, allowing fo
r debugging. In |
1560 // release builds, the invalid value will be recorded so that the reader wil
l know that there | 1626 // release builds, the invalid value will be recorded so that the reader wil
l know that there |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1796 void SkPictureRecord::validateRegions() const { | 1862 void SkPictureRecord::validateRegions() const { |
1797 int count = fRegions.count(); | 1863 int count = fRegions.count(); |
1798 SkASSERT((unsigned) count < 0x1000); | 1864 SkASSERT((unsigned) count < 0x1000); |
1799 for (int index = 0; index < count; index++) { | 1865 for (int index = 0; index < count; index++) { |
1800 const SkFlatData* region = fRegions[index]; | 1866 const SkFlatData* region = fRegions[index]; |
1801 SkASSERT(region); | 1867 SkASSERT(region); |
1802 // region->validate(); | 1868 // region->validate(); |
1803 } | 1869 } |
1804 } | 1870 } |
1805 #endif | 1871 #endif |
OLD | NEW |