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

Side by Side Diff: src/core/SkPicturePlayback.cpp

Issue 378343002: Refactor SkPicturePlayback for SkPictureReplacementPlayback (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Cleaned up Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | src/core/SkPictureStateTree.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 void get_text(SkReader32* reader, TextContainer* text) { 99 void get_text(SkReader32* reader, TextContainer* text) {
100 size_t length = text->fByteLength = reader->readInt(); 100 size_t length = text->fByteLength = reader->readInt();
101 text->fText = (const char*)reader->skip(length); 101 text->fText = (const char*)reader->skip(length);
102 } 102 }
103 103
104 // 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.
105 static SkBitmap shallow_copy(const SkBitmap& bitmap) { 105 static SkBitmap shallow_copy(const SkBitmap& bitmap) {
106 return bitmap; 106 return bitmap;
107 } 107 }
108 108
109 void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) { 109 const SkPicture::OperationList* SkPicturePlayback::getActiveOps(const SkCanvas* canvas) {
110 AutoResetOpID aroi(this);
111 SkASSERT(0 == fCurOffset);
112
113 // kDrawComplete will be the signal that we have reached the end of
114 // the command stream
115 static const uint32_t kDrawComplete = SK_MaxU32;
116
117 SkReader32 reader(fPictureData->fOpData->bytes(), fPictureData->fOpData->siz e());
118 SkAutoTDelete<const SkPicture::OperationList> activeOpsList;
119 const SkTDArray<void*>* activeOps = NULL;
120 110
121 if (fUseBBH && NULL != fPictureData->fStateTree && NULL != fPictureData->fBo undingHierarchy) { 111 if (fUseBBH && NULL != fPictureData->fStateTree && NULL != fPictureData->fBo undingHierarchy) {
122 SkRect clipBounds; 112 SkRect clipBounds;
123 if (canvas->getClipBounds(&clipBounds)) { 113 if (canvas->getClipBounds(&clipBounds)) {
124 SkIRect query; 114 SkIRect query;
125 clipBounds.roundOut(&query); 115 clipBounds.roundOut(&query);
126 116
127 activeOpsList.reset(fPictureData->getActiveOps(query)); 117 return fPictureData->getActiveOps(query);
128 if (NULL != activeOpsList.get()) { 118 }
129 if (0 == activeOpsList->numOps()) { 119 }
130 return; // nothing to draw 120
121 return NULL;
122 }
123
124 // Initialize the state tree iterator. Return false if there is nothing left to draw.
125 bool SkPicturePlayback::initIterator(SkPictureStateTree::Iterator* iter,
126 SkCanvas* canvas,
127 const SkPicture::OperationList *activeOpsLi st) {
128
129 if (NULL != activeOpsList) {
130 if (0 == activeOpsList->numOps()) {
131 return false; // nothing to draw
132 }
133
134 fPictureData->fStateTree->initIterator(iter, activeOpsList->fOps, canvas );
135 }
136
137 return true;
138 }
139
140 // If 'iter' is valid use it to skip forward through the picture.
141 void SkPicturePlayback::StepIterator(SkPictureStateTree::Iterator* iter, SkReade r32* reader) {
142 if (iter->isValid()) {
143 uint32_t skipTo = iter->nextDraw();
144 if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
145 reader->setOffset(reader->size()); // skip to end
146 } else {
147 reader->setOffset(skipTo);
148 }
149 }
150 }
151
152 bool SkPicturePlayback::replaceOps(SkPictureStateTree::Iterator* iter,
153 SkReader32* reader,
154 SkCanvas* canvas,
155 const SkMatrix& initialMatrix) {
156 if (NULL != fReplacements) {
157 // Potentially replace a block of operations with a single drawBitmap ca ll
158 SkPicturePlayback::PlaybackReplacements::ReplacementInfo* temp =
159 fReplacements->lookupByStart(reader- >offset());
160 if (NULL != temp) {
161 SkASSERT(NULL != temp->fBM);
162 SkASSERT(NULL != temp->fPaint);
163 canvas->save();
164 canvas->setMatrix(initialMatrix);
165 SkRect src = SkRect::Make(temp->fSrcRect);
166 SkRect dst = SkRect::MakeXYWH(temp->fPos.fX, temp->fPos.fY,
167 temp->fSrcRect.width(),
168 temp->fSrcRect.height());
169 canvas->drawBitmapRectToRect(*temp->fBM, &src, dst, temp->fPaint);
170 canvas->restore();
171
172 if (iter->isValid()) {
173 // This save is needed since the BBH will automatically issue
174 // a restore to balanced the saveLayer we're skipping
175 canvas->save();
176
177 // At this point we know that the PictureStateTree was aiming
178 // for some draw op within temp's saveLayer (although potentiall y
179 // in a separate saveLayer nested inside it).
180 // We need to skip all the operations inside temp's range
181 // along with all the associated state changes but update
182 // the state tree to the first operation outside temp's range.
183
184 uint32_t skipTo;
185 do {
186 skipTo = iter->nextDraw();
187 if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
188 break;
189 }
190
191 if (skipTo <= temp->fStop) {
192 reader->setOffset(skipTo);
193 uint32_t size;
194 DrawType op = ReadOpAndSize(reader, &size);
195 // Since we are relying on the normal SkPictureStateTree
196 // playback we need to convert any nested saveLayer call s
197 // it may issue into saves (so that all its internal
198 // restores will be balanced).
199 if (SAVE_LAYER == op) {
200 canvas->save();
201 }
202 }
203 } while (skipTo <= temp->fStop);
204
205 if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
206 reader->setOffset(reader->size()); // skip to end
207 return true;
131 } 208 }
132 209
133 activeOps = &(activeOpsList.get()->fOps); 210 reader->setOffset(skipTo);
211 } else {
212 reader->setOffset(temp->fStop);
213 uint32_t size;
214 SkDEBUGCODE(DrawType op = ) ReadOpAndSize(reader, &size);
215 SkASSERT(RESTORE == op);
134 } 216 }
217
218 return true;
135 } 219 }
136 } 220 }
137 221
138 SkPictureStateTree::Iterator it = (NULL == activeOps) ? 222 return false;
139 SkPictureStateTree::Iterator() : 223 }
140 fPictureData->fStateTree->getIterator(*activeOps, canvas);
141 224
142 if (it.isValid()) { 225 // Update the iterator and state tree to catch up with the skipped ops.
143 uint32_t skipTo = it.nextDraw(); 226 void SkPicturePlayback::SkipIterTo(SkPictureStateTree::Iterator* iter,
144 if (kDrawComplete == skipTo) { 227 SkReader32* reader,
145 return; 228 uint32_t skipTo) {
146 } 229 if (iter->isValid()) {
147 reader.setOffset(skipTo); 230 // If using a bounding box hierarchy, advance the state tree
231 // iterator until at or after skipTo
232 uint32_t adjustedSkipTo;
233 do {
234 adjustedSkipTo = iter->nextDraw();
235 } while (adjustedSkipTo < skipTo);
236 skipTo = adjustedSkipTo;
148 } 237 }
238 if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
mtklein 2014/07/09 17:55:01 Is there any chance we could have passed this whil
robertphillips 2014/07/09 18:12:39 skipTo will never be kDrawComplete on entry (I'll
239 reader->setOffset(reader->size()); // skip to end
240 } else {
241 reader->setOffset(skipTo);
242 }
243 }
244
245 void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) {
246 AutoResetOpID aroi(this);
247 SkASSERT(0 == fCurOffset);
248
249 SkAutoTDelete<const SkPicture::OperationList> activeOpsList(this->getActiveO ps(canvas));
250 SkPictureStateTree::Iterator it;
251
252 if (!this->initIterator(&it, canvas, activeOpsList.get())) {
253 return; // nothing to draw
254 }
255
256 SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->s ize());
257
258 StepIterator(&it, &reader);
149 259
150 // Record this, so we can concat w/ it if we encounter a setMatrix() 260 // Record this, so we can concat w/ it if we encounter a setMatrix()
151 SkMatrix initialMatrix = canvas->getTotalMatrix(); 261 SkMatrix initialMatrix = canvas->getTotalMatrix();
152 262
153 SkAutoCanvasRestore acr(canvas, false); 263 SkAutoCanvasRestore acr(canvas, false);
154 264
155 while (!reader.eof()) { 265 while (!reader.eof()) {
156 if (callback && callback->abortDrawing()) { 266 if (NULL != callback && callback->abortDrawing()) {
157 return; 267 return;
158 } 268 }
159 269
160 if (NULL != fReplacements) { 270 if (this->replaceOps(&it, &reader, canvas, initialMatrix)) {
161 // Potentially replace a block of operations with a single drawBitma p call 271 continue;
162 SkPicturePlayback::PlaybackReplacements::ReplacementInfo* temp =
163 fReplacements->lookupByStart(reader.offset());
164 if (NULL != temp) {
165 SkASSERT(NULL != temp->fBM);
166 SkASSERT(NULL != temp->fPaint);
167 canvas->save();
168 canvas->setMatrix(initialMatrix);
169 SkRect src = SkRect::Make(temp->fSrcRect);
170 SkRect dst = SkRect::MakeXYWH(temp->fPos.fX, temp->fPos.fY,
171 temp->fSrcRect.width(),
172 temp->fSrcRect.height());
173 canvas->drawBitmapRectToRect(*temp->fBM, &src, dst, temp->fPaint );
174 canvas->restore();
175
176 if (it.isValid()) {
177 // This save is needed since the BBH will automatically issu e
178 // a restore to balanced the saveLayer we're skipping
179 canvas->save();
180
181 // At this point we know that the PictureStateTree was aimin g
182 // for some draw op within temp's saveLayer (although potent ially
183 // in a separate saveLayer nested inside it).
184 // We need to skip all the operations inside temp's range
185 // along with all the associated state changes but update
186 // the state tree to the first operation outside temp's rang e.
187
188 uint32_t skipTo;
189 do {
190 skipTo = it.nextDraw();
191 if (kDrawComplete == skipTo) {
192 break;
193 }
194
195 if (skipTo <= temp->fStop) {
196 reader.setOffset(skipTo);
197 uint32_t size;
198 DrawType op = ReadOpAndSize(&reader, &size);
199 // Since we are relying on the normal SkPictureState Tree
200 // playback we need to convert any nested saveLayer calls
201 // it may issue into saves (so that all its internal
202 // restores will be balanced).
203 if (SAVE_LAYER == op) {
204 canvas->save();
205 }
206 }
207 } while (skipTo <= temp->fStop);
208
209 if (kDrawComplete == skipTo) {
210 break;
211 }
212
213 reader.setOffset(skipTo);
214 } else {
215 reader.setOffset(temp->fStop);
216 uint32_t size;
217 SkDEBUGCODE(DrawType op = ) ReadOpAndSize(&reader, &size);
218 SkASSERT(RESTORE == op);
219 }
220 continue;
221 }
222 } 272 }
223 273
224 fCurOffset = reader.offset(); 274 fCurOffset = reader.offset();
225 uint32_t size; 275 uint32_t size;
226 DrawType op = ReadOpAndSize(&reader, &size); 276 DrawType op = ReadOpAndSize(&reader, &size);
227 size_t skipTo = 0;
228 if (NOOP == op) { 277 if (NOOP == op) {
229 // NOOPs are to be ignored - do not propagate them any further 278 // NOOPs are to be ignored - do not propagate them any further
230 skipTo = fCurOffset + size; 279 SkipIterTo(&it, &reader, fCurOffset + size);
231 }
232
233 if (0 != skipTo) {
234 if (it.isValid()) {
235 // If using a bounding box hierarchy, advance the state tree
236 // iterator until at or after skipTo
237 uint32_t adjustedSkipTo;
238 do {
239 adjustedSkipTo = it.nextDraw();
240 } while (adjustedSkipTo < skipTo);
241 skipTo = adjustedSkipTo;
242 }
243 if (kDrawComplete == skipTo) {
244 break;
245 }
246 reader.setOffset(skipTo);
247 continue; 280 continue;
248 } 281 }
249 282
250 this->handleOp(&reader, op, size, canvas, initialMatrix); 283 this->handleOp(&reader, op, size, canvas, initialMatrix);
251 284
252 if (it.isValid()) { 285 StepIterator(&it, &reader);
253 uint32_t skipTo = it.nextDraw();
254 if (kDrawComplete == skipTo) {
255 break;
256 }
257 reader.setOffset(skipTo);
258 }
259 } 286 }
260 } 287 }
261 288
262 void SkPicturePlayback::handleOp(SkReader32* reader, 289 void SkPicturePlayback::handleOp(SkReader32* reader,
263 DrawType op, 290 DrawType op,
264 uint32_t size, 291 uint32_t size,
265 SkCanvas* canvas, 292 SkCanvas* canvas,
266 const SkMatrix& initialMatrix) { 293 const SkMatrix& initialMatrix) {
267 switch (op) { 294 switch (op) {
268 case CLIP_PATH: { 295 case CLIP_PATH: {
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 case TRANSLATE: { 593 case TRANSLATE: {
567 SkScalar dx = reader->readScalar(); 594 SkScalar dx = reader->readScalar();
568 SkScalar dy = reader->readScalar(); 595 SkScalar dy = reader->readScalar();
569 canvas->translate(dx, dy); 596 canvas->translate(dx, dy);
570 } break; 597 } break;
571 default: 598 default:
572 SkASSERT(0); 599 SkASSERT(0);
573 } 600 }
574 } 601 }
575 602
OLDNEW
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | src/core/SkPictureStateTree.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698