SkDeferredCanvas.cpp revision eed779d866e1e239bfb9ebc6a225b7345a41adf9
14370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
24370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com/*
3baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org * Copyright 2013 Google Inc.
44370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com *
54370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com * Use of this source code is governed by a BSD-style license that can be
64370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com * found in the LICENSE file.
74370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com */
84370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
94370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com#include "SkDeferredCanvas.h"
104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
1188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org#include "SkChunkAlloc.h"
124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com#include "SkColorFilter.h"
1388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org#include "SkDevice.h"
144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com#include "SkDrawFilter.h"
1588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org#include "SkGPipe.h"
1688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org#include "SkPaint.h"
17baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3junov@chromium.org#include "SkPaintPriv.h"
184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h"
1988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org#include "SkShader.h"
2067d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org#include "SkSurface.h"
214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
22bfeddae9da240693441556b2f278827e213f75e8junov@chromium.orgenum {
23bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    // Deferred canvas will auto-flush when recording reaches this limit
24bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    kDefaultMaxRecordingStorageBytes = 64*1024*1024,
25140d7286c5a40058932696eaa28818c313bd2ddfreed@google.com    kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature
26bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org};
27bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org
28eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.orgenum PlaybackMode {
29eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    kNormal_PlaybackMode,
30eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    kSilent_PlaybackMode,
31eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org};
32eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org
334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comnamespace {
347775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.combool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
357775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com                           size_t bitmapSizeThreshold) {
367775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
377775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        (bitmap->getSize() > bitmapSizeThreshold))) {
3810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        return true;
3910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    }
4010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    if (paint) {
4110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        SkShader* shader = paint->getShader();
4210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // Here we detect the case where the shader is an SkBitmapProcShader
4310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // with a gpu texture attached.  Checking this without RTTI
4410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // requires making the assumption that only gradient shaders
4510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // and SkBitmapProcShader implement asABitmap().  The following
4610f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // code may need to be revised if that assumption is ever broken.
4710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        if (shader && !shader->asAGradient(NULL)) {
4810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org            SkBitmap bm;
49d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (shader->asABitmap(&bm, NULL, NULL) &&
5010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org                NULL != bm.getTexture()) {
5110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org                return true;
5210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org            }
5310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        }
5410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    }
5510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    return false;
56b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
57b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
58b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org
5988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
6088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org// DeferredPipeController
6188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
6288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
6388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgclass DeferredPipeController : public SkGPipeController {
6488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgpublic:
6588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredPipeController();
6688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void setPlaybackCanvas(SkCanvas*);
6788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual ~DeferredPipeController();
6888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
6988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
70fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    void playback(bool silent);
71a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    bool hasPendingCommands() const { return fAllocator.blockCount() != 0; }
7288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); }
7388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprivate:
7488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    enum {
7588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        kMinBlockSize = 4096
7688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    };
7788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    struct PipeBlock {
7888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        PipeBlock(void* block, size_t size) { fBlock = block, fSize = size; }
7988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        void* fBlock;
8088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        size_t fSize;
8188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    };
8288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void* fBlock;
8388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t fBytesWritten;
8488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkChunkAlloc fAllocator;
8588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkTDArray<PipeBlock> fBlockList;
8688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkGPipeReader fReader;
8788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org};
8888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
8988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredPipeController::DeferredPipeController() :
9088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator(kMinBlockSize) {
9188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlock = NULL;
9288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten = 0;
9388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
9488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
9588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredPipeController::~DeferredPipeController() {
9688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator.reset();
9788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
9888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
9988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredPipeController::setPlaybackCanvas(SkCanvas* canvas) {
10088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fReader.setCanvas(canvas);
10188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
10288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
10388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid* DeferredPipeController::requestBlock(size_t minRequest, size_t *actual) {
10488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (fBlock) {
10588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        // Save the previous block for later
10688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        PipeBlock previousBloc(fBlock, fBytesWritten);
10788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fBlockList.push(previousBloc);
10888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
10988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    int32_t blockSize = SkMax32(minRequest, kMinBlockSize);
11088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlock = fAllocator.allocThrow(blockSize);
11188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten = 0;
11288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    *actual = blockSize;
11388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fBlock;
11488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
11588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
11688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredPipeController::notifyWritten(size_t bytes) {
11788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten += bytes;
11888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
11988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
120fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.orgvoid DeferredPipeController::playback(bool silent) {
121fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0;
12288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
123fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize,
124fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                         flags);
12588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
12688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlockList.reset();
12788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
12888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (fBlock) {
129fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        fReader.playback(fBlock, fBytesWritten, flags);
13088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fBlock = NULL;
13188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
13288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
13388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Release all allocated blocks
13488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator.reset();
13588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
13688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
13788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
13888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org// DeferredDevice
13988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
14088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgclass DeferredDevice : public SkDevice {
14188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgpublic:
14267d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    explicit DeferredDevice(SkDevice* immediateDevice);
14367d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    explicit DeferredDevice(SkSurface* surface);
14488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    ~DeferredDevice();
14588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
1469ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient);
14788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* recordingCanvas();
14888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
1499becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org    SkDevice* immediateDevice() const {return fImmediateCanvas->getTopDevice();}
1505ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.org    SkImage* newImageSnapshot();
1517070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    void setSurface(SkSurface* surface);
15288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool isFreshFrame();
153a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    bool hasPendingCommands();
15488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocatedForRecording() const;
15588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t freeMemoryIfPossible(size_t bytesToFree);
1567775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    size_t getBitmapSizeThreshold() const;
1577775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    void setBitmapSizeThreshold(size_t sizeThreshold);
158eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    void flushPendingCommands(PlaybackMode);
1590a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org    void skipPendingCommands();
16088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void setMaxRecordingStorage(size_t);
1619ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    void recordedDrawCommand();
16288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
16388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
16488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual int width() const SK_OVERRIDE;
16588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual int height() const SK_OVERRIDE;
166b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.org    virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE;
16788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
16888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
16988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               int width, int height,
17088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               bool isOpaque,
17188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               Usage usage) SK_OVERRIDE;
17288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
17388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
17488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkCanvas::Config8888 config8888) SK_OVERRIDE;
17588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
17688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprotected:
17788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE;
17888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual bool onReadPixels(const SkBitmap& bitmap,
17988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int x, int y,
18088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkCanvas::Config8888 config8888) SK_OVERRIDE;
18188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
18288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // The following methods are no-ops on a deferred device
18388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*)
18488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        SK_OVERRIDE
18588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {return false;}
18688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
18788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // None of the following drawing methods should ever get called on the
18888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // deferred device
1893e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org    virtual void clear(SkColor color) SK_OVERRIDE
19088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
1913e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE
19288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
19388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
19488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            size_t count, const SkPoint[],
1953e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                            const SkPaint& paint) SK_OVERRIDE
19688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
19788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawRect(const SkDraw&, const SkRect& r,
1983e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                            const SkPaint& paint) SK_OVERRIDE
19988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
20088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPath(const SkDraw&, const SkPath& path,
20188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint& paint,
20288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkMatrix* prePathMatrix = NULL,
2033e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                            bool pathIsMutable = false) SK_OVERRIDE
20488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
20588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
2063e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                            const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE
20788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
20888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
2093e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                            int x, int y, const SkPaint& paint) SK_OVERRIDE
21088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
21188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawText(const SkDraw&, const void* text, size_t len,
2123e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                            SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE
21388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
21488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
21588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkScalar pos[], SkScalar constY,
2163e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                                int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE
21788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
21888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawTextOnPath(const SkDraw&, const void* text,
21988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                size_t len, const SkPath& path,
22088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkMatrix* matrix,
2213e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                                const SkPaint& paint) SK_OVERRIDE
22288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
2233e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID
22488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
22588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    size_t len, const SkPoint pos[],
22688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkPaint& paint,
22788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkPath& path,
2283e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                                    const SkMatrix* matrix) SK_OVERRIDE
22988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
2303e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org#endif
23188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
23288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int vertexCount, const SkPoint verts[],
23388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkPoint texs[], const SkColor colors[],
23488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkXfermode* xmode, const uint16_t indices[],
2353e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                                int indexCount, const SkPaint& paint) SK_OVERRIDE
23688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
23788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
2383e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org                            const SkPaint&) SK_OVERRIDE
23988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
24088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprivate:
2413e2ea2565d12e572a977fa04b4b1996c8eb3fefccommit-bot@chromium.org    virtual void flush() SK_OVERRIDE;
24288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
24388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void beginRecording();
24467d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    void init();
24544324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    void aboutToDraw();
24644324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    void prepareForImmediatePixelWrite();
24788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
24888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredPipeController fPipeController;
24988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkGPipeWriter  fPipeWriter;
25088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* fImmediateCanvas;
25188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* fRecordingCanvas;
25267d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    SkSurface* fSurface;
2539ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDeferredCanvas::NotificationClient* fNotificationClient;
25488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool fFreshFrame;
255c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    bool fCanDiscardCanvasContents;
25688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t fMaxRecordingStorageBytes;
2579ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    size_t fPreviousStorageAllocated;
2587775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    size_t fBitmapSizeThreshold;
25988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org};
26088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
26167d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.orgDeferredDevice::DeferredDevice(SkDevice* immediateDevice)
26267d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    : SkDevice(SkBitmap::kNo_Config,
26367d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org               immediateDevice->width(), immediateDevice->height(),
26467d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org               immediateDevice->isOpaque(),
26567d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org               immediateDevice->getDeviceProperties()) {
26667d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fSurface = NULL;
2679becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org    fImmediateCanvas = SkNEW_ARGS(SkCanvas, (immediateDevice));
2687070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    fPipeController.setPlaybackCanvas(fImmediateCanvas);
26967d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    this->init();
27067d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org}
27188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
27267d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.orgDeferredDevice::DeferredDevice(SkSurface* surface)
27367d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    : SkDevice(SkBitmap::kNo_Config,
27467d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org               surface->getCanvas()->getDevice()->width(),
27567d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org               surface->getCanvas()->getDevice()->height(),
27667d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org               surface->getCanvas()->getDevice()->isOpaque(),
27767d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org               surface->getCanvas()->getDevice()->getDeviceProperties()) {
27888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
27967d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fNotificationClient = NULL;
2807070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    fImmediateCanvas = NULL;
2817070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    fSurface = NULL;
2827070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    this->setSurface(surface);
28367d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    this->init();
28467d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org}
28567d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org
2867070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.orgvoid DeferredDevice::setSurface(SkSurface* surface) {
2877070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas());
2887070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    SkRefCnt_SafeAssign(fSurface, surface);
2897070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    fPipeController.setPlaybackCanvas(fImmediateCanvas);
2907070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org}
2917070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org
29267d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.orgvoid DeferredDevice::init() {
29367d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fRecordingCanvas = NULL;
29467d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fFreshFrame = true;
295c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    fCanDiscardCanvasContents = false;
29667d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fPreviousStorageAllocated = 0;
29767d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
29867d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
29967d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    fNotificationClient = NULL;
30088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->beginRecording();
30188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
30288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
30388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice::~DeferredDevice() {
304eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kSilent_PlaybackMode);
30588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkSafeUnref(fImmediateCanvas);
30667d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    SkSafeUnref(fSurface);
30788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
30888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
30988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
31088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fMaxRecordingStorageBytes = maxStorage;
31188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->recordingCanvas(); // Accessing the recording canvas applies the new limit.
31288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
31388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
31488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::beginRecording() {
315a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org    SkASSERT(NULL == fRecordingCanvas);
316d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
3179becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org        immediateDevice()->width(), immediateDevice()->height());
31888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
319d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3209ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid DeferredDevice::setNotificationClient(
3219ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDeferredCanvas::NotificationClient* notificationClient) {
32252805485581cff7e13134aa1465a2950f7bed007junov@chromium.org    fNotificationClient = notificationClient;
32388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
32488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
3250a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.orgvoid DeferredDevice::skipPendingCommands() {
326c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    if (!fRecordingCanvas->isDrawingToLayer()) {
327c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org        fCanDiscardCanvasContents = true;
328c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org        if (fPipeController.hasPendingCommands()) {
329c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org            fFreshFrame = true;
330c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org            flushPendingCommands(kSilent_PlaybackMode);
331c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org            if (fNotificationClient) {
332c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org                fNotificationClient->skippedPendingDrawCommands();
333c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org            }
33452a00cac514dfd9cedb85a9c3e92fdb3e32a03f7junov@google.com        }
33588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
33688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
33788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
33888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool DeferredDevice::isFreshFrame() {
33988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool ret = fFreshFrame;
34088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fFreshFrame = false;
34188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return ret;
34288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
34388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
344a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.orgbool DeferredDevice::hasPendingCommands() {
345a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    return fPipeController.hasPendingCommands();
346a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org}
347a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org
34844324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.orgvoid DeferredDevice::aboutToDraw()
34944324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org{
35044324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    if (NULL != fNotificationClient) {
35144324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        fNotificationClient->prepareForDraw();
35244324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    }
35344324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    if (fCanDiscardCanvasContents) {
35444324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        if (NULL != fSurface) {
35544324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org            fSurface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
35644324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        }
357ea4b7970b9513d5ac3786ceab33a855b0b1b8577skia.committer@gmail.com        fCanDiscardCanvasContents = false;
35844324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    }
35944324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org}
36044324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org
361eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.orgvoid DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
362a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    if (!fPipeController.hasPendingCommands()) {
36388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        return;
36488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
365c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org    if (playbackMode == kNormal_PlaybackMode) {
36644324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        aboutToDraw();
36788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
36888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fPipeWriter.flushRecording(true);
369d4501a0aba2541489c32c89426bbfc59ed945da2junov@chromium.org    fPipeController.playback(kSilent_PlaybackMode == playbackMode);
370eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
3719ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->flushedDrawCommands();
3729ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
3739ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fPreviousStorageAllocated = storageAllocatedForRecording();
37488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
37588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
37688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::flush() {
377eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
37888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fImmediateCanvas->flush();
37988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
38088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
38188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgsize_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
3829ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
3839ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fPreviousStorageAllocated = storageAllocatedForRecording();
3849ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
38588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
38688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
3877775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comsize_t DeferredDevice::getBitmapSizeThreshold() const {
3887775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    return fBitmapSizeThreshold;
3897775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
3907775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
3917775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comvoid DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) {
3927775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    fBitmapSizeThreshold = sizeThreshold;
3937775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
3947775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
39588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgsize_t DeferredDevice::storageAllocatedForRecording() const {
39688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return (fPipeController.storageAllocatedForRecording()
39788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            + fPipeWriter.storageAllocatedForRecording());
39888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
39988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
4009ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid DeferredDevice::recordedDrawCommand() {
40188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocated = this->storageAllocatedForRecording();
4029ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
40388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (storageAllocated > fMaxRecordingStorageBytes) {
40488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        // First, attempt to reduce cache without flushing
40588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
40688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        if (this->freeMemoryIfPossible(tryFree) < tryFree) {
40788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // Flush is necessary to free more space.
408eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org            this->flushPendingCommands(kNormal_PlaybackMode);
40988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
41088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // which could cause a high flushing frequency.
411100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.com            this->freeMemoryIfPossible(~0U);
41288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        }
4139ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        storageAllocated = this->storageAllocatedForRecording();
41488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
4159ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
416d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fNotificationClient &&
4179ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        storageAllocated != fPreviousStorageAllocated) {
4189ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fPreviousStorageAllocated = storageAllocated;
4199ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->storageAllocatedForRecordingChanged(storageAllocated);
4209ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
4219ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org}
4229ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
4239ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgSkCanvas* DeferredDevice::recordingCanvas() {
42488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fRecordingCanvas;
42588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
42688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
4275ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.orgSkImage* DeferredDevice::newImageSnapshot() {
42867d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    this->flush();
4295ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.org    return fSurface ? fSurface->newImageSnapshot() : NULL;
43067d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org}
43167d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org
432d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comuint32_t DeferredDevice::getDeviceCapabilities() {
4339becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org    return immediateDevice()->getDeviceCapabilities();
43488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
43588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
436d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comint DeferredDevice::width() const {
4379becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org    return immediateDevice()->width();
43888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
43988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
44088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgint DeferredDevice::height() const {
4419becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org    return immediateDevice()->height();
44288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
44388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
444b8d00db075b5ea09e353508a26ef5ced50722a6ccommit-bot@chromium.orgGrRenderTarget* DeferredDevice::accessRenderTarget() {
445eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
4469becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org    return immediateDevice()->accessRenderTarget();
44788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
44888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
44944324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.orgvoid DeferredDevice::prepareForImmediatePixelWrite() {
45044324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    // The purpose of the following code is to make sure commands are flushed, that
45144324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    // aboutToDraw() is called and that notifyContentWillChange is called, without
45244324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    // calling anything redundantly.
45344324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    if (fPipeController.hasPendingCommands()) {
45444324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        this->flushPendingCommands(kNormal_PlaybackMode);
45544324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    } else {
45644324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        bool mustNotifyDirectly = !fCanDiscardCanvasContents;
45744324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        this->aboutToDraw();
45844324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        if (mustNotifyDirectly) {
45944324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org            fSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode);
46044324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        }
46144324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    }
46244324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org
46344324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org    fImmediateCanvas->flush();
46444324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org}
46544324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org
46688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::writePixels(const SkBitmap& bitmap,
46788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    int x, int y, SkCanvas::Config8888 config8888) {
46888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
46988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() &&
47088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        (y + bitmap.height()) >= height()) {
4710a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->skipPendingCommands();
47288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
47388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
47488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
47588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        SkCanvas::kNative_Premul_Config8888 != config8888 &&
47688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        kPMColorAlias != config8888) {
47788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        //Special case config: no deferral
47844324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        prepareForImmediatePixelWrite();
4799becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org        immediateDevice()->writePixels(bitmap, x, y, config8888);
48088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        return;
48188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
48288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
48388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkPaint paint;
48488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
4857775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) {
48644324fae1c231bf262af24fc7f8a0f489ae5a490junov@chromium.org        prepareForImmediatePixelWrite();
48788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
48888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    } else {
48988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
4909ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        this->recordedDrawCommand();
4919ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
49288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
49388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
49488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
49588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgconst SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) {
496eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
4979becf0090f9c1c14f42d161b9a1fb3af142f9420junov@chromium.org    return immediateDevice()->accessBitmap(false);
49888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
49988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
50088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkDevice* DeferredDevice::onCreateCompatibleDevice(
50188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkBitmap::Config config, int width, int height, bool isOpaque,
50288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    Usage usage) {
50388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
50488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Save layer usage not supported, and not required by SkDeferredCanvas.
50588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkASSERT(usage != kSaveLayer_Usage);
50688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Create a compatible non-deferred device.
507b1c725a108f57ac186542b43de80fa651a4dddbajunov@chromium.org    // We do not create a deferred device because we know the new device
508b1c725a108f57ac186542b43de80fa651a4dddbajunov@chromium.org    // will not be used with a deferred canvas (there is no API for that).
509b1c725a108f57ac186542b43de80fa651a4dddbajunov@chromium.org    // And connecting a DeferredDevice to non-deferred canvas can result
510b1c725a108f57ac186542b43de80fa651a4dddbajunov@chromium.org    // in unpredictable behavior.
511b1c725a108f57ac186542b43de80fa651a4dddbajunov@chromium.org    return immediateDevice()->createCompatibleDevice(config, width, height, isOpaque);
51288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
51388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
51488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool DeferredDevice::onReadPixels(
51588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
516eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
51788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
51888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                                   x, y, config8888);
51988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
52088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
5217775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comclass AutoImmediateDrawIfNeeded {
5227775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.compublic:
5237775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
5247775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com                              const SkPaint* paint) {
5257775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        this->init(canvas, bitmap, paint);
5267775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5277775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5287775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
5297775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        this->init(canvas, NULL, paint);
5307775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5317775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5327775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    ~AutoImmediateDrawIfNeeded() {
5337775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        if (fCanvas) {
5347775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas->setDeferredDrawing(true);
5357775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        }
5367775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5377775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comprivate:
5387775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint)
5397775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    {
5407775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        DeferredDevice* device = static_cast<DeferredDevice*>(canvas.getDevice());
5417775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        if (canvas.isDeferredDrawing() && (NULL != device) &&
5427775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) {
5437775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            canvas.setDeferredDrawing(false);
5447775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas = &canvas;
5457775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        } else {
5467775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas = NULL;
5477775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        }
5487775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5497775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5507775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    SkDeferredCanvas* fCanvas;
5517775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com};
55288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
55366070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.orgSkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) {
55466070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    SkAutoTUnref<DeferredDevice> deferredDevice(SkNEW_ARGS(DeferredDevice, (surface)));
55566070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
55666070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org}
55766070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org
55866070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.orgSkDeferredCanvas* SkDeferredCanvas::Create(SkDevice* device) {
55966070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    SkAutoTUnref<DeferredDevice> deferredDevice(SkNEW_ARGS(DeferredDevice, (device)));
56066070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice));
56166070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org}
56266070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org
56366070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.orgSkDeferredCanvas::SkDeferredCanvas(DeferredDevice* device) : SkCanvas (device) {
56466070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    this->init();
56566070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org}
56667d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org
567c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::init() {
5685e5a095a94281167056da707b03930f135748d71junov@chromium.org    fDeferredDrawing = true; // On by default
5694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
571bfeddae9da240693441556b2f278827e213f75e8junov@chromium.orgvoid SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
5729060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate();
573bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
574bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org}
575bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org
5762e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkDeferredCanvas::storageAllocatedForRecording() const {
5772e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    return this->getDeferredDevice()->storageAllocatedForRecording();
5782e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
5792e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
5802e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
5812e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
5822e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
5832e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
5847775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comvoid SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
5857775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    DeferredDevice* deferredDevice = this->getDeferredDevice();
5867775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    SkASSERT(deferredDevice);
5877775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    deferredDevice->setBitmapSizeThreshold(sizeThreshold);
5887775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
5897775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5909ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid SkDeferredCanvas::recordedDrawCommand() {
5919ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    if (fDeferredDrawing) {
5929ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        this->getDeferredDevice()->recordedDrawCommand();
5939ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
5949ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org}
5959ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
596c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::validate() const {
5979060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkASSERT(this->getDevice());
5984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6005e5a095a94281167056da707b03930f135748d71junov@chromium.orgSkCanvas* SkDeferredCanvas::drawingCanvas() const {
6019060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate();
6029060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
6039060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->getDeferredDevice()->immediateCanvas();
6045e5a095a94281167056da707b03930f135748d71junov@chromium.org}
6055e5a095a94281167056da707b03930f135748d71junov@chromium.org
60688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkCanvas* SkDeferredCanvas::immediateCanvas() const {
60788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->validate();
60888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return this->getDeferredDevice()->immediateCanvas();
60988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
61088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
61188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
61288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return static_cast<DeferredDevice*>(this->getDevice());
6134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
615c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setDeferredDrawing(bool val) {
6169060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate(); // Must set device before calling this method
6174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (val != fDeferredDrawing) {
6184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (fDeferredDrawing) {
6195e5a095a94281167056da707b03930f135748d71junov@chromium.org            // Going live.
620eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org            this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode);
6214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6224370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        fDeferredDrawing = val;
6234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
6244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
62688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool SkDeferredCanvas::isDeferredDrawing() const {
627b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org    return fDeferredDrawing;
628b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
629b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org
63088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool SkDeferredCanvas::isFreshFrame() const {
63188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return this->getDeferredDevice()->isFreshFrame();
63288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
63388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
634a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.orgbool SkDeferredCanvas::hasPendingCommands() const {
635a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    return this->getDeferredDevice()->hasPendingCommands();
636a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org}
637a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org
638fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.orgvoid SkDeferredCanvas::silentFlush() {
639fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    if (fDeferredDrawing) {
640eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
641fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    }
642fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org}
643fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
644c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::~SkDeferredCanvas() {
6454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6477070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.orgSkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) {
6487070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    DeferredDevice* deferredDevice = this->getDeferredDevice();
64966070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    SkASSERT(NULL != deferredDevice);
65066070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    // By swapping the surface into the existing device, we preserve
65166070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    // all pending commands, which can help to seamlessly recover from
65266070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    // a lost accelerated graphics context.
65366070a527c480d1cef5f7f7136f68d4f17b68f06junov@chromium.org    deferredDevice->setSurface(surface);
6547070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org    return surface;
6557070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org}
6567070f76b90b098b4713bc0d13dc129adea64d7efjunov@chromium.org
6579ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgSkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient(
6589ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    NotificationClient* notificationClient) {
659c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org
6609060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    DeferredDevice* deferredDevice = this->getDeferredDevice();
6614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    SkASSERT(deferredDevice);
6624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (deferredDevice) {
6639ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        deferredDevice->setNotificationClient(notificationClient);
6644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
6659ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return notificationClient;
6664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6685ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.orgSkImage* SkDeferredCanvas::newImageSnapshot() {
66967d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    DeferredDevice* deferredDevice = this->getDeferredDevice();
67067d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org    SkASSERT(deferredDevice);
6715ee449af7448c202cfc6e9a359d8f996392885b2junov@chromium.org    return deferredDevice ? deferredDevice->newImageSnapshot() : NULL;
67267d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org}
67367d74228448cab0f1eca77fff444ddbe8c2eaef3junov@chromium.org
6744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::isFullFrame(const SkRect* rect,
675c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                   const SkPaint* paint) const {
6769060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkCanvas* canvas = this->drawingCanvas();
6779060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkISize canvasSize = this->getDeviceSize();
6784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (rect) {
6794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (!canvas->getTotalMatrix().rectStaysRect()) {
6804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return false; // conservative
6814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        SkRect transformedRect;
6844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        canvas->getTotalMatrix().mapRect(&transformedRect, *rect);
6854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (paint) {
6874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            SkPaint::Style paintStyle = paint->getStyle();
688d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (!(paintStyle == SkPaint::kFill_Style ||
6894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                paintStyle == SkPaint::kStrokeAndFill_Style)) {
6904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                return false;
6914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
6924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            if (paint->getMaskFilter() || paint->getLooper()
6934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                || paint->getPathEffect() || paint->getImageFilter()) {
6944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                return false; // conservative
6954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
6964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        // The following test holds with AA enabled, and is conservative
6994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        // by a 0.5 pixel margin with AA disabled
700d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (transformedRect.fLeft > SkIntToScalar(0) ||
701d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            transformedRect.fTop > SkIntToScalar(0) ||
702b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org            transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) ||
703b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org            transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) {
7044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return false;
7054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
7064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
7074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7088f0ca06ef44f7b94da549fbb0c5fab27092c5116junov@chromium.org    return this->getClipStack()->quickContains(SkRect::MakeXYWH(0, 0,
7098f0ca06ef44f7b94da549fbb0c5fab27092c5116junov@chromium.org        SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight)));
7104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
712c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgint SkDeferredCanvas::save(SaveFlags flags) {
7139060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->save(flags);
7149ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    int val = this->INHERITED::save(flags);
7159ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7169ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
7179ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comint SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
721c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                SaveFlags flags) {
7229060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->saveLayer(bounds, paint, flags);
723a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    int count = this->INHERITED::save(flags);
724a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->clipRectBounds(bounds, flags, NULL);
7259ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7269ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
727a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    return count;
7284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
730c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::restore() {
7319060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->restore();
732a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->INHERITED::restore();
7339ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
736c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::isDrawingToLayer() const {
7379060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return this->drawingCanvas()->isDrawingToLayer();
7384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
740c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) {
7419060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->translate(dx, dy);
7429ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::translate(dx, dy);
7439ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7449ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
747c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) {
7489060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->scale(sx, sy);
7499ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::scale(sx, sy);
7509ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7519ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7524370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
754c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::rotate(SkScalar degrees) {
7559060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->rotate(degrees);
7569ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::rotate(degrees);
7579ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7589ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
761c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) {
7629060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->skew(sx, sy);
7639ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::skew(sx, sy);
7649ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7659ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
768c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::concat(const SkMatrix& matrix) {
7699060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->concat(matrix);
7709ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::concat(matrix);
7719ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7729ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
775c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setMatrix(const SkMatrix& matrix) {
7769060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->setMatrix(matrix);
777a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->INHERITED::setMatrix(matrix);
7789ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRect(const SkRect& rect,
7824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                SkRegion::Op op,
783c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                bool doAntiAlias) {
7849060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipRect(rect, op, doAntiAlias);
7859ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipRect(rect, op, doAntiAlias);
7869ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7879ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.combool SkDeferredCanvas::clipRRect(const SkRRect& rrect,
7914ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                                 SkRegion::Op op,
7924ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                                 bool doAntiAlias) {
7934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias);
7944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias);
7954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->recordedDrawCommand();
7964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    return val;
7974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
7984ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
7994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipPath(const SkPath& path,
8004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                SkRegion::Op op,
801c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                bool doAntiAlias) {
8029060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipPath(path, op, doAntiAlias);
8039ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipPath(path, op, doAntiAlias);
8049ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8059ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
8064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn,
809c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  SkRegion::Op op) {
8109060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipRegion(deviceRgn, op);
8119ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipRegion(deviceRgn, op);
8129ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8139ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
8144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
816c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::clear(SkColor color) {
8174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // purge pending commands
8184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (fDeferredDrawing) {
8190a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8229060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clear(color);
8239ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
826c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPaint(const SkPaint& paint) {
827d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing && this->isFullFrame(NULL, &paint) &&
828c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org        isPaintOpaque(&paint)) {
8290a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
83110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8329060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPaint(paint);
8339ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8364370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPoints(PointMode mode, size_t count,
837c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  const SkPoint pts[], const SkPaint& paint) {
83810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8399060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPoints(mode, count, pts, paint);
8409ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkDeferredCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
8444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8454ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->drawingCanvas()->drawOval(rect, paint);
8464ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->recordedDrawCommand();
8474ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
8484ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
849c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
850d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing && this->isFullFrame(&rect, &paint) &&
851c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org        isPaintOpaque(&paint)) {
8520a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
854306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com
85510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8569060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawRect(rect, paint);
8579ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
8614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    if (rrect.isRect()) {
8624ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
8634ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    } else if (rrect.isOval()) {
8644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
8654ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    } else {
8664ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8674ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->drawingCanvas()->drawRRect(rrect, paint);
8684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->recordedDrawCommand();
8694ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    }
8704ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
8714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
872c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
87310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8749060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPath(path, paint);
8759ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
879c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  SkScalar top, const SkPaint* paint) {
8808f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org    SkRect bitmapRect = SkRect::MakeXYWH(left, top,
8818f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
882d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
8839060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&bitmapRect, paint) &&
88487f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
8850a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
88810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
8899060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmap(bitmap, left, top, paint);
8909ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8937112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkDeferredCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
8947112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkRect* src,
8957112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkRect& dst,
896eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org                                            const SkPaint* paint,
897eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org                                            DrawBitmapRectFlags flags) {
898d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
8999060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&dst, paint) &&
90087f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
9010a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
9024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
9034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
90410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
905eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org    this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
9069ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9094370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
9114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                        const SkMatrix& m,
912c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                        const SkPaint* paint) {
9134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
9144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // covers canvas entirely and transformed bitmap covers canvas entirely
91510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
9169060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmapMatrix(bitmap, m, paint);
9179ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap,
9214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkIRect& center, const SkRect& dst,
922c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                      const SkPaint* paint) {
9234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
9244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // covers canvas entirely and dst covers canvas entirely
92510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
9269060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint);
9279ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
931c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  const SkPaint* paint) {
9328f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org    SkRect bitmapRect = SkRect::MakeXYWH(
9338f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(left),
934d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkIntToScalar(top),
9358f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.width()),
9368f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.height()));
937d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
9389060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&bitmapRect, paint) &&
93987f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
9400a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
9414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
9424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
94310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
9449060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawSprite(bitmap, left, top, paint);
9459ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawText(const void* text, size_t byteLength,
949c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                SkScalar x, SkScalar y, const SkPaint& paint) {
95010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9519060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawText(text, byteLength, x, y, paint);
9529ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosText(const void* text, size_t byteLength,
956c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                   const SkPoint pos[], const SkPaint& paint) {
95710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9589060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPosText(text, byteLength, pos, paint);
9599ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength,
9634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkScalar xpos[], SkScalar constY,
964c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                    const SkPaint& paint) {
96510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9669060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint);
9679ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawTextOnPath(const void* text, size_t byteLength,
9714370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkPath& path,
9724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkMatrix* matrix,
973c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                      const SkPaint& paint) {
97410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9759060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawTextOnPath(text, byteLength, path, matrix, paint);
9769ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
979c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPicture(SkPicture& picture) {
9809060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPicture(picture);
9819ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount,
9854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkPoint vertices[],
9864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkPoint texs[],
9874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkColor colors[], SkXfermode* xmode,
9884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const uint16_t indices[], int indexCount,
989c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                    const SkPaint& paint) {
99010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9919060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode,
9929060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org                                        indices, indexCount, paint);
9939ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
996c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder) {
9979060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->setBounder(bounder);
9989ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->INHERITED::setBounder(bounder);
9999ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
10009ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return bounder;
10014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
10024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
1003c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
1004d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->drawingCanvas()->setDrawFilter(filter);
10059ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->INHERITED::setDrawFilter(filter);
10069ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
1007d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return filter;
10084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
10094370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
10104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkDeferredCanvas::canvasForDrawIter() {
10119060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return this->drawingCanvas();
10124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
1013