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

Side by Side Diff: src/utils/SkDeferredCanvas.cpp

Issue 1269093002: remove SkDeferredCanvas (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 4 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/SkPictureRecord.cpp ('k') | tests/CanvasTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 /*
3 * Copyright 2013 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "SkDeferredCanvas.h"
10
11 #include "SkChunkAlloc.h"
12 #include "SkClipStack.h"
13 #include "SkColorFilter.h"
14 #include "SkDevice.h"
15 #include "SkDrawFilter.h"
16 #include "SkGPipe.h"
17 #include "SkImage_Base.h"
18 #include "SkPaint.h"
19 #include "SkPaintPriv.h"
20 #include "SkRRect.h"
21 #include "SkShader.h"
22 #include "SkSurface.h"
23
24 enum {
25 // Deferred canvas will auto-flush when recording reaches this limit
26 kDefaultMaxRecordingStorageBytes = 64*1024*1024,
27 kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature
28
29 kNoSaveLayerIndex = -1,
30 };
31
32 enum PlaybackMode {
33 kNormal_PlaybackMode,
34 kSilent_PlaybackMode,
35 };
36
37 static uint64_t image_area(const SkImage* image) {
38 return sk_64_mul(image->width(), image->height());
39 }
40
41 // HACK -- see crbug.com/485243
42 //
43 // Work around case where Blink gives us an image, but will "mutate" it (by chan ging its contents
44 // directly using webgl). Until that is fixed at the call-site, we treat gpu-bac ked-images as
45 // mutable for now (at least for the purposes of deferred canvas)
46 //
47 static bool should_draw_gpu_image_immediately(const SkImage* image) {
48 return as_IB(image)->getTexture() != NULL;
49 }
50
51 static bool should_draw_immediately(const SkBitmap* bitmap, const SkImage* image ,
52 const SkPaint* paint, size_t bitmapSizeThres hold) {
53 if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
54 (bitmap->getSize() > bitmapSizeThreshold))) {
55 return true;
56 }
57 if (image) {
58 if (should_draw_gpu_image_immediately(image) || image_area(image) > bitm apSizeThreshold) {
59 return true;
60 }
61 }
62 if (paint) {
63 SkShader* shader = paint->getShader();
64 // Here we detect the case where the shader is an SkBitmapProcShader
65 // with a gpu texture attached. Checking this without RTTI
66 // requires making the assumption that only gradient shaders
67 // and SkBitmapProcShader implement asABitmap(). The following
68 // code may need to be revised if that assumption is ever broken.
69 if (shader && !shader->asAGradient(NULL)) {
70 SkBitmap bm;
71 if (shader->asABitmap(&bm, NULL, NULL) &&
72 bm.getTexture()) {
73 return true;
74 }
75 }
76 }
77 return false;
78 }
79
80 //-----------------------------------------------------------------------------
81 // DeferredPipeController
82 //-----------------------------------------------------------------------------
83
84 class DeferredPipeController : public SkGPipeController {
85 public:
86 DeferredPipeController();
87 void setPlaybackCanvas(SkCanvas*);
88 virtual ~DeferredPipeController();
89 void* requestBlock(size_t minRequest, size_t* actual) override;
90 void notifyWritten(size_t bytes) override;
91 void playback(bool silent);
92 bool hasPendingCommands() const { return fAllocator.totalUsed() != 0; }
93 size_t storageAllocatedForRecording() const { return fAllocator.totalCapacit y(); }
94 private:
95 enum {
96 kMinBlockSize = 4096
97 };
98 struct PipeBlock {
99 PipeBlock(void* block, size_t size) { fBlock = block, fSize = size; }
100 void* fBlock;
101 size_t fSize;
102 };
103 void* fBlock;
104 size_t fBytesWritten;
105 SkChunkAlloc fAllocator;
106 SkTDArray<PipeBlock> fBlockList;
107 SkGPipeReader fReader;
108 };
109
110 DeferredPipeController::DeferredPipeController() :
111 fAllocator(kMinBlockSize) {
112 fBlock = NULL;
113 fBytesWritten = 0;
114 }
115
116 DeferredPipeController::~DeferredPipeController() {
117 fAllocator.reset();
118 }
119
120 void DeferredPipeController::setPlaybackCanvas(SkCanvas* canvas) {
121 fReader.setCanvas(canvas);
122 }
123
124 void* DeferredPipeController::requestBlock(size_t minRequest, size_t *actual) {
125 if (fBlock) {
126 // Save the previous block for later
127 PipeBlock previousBloc(fBlock, fBytesWritten);
128 fBlockList.push(previousBloc);
129 }
130 size_t blockSize = SkTMax<size_t>(minRequest, kMinBlockSize);
131 fBlock = fAllocator.allocThrow(blockSize);
132 fBytesWritten = 0;
133 *actual = blockSize;
134 return fBlock;
135 }
136
137 void DeferredPipeController::notifyWritten(size_t bytes) {
138 fBytesWritten += bytes;
139 }
140
141 void DeferredPipeController::playback(bool silent) {
142 uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0;
143 for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
144 fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBloc k].fSize,
145 flags);
146 }
147 fBlockList.reset();
148
149 if (fBlock) {
150 fReader.playback(fBlock, fBytesWritten, flags);
151 fBlock = NULL;
152 }
153
154 // Release all allocated blocks
155 fAllocator.reset();
156
157 this->purgeCaches();
158 }
159
160 //-----------------------------------------------------------------------------
161 // SkDeferredDevice
162 //-----------------------------------------------------------------------------
163 class SkDeferredDevice : public SkBaseDevice {
164 public:
165 explicit SkDeferredDevice(SkSurface* surface);
166 ~SkDeferredDevice();
167
168 void setNotificationClient(SkDeferredCanvas::NotificationClient* notificatio nClient);
169 SkCanvas* recordingCanvas();
170 SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
171 SkBaseDevice* immediateDevice() const {return fImmediateCanvas->getTopDevice ();}
172 SkImage* newImageSnapshot();
173 void setSurface(SkSurface* surface);
174 bool isFreshFrame();
175 bool hasPendingCommands();
176 size_t storageAllocatedForRecording() const;
177 size_t freeMemoryIfPossible(size_t bytesToFree);
178 void flushPendingCommands(PlaybackMode);
179 void skipPendingCommands();
180 void setMaxRecordingStorage(size_t);
181 void recordedDrawCommand();
182 void setIsDrawingToLayer(bool value) {fIsDrawingToLayer = value;}
183
184 SkImageInfo imageInfo() const override;
185
186 GrRenderTarget* accessRenderTarget() override;
187
188 SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
189
190 SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) override;
191
192 protected:
193 const SkBitmap& onAccessBitmap() override;
194 bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) override;
195 bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y) ov erride;
196
197 // None of the following drawing methods should ever get called on the
198 // deferred device
199 void drawPaint(const SkDraw&, const SkPaint& paint) override
200 {SkASSERT(0);}
201 void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
202 size_t count, const SkPoint[],
203 const SkPaint& paint) override
204 {SkASSERT(0);}
205 void drawRect(const SkDraw&, const SkRect& r,
206 const SkPaint& paint) override
207 {SkASSERT(0);}
208 void drawOval(const SkDraw&, const SkRect&, const SkPaint&) override
209 {SkASSERT(0);}
210 void drawRRect(const SkDraw&, const SkRRect& rr,
211 const SkPaint& paint) override
212 {SkASSERT(0);}
213 void drawPath(const SkDraw&, const SkPath& path,
214 const SkPaint& paint,
215 const SkMatrix* prePathMatrix = NULL,
216 bool pathIsMutable = false) override
217 {SkASSERT(0);}
218 void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
219 const SkMatrix& matrix, const SkPaint& paint) override
220 {SkASSERT(0);}
221 void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*,
222 const SkRect&, const SkPaint&, SkCanvas::SrcRectConstrai nt) override
223 {SkASSERT(0);}
224 void drawSprite(const SkDraw&, const SkBitmap& bitmap,
225 int x, int y, const SkPaint& paint) override
226 {SkASSERT(0);}
227 void drawImage(const SkDraw&, const SkImage*, SkScalar, SkScalar, const SkPa int&) override
228 {SkASSERT(0);}
229 void drawImageRect(const SkDraw&, const SkImage*, const SkRect*, const SkRec t&,
230 const SkPaint&, SkCanvas::SrcRectConstraint) override
231 {SkASSERT(0);}
232 void drawImageNine(const SkDraw&, const SkImage*, const SkIRect&, const SkRe ct&,
233 const SkPaint&) override
234 {SkASSERT(0);}
235 void drawText(const SkDraw&, const void* text, size_t len,
236 SkScalar x, SkScalar y, const SkPaint& paint) override
237 {SkASSERT(0);}
238 void drawPosText(const SkDraw&, const void* text, size_t len,
239 const SkScalar pos[], int scalarsPerPos,
240 const SkPoint& offset, const SkPaint& paint) override
241 {SkASSERT(0);}
242 void drawTextOnPath(const SkDraw&, const void* text,
243 size_t len, const SkPath& path,
244 const SkMatrix* matrix,
245 const SkPaint& paint) override
246 {SkASSERT(0);}
247 void drawVertices(const SkDraw&, SkCanvas::VertexMode,
248 int vertexCount, const SkPoint verts[],
249 const SkPoint texs[], const SkColor colors[],
250 SkXfermode* xmode, const uint16_t indices[],
251 int indexCount, const SkPaint& paint) override
252 {SkASSERT(0);}
253 void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors [4],
254 const SkPoint texCoords[4], SkXfermode* xmode,
255 const SkPaint& paint) override
256 {SkASSERT(0);}
257 void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
258 const SkColor[], int count, SkXfermode::Mode, const SkPaint&) override
259 {SkASSERT(0);}
260
261 void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
262 const SkPaint&) override
263 {SkASSERT(0);}
264
265 bool canHandleImageFilter(const SkImageFilter*) override {
266 return false;
267 }
268 bool filterImage(const SkImageFilter*, const SkBitmap&,
269 const SkImageFilter::Context&, SkBitmap*, SkIPoint*) overri de {
270 return false;
271 }
272
273 private:
274 void flush() override;
275 void replaceBitmapBackendForRasterSurface(const SkBitmap&) override {}
276
277 void beginRecording();
278 void init();
279 void aboutToDraw();
280 void prepareForImmediatePixelWrite();
281
282 DeferredPipeController fPipeController;
283 SkGPipeWriter fPipeWriter;
284 SkCanvas* fImmediateCanvas;
285 SkCanvas* fRecordingCanvas;
286 SkSurface* fSurface;
287 SkDeferredCanvas::NotificationClient* fNotificationClient;
288 bool fFreshFrame;
289 bool fCanDiscardCanvasContents;
290 bool fIsDrawingToLayer;
291 size_t fMaxRecordingStorageBytes;
292 size_t fPreviousStorageAllocated;
293
294 typedef SkBaseDevice INHERITED;
295 };
296
297 SkDeferredDevice::SkDeferredDevice(SkSurface* surface)
298 : INHERITED(surface->props()) {
299 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
300 fNotificationClient = NULL;
301 fImmediateCanvas = NULL;
302 fSurface = NULL;
303 this->setSurface(surface);
304 this->init();
305 }
306
307 void SkDeferredDevice::setSurface(SkSurface* surface) {
308 SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas());
309 SkRefCnt_SafeAssign(fSurface, surface);
310 fPipeController.setPlaybackCanvas(fImmediateCanvas);
311 }
312
313 void SkDeferredDevice::init() {
314 fRecordingCanvas = NULL;
315 fFreshFrame = true;
316 fIsDrawingToLayer = false;
317 fCanDiscardCanvasContents = false;
318 fPreviousStorageAllocated = 0;
319 fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
320 fNotificationClient = NULL;
321 this->beginRecording();
322 }
323
324 SkDeferredDevice::~SkDeferredDevice() {
325 this->flushPendingCommands(kSilent_PlaybackMode);
326 SkSafeUnref(fImmediateCanvas);
327 SkSafeUnref(fSurface);
328 }
329
330 void SkDeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
331 fMaxRecordingStorageBytes = maxStorage;
332 this->recordingCanvas(); // Accessing the recording canvas applies the new l imit.
333 }
334
335 void SkDeferredDevice::beginRecording() {
336 SkASSERT(NULL == fRecordingCanvas);
337 fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
338 immediateDevice()->width(), immediateDevice()->height());
339 }
340
341 void SkDeferredDevice::setNotificationClient(
342 SkDeferredCanvas::NotificationClient* notificationClient) {
343 fNotificationClient = notificationClient;
344 }
345
346 void SkDeferredDevice::skipPendingCommands() {
347 if (!fIsDrawingToLayer) {
348 fCanDiscardCanvasContents = true;
349 if (fPipeController.hasPendingCommands()) {
350 fFreshFrame = true;
351 flushPendingCommands(kSilent_PlaybackMode);
352 }
353 }
354 }
355
356 bool SkDeferredDevice::isFreshFrame() {
357 bool ret = fFreshFrame;
358 fFreshFrame = false;
359 return ret;
360 }
361
362 bool SkDeferredDevice::hasPendingCommands() {
363 return fPipeController.hasPendingCommands();
364 }
365
366 void SkDeferredDevice::aboutToDraw() {
367 if (fNotificationClient) {
368 fNotificationClient->prepareForDraw();
369 }
370 if (fCanDiscardCanvasContents) {
371 if (fSurface) {
372 fSurface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeM ode);
373 }
374 fCanDiscardCanvasContents = false;
375 }
376 }
377
378 void SkDeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
379 if (!fPipeController.hasPendingCommands()) {
380 return;
381 }
382 if (playbackMode == kNormal_PlaybackMode) {
383 aboutToDraw();
384 }
385 fPipeWriter.flushRecording(true);
386 fPipeController.playback(kSilent_PlaybackMode == playbackMode);
387 if (fNotificationClient) {
388 if (playbackMode == kSilent_PlaybackMode) {
389 fNotificationClient->skippedPendingDrawCommands();
390 } else {
391 fNotificationClient->flushedDrawCommands();
392 }
393 }
394
395 fPreviousStorageAllocated = storageAllocatedForRecording();
396 }
397
398 void SkDeferredDevice::flush() {
399 this->flushPendingCommands(kNormal_PlaybackMode);
400 fImmediateCanvas->flush();
401 }
402
403 size_t SkDeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
404 size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
405 fPreviousStorageAllocated = storageAllocatedForRecording();
406 return val;
407 }
408
409 size_t SkDeferredDevice::storageAllocatedForRecording() const {
410 return (fPipeController.storageAllocatedForRecording()
411 + fPipeWriter.storageAllocatedForRecording());
412 }
413
414 void SkDeferredDevice::recordedDrawCommand() {
415 size_t storageAllocated = this->storageAllocatedForRecording();
416
417 if (storageAllocated > fMaxRecordingStorageBytes) {
418 // First, attempt to reduce cache without flushing
419 size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
420 if (this->freeMemoryIfPossible(tryFree) < tryFree) {
421 // Flush is necessary to free more space.
422 this->flushPendingCommands(kNormal_PlaybackMode);
423 // Free as much as possible to avoid oscillating around fMaxRecordin gStorageBytes
424 // which could cause a high flushing frequency.
425 this->freeMemoryIfPossible(~0U);
426 }
427 storageAllocated = this->storageAllocatedForRecording();
428 }
429
430 if (fNotificationClient &&
431 storageAllocated != fPreviousStorageAllocated) {
432 fPreviousStorageAllocated = storageAllocated;
433 fNotificationClient->storageAllocatedForRecordingChanged(storageAllocate d);
434 }
435 }
436
437 SkCanvas* SkDeferredDevice::recordingCanvas() {
438 return fRecordingCanvas;
439 }
440
441 SkImage* SkDeferredDevice::newImageSnapshot() {
442 this->flush();
443 return fSurface ? fSurface->newImageSnapshot() : NULL;
444 }
445
446 SkImageInfo SkDeferredDevice::imageInfo() const {
447 return immediateDevice()->imageInfo();
448 }
449
450 GrRenderTarget* SkDeferredDevice::accessRenderTarget() {
451 this->flushPendingCommands(kNormal_PlaybackMode);
452 return immediateDevice()->accessRenderTarget();
453 }
454
455 void SkDeferredDevice::prepareForImmediatePixelWrite() {
456 // The purpose of the following code is to make sure commands are flushed, t hat
457 // aboutToDraw() is called and that notifyContentWillChange is called, witho ut
458 // calling anything redundantly.
459 if (fPipeController.hasPendingCommands()) {
460 this->flushPendingCommands(kNormal_PlaybackMode);
461 } else {
462 bool mustNotifyDirectly = !fCanDiscardCanvasContents;
463 this->aboutToDraw();
464 if (mustNotifyDirectly) {
465 fSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMo de);
466 }
467 }
468
469 fImmediateCanvas->flush();
470 }
471
472 bool SkDeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels , size_t rowBytes,
473 int x, int y) {
474 SkASSERT(x >= 0 && y >= 0);
475 SkASSERT(x + info.width() <= width());
476 SkASSERT(y + info.height() <= height());
477
478 const SkImageInfo deviceInfo = this->imageInfo();
479 if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height ()) {
480 this->skipPendingCommands();
481 } else {
482 this->flushPendingCommands(kNormal_PlaybackMode);
483 }
484
485 this->prepareForImmediatePixelWrite();
486 return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y);
487 }
488
489 const SkBitmap& SkDeferredDevice::onAccessBitmap() {
490 this->flushPendingCommands(kNormal_PlaybackMode);
491 return immediateDevice()->accessBitmap(false);
492 }
493
494 SkBaseDevice* SkDeferredDevice::onCreateDevice(const CreateInfo& cinfo, const Sk Paint* layerPaint) {
495 // Create a compatible non-deferred device.
496 // We do not create a deferred device because we know the new device
497 // will not be used with a deferred canvas (there is no API for that).
498 // And connecting a SkDeferredDevice to non-deferred canvas can result
499 // in unpredictable behavior.
500 return this->immediateDevice()->onCreateDevice(cinfo, layerPaint);
501 }
502
503 SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info, const SkSurface Props& props) {
504 return this->immediateDevice()->newSurface(info, props);
505 }
506
507 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_ t rowBytes,
508 int x, int y) {
509 this->flushPendingCommands(kNormal_PlaybackMode);
510 return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y);
511 }
512
513 class AutoImmediateDrawIfNeeded {
514 public:
515 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
516 const SkPaint* paint) {
517 this->init(canvas, bitmap, NULL, paint);
518 }
519 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkImage* image,
520 const SkPaint* paint) {
521 this->init(canvas, NULL, image, paint);
522 }
523
524 AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
525 this->init(canvas, NULL, NULL, paint);
526 }
527
528 ~AutoImmediateDrawIfNeeded() {
529 if (fCanvas) {
530 fCanvas->setDeferredDrawing(true);
531 }
532 }
533 private:
534 void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkImage* i mage,
535 const SkPaint* paint) {
536 if (canvas.isDeferredDrawing() &&
537 should_draw_immediately(bitmap, image, paint, canvas.getBitmapSizeTh reshold())) {
538 canvas.setDeferredDrawing(false);
539 fCanvas = &canvas;
540 } else {
541 fCanvas = NULL;
542 }
543 }
544
545 SkDeferredCanvas* fCanvas;
546 };
547
548 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) {
549 if (!surface) {
550 return NULL;
551 }
552
553 SkAutoTUnref<SkDeferredDevice> deferredDevice(SkNEW_ARGS(SkDeferredDevice, ( surface)));
554 return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
555 }
556
557 SkDeferredCanvas::SkDeferredCanvas(SkDeferredDevice* device) : SkCanvas (device) {
558 this->init();
559 }
560
561 void SkDeferredCanvas::init() {
562 fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
563 fDeferredDrawing = true; // On by default
564 fCachedCanvasSize.setEmpty();
565 fCachedCanvasSizeDirty = true;
566 fSaveLevel = 0;
567 fFirstSaveLayerIndex = kNoSaveLayerIndex;
568 }
569
570 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
571 this->validate();
572 this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
573 }
574
575 size_t SkDeferredCanvas::storageAllocatedForRecording() const {
576 return this->getDeferredDevice()->storageAllocatedForRecording();
577 }
578
579 size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
580 return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
581 }
582
583 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
584 fBitmapSizeThreshold = sizeThreshold;
585 }
586
587 void SkDeferredCanvas::recordedDrawCommand() {
588 if (fDeferredDrawing) {
589 this->getDeferredDevice()->recordedDrawCommand();
590 }
591 }
592
593 void SkDeferredCanvas::validate() const {
594 SkASSERT(this->getDevice());
595 }
596
597 SkCanvas* SkDeferredCanvas::drawingCanvas() const {
598 this->validate();
599 return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
600 this->getDeferredDevice()->immediateCanvas();
601 }
602
603 SkCanvas* SkDeferredCanvas::immediateCanvas() const {
604 this->validate();
605 return this->getDeferredDevice()->immediateCanvas();
606 }
607
608 SkDeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
609 return static_cast<SkDeferredDevice*>(this->getDevice());
610 }
611
612 void SkDeferredCanvas::setDeferredDrawing(bool val) {
613 this->validate(); // Must set device before calling this method
614 if (val != fDeferredDrawing) {
615 if (fDeferredDrawing) {
616 // Going live.
617 this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode );
618 }
619 fDeferredDrawing = val;
620 }
621 }
622
623 bool SkDeferredCanvas::isDeferredDrawing() const {
624 return fDeferredDrawing;
625 }
626
627 bool SkDeferredCanvas::isFreshFrame() const {
628 return this->getDeferredDevice()->isFreshFrame();
629 }
630
631 SkISize SkDeferredCanvas::getCanvasSize() const {
632 if (fCachedCanvasSizeDirty) {
633 fCachedCanvasSize = this->getBaseLayerSize();
634 fCachedCanvasSizeDirty = false;
635 }
636 return fCachedCanvasSize;
637 }
638
639 bool SkDeferredCanvas::hasPendingCommands() const {
640 return this->getDeferredDevice()->hasPendingCommands();
641 }
642
643 void SkDeferredCanvas::silentFlush() {
644 if (fDeferredDrawing) {
645 this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
646 }
647 }
648
649 SkDeferredCanvas::~SkDeferredCanvas() {
650 }
651
652 SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) {
653 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
654 SkASSERT(deferredDevice);
655 // By swapping the surface into the existing device, we preserve
656 // all pending commands, which can help to seamlessly recover from
657 // a lost accelerated graphics context.
658 deferredDevice->setSurface(surface);
659 fCachedCanvasSizeDirty = true;
660 return surface;
661 }
662
663 SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient(
664 NotificationClient* notificationClient) {
665
666 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
667 SkASSERT(deferredDevice);
668 if (deferredDevice) {
669 deferredDevice->setNotificationClient(notificationClient);
670 }
671 return notificationClient;
672 }
673
674 SkImage* SkDeferredCanvas::newImageSnapshot() {
675 SkDeferredDevice* deferredDevice = this->getDeferredDevice();
676 SkASSERT(deferredDevice);
677 return deferredDevice ? deferredDevice->newImageSnapshot() : NULL;
678 }
679
680 bool SkDeferredCanvas::isFullFrame(const SkRect* rect,
681 const SkPaint* paint) const {
682 SkCanvas* canvas = this->drawingCanvas();
683 SkISize canvasSize = this->getCanvasSize();
684 if (rect) {
685 if (!canvas->getTotalMatrix().rectStaysRect()) {
686 return false; // conservative
687 }
688
689 SkRect transformedRect;
690 canvas->getTotalMatrix().mapRect(&transformedRect, *rect);
691
692 if (paint) {
693 SkPaint::Style paintStyle = paint->getStyle();
694 if (!(paintStyle == SkPaint::kFill_Style ||
695 paintStyle == SkPaint::kStrokeAndFill_Style)) {
696 return false;
697 }
698 if (paint->getMaskFilter() || paint->getLooper()
699 || paint->getPathEffect() || paint->getImageFilter()) {
700 return false; // conservative
701 }
702 }
703
704 // The following test holds with AA enabled, and is conservative
705 // by a 0.5 pixel margin with AA disabled
706 if (transformedRect.fLeft > SkIntToScalar(0) ||
707 transformedRect.fTop > SkIntToScalar(0) ||
708 transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) ||
709 transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) {
710 return false;
711 }
712 }
713
714 return this->getClipStack()->quickContains(SkRect::MakeXYWH(0, 0,
715 SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight)));
716 }
717
718 void SkDeferredCanvas::willSave() {
719 fSaveLevel++;
720 this->drawingCanvas()->save();
721 this->recordedDrawCommand();
722 this->INHERITED::willSave();
723 }
724
725 SkCanvas::SaveLayerStrategy SkDeferredCanvas::willSaveLayer(const SkRect* bounds ,
726 const SkPaint* paint , SaveFlags flags) {
727 fSaveLevel++;
728 if (fFirstSaveLayerIndex == kNoSaveLayerIndex) {
729 fFirstSaveLayerIndex = fSaveLevel;
730 this->getDeferredDevice()->setIsDrawingToLayer(true);
731 }
732 this->drawingCanvas()->saveLayer(bounds, paint, flags);
733 this->recordedDrawCommand();
734 this->INHERITED::willSaveLayer(bounds, paint, flags);
735 // No need for a full layer.
736 return kNoLayer_SaveLayerStrategy;
737 }
738
739 void SkDeferredCanvas::willRestore() {
740 SkASSERT(fFirstSaveLayerIndex == kNoSaveLayerIndex || fFirstSaveLayerIndex < = fSaveLevel);
741 if (fFirstSaveLayerIndex == fSaveLevel) {
742 fFirstSaveLayerIndex = kNoSaveLayerIndex;
743 this->getDeferredDevice()->setIsDrawingToLayer(false);
744 }
745 fSaveLevel--;
746 this->drawingCanvas()->restore();
747 this->recordedDrawCommand();
748 this->INHERITED::willRestore();
749 }
750
751 void SkDeferredCanvas::didConcat(const SkMatrix& matrix) {
752 this->drawingCanvas()->concat(matrix);
753 this->recordedDrawCommand();
754 this->INHERITED::didConcat(matrix);
755 }
756
757 void SkDeferredCanvas::didSetMatrix(const SkMatrix& matrix) {
758 this->drawingCanvas()->setMatrix(matrix);
759 this->recordedDrawCommand();
760 this->INHERITED::didSetMatrix(matrix);
761 }
762
763 void SkDeferredCanvas::onClipRect(const SkRect& rect,
764 SkRegion::Op op,
765 ClipEdgeStyle edgeStyle) {
766 this->drawingCanvas()->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
767 this->INHERITED::onClipRect(rect, op, edgeStyle);
768 this->recordedDrawCommand();
769 }
770
771 void SkDeferredCanvas::onClipRRect(const SkRRect& rrect,
772 SkRegion::Op op,
773 ClipEdgeStyle edgeStyle) {
774 this->drawingCanvas()->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle );
775 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
776 this->recordedDrawCommand();
777 }
778
779 void SkDeferredCanvas::onClipPath(const SkPath& path,
780 SkRegion::Op op,
781 ClipEdgeStyle edgeStyle) {
782 this->drawingCanvas()->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle);
783 this->INHERITED::onClipPath(path, op, edgeStyle);
784 this->recordedDrawCommand();
785 }
786
787 void SkDeferredCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
788 this->drawingCanvas()->clipRegion(deviceRgn, op);
789 this->INHERITED::onClipRegion(deviceRgn, op);
790 this->recordedDrawCommand();
791 }
792
793 void SkDeferredCanvas::onDrawPaint(const SkPaint& paint) {
794 if (fDeferredDrawing && this->isFullFrame(NULL, &paint) && SkPaintPriv::Over writes(paint)) {
795 this->getDeferredDevice()->skipPendingCommands();
796 }
797 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
798 this->drawingCanvas()->drawPaint(paint);
799 this->recordedDrawCommand();
800 }
801
802 void SkDeferredCanvas::onDrawPoints(PointMode mode, size_t count,
803 const SkPoint pts[], const SkPaint& paint) {
804 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
805 this->drawingCanvas()->drawPoints(mode, count, pts, paint);
806 this->recordedDrawCommand();
807 }
808
809 void SkDeferredCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
810 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
811 this->drawingCanvas()->drawOval(rect, paint);
812 this->recordedDrawCommand();
813 }
814
815 void SkDeferredCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
816 if (fDeferredDrawing && this->isFullFrame(&rect, &paint) && SkPaintPriv::Ove rwrites(paint)) {
817 this->getDeferredDevice()->skipPendingCommands();
818 }
819
820 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
821 this->drawingCanvas()->drawRect(rect, paint);
822 this->recordedDrawCommand();
823 }
824
825 void SkDeferredCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
826 if (rrect.isRect()) {
827 this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
828 } else if (rrect.isOval()) {
829 this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
830 } else {
831 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
832 this->drawingCanvas()->drawRRect(rrect, paint);
833 this->recordedDrawCommand();
834 }
835 }
836
837 void SkDeferredCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
838 const SkPaint& paint) {
839 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
840 this->drawingCanvas()->drawDRRect(outer, inner, paint);
841 this->recordedDrawCommand();
842 }
843
844 void SkDeferredCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
845 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
846 this->drawingCanvas()->drawPath(path, paint);
847 this->recordedDrawCommand();
848 }
849
850 void SkDeferredCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar left,
851 SkScalar top, const SkPaint* paint) {
852 SkRect bitmapRect = SkRect::MakeXYWH(left, top,
853 SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
854 if (fDeferredDrawing &&
855 this->isFullFrame(&bitmapRect, paint) &&
856 SkPaintPriv::Overwrites(bitmap, paint)) {
857 this->getDeferredDevice()->skipPendingCommands();
858 }
859
860 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
861 this->drawingCanvas()->drawBitmap(bitmap, left, top, paint);
862 this->recordedDrawCommand();
863 }
864
865 void SkDeferredCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* sr c,
866 const SkRect& dst, const SkPaint* paint,
867 SrcRectConstraint constraint) {
868 if (fDeferredDrawing &&
869 this->isFullFrame(&dst, paint) &&
870 SkPaintPriv::Overwrites(bitmap, paint)) {
871 this->getDeferredDevice()->skipPendingCommands();
872 }
873
874 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
875 this->drawingCanvas()->legacy_drawBitmapRect(bitmap, src, dst, paint, (SrcRe ctConstraint)constraint);
876 this->recordedDrawCommand();
877 }
878
879
880 void SkDeferredCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y,
881 const SkPaint* paint) {
882 SkRect bounds = SkRect::MakeXYWH(x, y,
883 SkIntToScalar(image->width()), SkIntToScala r(image->height()));
884 if (fDeferredDrawing &&
885 this->isFullFrame(&bounds, paint) &&
886 SkPaintPriv::Overwrites(image, paint)) {
887 this->getDeferredDevice()->skipPendingCommands();
888 }
889
890 AutoImmediateDrawIfNeeded autoDraw(*this, image, paint);
891 this->drawingCanvas()->drawImage(image, x, y, paint);
892 this->recordedDrawCommand();
893 }
894 void SkDeferredCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
895 const SkPaint* paint, SrcRectConstraint c onstraint) {
896 if (fDeferredDrawing &&
897 this->isFullFrame(&dst, paint) &&
898 SkPaintPriv::Overwrites(image, paint)) {
899 this->getDeferredDevice()->skipPendingCommands();
900 }
901
902 AutoImmediateDrawIfNeeded autoDraw(*this, image, paint);
903 this->drawingCanvas()->legacy_drawImageRect(image, src, dst, paint, constrai nt);
904 this->recordedDrawCommand();
905 }
906
907 void SkDeferredCanvas::onDrawImageNine(const SkImage* image, const SkIRect& cent er,
908 const SkRect& dst, const SkPaint* paint) {
909 if (fDeferredDrawing &&
910 this->isFullFrame(&dst, paint) &&
911 SkPaintPriv::Overwrites(image, paint)) {
912 this->getDeferredDevice()->skipPendingCommands();
913 }
914
915 AutoImmediateDrawIfNeeded autoDraw(*this, image, paint);
916 this->drawingCanvas()->drawImageNine(image, center, dst, paint);
917 this->recordedDrawCommand();
918 }
919
920 void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
921 const SkIRect& center, const SkRect& dst ,
922 const SkPaint* paint) {
923 // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
924 // covers canvas entirely and dst covers canvas entirely
925 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
926 this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint);
927 this->recordedDrawCommand();
928 }
929
930 void SkDeferredCanvas::onDrawSprite(const SkBitmap& bitmap, int left, int top,
931 const SkPaint* paint) {
932 SkRect bitmapRect = SkRect::MakeXYWH(
933 SkIntToScalar(left),
934 SkIntToScalar(top),
935 SkIntToScalar(bitmap.width()),
936 SkIntToScalar(bitmap.height()));
937 if (fDeferredDrawing &&
938 this->isFullFrame(&bitmapRect, paint) &&
939 SkPaintPriv::Overwrites(bitmap, paint)) {
940 this->getDeferredDevice()->skipPendingCommands();
941 }
942
943 AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
944 this->drawingCanvas()->drawSprite(bitmap, left, top, paint);
945 this->recordedDrawCommand();
946 }
947
948 void SkDeferredCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
949 const SkPaint& paint) {
950 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
951 this->drawingCanvas()->drawText(text, byteLength, x, y, paint);
952 this->recordedDrawCommand();
953 }
954
955 void SkDeferredCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
956 const SkPaint& paint) {
957 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
958 this->drawingCanvas()->drawPosText(text, byteLength, pos, paint);
959 this->recordedDrawCommand();
960 }
961
962 void SkDeferredCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
963 SkScalar constY, const SkPaint& paint) {
964 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
965 this->drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint);
966 this->recordedDrawCommand();
967 }
968
969 void SkDeferredCanvas::onDrawTextOnPath(const void* text, size_t byteLength, con st SkPath& path,
970 const SkMatrix* matrix, const SkPaint& p aint) {
971 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
972 this->drawingCanvas()->drawTextOnPath(text, byteLength, path, matrix, paint) ;
973 this->recordedDrawCommand();
974 }
975
976 void SkDeferredCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScal ar y,
977 const SkPaint& paint) {
978 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
979 this->drawingCanvas()->drawTextBlob(blob, x, y, paint);
980 this->recordedDrawCommand();
981 }
982
983 void SkDeferredCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* m atrix,
984 const SkPaint* paint) {
985 this->drawingCanvas()->drawPicture(picture, matrix, paint);
986 this->recordedDrawCommand();
987 }
988
989 void SkDeferredCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
990 const SkPoint vertices[],
991 const SkPoint texs[],
992 const SkColor colors[], SkXfermode* xmode,
993 const uint16_t indices[], int indexCount,
994 const SkPaint& paint) {
995 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
996 this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colo rs, xmode,
997 indices, indexCount, paint);
998 this->recordedDrawCommand();
999 }
1000
1001 void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor color s[4],
1002 const SkPoint texCoords[4], SkXfermode* xmode ,
1003 const SkPaint& paint) {
1004 AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
1005 this->drawingCanvas()->drawPatch(cubics, colors, texCoords, xmode, paint);
1006 this->recordedDrawCommand();
1007 }
1008
1009 void SkDeferredCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[] ,
1010 const SkRect tex[], const SkColor colors[], i nt count,
1011 SkXfermode::Mode mode, const SkRect* cullRect ,
1012 const SkPaint* paint) {
1013 AutoImmediateDrawIfNeeded autoDraw(*this, paint);
1014 this->drawingCanvas()->drawAtlas(atlas, xform, tex, colors, count, mode, cul lRect, paint);
1015 this->recordedDrawCommand();
1016 }
1017
1018 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
1019 this->drawingCanvas()->setDrawFilter(filter);
1020 this->INHERITED::setDrawFilter(filter);
1021 this->recordedDrawCommand();
1022 return filter;
1023 }
1024
1025 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
1026 return this->drawingCanvas();
1027 }
OLDNEW
« no previous file with comments | « src/core/SkPictureRecord.cpp ('k') | tests/CanvasTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698