OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 #include "SkPictureData.h" | 9 #include "SkPictureData.h" |
10 #include "SkPicturePlayback.h" | 10 #include "SkPicturePlayback.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 if (start == fReplacements[i].fStart) { | 49 if (start == fReplacements[i].fStart) { |
50 return &fReplacements[i]; | 50 return &fReplacements[i]; |
51 } else if (start < fReplacements[i].fStart) { | 51 } else if (start < fReplacements[i].fStart) { |
52 return NULL; // the ranges are monotonically increasing and non-ove
rlapping | 52 return NULL; // the ranges are monotonically increasing and non-ove
rlapping |
53 } | 53 } |
54 } | 54 } |
55 | 55 |
56 return NULL; | 56 return NULL; |
57 } | 57 } |
58 | 58 |
59 | |
60 class SkAutoResetOpID { | |
61 public: | |
62 SkAutoResetOpID(SkPicturePlayback* playback) : fPlayback(playback) { } | |
63 ~SkAutoResetOpID() { | |
64 if (NULL != fPlayback) { | |
65 fPlayback->resetOpID(); | |
66 } | |
67 } | |
68 | |
69 private: | |
70 SkPicturePlayback* fPlayback; | |
71 }; | |
72 | |
73 /* | 59 /* |
74 * Read the next op code and chunk size from 'reader'. The returned size | 60 * Read the next op code and chunk size from 'reader'. The returned size |
75 * is the entire size of the chunk (including the opcode). Thus, the | 61 * is the entire size of the chunk (including the opcode). Thus, the |
76 * offset just prior to calling read_op_and_size + 'size' is the offset | 62 * offset just prior to calling ReadOpAndSize + 'size' is the offset |
77 * to the next chunk's op code. This also means that the size of a chunk | 63 * to the next chunk's op code. This also means that the size of a chunk |
78 * with no arguments (just an opcode) will be 4. | 64 * with no arguments (just an opcode) will be 4. |
79 */ | 65 */ |
80 static DrawType read_op_and_size(SkReader32* reader, uint32_t* size) { | 66 DrawType SkPicturePlayback::ReadOpAndSize(SkReader32* reader, uint32_t* size) { |
81 uint32_t temp = reader->readInt(); | 67 uint32_t temp = reader->readInt(); |
82 uint32_t op; | 68 uint32_t op; |
83 if (((uint8_t)temp) == temp) { | 69 if (((uint8_t)temp) == temp) { |
84 // old skp file - no size information | 70 // old skp file - no size information |
85 op = temp; | 71 op = temp; |
86 *size = 0; | 72 *size = 0; |
87 } else { | 73 } else { |
88 UNPACK_8_24(temp, op, *size); | 74 UNPACK_8_24(temp, op, *size); |
89 if (MASK_24 == *size) { | 75 if (MASK_24 == *size) { |
90 *size = reader->readInt(); | 76 *size = reader->readInt(); |
(...skipping 23 matching lines...) Expand all Loading... |
114 size_t length = text->fByteLength = reader->readInt(); | 100 size_t length = text->fByteLength = reader->readInt(); |
115 text->fText = (const char*)reader->skip(length); | 101 text->fText = (const char*)reader->skip(length); |
116 } | 102 } |
117 | 103 |
118 // FIXME: SkBitmaps are stateful, so we need to copy them to play back in multip
le threads. | 104 // FIXME: SkBitmaps are stateful, so we need to copy them to play back in multip
le threads. |
119 static SkBitmap shallow_copy(const SkBitmap& bitmap) { | 105 static SkBitmap shallow_copy(const SkBitmap& bitmap) { |
120 return bitmap; | 106 return bitmap; |
121 } | 107 } |
122 | 108 |
123 void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback)
{ | 109 void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback)
{ |
124 SkAutoResetOpID aroi(this); | 110 AutoResetOpID aroi(this); |
125 SkASSERT(0 == fCurOffset); | 111 SkASSERT(0 == fCurOffset); |
126 | 112 |
127 // kDrawComplete will be the signal that we have reached the end of | 113 // kDrawComplete will be the signal that we have reached the end of |
128 // the command stream | 114 // the command stream |
129 static const uint32_t kDrawComplete = SK_MaxU32; | 115 static const uint32_t kDrawComplete = SK_MaxU32; |
130 | 116 |
131 SkReader32 reader(fPictureData->fOpData->bytes(), fPictureData->fOpData->siz
e()); | 117 SkReader32 reader(fPictureData->fOpData->bytes(), fPictureData->fOpData->siz
e()); |
132 SkAutoTDelete<const SkPicture::OperationList> activeOpsList; | 118 SkAutoTDelete<const SkPicture::OperationList> activeOpsList; |
133 const SkTDArray<void*>* activeOps = NULL; | 119 const SkTDArray<void*>* activeOps = NULL; |
134 | 120 |
135 // When draw limits are enabled (i.e., 0 != fStart || 0 != fStop) the state | 121 if (fUseBBH && NULL != fPictureData->fStateTree && NULL != fPictureData->fBo
undingHierarchy) { |
136 // tree isn't used to pick and choose the draw operations | 122 SkRect clipBounds; |
137 if (0 == fStart && 0 == fStop) { | 123 if (canvas->getClipBounds(&clipBounds)) { |
138 if (fUseBBH && NULL != fPictureData->fStateTree && NULL != fPictureData-
>fBoundingHierarchy) { | 124 SkIRect query; |
139 SkRect clipBounds; | 125 clipBounds.roundOut(&query); |
140 if (canvas->getClipBounds(&clipBounds)) { | |
141 SkIRect query; | |
142 clipBounds.roundOut(&query); | |
143 | 126 |
144 activeOpsList.reset(fPictureData->getActiveOps(query)); | 127 activeOpsList.reset(fPictureData->getActiveOps(query)); |
145 if (NULL != activeOpsList.get()) { | 128 if (NULL != activeOpsList.get()) { |
146 if (0 == activeOpsList->numOps()) { | 129 if (0 == activeOpsList->numOps()) { |
147 return; // nothing to draw | 130 return; // nothing to draw |
148 } | 131 } |
149 | 132 |
150 // Since the opList is valid we know it is our derived class | 133 activeOps = &(activeOpsList.get()->fOps); |
151 activeOps = &(activeOpsList.get()->fOps); | |
152 } | |
153 } | 134 } |
154 } | 135 } |
155 } | 136 } |
156 | 137 |
157 SkPictureStateTree::Iterator it = (NULL == activeOps) ? | 138 SkPictureStateTree::Iterator it = (NULL == activeOps) ? |
158 SkPictureStateTree::Iterator() : | 139 SkPictureStateTree::Iterator() : |
159 fPictureData->fStateTree->getIterator(*activeOps, canvas); | 140 fPictureData->fStateTree->getIterator(*activeOps, canvas); |
160 | 141 |
161 if (0 != fStart || 0 != fStop) { | |
162 reader.setOffset(fStart); | |
163 uint32_t size; | |
164 SkDEBUGCODE(DrawType op = ) read_op_and_size(&reader, &size); | |
165 SkASSERT(SAVE_LAYER == op); | |
166 reader.setOffset(fStart + size); | |
167 } | |
168 | |
169 if (it.isValid()) { | 142 if (it.isValid()) { |
170 uint32_t skipTo = it.nextDraw(); | 143 uint32_t skipTo = it.nextDraw(); |
171 if (kDrawComplete == skipTo) { | 144 if (kDrawComplete == skipTo) { |
172 return; | 145 return; |
173 } | 146 } |
174 reader.setOffset(skipTo); | 147 reader.setOffset(skipTo); |
175 } | 148 } |
176 | 149 |
177 // Record this, so we can concat w/ it if we encounter a setMatrix() | 150 // Record this, so we can concat w/ it if we encounter a setMatrix() |
178 SkMatrix initialMatrix = canvas->getTotalMatrix(); | 151 SkMatrix initialMatrix = canvas->getTotalMatrix(); |
179 | 152 |
180 SkAutoCanvasRestore acr(canvas, false); | 153 SkAutoCanvasRestore acr(canvas, false); |
181 | 154 |
182 #ifdef SK_DEVELOPER | 155 #ifdef SK_DEVELOPER |
183 int opIndex = -1; | 156 int opIndex = -1; |
184 #endif | 157 #endif |
185 | 158 |
186 while (!reader.eof()) { | 159 while (!reader.eof()) { |
187 if (callback && callback->abortDrawing()) { | 160 if (callback && callback->abortDrawing()) { |
188 return; | 161 return; |
189 } | 162 } |
190 | 163 |
191 if (0 != fStart || 0 != fStop) { | |
192 size_t offset = reader.offset(); | |
193 if (offset >= fStop) { | |
194 uint32_t size; | |
195 SkDEBUGCODE(DrawType op = ) read_op_and_size(&reader, &size); | |
196 SkASSERT(RESTORE == op); | |
197 return; | |
198 } | |
199 } | |
200 | |
201 if (NULL != fReplacements) { | 164 if (NULL != fReplacements) { |
202 // Potentially replace a block of operations with a single drawBitma
p call | 165 // Potentially replace a block of operations with a single drawBitma
p call |
203 SkPicturePlayback::PlaybackReplacements::ReplacementInfo* temp = | 166 SkPicturePlayback::PlaybackReplacements::ReplacementInfo* temp = |
204 fReplacements->lookupByStart(reader.offset()); | 167 fReplacements->lookupByStart(reader.offset()); |
205 if (NULL != temp) { | 168 if (NULL != temp) { |
206 SkASSERT(NULL != temp->fBM); | 169 SkASSERT(NULL != temp->fBM); |
207 SkASSERT(NULL != temp->fPaint); | 170 SkASSERT(NULL != temp->fPaint); |
208 canvas->save(); | 171 canvas->save(); |
209 canvas->setMatrix(initialMatrix); | 172 canvas->setMatrix(initialMatrix); |
210 SkRect src = SkRect::Make(temp->fSrcRect); | 173 SkRect src = SkRect::Make(temp->fSrcRect); |
(...skipping 18 matching lines...) Expand all Loading... |
229 uint32_t skipTo; | 192 uint32_t skipTo; |
230 do { | 193 do { |
231 skipTo = it.nextDraw(); | 194 skipTo = it.nextDraw(); |
232 if (kDrawComplete == skipTo) { | 195 if (kDrawComplete == skipTo) { |
233 break; | 196 break; |
234 } | 197 } |
235 | 198 |
236 if (skipTo <= temp->fStop) { | 199 if (skipTo <= temp->fStop) { |
237 reader.setOffset(skipTo); | 200 reader.setOffset(skipTo); |
238 uint32_t size; | 201 uint32_t size; |
239 DrawType op = read_op_and_size(&reader, &size); | 202 DrawType op = ReadOpAndSize(&reader, &size); |
240 // Since we are relying on the normal SkPictureState
Tree | 203 // Since we are relying on the normal SkPictureState
Tree |
241 // playback we need to convert any nested saveLayer
calls | 204 // playback we need to convert any nested saveLayer
calls |
242 // it may issue into saves (so that all its internal | 205 // it may issue into saves (so that all its internal |
243 // restores will be balanced). | 206 // restores will be balanced). |
244 if (SAVE_LAYER == op) { | 207 if (SAVE_LAYER == op) { |
245 canvas->save(); | 208 canvas->save(); |
246 } | 209 } |
247 } | 210 } |
248 } while (skipTo <= temp->fStop); | 211 } while (skipTo <= temp->fStop); |
249 | 212 |
250 if (kDrawComplete == skipTo) { | 213 if (kDrawComplete == skipTo) { |
251 break; | 214 break; |
252 } | 215 } |
253 | 216 |
254 reader.setOffset(skipTo); | 217 reader.setOffset(skipTo); |
255 } else { | 218 } else { |
256 reader.setOffset(temp->fStop); | 219 reader.setOffset(temp->fStop); |
257 uint32_t size; | 220 uint32_t size; |
258 SkDEBUGCODE(DrawType op = ) read_op_and_size(&reader, &size)
; | 221 SkDEBUGCODE(DrawType op = ) ReadOpAndSize(&reader, &size); |
259 SkASSERT(RESTORE == op); | 222 SkASSERT(RESTORE == op); |
260 } | 223 } |
261 continue; | 224 continue; |
262 } | 225 } |
263 } | 226 } |
264 | 227 |
265 fCurOffset = reader.offset(); | 228 fCurOffset = reader.offset(); |
266 uint32_t size; | 229 uint32_t size; |
267 DrawType op = read_op_and_size(&reader, &size); | 230 DrawType op = ReadOpAndSize(&reader, &size); |
268 size_t skipTo = 0; | 231 size_t skipTo = 0; |
269 if (NOOP == op) { | 232 if (NOOP == op) { |
270 // NOOPs are to be ignored - do not propagate them any further | 233 // NOOPs are to be ignored - do not propagate them any further |
271 skipTo = fCurOffset + size; | 234 skipTo = fCurOffset + size; |
272 #ifdef SK_DEVELOPER | 235 #ifdef SK_DEVELOPER |
273 } else { | 236 } else { |
274 opIndex++; | 237 opIndex++; |
275 if (this->preDraw(opIndex, op)) { | 238 if (this->preDraw(opIndex, op)) { |
276 skipTo = fCurOffset + size; | 239 skipTo = fCurOffset + size; |
277 } | 240 } |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 case TRANSLATE: { | 581 case TRANSLATE: { |
619 SkScalar dx = reader->readScalar(); | 582 SkScalar dx = reader->readScalar(); |
620 SkScalar dy = reader->readScalar(); | 583 SkScalar dy = reader->readScalar(); |
621 canvas->translate(dx, dy); | 584 canvas->translate(dx, dy); |
622 } break; | 585 } break; |
623 default: | 586 default: |
624 SkASSERT(0); | 587 SkASSERT(0); |
625 } | 588 } |
626 } | 589 } |
627 | 590 |
OLD | NEW |