SkDeferredCanvas.cpp revision 306ab9d5de38f2a547fd1d69aedbe69b5c6617cc
14370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
24370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com/*
310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org * Copyright 2012 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"
174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h"
1888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org#include "SkShader.h"
194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
20bfeddae9da240693441556b2f278827e213f75e8junov@chromium.orgenum {
21bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    // Deferred canvas will auto-flush when recording reaches this limit
22bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    kDefaultMaxRecordingStorageBytes = 64*1024*1024,
235347de16116e7b8aaa7d06696fbaa37ffc08899csugoi@google.com    kDeferredCanvasBitmapSizeThreshold = ~0, // Disables this feature
24bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org};
25bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org
26eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.orgenum PlaybackMode {
27eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    kNormal_PlaybackMode,
28eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    kSilent_PlaybackMode,
29eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org};
30eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org
314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comnamespace {
327775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.combool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
337775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com                           size_t bitmapSizeThreshold) {
347775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
357775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        (bitmap->getSize() > bitmapSizeThreshold))) {
3610f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        return true;
3710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    }
3810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    if (paint) {
3910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        SkShader* shader = paint->getShader();
4010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // Here we detect the case where the shader is an SkBitmapProcShader
4110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // with a gpu texture attached.  Checking this without RTTI
4210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // requires making the assumption that only gradient shaders
4310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // and SkBitmapProcShader implement asABitmap().  The following
4410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        // code may need to be revised if that assumption is ever broken.
4510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        if (shader && !shader->asAGradient(NULL)) {
4610f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org            SkBitmap bm;
47d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (shader->asABitmap(&bm, NULL, NULL) &&
4810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org                NULL != bm.getTexture()) {
4910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org                return true;
5010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org            }
5110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org        }
5210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    }
5310f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    return false;
54b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
55b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
56b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org
57b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.orgnamespace {
584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
59d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool isPaintOpaque(const SkPaint* paint,
60c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                   const SkBitmap* bmpReplacesShader = NULL) {
614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // TODO: SkXfermode should have a virtual isOpaque method, which would
624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // make it possible to test modes that do not have a Coeff representation.
6387f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org
6487f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org    if (!paint) {
6587f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        return bmpReplacesShader ? bmpReplacesShader->isOpaque() : true;
6687f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org    }
6787f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org
684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    SkXfermode::Coeff srcCoeff, dstCoeff;
6987f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org    if (SkXfermode::AsCoeff(paint->getXfermode(), &srcCoeff, &dstCoeff)){
708cef67aada2e8776a6741dce6211dc77fc9272dfjunov@chromium.org        if (SkXfermode::kDA_Coeff == srcCoeff || SkXfermode::kDC_Coeff == srcCoeff ||
718cef67aada2e8776a6741dce6211dc77fc9272dfjunov@chromium.org            SkXfermode::kIDA_Coeff == srcCoeff || SkXfermode::kIDC_Coeff == srcCoeff) {
728cef67aada2e8776a6741dce6211dc77fc9272dfjunov@chromium.org            return false;
738cef67aada2e8776a6741dce6211dc77fc9272dfjunov@chromium.org        }
744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        switch (dstCoeff) {
754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        case SkXfermode::kZero_Coeff:
764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return true;
774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        case SkXfermode::kISA_Coeff:
7887f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org            if (paint->getAlpha() != 255) {
794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            if (bmpReplacesShader) {
824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                if (!bmpReplacesShader->isOpaque()) {
834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                    break;
844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                }
8587f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org            } else if (paint->getShader() && !paint->getShader()->isOpaque()) {
864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
88d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (paint->getColorFilter() &&
89c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                ((paint->getColorFilter()->getFlags() &
904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return true;
944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        case SkXfermode::kSA_Coeff:
9587f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org            if (paint->getAlpha() != 0) {
964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
98d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (paint->getColorFilter() &&
99c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                ((paint->getColorFilter()->getFlags() &
1004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
1014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
1024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
1034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return true;
1044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        case SkXfermode::kSC_Coeff:
10587f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org            if (paint->getColor() != 0) { // all components must be 0
1064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
1074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
10887f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org            if (bmpReplacesShader || paint->getShader()) {
1094370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
1104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
111c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org            if (paint->getColorFilter() && (
112c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                (paint->getColorFilter()->getFlags() &
1134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                SkColorFilter::kAlphaUnchanged_Flag) == 0)) {
1144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                break;
1154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
1164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return true;
1174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        default:
1184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            break;
1194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
1204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
1214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    return false;
1224370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
1234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
1244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} // unnamed namespace
1254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
12688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
12788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org// DeferredPipeController
12888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
12988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
13088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgclass DeferredPipeController : public SkGPipeController {
13188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgpublic:
13288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredPipeController();
13388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void setPlaybackCanvas(SkCanvas*);
13488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual ~DeferredPipeController();
13588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void* requestBlock(size_t minRequest, size_t* actual) SK_OVERRIDE;
13688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void notifyWritten(size_t bytes) SK_OVERRIDE;
137fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    void playback(bool silent);
138a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    bool hasPendingCommands() const { return fAllocator.blockCount() != 0; }
13988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocatedForRecording() const { return fAllocator.totalCapacity(); }
14088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprivate:
14188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    enum {
14288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        kMinBlockSize = 4096
14388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    };
14488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    struct PipeBlock {
14588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        PipeBlock(void* block, size_t size) { fBlock = block, fSize = size; }
14688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        void* fBlock;
14788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        size_t fSize;
14888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    };
14988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void* fBlock;
15088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t fBytesWritten;
15188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkChunkAlloc fAllocator;
15288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkTDArray<PipeBlock> fBlockList;
15388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkGPipeReader fReader;
15488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org};
15588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
15688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredPipeController::DeferredPipeController() :
15788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator(kMinBlockSize) {
15888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlock = NULL;
15988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten = 0;
16088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
16188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
16288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredPipeController::~DeferredPipeController() {
16388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator.reset();
16488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
16588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
16688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredPipeController::setPlaybackCanvas(SkCanvas* canvas) {
16788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fReader.setCanvas(canvas);
16888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
16988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
17088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid* DeferredPipeController::requestBlock(size_t minRequest, size_t *actual) {
17188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (fBlock) {
17288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        // Save the previous block for later
17388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        PipeBlock previousBloc(fBlock, fBytesWritten);
17488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fBlockList.push(previousBloc);
17588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
17688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    int32_t blockSize = SkMax32(minRequest, kMinBlockSize);
17788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlock = fAllocator.allocThrow(blockSize);
17888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten = 0;
17988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    *actual = blockSize;
18088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fBlock;
18188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
18288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
18388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredPipeController::notifyWritten(size_t bytes) {
18488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBytesWritten += bytes;
18588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
18688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
187fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.orgvoid DeferredPipeController::playback(bool silent) {
188fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    uint32_t flags = silent ? SkGPipeReader::kSilent_PlaybackFlag : 0;
18988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) {
190fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        fReader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fSize,
191fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                         flags);
19288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
19388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fBlockList.reset();
19488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
19588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (fBlock) {
196fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        fReader.playback(fBlock, fBytesWritten, flags);
19788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fBlock = NULL;
19888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
19988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
20088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Release all allocated blocks
20188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fAllocator.reset();
20288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
20388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
20488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
20588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org// DeferredDevice
20688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org//-----------------------------------------------------------------------------
20788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgclass DeferredDevice : public SkDevice {
20888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgpublic:
20988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredDevice(SkDevice* immediateDevice,
2109ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        SkDeferredCanvas::NotificationClient* notificationClient = NULL);
21188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    ~DeferredDevice();
21288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
2139ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient);
21488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* recordingCanvas();
21588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
21688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkDevice* immediateDevice() const {return fImmediateDevice;}
21788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool isFreshFrame();
218a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    bool hasPendingCommands();
21988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocatedForRecording() const;
22088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t freeMemoryIfPossible(size_t bytesToFree);
2217775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    size_t getBitmapSizeThreshold() const;
2227775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    void setBitmapSizeThreshold(size_t sizeThreshold);
223eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    void flushPendingCommands(PlaybackMode);
2240a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org    void skipPendingCommands();
22588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void setMaxRecordingStorage(size_t);
2269ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    void recordedDrawCommand();
22788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
22888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
22988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual int width() const SK_OVERRIDE;
23088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual int height() const SK_OVERRIDE;
23188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
23288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
23388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
23488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               int width, int height,
23588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               bool isOpaque,
23688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                               Usage usage) SK_OVERRIDE;
23788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
23888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
23988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkCanvas::Config8888 config8888) SK_OVERRIDE;
24088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
24188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprotected:
24288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE;
24388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual bool onReadPixels(const SkBitmap& bitmap,
24488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int x, int y,
24588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkCanvas::Config8888 config8888) SK_OVERRIDE;
24688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
24788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // The following methods are no-ops on a deferred device
24888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*)
24988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        SK_OVERRIDE
25088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {return false;}
25188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
25288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // None of the following drawing methods should ever get called on the
25388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // deferred device
25488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void clear(SkColor color)
25588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
25688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPaint(const SkDraw&, const SkPaint& paint)
25788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
25888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
25988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            size_t count, const SkPoint[],
26088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint& paint)
26188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
26288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawRect(const SkDraw&, const SkRect& r,
26388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint& paint)
26488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
26588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPath(const SkDraw&, const SkPath& path,
26688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint& paint,
26788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkMatrix* prePathMatrix = NULL,
26888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            bool pathIsMutable = false)
26988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
27088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
27188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkIRect* srcRectOrNull,
27288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkMatrix& matrix, const SkPaint& paint)
27388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
27488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
27588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            int x, int y, const SkPaint& paint)
27688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
27788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawText(const SkDraw&, const void* text, size_t len,
27888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            SkScalar x, SkScalar y, const SkPaint& paint)
27988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
28088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
28188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkScalar pos[], SkScalar constY,
28288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int scalarsPerPos, const SkPaint& paint)
28388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
28488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawTextOnPath(const SkDraw&, const void* text,
28588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                size_t len, const SkPath& path,
28688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkMatrix* matrix,
28788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkPaint& paint)
28888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
28988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
29088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    size_t len, const SkPoint pos[],
29188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkPaint& paint,
29288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkPath& path,
29388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                    const SkMatrix* matrix)
29488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
29588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
29688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int vertexCount, const SkPoint verts[],
29788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                const SkPoint texs[], const SkColor colors[],
29888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                SkXfermode* xmode, const uint16_t indices[],
29988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                int indexCount, const SkPaint& paint)
30088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
30188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
30288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                            const SkPaint&)
30388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        {SkASSERT(0);}
30488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgprivate:
30588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    virtual void flush();
30688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
30788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    void beginRecording();
30888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
30988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    DeferredPipeController fPipeController;
31088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkGPipeWriter  fPipeWriter;
31188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkDevice* fImmediateDevice;
31288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* fImmediateCanvas;
31388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkCanvas* fRecordingCanvas;
3149ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDeferredCanvas::NotificationClient* fNotificationClient;
31588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool fFreshFrame;
31688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t fMaxRecordingStorageBytes;
3179ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    size_t fPreviousStorageAllocated;
3187775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    size_t fBitmapSizeThreshold;
31988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org};
32088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
32188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice::DeferredDevice(
3229ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDevice* immediateDevice, SkDeferredCanvas::NotificationClient* notificationClient) :
32388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkDevice(SkBitmap::kNo_Config, immediateDevice->width(),
32488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org             immediateDevice->height(), immediateDevice->isOpaque())
325a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org    , fRecordingCanvas(NULL)
3269ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    , fFreshFrame(true)
3277775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    , fPreviousStorageAllocated(0)
3285347de16116e7b8aaa7d06696fbaa37ffc08899csugoi@google.com    , fBitmapSizeThreshold(kDeferredCanvasBitmapSizeThreshold){
32988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
33088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
3319ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fNotificationClient = notificationClient;
33288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas
33388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice));
33488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fPipeController.setPlaybackCanvas(fImmediateCanvas);
33588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->beginRecording();
33688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
33788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
33888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice::~DeferredDevice() {
339eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kSilent_PlaybackMode);
34088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkSafeUnref(fImmediateCanvas);
34188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
34288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
34388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::setMaxRecordingStorage(size_t maxStorage) {
34488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fMaxRecordingStorageBytes = maxStorage;
34588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->recordingCanvas(); // Accessing the recording canvas applies the new limit.
34688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
34788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
34888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::beginRecording() {
349a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org    SkASSERT(NULL == fRecordingCanvas);
350d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0,
351a8db8fe39a640bda4b85b9342c3b6b2525142afajunov@chromium.org        fImmediateDevice->width(), fImmediateDevice->height());
35288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
353d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
3549ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid DeferredDevice::setNotificationClient(
3559ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    SkDeferredCanvas::NotificationClient* notificationClient) {
35652805485581cff7e13134aa1465a2950f7bed007junov@chromium.org    fNotificationClient = notificationClient;
35788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
35888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
3590a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.orgvoid DeferredDevice::skipPendingCommands() {
360a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    if (!fRecordingCanvas->isDrawingToLayer() && fPipeController.hasPendingCommands()) {
36188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fFreshFrame = true;
362eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        flushPendingCommands(kSilent_PlaybackMode);
36352a00cac514dfd9cedb85a9c3e92fdb3e32a03f7junov@google.com        if (fNotificationClient) {
36452a00cac514dfd9cedb85a9c3e92fdb3e32a03f7junov@google.com            fNotificationClient->skippedPendingDrawCommands();
36552a00cac514dfd9cedb85a9c3e92fdb3e32a03f7junov@google.com        }
36688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
36788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
36888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
36988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool DeferredDevice::isFreshFrame() {
37088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    bool ret = fFreshFrame;
37188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fFreshFrame = false;
37288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return ret;
37388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
37488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
375a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.orgbool DeferredDevice::hasPendingCommands() {
376a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    return fPipeController.hasPendingCommands();
377a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org}
378a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org
379eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.orgvoid DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) {
380a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    if (!fPipeController.hasPendingCommands()) {
38188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        return;
38288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
383eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
3849ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->prepareForDraw();
38588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
38688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fPipeWriter.flushRecording(true);
387d4501a0aba2541489c32c89426bbfc59ed945da2junov@chromium.org    fPipeController.playback(kSilent_PlaybackMode == playbackMode);
388eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    if (playbackMode == kNormal_PlaybackMode && fNotificationClient) {
3899ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->flushedDrawCommands();
3909ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
3919ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fPreviousStorageAllocated = storageAllocatedForRecording();
39288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
39388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
39488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::flush() {
395eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
39688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    fImmediateCanvas->flush();
39788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
39888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
39988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgsize_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) {
4009ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree);
4019ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    fPreviousStorageAllocated = storageAllocatedForRecording();
4029ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
40388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
40488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
4057775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comsize_t DeferredDevice::getBitmapSizeThreshold() const {
4067775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    return fBitmapSizeThreshold;
4077775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
4087775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
4097775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comvoid DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) {
4107775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    fBitmapSizeThreshold = sizeThreshold;
4117775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
4127775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
41388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgsize_t DeferredDevice::storageAllocatedForRecording() const {
41488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return (fPipeController.storageAllocatedForRecording()
41588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            + fPipeWriter.storageAllocatedForRecording());
41688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
41788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
4189ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid DeferredDevice::recordedDrawCommand() {
41988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    size_t storageAllocated = this->storageAllocatedForRecording();
4209ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
42188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (storageAllocated > fMaxRecordingStorageBytes) {
42288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        // First, attempt to reduce cache without flushing
42388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        size_t tryFree = storageAllocated - fMaxRecordingStorageBytes;
42488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        if (this->freeMemoryIfPossible(tryFree) < tryFree) {
42588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // Flush is necessary to free more space.
426eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org            this->flushPendingCommands(kNormal_PlaybackMode);
42788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // Free as much as possible to avoid oscillating around fMaxRecordingStorageBytes
42888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            // which could cause a high flushing frequency.
429100abf49e10544bc4f436bf1f38e6929779621f4bsalomon@google.com            this->freeMemoryIfPossible(~0U);
43088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        }
4319ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        storageAllocated = this->storageAllocatedForRecording();
43288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
4339ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
434d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fNotificationClient &&
4359ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        storageAllocated != fPreviousStorageAllocated) {
4369ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fPreviousStorageAllocated = storageAllocated;
4379ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        fNotificationClient->storageAllocatedForRecordingChanged(storageAllocated);
4389ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
4399ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org}
4409ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
4419ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgSkCanvas* DeferredDevice::recordingCanvas() {
44288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fRecordingCanvas;
44388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
44488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
445d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comuint32_t DeferredDevice::getDeviceCapabilities() {
44688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->getDeviceCapabilities();
44788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
44888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
449d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comint DeferredDevice::width() const {
45088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->width();
45188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
45288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
45388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgint DeferredDevice::height() const {
454d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return fImmediateDevice->height();
45588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
45688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
45788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkGpuRenderTarget* DeferredDevice::accessRenderTarget() {
458eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
45988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->accessRenderTarget();
46088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
46188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
46288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgvoid DeferredDevice::writePixels(const SkBitmap& bitmap,
46388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    int x, int y, SkCanvas::Config8888 config8888) {
46488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
46588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() &&
46688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        (y + bitmap.height()) >= height()) {
4670a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->skipPendingCommands();
46888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
46988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
47088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
47188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        SkCanvas::kNative_Premul_Config8888 != config8888 &&
47288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        kPMColorAlias != config8888) {
47388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        //Special case config: no deferral
474eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        this->flushPendingCommands(kNormal_PlaybackMode);
47588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fImmediateDevice->writePixels(bitmap, x, y, config8888);
47688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        return;
47788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
47888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
47988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkPaint paint;
48088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
4817775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    if (shouldDrawImmediately(&bitmap, NULL, getBitmapSizeThreshold())) {
482eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        this->flushPendingCommands(kNormal_PlaybackMode);
48388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        fImmediateCanvas->drawSprite(bitmap, x, y, &paint);
48488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    } else {
48588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        this->recordingCanvas()->drawSprite(bitmap, x, y, &paint);
4869ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        this->recordedDrawCommand();
4879ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
48888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    }
48988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
49088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
49188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgconst SkBitmap& DeferredDevice::onAccessBitmap(SkBitmap*) {
492eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
49388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateDevice->accessBitmap(false);
49488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
49588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
49688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkDevice* DeferredDevice::onCreateCompatibleDevice(
49788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkBitmap::Config config, int width, int height, bool isOpaque,
49888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    Usage usage) {
49988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
50088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Save layer usage not supported, and not required by SkDeferredCanvas.
50188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkASSERT(usage != kSaveLayer_Usage);
50288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    // Create a compatible non-deferred device.
50388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    SkAutoTUnref<SkDevice> compatibleDevice
50488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org        (fImmediateDevice->createCompatibleDevice(config, width, height,
50588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org            isOpaque));
5069ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return SkNEW_ARGS(DeferredDevice, (compatibleDevice, fNotificationClient));
50788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
50888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
50988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool DeferredDevice::onReadPixels(
51088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) {
511eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org    this->flushPendingCommands(kNormal_PlaybackMode);
51288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap),
51388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org                                                   x, y, config8888);
51488e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
51588e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
5167775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comclass AutoImmediateDrawIfNeeded {
5177775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.compublic:
5187775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkBitmap* bitmap,
5197775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com                              const SkPaint* paint) {
5207775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        this->init(canvas, bitmap, paint);
5217775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5227775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5237775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    AutoImmediateDrawIfNeeded(SkDeferredCanvas& canvas, const SkPaint* paint) {
5247775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        this->init(canvas, NULL, paint);
5257775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5267775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5277775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    ~AutoImmediateDrawIfNeeded() {
5287775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        if (fCanvas) {
5297775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas->setDeferredDrawing(true);
5307775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        }
5317775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5327775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comprivate:
5337775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint)
5347775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    {
5357775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        DeferredDevice* device = static_cast<DeferredDevice*>(canvas.getDevice());
5367775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        if (canvas.isDeferredDrawing() && (NULL != device) &&
5377775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) {
5387775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            canvas.setDeferredDrawing(false);
5397775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas = &canvas;
5407775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        } else {
5417775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com            fCanvas = NULL;
5427775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com        }
5437775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    }
5447775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5457775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    SkDeferredCanvas* fCanvas;
5467775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com};
54788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
548c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::SkDeferredCanvas() {
5499060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->init();
5504370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5514370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
552c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::SkDeferredCanvas(SkDevice* device) {
5539060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->init();
5549060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->setDevice(device);
5554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5564370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
557c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::init() {
5585e5a095a94281167056da707b03930f135748d71junov@chromium.org    fDeferredDrawing = true; // On by default
5594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
561bfeddae9da240693441556b2f278827e213f75e8junov@chromium.orgvoid SkDeferredCanvas::setMaxRecordingStorage(size_t maxStorage) {
5629060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate();
563bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org    this->getDeferredDevice()->setMaxRecordingStorage(maxStorage);
564bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org}
565bfeddae9da240693441556b2f278827e213f75e8junov@chromium.org
5662e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkDeferredCanvas::storageAllocatedForRecording() const {
5672e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    return this->getDeferredDevice()->storageAllocatedForRecording();
5682e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
5692e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
5702e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.orgsize_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) {
5712e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org    return this->getDeferredDevice()->freeMemoryIfPossible(bytesToFree);
5722e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org}
5732e14ba8ceb41c68042ff133fecf0561a2c22efcajunov@chromium.org
5747775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.comvoid SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
5757775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    DeferredDevice* deferredDevice = this->getDeferredDevice();
5767775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    SkASSERT(deferredDevice);
5777775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com    deferredDevice->setBitmapSizeThreshold(sizeThreshold);
5787775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com}
5797775fd5779e632d6f5724e0e5d39ed347cf965b0sugoi@google.com
5809ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgvoid SkDeferredCanvas::recordedDrawCommand() {
5819ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    if (fDeferredDrawing) {
5829ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        this->getDeferredDevice()->recordedDrawCommand();
5839ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    }
5849ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org}
5859ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
586c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::validate() const {
5879060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkASSERT(this->getDevice());
5884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
5894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
5905e5a095a94281167056da707b03930f135748d71junov@chromium.orgSkCanvas* SkDeferredCanvas::drawingCanvas() const {
5919060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate();
5929060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return fDeferredDrawing ? this->getDeferredDevice()->recordingCanvas() :
5939060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->getDeferredDevice()->immediateCanvas();
5945e5a095a94281167056da707b03930f135748d71junov@chromium.org}
5955e5a095a94281167056da707b03930f135748d71junov@chromium.org
59688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgSkCanvas* SkDeferredCanvas::immediateCanvas() const {
59788e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    this->validate();
59888e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return this->getDeferredDevice()->immediateCanvas();
59988e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
60088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
60188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgDeferredDevice* SkDeferredCanvas::getDeferredDevice() const {
60288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return static_cast<DeferredDevice*>(this->getDevice());
6034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
605c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setDeferredDrawing(bool val) {
6069060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->validate(); // Must set device before calling this method
6074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (val != fDeferredDrawing) {
6084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (fDeferredDrawing) {
6095e5a095a94281167056da707b03930f135748d71junov@chromium.org            // Going live.
610eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org            this->getDeferredDevice()->flushPendingCommands(kNormal_PlaybackMode);
6114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        fDeferredDrawing = val;
6134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
6144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
61688e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool SkDeferredCanvas::isDeferredDrawing() const {
617b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org    return fDeferredDrawing;
618b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org}
619b10a6bd0a7df0ceeea0d53585c049450ec58b4b9junov@chromium.org
62088e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.orgbool SkDeferredCanvas::isFreshFrame() const {
62188e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org    return this->getDeferredDevice()->isFreshFrame();
62288e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org}
62388e29146c1efc5ff8eec06076c9dce12684f2c11junov@chromium.org
624a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.orgbool SkDeferredCanvas::hasPendingCommands() const {
625a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org    return this->getDeferredDevice()->hasPendingCommands();
626a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org}
627a38dfb6981379770221b16b5ec036b08f3005973junov@chromium.org
628fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.orgvoid SkDeferredCanvas::silentFlush() {
629fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    if (fDeferredDrawing) {
630eeaf47f638dbab2cbe3306e099d93dc6244b25a5junov@chromium.org        this->getDeferredDevice()->flushPendingCommands(kSilent_PlaybackMode);
631fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    }
632fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org}
633fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
634c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::~SkDeferredCanvas() {
6354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6364370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
637c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDevice* SkDeferredCanvas::setDevice(SkDevice* device) {
6389060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (device)))->unref();
6394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    return device;
6404370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6429ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.orgSkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient(
6439ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    NotificationClient* notificationClient) {
644c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org
6459060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    DeferredDevice* deferredDevice = this->getDeferredDevice();
6464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    SkASSERT(deferredDevice);
6474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (deferredDevice) {
6489ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org        deferredDevice->setNotificationClient(notificationClient);
6494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
6509ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return notificationClient;
6514370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
6524370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::isFullFrame(const SkRect* rect,
654c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                   const SkPaint* paint) const {
6559060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkCanvas* canvas = this->drawingCanvas();
6569060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    SkISize canvasSize = this->getDeviceSize();
6574370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (rect) {
6584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (!canvas->getTotalMatrix().rectStaysRect()) {
6594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return false; // conservative
6604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        SkRect transformedRect;
6634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        canvas->getTotalMatrix().mapRect(&transformedRect, *rect);
6644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        if (paint) {
6664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            SkPaint::Style paintStyle = paint->getStyle();
667d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            if (!(paintStyle == SkPaint::kFill_Style ||
6684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                paintStyle == SkPaint::kStrokeAndFill_Style)) {
6694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                return false;
6704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
6714370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            if (paint->getMaskFilter() || paint->getLooper()
6724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                || paint->getPathEffect() || paint->getImageFilter()) {
6734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                return false; // conservative
6744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
6754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        // The following test holds with AA enabled, and is conservative
6784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        // by a 0.5 pixel margin with AA disabled
679d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (transformedRect.fLeft > SkIntToScalar(0) ||
680d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            transformedRect.fTop > SkIntToScalar(0) ||
681b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org            transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) ||
682b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org            transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) {
6834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return false;
6844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        }
6854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
6864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
6874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    switch (canvas->getClipType()) {
6884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        case SkCanvas::kRect_ClipType :
6894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            {
6904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                SkIRect bounds;
6914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                canvas->getClipDeviceBounds(&bounds);
692d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                if (bounds.fLeft > 0 || bounds.fTop > 0 ||
693d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                    bounds.fRight < canvasSize.fWidth ||
6944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                    bounds.fBottom < canvasSize.fHeight)
6954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                    return false;
6964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            }
6974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            break;
6984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        case SkCanvas::kComplex_ClipType :
6994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            return false; // conservative
7004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        case SkCanvas::kEmpty_ClipType:
7014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com        default:
7024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com            break;
7034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    };
7044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    return true;
7064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
708c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgint SkDeferredCanvas::save(SaveFlags flags) {
7099060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->save(flags);
7109ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    int val = this->INHERITED::save(flags);
7119ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7129ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
7139ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comint SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
717c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                SaveFlags flags) {
7189060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->saveLayer(bounds, paint, flags);
719a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    int count = this->INHERITED::save(flags);
720a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->clipRectBounds(bounds, flags, NULL);
7219ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7229ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org
723a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    return count;
7244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
726c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::restore() {
7279060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->restore();
728a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->INHERITED::restore();
7299ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
732c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::isDrawingToLayer() const {
7339060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return this->drawingCanvas()->isDrawingToLayer();
7344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
736c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) {
7379060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->translate(dx, dy);
7389ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::translate(dx, dy);
7399ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7409ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
743c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) {
7449060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->scale(sx, sy);
7459ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::scale(sx, sy);
7469ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7479ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
750c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::rotate(SkScalar degrees) {
7519060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->rotate(degrees);
7529ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::rotate(degrees);
7539ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7549ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7564370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
757c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) {
7589060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->skew(sx, sy);
7599ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::skew(sx, sy);
7609ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7619ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
764c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::concat(const SkMatrix& matrix) {
7659060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->concat(matrix);
7669ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::concat(matrix);
7679ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7689ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
771c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setMatrix(const SkMatrix& matrix) {
7729060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->setMatrix(matrix);
773a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org    this->INHERITED::setMatrix(matrix);
7749ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRect(const SkRect& rect,
7784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                SkRegion::Op op,
779c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                bool doAntiAlias) {
7809060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipRect(rect, op, doAntiAlias);
7819ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipRect(rect, op, doAntiAlias);
7829ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
7839ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
7844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
7854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
7864ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.combool SkDeferredCanvas::clipRRect(const SkRRect& rrect,
7874ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                                 SkRegion::Op op,
7884ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                                 bool doAntiAlias) {
7894ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias);
7904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias);
7914ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->recordedDrawCommand();
7924ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    return val;
7934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
7944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
7954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipPath(const SkPath& path,
7964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                SkRegion::Op op,
797c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                bool doAntiAlias) {
7989060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipPath(path, op, doAntiAlias);
7999ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipPath(path, op, doAntiAlias);
8009ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8019ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
8024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn,
805c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  SkRegion::Op op) {
8069060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clipRegion(deviceRgn, op);
8079ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    bool val = this->INHERITED::clipRegion(deviceRgn, op);
8089ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8099ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return val;
8104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
812c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::clear(SkColor color) {
8134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // purge pending commands
8144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    if (fDeferredDrawing) {
8150a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8189060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->clear(color);
8199ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
822c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPaint(const SkPaint& paint) {
823d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing && this->isFullFrame(NULL, &paint) &&
824c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org        isPaintOpaque(&paint)) {
8250a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8264370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
82710f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8289060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPaint(paint);
8299ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8324370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPoints(PointMode mode, size_t count,
833c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  const SkPoint pts[], const SkPaint& paint) {
83410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8359060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPoints(mode, count, pts, paint);
8369ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8374370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8394ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkDeferredCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
8404ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->drawingCanvas()->drawOval(rect, paint);
8424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    this->recordedDrawCommand();
8434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
8444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
845c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
846d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing && this->isFullFrame(&rect, &paint) &&
847c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org        isPaintOpaque(&paint)) {
8480a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
850306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com
85110f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8529060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawRect(rect, paint);
8539ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8564ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
8574ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    if (rrect.isRect()) {
8584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
8594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    } else if (rrect.isOval()) {
8604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
8614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    } else {
8624ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8634ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->drawingCanvas()->drawRRect(rrect, paint);
8644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        this->recordedDrawCommand();
8654ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    }
8664ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com}
8674ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com
868c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
86910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
8709060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPath(path, paint);
8719ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
875c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  SkScalar top, const SkPaint* paint) {
8768f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org    SkRect bitmapRect = SkRect::MakeXYWH(left, top,
8778f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
878d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
8799060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&bitmapRect, paint) &&
88087f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
8810a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
88410f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
8859060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmap(bitmap, left, top, paint);
8869ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
8874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
8884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
8897112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkDeferredCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
8907112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkRect* src,
8917112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkRect& dst,
8927112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                                            const SkPaint* paint) {
893d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
8949060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&dst, paint) &&
89587f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
8960a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
8974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
8984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
89910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
9007112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com    this->drawingCanvas()->drawBitmapRectToRect(bitmap, src, dst, paint);
9019ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
9064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                        const SkMatrix& m,
907c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                        const SkPaint* paint) {
9084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
9094370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // covers canvas entirely and transformed bitmap covers canvas entirely
91010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
9119060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmapMatrix(bitmap, m, paint);
9129ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap,
9164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkIRect& center, const SkRect& dst,
917c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                      const SkPaint* paint) {
9184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // TODO: reset recording canvas if paint+bitmap is opaque and clip rect
9194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    // covers canvas entirely and dst covers canvas entirely
92010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
9219060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawBitmapNine(bitmap, center, dst, paint);
9229ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
926c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                  const SkPaint* paint) {
9278f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org    SkRect bitmapRect = SkRect::MakeXYWH(
9288f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(left),
929d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkIntToScalar(top),
9308f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.width()),
9318f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org        SkIntToScalar(bitmap.height()));
932d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fDeferredDrawing &&
9339060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org        this->isFullFrame(&bitmapRect, paint) &&
93487f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org        isPaintOpaque(paint, &bitmap)) {
9350a67f964b3ed6046303655ced757be7c0f2c060cjunov@chromium.org        this->getDeferredDevice()->skipPendingCommands();
9364370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com    }
9374370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
93810f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &bitmap, paint);
9399060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawSprite(bitmap, left, top, paint);
9409ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9434370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawText(const void* text, size_t byteLength,
944c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                SkScalar x, SkScalar y, const SkPaint& paint) {
94510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9469060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawText(text, byteLength, x, y, paint);
9479ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9504370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosText(const void* text, size_t byteLength,
951c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                   const SkPoint pos[], const SkPaint& paint) {
95210f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9539060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPosText(text, byteLength, pos, paint);
9549ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9564370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9574370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength,
9584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkScalar xpos[], SkScalar constY,
959c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                    const SkPaint& paint) {
96010f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9619060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint);
9629ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawTextOnPath(const void* text, size_t byteLength,
9664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkPath& path,
9674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                      const SkMatrix* matrix,
968c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                      const SkPaint& paint) {
96910f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9709060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawTextOnPath(text, byteLength, path, matrix, paint);
9719ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
974c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPicture(SkPicture& picture) {
9759060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawPicture(picture);
9769ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
9794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount,
9804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkPoint vertices[],
9814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkPoint texs[],
9824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const SkColor colors[], SkXfermode* xmode,
9834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com                                    const uint16_t indices[], int indexCount,
984c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org                                    const SkPaint& paint) {
98510f7f97d4213a251d63fcfcfd6e55b7b528d949ajunov@chromium.org    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
9869060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode,
9879060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org                                        indices, indexCount, paint);
9889ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
991c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder) {
9929060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    this->drawingCanvas()->setBounder(bounder);
9939ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->INHERITED::setBounder(bounder);
9949ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
9959ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    return bounder;
9964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
9974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
998c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
999d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->drawingCanvas()->setDrawFilter(filter);
10009ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->INHERITED::setDrawFilter(filter);
10019ed02b9da25a76ee4c73c1ab19c18b899a223a17junov@chromium.org    this->recordedDrawCommand();
1002d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return filter;
10034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
10044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
10054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkDeferredCanvas::canvasForDrawIter() {
10069060c9bae9dc895ffe73adefccbc896d2973882djunov@chromium.org    return this->drawingCanvas();
10074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com}
1008