SkDeferredCanvas.cpp revision 5e5a095a94281167056da707b03930f135748d71
14370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 24370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com/* 34370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com * Copyright 2011 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 114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com#include "SkPaint.h" 124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com#include "SkShader.h" 134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com#include "SkColorFilter.h" 144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com#include "SkDrawFilter.h" 154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comnamespace { 174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 18c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool isPaintOpaque(const SkPaint* paint, 19c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkBitmap* bmpReplacesShader = NULL) { 204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // TODO: SkXfermode should have a virtual isOpaque method, which would 214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // make it possible to test modes that do not have a Coeff representation. 2287f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org 2387f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org if (!paint) { 2487f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org return bmpReplacesShader ? bmpReplacesShader->isOpaque() : true; 2587f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org } 2687f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org 274370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkXfermode::Coeff srcCoeff, dstCoeff; 2887f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org if (SkXfermode::AsCoeff(paint->getXfermode(), &srcCoeff, &dstCoeff)){ 294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com switch (dstCoeff) { 304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com case SkXfermode::kZero_Coeff: 314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return true; 324370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com case SkXfermode::kISA_Coeff: 3387f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org if (paint->getAlpha() != 255) { 344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 364370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (bmpReplacesShader) { 374370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (!bmpReplacesShader->isOpaque()) { 384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 4087f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org } else if (paint->getShader() && !paint->getShader()->isOpaque()) { 414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 43c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org if (paint->getColorFilter() && 44c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org ((paint->getColorFilter()->getFlags() & 454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkColorFilter::kAlphaUnchanged_Flag) == 0)) { 464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return true; 494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com case SkXfermode::kSA_Coeff: 5087f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org if (paint->getAlpha() != 0) { 514370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 524370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 53c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org if (paint->getColorFilter() && 54c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org ((paint->getColorFilter()->getFlags() & 554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkColorFilter::kAlphaUnchanged_Flag) == 0)) { 564370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 574370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return true; 594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com case SkXfermode::kSC_Coeff: 6087f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org if (paint->getColor() != 0) { // all components must be 0 614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 6387f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org if (bmpReplacesShader || paint->getShader()) { 644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 66c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org if (paint->getColorFilter() && ( 67c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org (paint->getColorFilter()->getFlags() & 684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkColorFilter::kAlphaUnchanged_Flag) == 0)) { 694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 714370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return true; 724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com default: 734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return false; 774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} // unnamed namespace 804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 81c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::SkDeferredCanvas() { 824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com init(); 834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 85c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::SkDeferredCanvas(SkDevice* device) { 864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com init(); 874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com setDevice(device); 884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkDeferredCanvas::SkDeferredCanvas(SkDevice* device, 91c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org DeviceContext* deviceContext) { 924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com init(); 934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com setDevice(device); 944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com setDeviceContext(deviceContext); 954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 97c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::init() { 985e5a095a94281167056da707b03930f135748d71junov@chromium.org fDeferredDrawing = true; // On by default 994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 101c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::validate() const { 1024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkASSERT(getDevice()); 1034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 1055e5a095a94281167056da707b03930f135748d71junov@chromium.orgSkCanvas* SkDeferredCanvas::drawingCanvas() const { 1065e5a095a94281167056da707b03930f135748d71junov@chromium.org validate(); 1075e5a095a94281167056da707b03930f135748d71junov@chromium.org return fDeferredDrawing ? getDeferredDevice()->recordingCanvas() : 1085e5a095a94281167056da707b03930f135748d71junov@chromium.org getDeferredDevice()->immediateCanvas(); 1095e5a095a94281167056da707b03930f135748d71junov@chromium.org} 1105e5a095a94281167056da707b03930f135748d71junov@chromium.org 111c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::flushIfNeeded(const SkBitmap& bitmap) { 1124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com validate(); 1134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (fDeferredDrawing) { 1144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com getDeferredDevice()->flushIfNeeded(bitmap); 1154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 118c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::DeferredDevice* SkDeferredCanvas::getDeferredDevice() const { 1194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return static_cast<SkDeferredCanvas::DeferredDevice*>(getDevice()); 1204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 122c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setDeferredDrawing(bool val) { 1234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com validate(); // Must set device before calling this method 1245e5a095a94281167056da707b03930f135748d71junov@chromium.org SkASSERT(drawingCanvas()->getSaveCount() == 1); 1254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (val != fDeferredDrawing) { 1264370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (fDeferredDrawing) { 1275e5a095a94281167056da707b03930f135748d71junov@chromium.org // Going live. 1284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com getDeferredDevice()->flushPending(); 1294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fDeferredDrawing = val; 1314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1324370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 134c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::~SkDeferredCanvas() { 1354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1364370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 137c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDevice* SkDeferredCanvas::setDevice(SkDevice* device) { 1384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (device)))->unref(); 1394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return device; 1404370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 1424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkDeferredCanvas::DeviceContext* SkDeferredCanvas::setDeviceContext( 143c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org DeviceContext* deviceContext) { 144c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org 1454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com DeferredDevice* deferredDevice = getDeferredDevice(); 1464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkASSERT(deferredDevice); 1474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (deferredDevice) { 1484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com deferredDevice->setDeviceContext(deviceContext); 1494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1504370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return deviceContext; 1514370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 1524370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 1534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::isFullFrame(const SkRect* rect, 154c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint* paint) const { 1555e5a095a94281167056da707b03930f135748d71junov@chromium.org SkCanvas* canvas = drawingCanvas(); 1564370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkISize canvasSize = getDeviceSize(); 1574370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (rect) { 1584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (!canvas->getTotalMatrix().rectStaysRect()) { 1594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return false; // conservative 1604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 1624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkRect transformedRect; 1634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas->getTotalMatrix().mapRect(&transformedRect, *rect); 1644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 1654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (paint) { 1664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkPaint::Style paintStyle = paint->getStyle(); 1674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (!(paintStyle == SkPaint::kFill_Style || 1684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com paintStyle == SkPaint::kStrokeAndFill_Style)) { 1694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return false; 1704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1714370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (paint->getMaskFilter() || paint->getLooper() 1724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com || paint->getPathEffect() || paint->getImageFilter()) { 1734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return false; // conservative 1744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 1774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // The following test holds with AA enabled, and is conservative 1784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // by a 0.5 pixel margin with AA disabled 179b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org if (transformedRect.fLeft > SkIntToScalar(0) || 180b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org transformedRect.fTop > SkIntToScalar(0) || 181b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) || 182b1e218e782261304440199642f1b98e7ba96b525junov@chromium.org transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) { 1834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return false; 1844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 1874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com switch (canvas->getClipType()) { 1884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com case SkCanvas::kRect_ClipType : 1894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com { 1904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkIRect bounds; 1914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas->getClipDeviceBounds(&bounds); 1924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (bounds.fLeft > 0 || bounds.fTop > 0 || 1934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com bounds.fRight < canvasSize.fWidth || 1944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com bounds.fBottom < canvasSize.fHeight) 1954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return false; 1964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 1974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 1984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com case SkCanvas::kComplex_ClipType : 1994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return false; // conservative 2004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com case SkCanvas::kEmpty_ClipType: 2014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com default: 2024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com break; 2034370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com }; 2044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return true; 2064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 208c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgint SkDeferredCanvas::save(SaveFlags flags) { 2095e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->save(flags); 210a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::save(flags); 2114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comint SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 214c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org SaveFlags flags) { 2155e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->saveLayer(bounds, paint, flags); 216a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org int count = this->INHERITED::save(flags); 217a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org this->clipRectBounds(bounds, flags, NULL); 218a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return count; 2194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 221c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::restore() { 2225e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->restore(); 223a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org this->INHERITED::restore(); 2244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 226c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::isDrawingToLayer() const { 2275e5a095a94281167056da707b03930f135748d71junov@chromium.org return drawingCanvas()->isDrawingToLayer(); 2284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 230c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) { 2315e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->translate(dx, dy); 232a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::translate(dx, dy); 2334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 235c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) { 2365e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->scale(sx, sy); 237a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::scale(sx, sy); 2384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 240c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::rotate(SkScalar degrees) { 2415e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->rotate(degrees); 242a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::rotate(degrees); 2434370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2444370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 245c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) { 2465e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->skew(sx, sy); 247a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::skew(sx, sy); 2484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 250c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgbool SkDeferredCanvas::concat(const SkMatrix& matrix) { 2515e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->concat(matrix); 252a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::concat(matrix); 2534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 255c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::setMatrix(const SkMatrix& matrix) { 2565e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->setMatrix(matrix); 257a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org this->INHERITED::setMatrix(matrix); 2584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRect(const SkRect& rect, 2614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkRegion::Op op, 262c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org bool doAntiAlias) { 2635e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->clipRect(rect, op, doAntiAlias); 264a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::clipRect(rect, op, doAntiAlias); 2654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipPath(const SkPath& path, 2684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkRegion::Op op, 269c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org bool doAntiAlias) { 2705e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->clipPath(path, op, doAntiAlias); 271a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::clipPath(path, op, doAntiAlias); 2724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn, 275c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org SkRegion::Op op) { 2765e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->clipRegion(deviceRgn, op); 277a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return this->INHERITED::clipRegion(deviceRgn, op); 2784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 280c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::clear(SkColor color) { 2814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // purge pending commands 2824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (fDeferredDrawing) { 2838f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org getDeferredDevice()->contentsCleared(); 2844370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 2854370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2865e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->clear(color); 2874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 289c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPaint(const SkPaint& paint) { 290c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org if (fDeferredDrawing && isFullFrame(NULL, &paint) && 291c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org isPaintOpaque(&paint)) { 2928f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org getDeferredDevice()->contentsCleared(); 2934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 2944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2955e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawPaint(paint); 2964370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 2974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 2984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPoints(PointMode mode, size_t count, 299c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPoint pts[], const SkPaint& paint) { 3005e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawPoints(mode, count, pts, paint); 3014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3024370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 303c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { 304c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org if (fDeferredDrawing && isFullFrame(&rect, &paint) && 305c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org isPaintOpaque(&paint)) { 3068f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org getDeferredDevice()->contentsCleared(); 3074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 3084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3095e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawRect(rect, paint); 3104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 312c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 3135e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawPath(path, paint); 3144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, 317c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org SkScalar top, const SkPaint* paint) { 3188f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkRect bitmapRect = SkRect::MakeXYWH(left, top, 3198f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())); 3204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (fDeferredDrawing && 3214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com isFullFrame(&bitmapRect, paint) && 32287f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org isPaintOpaque(paint, &bitmap)) { 3238f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org getDeferredDevice()->contentsCleared(); 3244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 3254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3265e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawBitmap(bitmap, left, top, paint); 3274370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushIfNeeded(bitmap); 3284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapRect(const SkBitmap& bitmap, 3314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkIRect* src, 332c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkRect& dst, 333c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint* paint) { 3344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (fDeferredDrawing && 3354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com isFullFrame(&dst, paint) && 33687f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org isPaintOpaque(paint, &bitmap)) { 3378f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org getDeferredDevice()->contentsCleared(); 3384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 3394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3405e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawBitmapRect(bitmap, src, 3414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com dst, paint); 3424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushIfNeeded(bitmap); 3434370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3444370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapMatrix(const SkBitmap& bitmap, 3474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkMatrix& m, 348c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint* paint) { 3494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // TODO: reset recording canvas if paint+bitmap is opaque and clip rect 3504370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // covers canvas entirely and transformed bitmap covers canvas entirely 3515e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawBitmapMatrix(bitmap, m, paint); 3524370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushIfNeeded(bitmap); 3534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap, 3564370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkIRect& center, const SkRect& dst, 357c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint* paint) { 3584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // TODO: reset recording canvas if paint+bitmap is opaque and clip rect 3594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // covers canvas entirely and dst covers canvas entirely 3605e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawBitmapNine(bitmap, center, 3614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com dst, paint); 3624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushIfNeeded(bitmap); 3634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, 366c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint* paint) { 3678f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkRect bitmapRect = SkRect::MakeXYWH( 3688f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkIntToScalar(left), 3698f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkIntToScalar(top), 3708f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkIntToScalar(bitmap.width()), 3718f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkIntToScalar(bitmap.height())); 3724370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (fDeferredDrawing && 3734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com isFullFrame(&bitmapRect, paint) && 37487f982c80833eeebf541becec8e27b96c8c889f7junov@chromium.org isPaintOpaque(paint, &bitmap)) { 3758f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org getDeferredDevice()->contentsCleared(); 3764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 3774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3785e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawSprite(bitmap, left, top, 3794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com paint); 3804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushIfNeeded(bitmap); 3814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawText(const void* text, size_t byteLength, 384c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org SkScalar x, SkScalar y, const SkPaint& paint) { 3855e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawText(text, byteLength, x, y, paint); 3864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosText(const void* text, size_t byteLength, 389c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPoint pos[], const SkPaint& paint) { 3905e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawPosText(text, byteLength, pos, paint); 3914370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength, 3944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkScalar xpos[], SkScalar constY, 395c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint& paint) { 3965e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint); 3974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 3984370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 3994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawTextOnPath(const void* text, size_t byteLength, 4004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkPath& path, 4014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkMatrix* matrix, 402c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint& paint) { 4035e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawTextOnPath(text, byteLength, 4044370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com path, matrix, 4054370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com paint); 4064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 408c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::drawPicture(SkPicture& picture) { 4095e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawPicture(picture); 4104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount, 4134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkPoint vertices[], 4144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkPoint texs[], 4154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const SkColor colors[], SkXfermode* xmode, 4164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com const uint16_t indices[], int indexCount, 417c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkPaint& paint) { 4185e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->drawVertices(vmode, vertexCount, 4194370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com vertices, texs, 4204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com colors, xmode, 4214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com indices, indexCount, 4224370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com paint); 4234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 425c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder) { 4265e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->setBounder(bounder); 427a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return INHERITED::setBounder(bounder); 4284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 430c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { 4315e5a095a94281167056da707b03930f135748d71junov@chromium.org drawingCanvas()->setDrawFilter(filter); 432c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org return INHERITED::setDrawFilter(filter); 4334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkDeferredCanvas::canvasForDrawIter() { 4365e5a095a94281167056da707b03930f135748d71junov@chromium.org return drawingCanvas(); 4374370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com// SkDeferredCanvas::DeferredDevice 4404370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com//------------------------------------ 4414370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkDeferredCanvas::DeferredDevice::DeferredDevice( 4434370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkDevice* immediateDevice, DeviceContext* deviceContext) : 4444370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkDevice(SkBitmap::kNo_Config, immediateDevice->width(), 4454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com immediateDevice->height(), immediateDevice->isOpaque()) 446c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org , fFreshFrame(true) { 447c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org 4484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fDeviceContext = deviceContext; 4494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkSafeRef(fDeviceContext); 4504370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas 4514370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice)); 4524370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fRecordingCanvas = fPicture.beginRecording(fImmediateDevice->width(), 453a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fImmediateDevice->height(), 0); 4544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4554370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 456c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkDeferredCanvas::DeferredDevice::~DeferredDevice() { 4574370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkSafeUnref(fImmediateCanvas); 4584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkSafeUnref(fDeviceContext); 4594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::DeferredDevice::setDeviceContext( 462c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org DeviceContext* deviceContext) { 4634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkRefCnt_SafeAssign(fDeviceContext, deviceContext); 4644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 4654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 466c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::DeferredDevice::contentsCleared() { 4678f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org if (!fRecordingCanvas->isDrawingToLayer()) { 4688f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org fFreshFrame = true; 4694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4708f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org // TODO: find a way to transfer the state stack and layers 4718f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org // to the new recording canvas. For now, purging only works 4728f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org // with an empty stack. 4738f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org if (fRecordingCanvas->getSaveCount() == 0) { 4744370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4758f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org // Save state that is trashed by the purge 4768f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkDrawFilter* drawFilter = fRecordingCanvas->getDrawFilter(); 4778f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkSafeRef(drawFilter); // So that it survives the purge 4788f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkMatrix matrix = fRecordingCanvas->getTotalMatrix(); 4798f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org SkRegion clipRegion = fRecordingCanvas->getTotalClip(); 4804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 4818f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org // beginRecording creates a new recording canvas and discards the 4828f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org // old one, hence purging deferred draw ops. 4838f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org fRecordingCanvas = fPicture.beginRecording( 4848f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org fImmediateDevice->width(), 485a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fImmediateDevice->height(), 0); 4868f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org 4878f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org // Restore pre-purge state 4888f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org if (!clipRegion.isEmpty()) { 489c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org fRecordingCanvas->clipRegion(clipRegion, 490c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org SkRegion::kReplace_Op); 4918f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org } 4928f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org if (!matrix.isIdentity()) { 4938f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org fRecordingCanvas->setMatrix(matrix); 4948f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org } 4958f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org if (drawFilter) { 4968f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org fRecordingCanvas->setDrawFilter(drawFilter)->unref(); 4978f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org } 4988f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org } 4994370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 5004370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5014370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 5028f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.orgbool SkDeferredCanvas::DeferredDevice::isFreshFrame() { 5038f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org bool ret = fFreshFrame; 5048f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org fFreshFrame = false; 5058f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org return ret; 5068f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org} 5078f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org 508c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::DeferredDevice::flushPending() { 5094370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (fDeviceContext) { 5104370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fDeviceContext->prepareForDraw(); 5114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 5124370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fPicture.draw(fImmediateCanvas); 5134370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fRecordingCanvas = fPicture.beginRecording(fImmediateDevice->width(), 514a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fImmediateDevice->height(), 0); 5154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 517c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::DeferredDevice::flush() { 5184370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushPending(); 519bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org fImmediateCanvas->flush(); 5204370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5214370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 522c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgvoid SkDeferredCanvas::DeferredDevice::flushIfNeeded(const SkBitmap& bitmap) { 5234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (bitmap.isImmutable()) { 5244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return; // safe to deffer without registering a dependency 5254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 5264370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 5274370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // For now, drawing a writable bitmap triggers a flush 5284370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // TODO: implement read-only semantics and auto buffer duplication on write 5294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // in SkBitmap/SkPixelRef, which will make deferral possible in this case. 5304370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushPending(); 5314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5324370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 533c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orguint32_t SkDeferredCanvas::DeferredDevice::getDeviceCapabilities() { 5344370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return fImmediateDevice->getDeviceCapabilities(); 5354370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5364370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 537c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgint SkDeferredCanvas::DeferredDevice::width() const { 5384370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return fImmediateDevice->width(); 5394370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5404370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 541c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgint SkDeferredCanvas::DeferredDevice::height() const { 5424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return fImmediateDevice->height(); 5434370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5444370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 545c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgSkGpuRenderTarget* SkDeferredCanvas::DeferredDevice::accessRenderTarget() { 5464370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushPending(); 5474370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return fImmediateDevice->accessRenderTarget(); 5484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 5504370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comvoid SkDeferredCanvas::DeferredDevice::writePixels(const SkBitmap& bitmap, 551c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org int x, int y, SkCanvas::Config8888 config8888) { 552c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org 5534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && 5544370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com (y + bitmap.height()) >= height()) { 5558f9ecbd3466d4330886b4c23b06e75b468c795adjunov@chromium.org contentsCleared(); 5564370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 5574370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 5584370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com if (SkBitmap::kARGB_8888_Config == bitmap.config() && 5594370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkCanvas::kNative_Premul_Config8888 != config8888 && 5604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com kPMColorAlias != config8888) { 5614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com //Special case config: no deferral 5624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushPending(); 5634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fImmediateDevice->writePixels(bitmap, x, y, config8888); 5644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com } 5654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 5664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkPaint paint; 5674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com paint.setXfermodeMode(SkXfermode::kSrc_Mode); 5684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com fRecordingCanvas->drawSprite(bitmap, x, y, &paint); 5694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushIfNeeded(bitmap); 5704370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5714370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 572c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.orgconst SkBitmap& SkDeferredCanvas::DeferredDevice::onAccessBitmap(SkBitmap*) { 5734370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushPending(); 5741f9767c03bad1ef85e5388d84e23e4b5dff4bc1ajunov@chromium.org return fImmediateDevice->accessBitmap(false); 5754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 5774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkDevice* SkDeferredCanvas::DeferredDevice::onCreateCompatibleDevice( 578c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org SkBitmap::Config config, int width, int height, bool isOpaque, 579c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org Usage usage) { 580c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org 5814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // Save layer usage not supported, and not required by SkDeferredCanvas. 5824370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com SkASSERT(usage != kSaveLayer_Usage); 5834370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com // Create a compatible non-deferred device. 584c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org SkDevice* compatibleDevice = 585c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org fImmediateDevice->createCompatibleDevice(config, width, height, 586c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org isOpaque); 5874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return SkNEW_ARGS(DeferredDevice, (compatibleDevice, fDeviceContext)); 5884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 5894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 5904370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.combool SkDeferredCanvas::DeferredDevice::onReadPixels( 591c16ca92fd1ca609eb2902d14727bec78848ba767junov@chromium.org const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { 5924370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com flushPending(); 5934370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), 5944370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com x, y, config8888); 5954370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 596