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