Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / utils / SkDeferredCanvas.cpp
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 "SkBitmapDevice.h"
12 #include "SkChunkAlloc.h"
13 #include "SkColorFilter.h"
14 #include "SkDrawFilter.h"
15 #include "SkGPipe.h"
16 #include "SkPaint.h"
17 #include "SkPaintPriv.h"
18 #include "SkRRect.h"
19 #include "SkShader.h"
20 #include "SkSurface.h"
21
22 enum {
23     // Deferred canvas will auto-flush when recording reaches this limit
24     kDefaultMaxRecordingStorageBytes = 64*1024*1024,
25     kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature
26 };
27
28 enum PlaybackMode {
29     kNormal_PlaybackMode,
30     kSilent_PlaybackMode,
31 };
32
33 namespace {
34 bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
35                            size_t bitmapSizeThreshold) {
36     if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
37         (bitmap->getSize() > bitmapSizeThreshold))) {
38         return true;
39     }
40     if (paint) {
41         SkShader* shader = paint->getShader();
42         // Here we detect the case where the shader is an SkBitmapProcShader
43         // with a gpu texture attached.  Checking this without RTTI
44         // requires making the assumption that only gradient shaders
45         // and SkBitmapProcShader implement asABitmap().  The following
46         // code may need to be revised if that assumption is ever broken.
47         if (shader && !shader->asAGradient(NULL)) {
48             SkBitmap bm;
49             if (shader->asABitmap(&bm, NULL, NULL) &&
50                 NULL != bm.getTexture()) {
51                 return true;
52             }
53         }
54     }
55     return false;
56 }
57 }
58
59 //-----------------------------------------------------------------------------
60 // DeferredPipeController
61 //-----------------------------------------------------------------------------
62
63 class DeferredPipeController : public SkGPipeController {
64 public:
65     DeferredPipeController();
66     void setPlaybackCanvas(SkCanvas*);
67     virtual ~DeferredPipeController();
68     virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
69     virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
70     void playback(bool silent);
71     bool hasPendingCommands() const { return fAllocator.blockCount() != 0; }
72     size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); }
73 private:
74     enum {
75         kMinBlockSize = 4096
76     };
77     struct PipeBlock {
78         PipeBlock(void* block, size_t size) { fBlock = block, fSize = size; }
79         void* fBlock;
80         size_t fSize;
81     };
82     void* fBlock;
83     size_t fBytesWritten;
84     SkChunkAlloc fAllocator;
85     SkTDArray<PipeBlock> fBlockList;
86     SkGPipeReader fReader;
87 };
88
89 DeferredPipeController::DeferredPipeController() :
90     fAllocator(kMinBlockSize) {
91     fBlock = NULL;
92     fBytesWritten = 0;
93 }
94
95 DeferredPipeController::~DeferredPipeController() {
96     fAllocator.reset();
97 }
98
99 void DeferredPipeController::setPlaybackCanvas(SkCanvas* canvas) {
100     fReader.setCanvas(canvas);
101 }
102
103 void* DeferredPipeController::requestBlock(size_t minRequest, size_t *actual) {
104     if (fBlock) {
105         // Save the previous block for later
106         PipeBlock previousBloc(fBlock, fBytesWritten);
107         fBlockList.push(previousBloc);
108     }
109     size_t blockSize = SkTMax<size_t>(minRequest, kMinBlockSize);
110     fBlock = fAllocator.allocThrow(blockSize);
111     fBytesWritten = 0;
112     *actual = blockSize;
113     return fBlock;
114 }
115
116 void DeferredPipeController::notifyWritten(size_t bytes) {
117     fBytesWritten += bytes;
118 }
119
120 void DeferredPipeController::playback(bool silent) {
121     uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0;
122     for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
123         fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize,
124                          flags);
125     }
126     fBlockList.reset();
127
128     if (fBlock) {
129         fReader.playback(fBlock, fBytesWritten, flags);
130         fBlock = NULL;
131     }
132
133     // Release all allocated blocks
134     fAllocator.reset();
135 }
136
137 //-----------------------------------------------------------------------------
138 // DeferredDevice
139 //-----------------------------------------------------------------------------
140 // FIXME: Derive from SkBaseDevice.
141 class DeferredDevice : public SkBitmapDevice {
142 public:
143     explicit DeferredDevice(SkBaseDevice* immediateDevice);
144     explicit DeferredDevice(SkSurface* surface);
145     ~DeferredDevice();
146
147     void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient);
148     SkCanvas* recordingCanvas();
149     SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
150     SkBaseDevice* immediateDevice() const {return fImmediateCanvas->getTopDevice();}
151     SkImage* newImageSnapshot();
152     void setSurface(SkSurface* surface);
153     bool isFreshFrame();
154     bool hasPendingCommands();
155     size_t storageAllocatedForRecording() const;
156     size_t freeMemoryIfPossible(size_t bytesToFree);
157     size_t getBitmapSizeThreshold() const;
158     void setBitmapSizeThreshold(size_t sizeThreshold);
159     void flushPendingCommands(PlaybackMode);
160     void skipPendingCommands();
161     void setMaxRecordingStorage(size_t);
162     void recordedDrawCommand();
163
164     virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
165     virtual int width() const SK_OVERRIDE;
166     virtual int height() const SK_OVERRIDE;
167     virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE;
168
169     virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config,
170                                                    int width, int height,
171                                                    bool isOpaque,
172                                                    Usage usage) SK_OVERRIDE;
173
174     virtual void writePixels(const SkBitmap& bitmap, int x, int y,
175                                 SkCanvas::Config8888 config8888) SK_OVERRIDE;
176
177 protected:
178     virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
179     virtual bool onReadPixels(const SkBitmap& bitmap,
180                                 int x, int y,
181                                 SkCanvas::Config8888 config8888) SK_OVERRIDE;
182
183     // The following methods are no-ops on a deferred device
184     virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
185         return false;
186     }
187
188     // None of the following drawing methods should ever get called on the
189     // deferred device
190     virtual void clear(SkColor color) SK_OVERRIDE
191         {SkASSERT(0);}
192     virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE
193         {SkASSERT(0);}
194     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
195                             size_t count, const SkPoint[],
196                             const SkPaint& paint) SK_OVERRIDE
197         {SkASSERT(0);}
198     virtual void drawRect(const SkDraw&, const SkRect& r,
199                             const SkPaint& paint) SK_OVERRIDE
200         {SkASSERT(0);}
201     virtual void drawRRect(const SkDraw&, const SkRRect& rr,
202                            const SkPaint& paint) SK_OVERRIDE
203         {SkASSERT(0);}
204     virtual void drawPath(const SkDraw&, const SkPath& path,
205                             const SkPaint& paint,
206                             const SkMatrix* prePathMatrix = NULL,
207                             bool pathIsMutable = false) SK_OVERRIDE
208         {SkASSERT(0);}
209     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
210                             const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE
211         {SkASSERT(0);}
212     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
213                             int x, int y, const SkPaint& paint) SK_OVERRIDE
214         {SkASSERT(0);}
215     virtual void drawText(const SkDraw&, const void* text, size_t len,
216                             SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE
217         {SkASSERT(0);}
218     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
219                                 const SkScalar pos[], SkScalar constY,
220                                 int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE
221         {SkASSERT(0);}
222     virtual void drawTextOnPath(const SkDraw&, const void* text,
223                                 size_t len, const SkPath& path,
224                                 const SkMatrix* matrix,
225                                 const SkPaint& paint) SK_OVERRIDE
226         {SkASSERT(0);}
227     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
228                                 int vertexCount, const SkPoint verts[],
229                                 const SkPoint texs[], const SkColor colors[],
230                                 SkXfermode* xmode, const uint16_t indices[],
231                                 int indexCount, const SkPaint& paint) SK_OVERRIDE
232         {SkASSERT(0);}
233     virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
234                             const SkPaint&) SK_OVERRIDE
235         {SkASSERT(0);}
236 private:
237     virtual void flush() SK_OVERRIDE;
238
239     void beginRecording();
240     void init();
241     void aboutToDraw();
242     void prepareForImmediatePixelWrite();
243
244     DeferredPipeController fPipeController;
245     SkGPipeWriter  fPipeWriter;
246     SkCanvas* fImmediateCanvas;
247     SkCanvas* fRecordingCanvas;
248     SkSurface* fSurface;
249     SkDeferredCanvas::NotificationClient* fNotificationClient;
250     bool fFreshFrame;
251     bool fCanDiscardCanvasContents;
252     size_t fMaxRecordingStorageBytes;
253     size_t fPreviousStorageAllocated;
254     size_t fBitmapSizeThreshold;
255 };
256
257 DeferredDevice::DeferredDevice(SkBaseDevice* immediateDevice)
258     : SkBitmapDevice(SkBitmap::kNo_Config,
259                      immediateDevice->width(), immediateDevice->height(),
260                      immediateDevice->isOpaque(),
261                      immediateDevice->getDeviceProperties()) {
262     fSurface = NULL;
263     fImmediateCanvas = SkNEW_ARGS(SkCanvas, (immediateDevice));
264     fPipeController.setPlaybackCanvas(fImmediateCanvas);
265     this->init();
266 }
267
268 DeferredDevice::DeferredDevice(SkSurface* surface)
269     : SkBitmapDevice(SkBitmap::kNo_Config,
270                      surface->getCanvas()->getDevice()->width(),
271                      surface->getCanvas()->getDevice()->height(),
272                      surface->getCanvas()->getDevice()->isOpaque(),
273                      surface->getCanvas()->getDevice()->getDeviceProperties()) {
274     fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
275     fNotificationClient = NULL;
276     fImmediateCanvas = NULL;
277     fSurface = NULL;
278     this->setSurface(surface);
279     this->init();
280 }
281
282 void DeferredDevice::setSurface(SkSurface* surface) {
283     SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas());
284     SkRefCnt_SafeAssign(fSurface, surface);
285     fPipeController.setPlaybackCanvas(fImmediateCanvas);
286 }
287
288 void DeferredDevice::init() {
289     fRecordingCanvas = NULL;
290     fFreshFrame = true;
291     fCanDiscardCanvasContents = false;
292     fPreviousStorageAllocated = 0;
293     fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
294     fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
295     fNotificationClient = NULL;
296     this->beginRecording();
297 }
298
299 DeferredDevice::~DeferredDevice() {
300     this->flushPendingCommands(kSilent_PlaybackMode);
301     SkSafeUnref(fImmediateCanvas);
302     SkSafeUnref(fSurface);
303 }
304
305 void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
306     fMaxRecordingStorageBytes = maxStorage;
307     this->recordingCanvas(); // Accessing the recording canvas applies the new limit.
308 }
309
310 void DeferredDevice::beginRecording() {
311     SkASSERT(NULL == fRecordingCanvas);
312     fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
313         immediateDevice()->width(), immediateDevice()->height());
314 }
315
316 void DeferredDevice::setNotificationClient(
317     SkDeferredCanvas::NotificationClient* notificationClient) {
318     fNotificationClient = notificationClient;
319 }
320
321 void DeferredDevice::skipPendingCommands() {
322     if (!fRecordingCanvas->isDrawingToLayer()) {
323         fCanDiscardCanvasContents = true;
324         if (fPipeController.hasPendingCommands()) {
325             fFreshFrame = true;
326             flushPendingCommands(kSilent_PlaybackMode);
327             if (fNotificationClient) {
328                 fNotificationClient->skippedPendingDrawCommands();
329             }
330         }
331     }
332 }
333
334 bool DeferredDevice::isFreshFrame() {
335     bool ret = fFreshFrame;
336     fFreshFrame = false;
337     return ret;
338 }
339
340 bool DeferredDevice::hasPendingCommands() {
341     return fPipeController.hasPendingCommands();
342 }
343
344 void DeferredDevice::aboutToDraw()
345 {
346     if (NULL != fNotificationClient) {
347         fNotificationClient->prepareForDraw();
348     }
349     if (fCanDiscardCanvasContents) {
350         if (NULL != fSurface) {
351             fSurface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
352         }
353         fCanDiscardCanvasContents = false;
354     }
355 }
356
357 void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
358     if (!fPipeController.hasPendingCommands()) {
359         return;
360     }
361     if (playbackMode == kNormal_PlaybackMode) {
362         aboutToDraw();
363     }
364     fPipeWriter.flushRecording(true);
365     fPipeController.playback(kSilent_PlaybackMode == playbackMode);
366     if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
367         fNotificationClient->flushedDrawCommands();
368     }
369     fPreviousStorageAllocated = storageAllocatedForRecording();
370 }
371
372 void DeferredDevice::flush() {
373     this->flushPendingCommands(kNormal_PlaybackMode);
374     fImmediateCanvas->flush();
375 }
376
377 size_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
378     size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
379     fPreviousStorageAllocated = storageAllocatedForRecording();
380     return val;
381 }
382
383 size_t DeferredDevice::getBitmapSizeThreshold() const {
384     return fBitmapSizeThreshold;
385 }
386
387 void DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) {
388     fBitmapSizeThreshold = sizeThreshold;
389 }
390
391 size_t DeferredDevice::storageAllocatedForRecording() const {
392     return (fPipeController.storageAllocatedForRecording()
393             + fPipeWriter.storageAllocatedForRecording());
394 }
395
396 void DeferredDevice::recordedDrawCommand() {
397     size_t storageAllocated = this->storageAllocatedForRecording();
398
399     if (storageAllocated > fMaxRecordingStorageBytes) {
400         // First, attempt to reduce cache without flushing
401         size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
402         if (this->freeMemoryIfPossible(tryFree) < tryFree) {
403             // Flush is necessary to free more space.
404             this->flushPendingCommands(kNormal_PlaybackMode);
405             // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
406             // which could cause a high flushing frequency.
407             this->freeMemoryIfPossible(~0U);
408         }
409         storageAllocated = this->storageAllocatedForRecording();
410     }
411
412     if (fNotificationClient &&
413         storageAllocated != fPreviousStorageAllocated) {
414         fPreviousStorageAllocated = storageAllocated;
415         fNotificationClient->storageAllocatedForRecordingChanged(storageAllocated);
416     }
417 }
418
419 SkCanvas* DeferredDevice::recordingCanvas() {
420     return fRecordingCanvas;
421 }
422
423 SkImage* DeferredDevice::newImageSnapshot() {
424     this->flush();
425     return fSurface ? fSurface->newImageSnapshot() : NULL;
426 }
427
428 uint32_t DeferredDevice::getDeviceCapabilities() {
429     return immediateDevice()->getDeviceCapabilities();
430 }
431
432 int DeferredDevice::width() const {
433     return immediateDevice()->width();
434 }
435
436 int DeferredDevice::height() const {
437     return immediateDevice()->height();
438 }
439
440 GrRenderTarget* DeferredDevice::accessRenderTarget() {
441     this->flushPendingCommands(kNormal_PlaybackMode);
442     return immediateDevice()->accessRenderTarget();
443 }
444
445 void DeferredDevice::prepareForImmediatePixelWrite() {
446     // The purpose of the following code is to make sure commands are flushed, that
447     // aboutToDraw() is called and that notifyContentWillChange is called, without
448     // calling anything redundantly.
449     if (fPipeController.hasPendingCommands()) {
450         this->flushPendingCommands(kNormal_PlaybackMode);
451     } else {
452         bool mustNotifyDirectly = !fCanDiscardCanvasContents;
453         this->aboutToDraw();
454         if (mustNotifyDirectly) {
455             fSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode);
456         }
457     }
458
459     fImmediateCanvas->flush();
460 }
461
462 void DeferredDevice::writePixels(const SkBitmap& bitmap,
463     int x, int y, SkCanvas::Config8888 config8888) {
464
465     if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() &&
466         (y + bitmap.height()) >= height()) {
467         this->skipPendingCommands();
468     }
469
470     if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
471         SkCanvas::kNative_Premul_Config8888 != config8888 &&
472         kPMColorAlias != config8888) {
473         //Special case config: no deferral
474         prepareForImmediatePixelWrite();
475         immediateDevice()->writePixels(bitmap, x, y, config8888);
476         return;
477     }
478
479     SkPaint paint;
480     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
481     if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) {
482         prepareForImmediatePixelWrite();
483         fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
484     } else {
485         this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
486         this->recordedDrawCommand();
487
488     }
489 }
490
491 const SkBitmap& DeferredDevice::onAccessBitmap() {
492     this->flushPendingCommands(kNormal_PlaybackMode);
493     return immediateDevice()->accessBitmap(false);
494 }
495
496 SkBaseDevice* DeferredDevice::onCreateCompatibleDevice(
497     SkBitmap::Config config, int width, int height, bool isOpaque,
498     Usage usage) {
499
500     // Save layer usage not supported, and not required by SkDeferredCanvas.
501     SkASSERT(usage != kSaveLayer_Usage);
502     // Create a compatible non-deferred device.
503     // We do not create a deferred device because we know the new device
504     // will not be used with a deferred canvas (there is no API for that).
505     // And connecting a DeferredDevice to non-deferred canvas can result
506     // in unpredictable behavior.
507     return immediateDevice()->createCompatibleDevice(config, width, height, isOpaque);
508 }
509
510 bool DeferredDevice::onReadPixels(
511     const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
512     this->flushPendingCommands(kNormal_PlaybackMode);
513     return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
514                                                    x, y, config8888);
515 }
516
517 class AutoImmediateDrawIfNeeded {
518 public:
519     AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
520                               const SkPaint* paint) {
521         this->init(canvas, bitmap, paint);
522     }
523
524     AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
525         this->init(canvas, 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 SkPaint* paint)
535     {
536         DeferredDevice* device = static_cast<DeferredDevice*>(canvas.getDevice());
537         if (canvas.isDeferredDrawing() && (NULL != device) &&
538             shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) {
539             canvas.setDeferredDrawing(false);
540             fCanvas = &canvas;
541         } else {
542             fCanvas = NULL;
543         }
544     }
545
546     SkDeferredCanvas* fCanvas;
547 };
548
549 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) {
550     SkAutoTUnref<DeferredDevice> deferredDevice(SkNEW_ARGS(DeferredDevice, (surface)));
551     return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
552 }
553
554 SkDeferredCanvas* SkDeferredCanvas::Create(SkBaseDevice* device) {
555     SkAutoTUnref<DeferredDevice> deferredDevice(SkNEW_ARGS(DeferredDevice, (device)));
556     return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
557 }
558
559 SkDeferredCanvas::SkDeferredCanvas(DeferredDevice* device) : SkCanvas (device) {
560     this->init();
561 }
562
563 void SkDeferredCanvas::init() {
564     fDeferredDrawing = true; // On by default
565 }
566
567 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
568     this->validate();
569     this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
570 }
571
572 size_t SkDeferredCanvas::storageAllocatedForRecording() const {
573     return this->getDeferredDevice()->storageAllocatedForRecording();
574 }
575
576 size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
577     return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
578 }
579
580 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
581     DeferredDevice* deferredDevice = this->getDeferredDevice();
582     SkASSERT(deferredDevice);
583     deferredDevice->setBitmapSizeThreshold(sizeThreshold);
584 }
585
586 void SkDeferredCanvas::recordedDrawCommand() {
587     if (fDeferredDrawing) {
588         this->getDeferredDevice()->recordedDrawCommand();
589     }
590 }
591
592 void SkDeferredCanvas::validate() const {
593     SkASSERT(this->getDevice());
594 }
595
596 SkCanvas* SkDeferredCanvas::drawingCanvas() const {
597     this->validate();
598     return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
599         this->getDeferredDevice()->immediateCanvas();
600 }
601
602 SkCanvas* SkDeferredCanvas::immediateCanvas() const {
603     this->validate();
604     return this->getDeferredDevice()->immediateCanvas();
605 }
606
607 DeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
608     return static_cast<DeferredDevice*>(this->getDevice());
609 }
610
611 void SkDeferredCanvas::setDeferredDrawing(bool val) {
612     this->validate(); // Must set device before calling this method
613     if (val != fDeferredDrawing) {
614         if (fDeferredDrawing) {
615             // Going live.
616             this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode);
617         }
618         fDeferredDrawing = val;
619     }
620 }
621
622 bool SkDeferredCanvas::isDeferredDrawing() const {
623     return fDeferredDrawing;
624 }
625
626 bool SkDeferredCanvas::isFreshFrame() const {
627     return this->getDeferredDevice()->isFreshFrame();
628 }
629
630 bool SkDeferredCanvas::hasPendingCommands() const {
631     return this->getDeferredDevice()->hasPendingCommands();
632 }
633
634 void SkDeferredCanvas::silentFlush() {
635     if (fDeferredDrawing) {
636         this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
637     }
638 }
639
640 SkDeferredCanvas::~SkDeferredCanvas() {
641 }
642
643 SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) {
644     DeferredDevice* deferredDevice = this->getDeferredDevice();
645     SkASSERT(NULL != deferredDevice);
646     // By swapping the surface into the existing device, we preserve
647     // all pending commands, which can help to seamlessly recover from
648     // a lost accelerated graphics context.
649     deferredDevice->setSurface(surface);
650     return surface;
651 }
652
653 SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient(
654     NotificationClient* notificationClient) {
655
656     DeferredDevice* deferredDevice = this->getDeferredDevice();
657     SkASSERT(deferredDevice);
658     if (deferredDevice) {
659         deferredDevice->setNotificationClient(notificationClient);
660     }
661     return notificationClient;
662 }
663
664 SkImage* SkDeferredCanvas::newImageSnapshot() {
665     DeferredDevice* deferredDevice = this->getDeferredDevice();
666     SkASSERT(deferredDevice);
667     return deferredDevice ? deferredDevice->newImageSnapshot() : NULL;
668 }
669
670 bool SkDeferredCanvas::isFullFrame(const SkRect* rect,
671                                    const SkPaint* paint) const {
672     SkCanvas* canvas = this->drawingCanvas();
673     SkISize canvasSize = this->getDeviceSize();
674     if (rect) {
675         if (!canvas->getTotalMatrix().rectStaysRect()) {
676             return false; // conservative
677         }
678
679         SkRect transformedRect;
680         canvas->getTotalMatrix().mapRect(&transformedRect, *rect);
681
682         if (paint) {
683             SkPaint::Style paintStyle = paint->getStyle();
684             if (!(paintStyle == SkPaint::kFill_Style ||
685                 paintStyle == SkPaint::kStrokeAndFill_Style)) {
686                 return false;
687             }
688             if (paint->getMaskFilter() || paint->getLooper()
689                 || paint->getPathEffect() || paint->getImageFilter()) {
690                 return false; // conservative
691             }
692         }
693
694         // The following test holds with AA enabled, and is conservative
695         // by a 0.5 pixel margin with AA disabled
696         if (transformedRect.fLeft > SkIntToScalar(0) ||
697             transformedRect.fTop > SkIntToScalar(0) ||
698             transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) ||
699             transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) {
700             return false;
701         }
702     }
703
704     return this->getClipStack()->quickContains(SkRect::MakeXYWH(0, 0,
705         SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight)));
706 }
707
708 int SkDeferredCanvas::save(SaveFlags flags) {
709     this->drawingCanvas()->save(flags);
710     int val = this->INHERITED::save(flags);
711     this->recordedDrawCommand();
712
713     return val;
714 }
715
716 int SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
717                                 SaveFlags flags) {
718     this->drawingCanvas()->saveLayer(bounds, paint, flags);
719     int count = this->INHERITED::save(flags);
720     this->clipRectBounds(bounds, flags, NULL);
721     this->recordedDrawCommand();
722
723     return count;
724 }
725
726 void SkDeferredCanvas::restore() {
727     this->drawingCanvas()->restore();
728     this->INHERITED::restore();
729     this->recordedDrawCommand();
730 }
731
732 bool SkDeferredCanvas::isDrawingToLayer() const {
733     return this->drawingCanvas()->isDrawingToLayer();
734 }
735
736 bool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) {
737     this->drawingCanvas()->translate(dx, dy);
738     bool val = this->INHERITED::translate(dx, dy);
739     this->recordedDrawCommand();
740     return val;
741 }
742
743 bool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) {
744     this->drawingCanvas()->scale(sx, sy);
745     bool val = this->INHERITED::scale(sx, sy);
746     this->recordedDrawCommand();
747     return val;
748 }
749
750 bool SkDeferredCanvas::rotate(SkScalar degrees) {
751     this->drawingCanvas()->rotate(degrees);
752     bool val = this->INHERITED::rotate(degrees);
753     this->recordedDrawCommand();
754     return val;
755 }
756
757 bool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) {
758     this->drawingCanvas()->skew(sx, sy);
759     bool val = this->INHERITED::skew(sx, sy);
760     this->recordedDrawCommand();
761     return val;
762 }
763
764 bool SkDeferredCanvas::concat(const SkMatrix& matrix) {
765     this->drawingCanvas()->concat(matrix);
766     bool val = this->INHERITED::concat(matrix);
767     this->recordedDrawCommand();
768     return val;
769 }
770
771 void SkDeferredCanvas::setMatrix(const SkMatrix& matrix) {
772     this->drawingCanvas()->setMatrix(matrix);
773     this->INHERITED::setMatrix(matrix);
774     this->recordedDrawCommand();
775 }
776
777 bool SkDeferredCanvas::clipRect(const SkRect& rect,
778                                 SkRegion::Op op,
779                                 bool doAntiAlias) {
780     this->drawingCanvas()->clipRect(rect, op, doAntiAlias);
781     bool val = this->INHERITED::clipRect(rect, op, doAntiAlias);
782     this->recordedDrawCommand();
783     return val;
784 }
785
786 bool SkDeferredCanvas::clipRRect(const SkRRect& rrect,
787                                  SkRegion::Op op,
788                                  bool doAntiAlias) {
789     this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias);
790     bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias);
791     this->recordedDrawCommand();
792     return val;
793 }
794
795 bool SkDeferredCanvas::clipPath(const SkPath& path,
796                                 SkRegion::Op op,
797                                 bool doAntiAlias) {
798     this->drawingCanvas()->clipPath(path, op, doAntiAlias);
799     bool val = this->INHERITED::clipPath(path, op, doAntiAlias);
800     this->recordedDrawCommand();
801     return val;
802 }
803
804 bool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn,
805                                   SkRegion::Op op) {
806     this->drawingCanvas()->clipRegion(deviceRgn, op);
807     bool val = this->INHERITED::clipRegion(deviceRgn, op);
808     this->recordedDrawCommand();
809     return val;
810 }
811
812 void SkDeferredCanvas::clear(SkColor color) {
813     // purge pending commands
814     if (fDeferredDrawing) {
815         this->getDeferredDevice()->skipPendingCommands();
816     }
817
818     this->drawingCanvas()->clear(color);
819     this->recordedDrawCommand();
820 }
821
822 void SkDeferredCanvas::drawPaint(const SkPaint& paint) {
823     if (fDeferredDrawing && this->isFullFrame(NULL, &paint) &&
824         isPaintOpaque(&paint)) {
825         this->getDeferredDevice()->skipPendingCommands();
826     }
827     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
828     this->drawingCanvas()->drawPaint(paint);
829     this->recordedDrawCommand();
830 }
831
832 void SkDeferredCanvas::drawPoints(PointMode mode, size_t count,
833                                   const SkPoint pts[], const SkPaint& paint) {
834     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
835     this->drawingCanvas()->drawPoints(mode, count, pts, paint);
836     this->recordedDrawCommand();
837 }
838
839 void SkDeferredCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
840     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
841     this->drawingCanvas()->drawOval(rect, paint);
842     this->recordedDrawCommand();
843 }
844
845 void SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
846     if (fDeferredDrawing && this->isFullFrame(&rect, &paint) &&
847         isPaintOpaque(&paint)) {
848         this->getDeferredDevice()->skipPendingCommands();
849     }
850
851     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
852     this->drawingCanvas()->drawRect(rect, paint);
853     this->recordedDrawCommand();
854 }
855
856 void SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
857     if (rrect.isRect()) {
858         this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
859     } else if (rrect.isOval()) {
860         this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
861     } else {
862         AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
863         this->drawingCanvas()->drawRRect(rrect, paint);
864         this->recordedDrawCommand();
865     }
866 }
867
868 void SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
869     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
870     this->drawingCanvas()->drawPath(path, paint);
871     this->recordedDrawCommand();
872 }
873
874 void SkDeferredCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
875                                   SkScalar top, const SkPaint* paint) {
876     SkRect bitmapRect = SkRect::MakeXYWH(left, top,
877         SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
878     if (fDeferredDrawing &&
879         this->isFullFrame(&bitmapRect, paint) &&
880         isPaintOpaque(paint, &bitmap)) {
881         this->getDeferredDevice()->skipPendingCommands();
882     }
883
884     AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
885     this->drawingCanvas()->drawBitmap(bitmap, left, top, paint);
886     this->recordedDrawCommand();
887 }
888
889 void SkDeferredCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
890                                             const SkRect* src,
891                                             const SkRect& dst,
892                                             const SkPaint* paint,
893                                             DrawBitmapRectFlags flags) {
894     if (fDeferredDrawing &&
895         this->isFullFrame(&dst, paint) &&
896         isPaintOpaque(paint, &bitmap)) {
897         this->getDeferredDevice()->skipPendingCommands();
898     }
899
900     AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
901     this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
902     this->recordedDrawCommand();
903 }
904
905
906 void SkDeferredCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
907                                         const SkMatrix& m,
908                                         const SkPaint* paint) {
909     // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
910     // covers canvas entirely and transformed bitmap covers canvas entirely
911     AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
912     this->drawingCanvas()->drawBitmapMatrix(bitmap, m, paint);
913     this->recordedDrawCommand();
914 }
915
916 void SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap,
917                                       const SkIRect& center, const SkRect& dst,
918                                       const SkPaint* paint) {
919     // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
920     // covers canvas entirely and dst covers canvas entirely
921     AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
922     this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint);
923     this->recordedDrawCommand();
924 }
925
926 void SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
927                                   const SkPaint* paint) {
928     SkRect bitmapRect = SkRect::MakeXYWH(
929         SkIntToScalar(left),
930         SkIntToScalar(top),
931         SkIntToScalar(bitmap.width()),
932         SkIntToScalar(bitmap.height()));
933     if (fDeferredDrawing &&
934         this->isFullFrame(&bitmapRect, paint) &&
935         isPaintOpaque(paint, &bitmap)) {
936         this->getDeferredDevice()->skipPendingCommands();
937     }
938
939     AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
940     this->drawingCanvas()->drawSprite(bitmap, left, top, paint);
941     this->recordedDrawCommand();
942 }
943
944 void SkDeferredCanvas::drawText(const void* text, size_t byteLength,
945                                 SkScalar x, SkScalar y, const SkPaint& paint) {
946     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
947     this->drawingCanvas()->drawText(text, byteLength, x, y, paint);
948     this->recordedDrawCommand();
949 }
950
951 void SkDeferredCanvas::drawPosText(const void* text, size_t byteLength,
952                                    const SkPoint pos[], const SkPaint& paint) {
953     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
954     this->drawingCanvas()->drawPosText(text, byteLength, pos, paint);
955     this->recordedDrawCommand();
956 }
957
958 void SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength,
959                                     const SkScalar xpos[], SkScalar constY,
960                                     const SkPaint& paint) {
961     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
962     this->drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint);
963     this->recordedDrawCommand();
964 }
965
966 void SkDeferredCanvas::drawTextOnPath(const void* text, size_t byteLength,
967                                       const SkPath& path,
968                                       const SkMatrix* matrix,
969                                       const SkPaint& paint) {
970     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
971     this->drawingCanvas()->drawTextOnPath(text, byteLength, path, matrix, paint);
972     this->recordedDrawCommand();
973 }
974
975 void SkDeferredCanvas::drawPicture(SkPicture& picture) {
976     this->drawingCanvas()->drawPicture(picture);
977     this->recordedDrawCommand();
978 }
979
980 void SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount,
981                                     const SkPoint vertices[],
982                                     const SkPoint texs[],
983                                     const SkColor colors[], SkXfermode* xmode,
984                                     const uint16_t indices[], int indexCount,
985                                     const SkPaint& paint) {
986     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
987     this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode,
988                                         indices, indexCount, paint);
989     this->recordedDrawCommand();
990 }
991
992 SkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder) {
993     this->drawingCanvas()->setBounder(bounder);
994     this->INHERITED::setBounder(bounder);
995     this->recordedDrawCommand();
996     return bounder;
997 }
998
999 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
1000     this->drawingCanvas()->setDrawFilter(filter);
1001     this->INHERITED::setDrawFilter(filter);
1002     this->recordedDrawCommand();
1003     return filter;
1004 }
1005
1006 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
1007     return this->drawingCanvas();
1008 }