SkDeferredCanvas.cpp revision baa0220dfddda3cd44f0ffb5f95a4a60443eb8c3
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"
204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
21bfeddae9da240693441556b2f278827e213f75e8junov@chromium.orgenum {
22bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    // Deferred canvas will auto-flush when recording reaches this limit
23bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    kDefaultMaxRecordingStorageBytes = 64*1024*1024,
24140d7286c5a40058932696eaa28818c313bd2ddfreed@google.com    kDeferredCanvasBitmapSizeThreshold = ~0U, // Disables this feature
25bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org};
26bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org
27eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.orgenum PlaybackMode {
28eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    kNormal_PlaybackMode,
29eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    kSilent_PlaybackMode,
30eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org};
31eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org
324370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comnamespace {
337775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.combool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
347775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com                           size_t bitmapSizeThreshold) {
357775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
367775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        (bitmap->getSize() > bitmapSizeThreshold))) {
3710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        return true;
3810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    }
3910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    if (paint) {
4010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        SkShader* shader = paint->getShader();
4110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // Here we detect the case where the shader is an SkBitmapProcShader
4210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // with a gpu texture attached.  Checking this without RTTI
4310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // requires making the assumption that only gradient shaders
4410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // and SkBitmapProcShader implement asABitmap().  The following
4510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // code may need to be revised if that assumption is ever broken.
4610f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        if (shader && !shader->asAGradient(NULL)) {
4710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org            SkBitmap bm;
48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (shader->asABitmap(&bm, NULL, NULL) &&
4910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org                NULL != bm.getTexture()) {
5010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org                return true;
5110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org            }
5210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        }
5310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    }
5410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    return false;
55b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
56b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
57b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org
5888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
5988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org// DeferredPipeController
6088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
6188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
6288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgclass DeferredPipeController : public SkGPipeController {
6388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgpublic:
6488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredPipeController();
6588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void setPlaybackCanvas(SkCanvas*);
6688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual ~DeferredPipeController();
6788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
6888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
69fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    void playback(bool silent);
70a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    bool hasPendingCommands() const { return fAllocator.blockCount() != 0; }
7188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); }
7288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprivate:
7388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    enum {
7488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        kMinBlockSize = 4096
7588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    };
7688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    struct PipeBlock {
7788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        PipeBlock(void* block, size_t size) { fBlock = block, fSize = size; }
7888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        void* fBlock;
7988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        size_t fSize;
8088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    };
8188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void* fBlock;
8288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t fBytesWritten;
8388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkChunkAlloc fAllocator;
8488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkTDArray<PipeBlock> fBlockList;
8588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkGPipeReader fReader;
8688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org};
8788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
8888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredPipeController::DeferredPipeController() :
8988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator(kMinBlockSize) {
9088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlock = NULL;
9188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten = 0;
9288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
9388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
9488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredPipeController::~DeferredPipeController() {
9588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator.reset();
9688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
9788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
9888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredPipeController::setPlaybackCanvas(SkCanvas* canvas) {
9988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fReader.setCanvas(canvas);
10088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
10188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
10288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid* DeferredPipeController::requestBlock(size_t minRequest, size_t *actual) {
10388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (fBlock) {
10488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        // Save the previous block for later
10588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        PipeBlock previousBloc(fBlock, fBytesWritten);
10688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fBlockList.push(previousBloc);
10788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
10888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    int32_t blockSize = SkMax32(minRequest, kMinBlockSize);
10988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlock = fAllocator.allocThrow(blockSize);
11088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten = 0;
11188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    *actual = blockSize;
11288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fBlock;
11388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
11488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
11588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredPipeController::notifyWritten(size_t bytes) {
11688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten += bytes;
11788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
11888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
119fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.orgvoid DeferredPipeController::playback(bool silent) {
120fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0;
12188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
122fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize,
123fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                         flags);
12488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
12588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlockList.reset();
12688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
12788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (fBlock) {
128fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        fReader.playback(fBlock, fBytesWritten, flags);
12988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fBlock = NULL;
13088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
13188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
13288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Release all allocated blocks
13388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator.reset();
13488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
13588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
13688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
13788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org// DeferredDevice
13888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
13988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgclass DeferredDevice : public SkDevice {
14088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgpublic:
14188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredDevice(SkDevice* immediateDevice,
1429ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        SkDeferredCanvas::NotificationClient* notificationClient = NULL);
14388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    ~DeferredDevice();
14488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
1459ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient);
14688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* recordingCanvas();
14788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
14888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkDevice* immediateDevice() const {return fImmediateDevice;}
14988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool isFreshFrame();
150a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    bool hasPendingCommands();
15188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocatedForRecording() const;
15288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t freeMemoryIfPossible(size_t bytesToFree);
1537775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    size_t getBitmapSizeThreshold() const;
1547775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    void setBitmapSizeThreshold(size_t sizeThreshold);
155eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    void flushPendingCommands(PlaybackMode);
1560a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org    void skipPendingCommands();
15788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void setMaxRecordingStorage(size_t);
1589ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    void recordedDrawCommand();
15988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
16088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
16188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual int width() const SK_OVERRIDE;
16288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual int height() const SK_OVERRIDE;
16388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
16488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
16588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
16688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               int width, int height,
16788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               bool isOpaque,
16888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               Usage usage) SK_OVERRIDE;
16988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
17088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
17188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkCanvas::Config8888 config8888) SK_OVERRIDE;
17288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
17388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprotected:
17488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE;
17588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual bool onReadPixels(const SkBitmap& bitmap,
17688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int x, int y,
17788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkCanvas::Config8888 config8888) SK_OVERRIDE;
17888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
17988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // The following methods are no-ops on a deferred device
18088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*)
18188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        SK_OVERRIDE
18288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {return false;}
18388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
18488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // None of the following drawing methods should ever get called on the
18588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // deferred device
18688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void clear(SkColor color)
18788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
18888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPaint(const SkDraw&, const SkPaint& paint)
18988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
19088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
19188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            size_t count, const SkPoint[],
19288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint& paint)
19388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
19488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawRect(const SkDraw&, const SkRect& r,
19588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint& paint)
19688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
19788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPath(const SkDraw&, const SkPath& path,
19888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint& paint,
19988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkMatrix* prePathMatrix = NULL,
20088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            bool pathIsMutable = false)
20188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
20288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
20388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkIRect* srcRectOrNull,
20488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkMatrix& matrix, const SkPaint& paint)
20588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
20688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
20788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            int x, int y, const SkPaint& paint)
20888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
20988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawText(const SkDraw&, const void* text, size_t len,
21088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            SkScalar x, SkScalar y, const SkPaint& paint)
21188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
21288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
21388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkScalar pos[], SkScalar constY,
21488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int scalarsPerPos, const SkPaint& paint)
21588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
21688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawTextOnPath(const SkDraw&, const void* text,
21788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                size_t len, const SkPath& path,
21888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkMatrix* matrix,
21988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkPaint& paint)
22088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
22188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
22288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    size_t len, const SkPoint pos[],
22388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkPaint& paint,
22488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkPath& path,
22588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkMatrix* matrix)
22688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
22788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
22888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int vertexCount, const SkPoint verts[],
22988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkPoint texs[], const SkColor colors[],
23088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkXfermode* xmode, const uint16_t indices[],
23188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int indexCount, const SkPaint& paint)
23288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
23388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
23488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint&)
23588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
23688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprivate:
23788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void flush();
23888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
23988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void beginRecording();
24088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
24188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredPipeController fPipeController;
24288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkGPipeWriter  fPipeWriter;
24388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkDevice* fImmediateDevice;
24488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* fImmediateCanvas;
24588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* fRecordingCanvas;
2469ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDeferredCanvas::NotificationClient* fNotificationClient;
24788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool fFreshFrame;
24888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t fMaxRecordingStorageBytes;
2499ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    size_t fPreviousStorageAllocated;
2507775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    size_t fBitmapSizeThreshold;
25188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org};
25288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
25388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice::DeferredDevice(
2549ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDevice* immediateDevice, SkDeferredCanvas::NotificationClient* notificationClient) :
255532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    SkDevice(SkBitmap::kNo_Config,
256532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com             immediateDevice->width(), immediateDevice->height(),
257532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com             immediateDevice->isOpaque(),
258532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com             immediateDevice->getDeviceProperties())
259a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org    , fRecordingCanvas(NULL)
2609ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    , fFreshFrame(true)
2617775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    , fPreviousStorageAllocated(0)
2625347de16116e7b8aaa7d06696fbaa37ffc08899csugoi@google.com    , fBitmapSizeThreshold(kDeferredCanvasBitmapSizeThreshold){
26388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
26488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
2659ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fNotificationClient = notificationClient;
26688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas
26788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice));
26888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fPipeController.setPlaybackCanvas(fImmediateCanvas);
26988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->beginRecording();
27088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
27188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
27288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice::~DeferredDevice() {
273eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kSilent_PlaybackMode);
27488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkSafeUnref(fImmediateCanvas);
27588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
27688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
27788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
27888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fMaxRecordingStorageBytes = maxStorage;
27988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->recordingCanvas(); // Accessing the recording canvas applies the new limit.
28088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
28188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
28288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::beginRecording() {
283a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org    SkASSERT(NULL == fRecordingCanvas);
284d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
285a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org        fImmediateDevice->width(), fImmediateDevice->height());
28688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
287d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2889ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid DeferredDevice::setNotificationClient(
2899ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDeferredCanvas::NotificationClient* notificationClient) {
29052805485581cff7e13134aa1465a2950f7bed007junov@chromium.org    fNotificationClient = notificationClient;
29188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
29288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
2930a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.orgvoid DeferredDevice::skipPendingCommands() {
294a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasPendingCommands()) {
29588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fFreshFrame = true;
296eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        flushPendingCommands(kSilent_PlaybackMode);
29752a00cac514dfd9cedb85a9c3e92fdb3e32a03f7junov@google.com        if (fNotificationClient) {
29852a00cac514dfd9cedb85a9c3e92fdb3e32a03f7junov@google.com            fNotificationClient->skippedPendingDrawCommands();
29952a00cac514dfd9cedb85a9c3e92fdb3e32a03f7junov@google.com        }
30088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
30188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
30288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
30388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool DeferredDevice::isFreshFrame() {
30488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool ret = fFreshFrame;
30588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fFreshFrame = false;
30688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return ret;
30788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
30888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
309a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.orgbool DeferredDevice::hasPendingCommands() {
310a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    return fPipeController.hasPendingCommands();
311a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org}
312a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org
313eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.orgvoid DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
314a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    if (!fPipeController.hasPendingCommands()) {
31588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        return;
31688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
317eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
3189ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->prepareForDraw();
31988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
32088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fPipeWriter.flushRecording(true);
321d4501a0aba2541489c32c89426bbfc59ed945da2junov@chromium.org    fPipeController.playback(kSilent_PlaybackMode == playbackMode);
322eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
3239ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->flushedDrawCommands();
3249ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
3259ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fPreviousStorageAllocated = storageAllocatedForRecording();
32688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
32788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
32888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::flush() {
329eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
33088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fImmediateCanvas->flush();
33188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
33288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
33388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgsize_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
3349ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
3359ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fPreviousStorageAllocated = storageAllocatedForRecording();
3369ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
33788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
33888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
3397775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comsize_t DeferredDevice::getBitmapSizeThreshold() const {
3407775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    return fBitmapSizeThreshold;
3417775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
3427775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
3437775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comvoid DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) {
3447775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    fBitmapSizeThreshold = sizeThreshold;
3457775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
3467775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
34788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgsize_t DeferredDevice::storageAllocatedForRecording() const {
34888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return (fPipeController.storageAllocatedForRecording()
34988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            + fPipeWriter.storageAllocatedForRecording());
35088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
35188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
3529ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid DeferredDevice::recordedDrawCommand() {
35388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocated = this->storageAllocatedForRecording();
3549ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
35588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (storageAllocated > fMaxRecordingStorageBytes) {
35688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        // First, attempt to reduce cache without flushing
35788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
35888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        if (this->freeMemoryIfPossible(tryFree) < tryFree) {
35988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // Flush is necessary to free more space.
360eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org            this->flushPendingCommands(kNormal_PlaybackMode);
36188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
36288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // which could cause a high flushing frequency.
363100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.com            this->freeMemoryIfPossible(~0U);
36488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        }
3659ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        storageAllocated = this->storageAllocatedForRecording();
36688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
3679ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
368d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fNotificationClient &&
3699ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        storageAllocated != fPreviousStorageAllocated) {
3709ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fPreviousStorageAllocated = storageAllocated;
3719ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->storageAllocatedForRecordingChanged(storageAllocated);
3729ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
3739ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org}
3749ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
3759ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgSkCanvas* DeferredDevice::recordingCanvas() {
37688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fRecordingCanvas;
37788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
37888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
379d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comuint32_t DeferredDevice::getDeviceCapabilities() {
38088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->getDeviceCapabilities();
38188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
38288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
383d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comint DeferredDevice::width() const {
38488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->width();
38588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
38688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
38788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgint DeferredDevice::height() const {
388d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return fImmediateDevice->height();
38988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
39088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
39188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkGpuRenderTarget* DeferredDevice::accessRenderTarget() {
392eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
39388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->accessRenderTarget();
39488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
39588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
39688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::writePixels(const SkBitmap& bitmap,
39788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    int x, int y, SkCanvas::Config8888 config8888) {
39888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
39988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() &&
40088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        (y + bitmap.height()) >= height()) {
4010a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->skipPendingCommands();
40288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
40388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
40488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
40588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        SkCanvas::kNative_Premul_Config8888 != config8888 &&
40688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        kPMColorAlias != config8888) {
40788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        //Special case config: no deferral
408eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        this->flushPendingCommands(kNormal_PlaybackMode);
40988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fImmediateDevice->writePixels(bitmap, x, y, config8888);
41088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        return;
41188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
41288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
41388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkPaint paint;
41488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
4157775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) {
416eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        this->flushPendingCommands(kNormal_PlaybackMode);
41788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
41888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    } else {
41988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
4209ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        this->recordedDrawCommand();
4219ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
42288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
42388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
42488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
42588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgconst SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) {
426eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
42788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->accessBitmap(false);
42888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
42988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
43088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkDevice* DeferredDevice::onCreateCompatibleDevice(
43188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkBitmap::Config config, int width, int height, bool isOpaque,
43288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    Usage usage) {
43388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
43488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Save layer usage not supported, and not required by SkDeferredCanvas.
43588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkASSERT(usage != kSaveLayer_Usage);
43688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Create a compatible non-deferred device.
43788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkAutoTUnref<SkDevice> compatibleDevice
43888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        (fImmediateDevice->createCompatibleDevice(config, width, height,
43988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            isOpaque));
4409ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return SkNEW_ARGS(DeferredDevice, (compatibleDevice, fNotificationClient));
44188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
44288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
44388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool DeferredDevice::onReadPixels(
44488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
445eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
44688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
44788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                                   x, y, config8888);
44888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
44988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
4507775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comclass AutoImmediateDrawIfNeeded {
4517775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.compublic:
4527775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
4537775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com                              const SkPaint* paint) {
4547775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        this->init(canvas, bitmap, paint);
4557775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
4567775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
4577775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
4587775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        this->init(canvas, NULL, paint);
4597775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
4607775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
4617775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    ~AutoImmediateDrawIfNeeded() {
4627775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        if (fCanvas) {
4637775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas->setDeferredDrawing(true);
4647775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        }
4657775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
4667775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comprivate:
4677775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint)
4687775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    {
4697775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        DeferredDevice* device = static_cast<DeferredDevice*>(canvas.getDevice());
4707775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        if (canvas.isDeferredDrawing() && (NULL != device) &&
4717775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) {
4727775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            canvas.setDeferredDrawing(false);
4737775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas = &canvas;
4747775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        } else {
4757775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas = NULL;
4767775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        }
4777775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
4787775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
4797775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    SkDeferredCanvas* fCanvas;
4807775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com};
48188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
482c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::SkDeferredCanvas() {
4839060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->init();
4844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
4854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
486c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::SkDeferredCanvas(SkDevice* device) {
4879060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->init();
4889060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->setDevice(device);
4894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
4904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
491c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::init() {
4925e5a095a94281167056da707b03930f135748d71junov@chromium.org    fDeferredDrawing = true; // On by default
4934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
4944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
495bfeddae9da240693441556b2f278827e213f75e8junov@chromium.orgvoid SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
4969060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate();
497bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
498bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org}
499bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org
5002e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkDeferredCanvas::storageAllocatedForRecording() const {
5012e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    return this->getDeferredDevice()->storageAllocatedForRecording();
5022e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
5032e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
5042e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
5052e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
5062e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
5072e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
5087775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comvoid SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
5097775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    DeferredDevice* deferredDevice = this->getDeferredDevice();
5107775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    SkASSERT(deferredDevice);
5117775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    deferredDevice->setBitmapSizeThreshold(sizeThreshold);
5127775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
5137775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5149ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid SkDeferredCanvas::recordedDrawCommand() {
5159ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    if (fDeferredDrawing) {
5169ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        this->getDeferredDevice()->recordedDrawCommand();
5179ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
5189ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org}
5199ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
520c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::validate() const {
5219060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkASSERT(this->getDevice());
5224370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
5245e5a095a94281167056da707b03930f135748d71junov@chromium.orgSkCanvas* SkDeferredCanvas::drawingCanvas() const {
5259060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate();
5269060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
5279060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->getDeferredDevice()->immediateCanvas();
5285e5a095a94281167056da707b03930f135748d71junov@chromium.org}
5295e5a095a94281167056da707b03930f135748d71junov@chromium.org
53088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkCanvas* SkDeferredCanvas::immediateCanvas() const {
53188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->validate();
53288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return this->getDeferredDevice()->immediateCanvas();
53388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
53488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
53588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
53688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return static_cast<DeferredDevice*>(this->getDevice());
5374370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
539c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setDeferredDrawing(bool val) {
5409060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate(); // Must set device before calling this method
5414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (val != fDeferredDrawing) {
5424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (fDeferredDrawing) {
5435e5a095a94281167056da707b03930f135748d71junov@chromium.org            // Going live.
544eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org            this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode);
5454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
5464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        fDeferredDrawing = val;
5474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
5484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
55088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool SkDeferredCanvas::isDeferredDrawing() const {
551b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org    return fDeferredDrawing;
552b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
553b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org
55488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool SkDeferredCanvas::isFreshFrame() const {
55588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return this->getDeferredDevice()->isFreshFrame();
55688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
55788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
558a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.orgbool SkDeferredCanvas::hasPendingCommands() const {
559a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    return this->getDeferredDevice()->hasPendingCommands();
560a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org}
561a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org
562fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.orgvoid SkDeferredCanvas::silentFlush() {
563fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    if (fDeferredDrawing) {
564eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
565fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    }
566fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org}
567fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
568c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::~SkDeferredCanvas() {
5694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
571c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDevice* SkDeferredCanvas::setDevice(SkDevice* device) {
5729060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (device)))->unref();
5734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    return device;
5744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
5769ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgSkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient(
5779ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    NotificationClient* notificationClient) {
578c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org
5799060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    DeferredDevice* deferredDevice = this->getDeferredDevice();
5804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    SkASSERT(deferredDevice);
5814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (deferredDevice) {
5829ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        deferredDevice->setNotificationClient(notificationClient);
5834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
5849ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return notificationClient;
5854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
5874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::isFullFrame(const SkRect* rect,
588c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                   const SkPaint* paint) const {
5899060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkCanvas* canvas = this->drawingCanvas();
5909060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkISize canvasSize = this->getDeviceSize();
5914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (rect) {
5924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (!canvas->getTotalMatrix().rectStaysRect()) {
5934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return false; // conservative
5944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
5954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
5964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        SkRect transformedRect;
5974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        canvas->getTotalMatrix().mapRect(&transformedRect, *rect);
5984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
5994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (paint) {
6004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            SkPaint::Style paintStyle = paint->getStyle();
601d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (!(paintStyle == SkPaint::kFill_Style ||
6024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                paintStyle == SkPaint::kStrokeAndFill_Style)) {
6034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                return false;
6044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
6054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            if (paint->getMaskFilter() || paint->getLooper()
6064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                || paint->getPathEffect() || paint->getImageFilter()) {
6074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                return false; // conservative
6084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
6094370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        // The following test holds with AA enabled, and is conservative
6124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        // by a 0.5 pixel margin with AA disabled
613d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (transformedRect.fLeft > SkIntToScalar(0) ||
614d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            transformedRect.fTop > SkIntToScalar(0) ||
615b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org            transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) ||
616b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org            transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) {
6174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return false;
6184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
6204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6218f0ca06ef44f7b94da549fbb0c5fab27092c5116junov@chromium.org    return this->getClipStack()->quickContains(SkRect::MakeXYWH(0, 0,
6228f0ca06ef44f7b94da549fbb0c5fab27092c5116junov@chromium.org        SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight)));
6234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
625c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgint SkDeferredCanvas::save(SaveFlags flags) {
6269060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->save(flags);
6279ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    int val = this->INHERITED::save(flags);
6289ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6299ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
6309ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
6314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6324370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comint SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
634c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                SaveFlags flags) {
6359060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->saveLayer(bounds, paint, flags);
636a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    int count = this->INHERITED::save(flags);
637a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->clipRectBounds(bounds, flags, NULL);
6389ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6399ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
640a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    return count;
6414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
643c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::restore() {
6449060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->restore();
645a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->INHERITED::restore();
6469ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
649c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::isDrawingToLayer() const {
6509060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return this->drawingCanvas()->isDrawingToLayer();
6514370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6524370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
653c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) {
6549060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->translate(dx, dy);
6559ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::translate(dx, dy);
6569ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6579ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
6584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
660c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) {
6619060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->scale(sx, sy);
6629ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::scale(sx, sy);
6639ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6649ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
6654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
667c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::rotate(SkScalar degrees) {
6689060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->rotate(degrees);
6699ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::rotate(degrees);
6709ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6719ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
6724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
674c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) {
6759060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->skew(sx, sy);
6769ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::skew(sx, sy);
6779ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6789ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
6794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
681c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::concat(const SkMatrix& matrix) {
6829060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->concat(matrix);
6839ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::concat(matrix);
6849ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6859ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
6864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
688c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setMatrix(const SkMatrix& matrix) {
6899060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->setMatrix(matrix);
690a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->INHERITED::setMatrix(matrix);
6919ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
6924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRect(const SkRect& rect,
6954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                SkRegion::Op op,
696c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                bool doAntiAlias) {
6979060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipRect(rect, op, doAntiAlias);
6989ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipRect(rect, op, doAntiAlias);
6999ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7009ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7034ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.combool SkDeferredCanvas::clipRRect(const SkRRect& rrect,
7044ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                                 SkRegion::Op op,
7054ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                                 bool doAntiAlias) {
7064ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias);
7074ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias);
7084ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->recordedDrawCommand();
7094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    return val;
7104ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
7114ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
7124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipPath(const SkPath& path,
7134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                SkRegion::Op op,
714c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                bool doAntiAlias) {
7159060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipPath(path, op, doAntiAlias);
7169ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipPath(path, op, doAntiAlias);
7179ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7189ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn,
722c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  SkRegion::Op op) {
7239060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipRegion(deviceRgn, op);
7249ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipRegion(deviceRgn, op);
7259ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7269ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7274370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
729c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::clear(SkColor color) {
7304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // purge pending commands
7314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (fDeferredDrawing) {
7320a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
7334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
7344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7359060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clear(color);
7369ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7374370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
739c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPaint(const SkPaint& paint) {
740d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing && this->isFullFrame(NULL, &paint) &&
741c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org        isPaintOpaque(&paint)) {
7420a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
7434370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
74410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
7459060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPaint(paint);
7469ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPoints(PointMode mode, size_t count,
750c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  const SkPoint pts[], const SkPaint& paint) {
75110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
7529060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPoints(mode, count, pts, paint);
7539ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7564ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkDeferredCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
7574ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
7584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->drawingCanvas()->drawOval(rect, paint);
7594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->recordedDrawCommand();
7604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
7614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
762c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
763d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing && this->isFullFrame(&rect, &paint) &&
764c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org        isPaintOpaque(&paint)) {
7650a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
7664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
767306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com
76810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
7699060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawRect(rect, paint);
7709ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7714370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
7744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    if (rrect.isRect()) {
7754ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
7764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    } else if (rrect.isOval()) {
7774ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
7784ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    } else {
7794ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
7804ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->drawingCanvas()->drawRRect(rrect, paint);
7814ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->recordedDrawCommand();
7824ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    }
7834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
7844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
785c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
78610f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
7879060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPath(path, paint);
7889ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
792c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  SkScalar top, const SkPaint* paint) {
7938f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org    SkRect bitmapRect = SkRect::MakeXYWH(left, top,
7948f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
795d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
7969060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&bitmapRect, paint) &&
79787f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
7980a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
7994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
80110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
8029060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmap(bitmap, left, top, paint);
8039ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8067112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkDeferredCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
8077112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkRect* src,
8087112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkRect& dst,
8097112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkPaint* paint) {
810d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
8119060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&dst, paint) &&
81287f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
8130a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
81610f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
8177112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com    this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint);
8189ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8224370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
8234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                        const SkMatrix& m,
824c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                        const SkPaint* paint) {
8254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
8264370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // covers canvas entirely and transformed bitmap covers canvas entirely
82710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
8289060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmapMatrix(bitmap, m, paint);
8299ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8324370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap,
8334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkIRect& center, const SkRect& dst,
834c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                      const SkPaint* paint) {
8354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
8364370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // covers canvas entirely and dst covers canvas entirely
83710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
8389060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint);
8399ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8404370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
843c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  const SkPaint* paint) {
8448f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org    SkRect bitmapRect = SkRect::MakeXYWH(
8458f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(left),
846d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkIntToScalar(top),
8478f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.width()),
8488f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.height()));
849d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
8509060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&bitmapRect, paint) &&
85187f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
8520a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
85510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
8569060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawSprite(bitmap, left, top, paint);
8579ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawText(const void* text, size_t byteLength,
861c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                SkScalar x, SkScalar y, const SkPaint& paint) {
86210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8639060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawText(text, byteLength, x, y, paint);
8649ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosText(const void* text, size_t byteLength,
868c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                   const SkPoint pos[], const SkPaint& paint) {
86910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8709060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPosText(text, byteLength, pos, paint);
8719ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength,
8754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkScalar xpos[], SkScalar constY,
876c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                    const SkPaint& paint) {
87710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8789060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint);
8799ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawTextOnPath(const void* text, size_t byteLength,
8834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkPath& path,
8844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkMatrix* matrix,
885c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                      const SkPaint& paint) {
88610f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8879060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawTextOnPath(text, byteLength, path, matrix, paint);
8889ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
891c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPicture(SkPicture& picture) {
8929060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPicture(picture);
8939ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount,
8974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkPoint vertices[],
8984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkPoint texs[],
8994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkColor colors[], SkXfermode* xmode,
9004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const uint16_t indices[], int indexCount,
901c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                    const SkPaint& paint) {
90210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9039060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode,
9049060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org                                        indices, indexCount, paint);
9059ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
908c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder) {
9099060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->setBounder(bounder);
9109ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->INHERITED::setBounder(bounder);
9119ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9129ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return bounder;
9134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
915c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
916d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->drawingCanvas()->setDrawFilter(filter);
9179ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->INHERITED::setDrawFilter(filter);
9189ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
919d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return filter;
9204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9224370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkDeferredCanvas::canvasForDrawIter() {
9239060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return this->drawingCanvas();
9244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
925