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 should_draw_immediately(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                 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     void flushPendingCommands(PlaybackMode);
    154     void skipPendingCommands();
    155     void setMaxRecordingStorage(size_t);
    156     void recordedDrawCommand();
    157 
    158     virtual SkImageInfo imageInfo() const SK_OVERRIDE;
    159 
    160     virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE;
    161 
    162     virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
    163 
    164     virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
    165 
    166 protected:
    167     virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
    168     virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) SK_OVERRIDE;
    169     virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y) SK_OVERRIDE;
    170 
    171     // The following methods are no-ops on a deferred device
    172     virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
    173         return false;
    174     }
    175 
    176     // None of the following drawing methods should ever get called on the
    177     // deferred device
    178     virtual void clear(SkColor color) SK_OVERRIDE
    179         {SkASSERT(0);}
    180     virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE
    181         {SkASSERT(0);}
    182     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
    183                             size_t count, const SkPoint[],
    184                             const SkPaint& paint) SK_OVERRIDE
    185         {SkASSERT(0);}
    186     virtual void drawRect(const SkDraw&, const SkRect& r,
    187                             const SkPaint& paint) SK_OVERRIDE
    188         {SkASSERT(0);}
    189     virtual void drawOval(const SkDraw&, const SkRect&, const SkPaint&) SK_OVERRIDE
    190         {SkASSERT(0);}
    191     virtual void drawRRect(const SkDraw&, const SkRRect& rr,
    192                            const SkPaint& paint) SK_OVERRIDE
    193     {SkASSERT(0);}
    194     virtual void drawPath(const SkDraw&, const SkPath& path,
    195                             const SkPaint& paint,
    196                             const SkMatrix* prePathMatrix = NULL,
    197                             bool pathIsMutable = false) SK_OVERRIDE
    198         {SkASSERT(0);}
    199     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
    200                             const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE
    201         {SkASSERT(0);}
    202     virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*,
    203                                 const SkRect&, const SkPaint&,
    204                                 SkCanvas::DrawBitmapRectFlags) SK_OVERRIDE
    205         {SkASSERT(0);}
    206     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
    207                             int x, int y, const SkPaint& paint) SK_OVERRIDE
    208         {SkASSERT(0);}
    209     virtual void drawText(const SkDraw&, const void* text, size_t len,
    210                             SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE
    211         {SkASSERT(0);}
    212     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
    213                                 const SkScalar pos[], SkScalar constY,
    214                                 int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE
    215         {SkASSERT(0);}
    216     virtual void drawTextOnPath(const SkDraw&, const void* text,
    217                                 size_t len, const SkPath& path,
    218                                 const SkMatrix* matrix,
    219                                 const SkPaint& paint) SK_OVERRIDE
    220         {SkASSERT(0);}
    221     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
    222                                 int vertexCount, const SkPoint verts[],
    223                                 const SkPoint texs[], const SkColor colors[],
    224                                 SkXfermode* xmode, const uint16_t indices[],
    225                                 int indexCount, const SkPaint& paint) SK_OVERRIDE
    226         {SkASSERT(0);}
    227     virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
    228                            const SkPoint texCoords[4], SkXfermode* xmode,
    229                            const SkPaint& paint) SK_OVERRIDE
    230         {SkASSERT(0);}
    231     virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
    232                             const SkPaint&) SK_OVERRIDE
    233         {SkASSERT(0);}
    234 
    235     virtual void lockPixels() SK_OVERRIDE {}
    236     virtual void unlockPixels() SK_OVERRIDE {}
    237 
    238     virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE {
    239         return false;
    240     }
    241     virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE {
    242         return false;
    243     }
    244     virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
    245                              const SkImageFilter::Context&, SkBitmap*, SkIPoint*) SK_OVERRIDE {
    246         return false;
    247     }
    248 
    249 private:
    250     virtual void flush() SK_OVERRIDE;
    251     virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {}
    252 
    253     void beginRecording();
    254     void init();
    255     void aboutToDraw();
    256     void prepareForImmediatePixelWrite();
    257 
    258     DeferredPipeController fPipeController;
    259     SkGPipeWriter  fPipeWriter;
    260     SkCanvas* fImmediateCanvas;
    261     SkCanvas* fRecordingCanvas;
    262     SkSurface* fSurface;
    263     SkDeferredCanvas::NotificationClient* fNotificationClient;
    264     bool fFreshFrame;
    265     bool fCanDiscardCanvasContents;
    266     size_t fMaxRecordingStorageBytes;
    267     size_t fPreviousStorageAllocated;
    268 };
    269 
    270 SkDeferredDevice::SkDeferredDevice(SkSurface* surface) {
    271     fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
    272     fNotificationClient = NULL;
    273     fImmediateCanvas = NULL;
    274     fSurface = NULL;
    275     this->setSurface(surface);
    276     this->init();
    277 }
    278 
    279 void SkDeferredDevice::setSurface(SkSurface* surface) {
    280     SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas());
    281     SkRefCnt_SafeAssign(fSurface, surface);
    282     fPipeController.setPlaybackCanvas(fImmediateCanvas);
    283 }
    284 
    285 void SkDeferredDevice::init() {
    286     fRecordingCanvas = NULL;
    287     fFreshFrame = true;
    288     fCanDiscardCanvasContents = false;
    289     fPreviousStorageAllocated = 0;
    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 (fNotificationClient) {
    340         fNotificationClient->prepareForDraw();
    341     }
    342     if (fCanDiscardCanvasContents) {
    343         if (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::storageAllocatedForRecording() const {
    382     return (fPipeController.storageAllocatedForRecording()
    383             + fPipeWriter.storageAllocatedForRecording());
    384 }
    385 
    386 void SkDeferredDevice::recordedDrawCommand() {
    387     size_t storageAllocated = this->storageAllocatedForRecording();
    388 
    389     if (storageAllocated > fMaxRecordingStorageBytes) {
    390         // First, attempt to reduce cache without flushing
    391         size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
    392         if (this->freeMemoryIfPossible(tryFree) < tryFree) {
    393             // Flush is necessary to free more space.
    394             this->flushPendingCommands(kNormal_PlaybackMode);
    395             // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
    396             // which could cause a high flushing frequency.
    397             this->freeMemoryIfPossible(~0U);
    398         }
    399         storageAllocated = this->storageAllocatedForRecording();
    400     }
    401 
    402     if (fNotificationClient &&
    403         storageAllocated != fPreviousStorageAllocated) {
    404         fPreviousStorageAllocated = storageAllocated;
    405         fNotificationClient->storageAllocatedForRecordingChanged(storageAllocated);
    406     }
    407 }
    408 
    409 SkCanvas* SkDeferredDevice::recordingCanvas() {
    410     return fRecordingCanvas;
    411 }
    412 
    413 SkImage* SkDeferredDevice::newImageSnapshot() {
    414     this->flush();
    415     return fSurface ? fSurface->newImageSnapshot() : NULL;
    416 }
    417 
    418 SkImageInfo SkDeferredDevice::imageInfo() const {
    419     return immediateDevice()->imageInfo();
    420 }
    421 
    422 GrRenderTarget* SkDeferredDevice::accessRenderTarget() {
    423     this->flushPendingCommands(kNormal_PlaybackMode);
    424     return immediateDevice()->accessRenderTarget();
    425 }
    426 
    427 void SkDeferredDevice::prepareForImmediatePixelWrite() {
    428     // The purpose of the following code is to make sure commands are flushed, that
    429     // aboutToDraw() is called and that notifyContentWillChange is called, without
    430     // calling anything redundantly.
    431     if (fPipeController.hasPendingCommands()) {
    432         this->flushPendingCommands(kNormal_PlaybackMode);
    433     } else {
    434         bool mustNotifyDirectly = !fCanDiscardCanvasContents;
    435         this->aboutToDraw();
    436         if (mustNotifyDirectly) {
    437             fSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode);
    438         }
    439     }
    440 
    441     fImmediateCanvas->flush();
    442 }
    443 
    444 bool SkDeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
    445                                    int x, int y) {
    446     SkASSERT(x >= 0 && y >= 0);
    447     SkASSERT(x + info.width() <= width());
    448     SkASSERT(y + info.height() <= height());
    449 
    450     this->flushPendingCommands(kNormal_PlaybackMode);
    451 
    452     const SkImageInfo deviceInfo = this->imageInfo();
    453     if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height()) {
    454         this->skipPendingCommands();
    455     }
    456 
    457     this->prepareForImmediatePixelWrite();
    458     return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y);
    459 }
    460 
    461 const SkBitmap& SkDeferredDevice::onAccessBitmap() {
    462     this->flushPendingCommands(kNormal_PlaybackMode);
    463     return immediateDevice()->accessBitmap(false);
    464 }
    465 
    466 SkBaseDevice* SkDeferredDevice::onCreateDevice(const SkImageInfo& info, Usage usage) {
    467     // Save layer usage not supported, and not required by SkDeferredCanvas.
    468     SkASSERT(usage != kSaveLayer_Usage);
    469     // Create a compatible non-deferred device.
    470     // We do not create a deferred device because we know the new device
    471     // will not be used with a deferred canvas (there is no API for that).
    472     // And connecting a SkDeferredDevice to non-deferred canvas can result
    473     // in unpredictable behavior.
    474     return immediateDevice()->createCompatibleDevice(info);
    475 }
    476 
    477 SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
    478     return this->immediateDevice()->newSurface(info, props);
    479 }
    480 
    481 bool SkDeferredDevice::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
    482                                     int x, int y) {
    483     this->flushPendingCommands(kNormal_PlaybackMode);
    484     return fImmediateCanvas->readPixels(info, pixels, rowBytes, x, y);
    485 }
    486 
    487 class AutoImmediateDrawIfNeeded {
    488 public:
    489     AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
    490                               const SkPaint* paint) {
    491         this->init(canvas, bitmap, paint);
    492     }
    493 
    494     AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
    495         this->init(canvas, NULL, paint);
    496     }
    497 
    498     ~AutoImmediateDrawIfNeeded() {
    499         if (fCanvas) {
    500             fCanvas->setDeferredDrawing(true);
    501         }
    502     }
    503 private:
    504     void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) {
    505         if (canvas.isDeferredDrawing() &&
    506             should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold())) {
    507             canvas.setDeferredDrawing(false);
    508             fCanvas = &canvas;
    509         } else {
    510             fCanvas = NULL;
    511         }
    512     }
    513 
    514     SkDeferredCanvas* fCanvas;
    515 };
    516 
    517 SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) {
    518     SkAutoTUnref<SkDeferredDevice> deferredDevice(SkNEW_ARGS(SkDeferredDevice, (surface)));
    519     return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
    520 }
    521 
    522 SkDeferredCanvas::SkDeferredCanvas(SkDeferredDevice* device) : SkCanvas (device) {
    523     this->init();
    524 }
    525 
    526 void SkDeferredCanvas::init() {
    527     fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
    528     fDeferredDrawing = true; // On by default
    529     fCachedCanvasSize.setEmpty();
    530     fCachedCanvasSizeDirty = true;
    531 }
    532 
    533 void SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
    534     this->validate();
    535     this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
    536 }
    537 
    538 size_t SkDeferredCanvas::storageAllocatedForRecording() const {
    539     return this->getDeferredDevice()->storageAllocatedForRecording();
    540 }
    541 
    542 size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
    543     return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
    544 }
    545 
    546 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
    547     fBitmapSizeThreshold = sizeThreshold;
    548 }
    549 
    550 void SkDeferredCanvas::recordedDrawCommand() {
    551     if (fDeferredDrawing) {
    552         this->getDeferredDevice()->recordedDrawCommand();
    553     }
    554 }
    555 
    556 void SkDeferredCanvas::validate() const {
    557     SkASSERT(this->getDevice());
    558 }
    559 
    560 SkCanvas* SkDeferredCanvas::drawingCanvas() const {
    561     this->validate();
    562     return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
    563         this->getDeferredDevice()->immediateCanvas();
    564 }
    565 
    566 SkCanvas* SkDeferredCanvas::immediateCanvas() const {
    567     this->validate();
    568     return this->getDeferredDevice()->immediateCanvas();
    569 }
    570 
    571 SkDeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
    572     return static_cast<SkDeferredDevice*>(this->getDevice());
    573 }
    574 
    575 void SkDeferredCanvas::setDeferredDrawing(bool val) {
    576     this->validate(); // Must set device before calling this method
    577     if (val != fDeferredDrawing) {
    578         if (fDeferredDrawing) {
    579             // Going live.
    580             this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode);
    581         }
    582         fDeferredDrawing = val;
    583     }
    584 }
    585 
    586 bool SkDeferredCanvas::isDeferredDrawing() const {
    587     return fDeferredDrawing;
    588 }
    589 
    590 bool SkDeferredCanvas::isFreshFrame() const {
    591     return this->getDeferredDevice()->isFreshFrame();
    592 }
    593 
    594 SkISize SkDeferredCanvas::getCanvasSize() const {
    595     if (fCachedCanvasSizeDirty) {
    596         fCachedCanvasSize = this->getBaseLayerSize();
    597         fCachedCanvasSizeDirty = false;
    598     }
    599     return fCachedCanvasSize;
    600 }
    601 
    602 bool SkDeferredCanvas::hasPendingCommands() const {
    603     return this->getDeferredDevice()->hasPendingCommands();
    604 }
    605 
    606 void SkDeferredCanvas::silentFlush() {
    607     if (fDeferredDrawing) {
    608         this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
    609     }
    610 }
    611 
    612 SkDeferredCanvas::~SkDeferredCanvas() {
    613 }
    614 
    615 SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) {
    616     SkDeferredDevice* deferredDevice = this->getDeferredDevice();
    617     SkASSERT(deferredDevice);
    618     // By swapping the surface into the existing device, we preserve
    619     // all pending commands, which can help to seamlessly recover from
    620     // a lost accelerated graphics context.
    621     deferredDevice->setSurface(surface);
    622     fCachedCanvasSizeDirty = true;
    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->getCanvasSize();
    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() {
    682     this->drawingCanvas()->save();
    683     this->recordedDrawCommand();
    684     this->INHERITED::willSave();
    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::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
    916                                       const SkPaint& paint) {
    917     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
    918     this->drawingCanvas()->drawTextBlob(blob, x, y, paint);
    919     this->recordedDrawCommand();
    920 }
    921 
    922 void SkDeferredCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
    923                                      const SkPaint* paint) {
    924     this->drawingCanvas()->drawPicture(picture, matrix, paint);
    925     this->recordedDrawCommand();
    926 }
    927 
    928 void SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount,
    929                                     const SkPoint vertices[],
    930                                     const SkPoint texs[],
    931                                     const SkColor colors[], SkXfermode* xmode,
    932                                     const uint16_t indices[], int indexCount,
    933                                     const SkPaint& paint) {
    934     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
    935     this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode,
    936                                         indices, indexCount, paint);
    937     this->recordedDrawCommand();
    938 }
    939 
    940 void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
    941                                    const SkPoint texCoords[4], SkXfermode* xmode,
    942                                    const SkPaint& paint) {
    943     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
    944     this->drawingCanvas()->drawPatch(cubics, colors, texCoords, xmode, paint);
    945     this->recordedDrawCommand();
    946 }
    947 
    948 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
    949     this->drawingCanvas()->setDrawFilter(filter);
    950     this->INHERITED::setDrawFilter(filter);
    951     this->recordedDrawCommand();
    952     return filter;
    953 }
    954 
    955 SkCanvas* SkDeferredCanvas::canvasForDrawIter() {
    956     return this->drawingCanvas();
    957 }
    958