14f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 24f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/* 34f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * Copyright 2011 Google Inc. 44f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * 54f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 64f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * found in the LICENSE file. 74f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 84f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 94f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkDeferredCanvas.h" 104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkPaint.h" 124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkShader.h" 134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkColorFilter.h" 144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkDrawFilter.h" 154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergernamespace { 174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool isPaintOpaque(const SkPaint* paint, 194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkBitmap* bmpReplacesShader = NULL) { 204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // TODO: SkXfermode should have a virtual isOpaque method, which would 214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // make it possible to test modes that do not have a Coeff representation. 224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!paint) { 244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return bmpReplacesShader ? bmpReplacesShader->isOpaque() : true; 254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkXfermode::Coeff srcCoeff, dstCoeff; 284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (SkXfermode::AsCoeff(paint->getXfermode(), &srcCoeff, &dstCoeff)){ 294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (dstCoeff) { 304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkXfermode::kZero_Coeff: 314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkXfermode::kISA_Coeff: 334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint->getAlpha() != 255) { 344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (bmpReplacesShader) { 374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!bmpReplacesShader->isOpaque()) { 384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else if (paint->getShader() && !paint->getShader()->isOpaque()) { 414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint->getColorFilter() && 444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ((paint->getColorFilter()->getFlags() & 454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColorFilter::kAlphaUnchanged_Flag) == 0)) { 464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkXfermode::kSA_Coeff: 504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint->getAlpha() != 0) { 514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint->getColorFilter() && 544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger ((paint->getColorFilter()->getFlags() & 554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColorFilter::kAlphaUnchanged_Flag) == 0)) { 564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkXfermode::kSC_Coeff: 604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint->getColor() != 0) { // all components must be 0 614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (bmpReplacesShader || paint->getShader()) { 644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint->getColorFilter() && ( 674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger (paint->getColorFilter()->getFlags() & 684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColorFilter::kAlphaUnchanged_Flag) == 0)) { 694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger default: 734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} // unnamed namespace 804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 814f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::SkDeferredCanvas() { 824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger init(); 834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 854f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::SkDeferredCanvas(SkDevice* device) { 864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger init(); 874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger setDevice(device); 884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 904f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::SkDeferredCanvas(SkDevice* device, 914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger DeviceContext* deviceContext) { 924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger init(); 934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger setDevice(device); 944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger setDeviceContext(deviceContext); 954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::init() { 984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fDeferredDrawing = true; // On by default 994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::validate() const { 1024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkASSERT(getDevice()); 1034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1054f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkCanvas* SkDeferredCanvas::drawingCanvas() const { 1064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger validate(); 1074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fDeferredDrawing ? getDeferredDevice()->recordingCanvas() : 1084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->immediateCanvas(); 1094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::flushIfNeeded(const SkBitmap& bitmap) { 1124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger validate(); 1134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing) { 1144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->flushIfNeeded(bitmap); 1154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1184f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::DeferredDevice* SkDeferredCanvas::getDeferredDevice() const { 1194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return static_cast<SkDeferredCanvas::DeferredDevice*>(getDevice()); 1204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::setDeferredDrawing(bool val) { 1234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger validate(); // Must set device before calling this method 1244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkASSERT(drawingCanvas()->getSaveCount() == 1); 1254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (val != fDeferredDrawing) { 1264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing) { 1274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Going live. 1284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->flushPending(); 1294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fDeferredDrawing = val; 1314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1344f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::~SkDeferredCanvas() { 1354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1374f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDevice* SkDeferredCanvas::setDevice(SkDevice* device) { 1384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger INHERITED::setDevice(SkNEW_ARGS(DeferredDevice, (device)))->unref(); 1394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return device; 1404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1424f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::DeviceContext* SkDeferredCanvas::setDeviceContext( 1434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger DeviceContext* deviceContext) { 1444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger DeferredDevice* deferredDevice = getDeferredDevice(); 1464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkASSERT(deferredDevice); 1474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (deferredDevice) { 1484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger deferredDevice->setDeviceContext(deviceContext); 1494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return deviceContext; 1514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 1524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::isFullFrame(const SkRect* rect, 1544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint* paint) const { 1554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkCanvas* canvas = drawingCanvas(); 1564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkISize canvasSize = getDeviceSize(); 1574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (rect) { 1584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!canvas->getTotalMatrix().rectStaysRect()) { 1594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; // conservative 1604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRect transformedRect; 1634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger canvas->getTotalMatrix().mapRect(&transformedRect, *rect); 1644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint) { 1664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkPaint::Style paintStyle = paint->getStyle(); 1674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!(paintStyle == SkPaint::kFill_Style || 1684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paintStyle == SkPaint::kStrokeAndFill_Style)) { 1694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 1704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint->getMaskFilter() || paint->getLooper() 1724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger || paint->getPathEffect() || paint->getImageFilter()) { 1734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; // conservative 1744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // The following test holds with AA enabled, and is conservative 1784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // by a 0.5 pixel margin with AA disabled 1794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (transformedRect.fLeft > SkIntToScalar(0) || 1804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger transformedRect.fTop > SkIntToScalar(0) || 1814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger transformedRect.fRight < SkIntToScalar(canvasSize.fWidth) || 1824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger transformedRect.fBottom < SkIntToScalar(canvasSize.fHeight)) { 1834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 1844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 1874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (canvas->getClipType()) { 1884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkCanvas::kRect_ClipType : 1894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger { 1904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIRect bounds; 1914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger canvas->getClipDeviceBounds(&bounds); 1924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (bounds.fLeft > 0 || bounds.fTop > 0 || 1934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bounds.fRight < canvasSize.fWidth || 1944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bounds.fBottom < canvasSize.fHeight) 1954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 1964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 1974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 1984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkCanvas::kComplex_ClipType : 1994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; // conservative 2004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkCanvas::kEmpty_ClipType: 2014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger default: 2024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 2034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger }; 2044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return true; 2064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerint SkDeferredCanvas::save(SaveFlags flags) { 2094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->save(flags); 2104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::save(flags); 2114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerint SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 2144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SaveFlags flags) { 2154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->saveLayer(bounds, paint, flags); 2164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int count = this->INHERITED::save(flags); 2174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->clipRectBounds(bounds, flags, NULL); 2184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return count; 2194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::restore() { 2224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->restore(); 2234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->INHERITED::restore(); 2244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::isDrawingToLayer() const { 2274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return drawingCanvas()->isDrawingToLayer(); 2284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) { 2314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->translate(dx, dy); 2324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::translate(dx, dy); 2334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) { 2364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->scale(sx, sy); 2374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::scale(sx, sy); 2384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::rotate(SkScalar degrees) { 2414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->rotate(degrees); 2424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::rotate(degrees); 2434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) { 2464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->skew(sx, sy); 2474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::skew(sx, sy); 2484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::concat(const SkMatrix& matrix) { 2514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->concat(matrix); 2524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::concat(matrix); 2534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::setMatrix(const SkMatrix& matrix) { 2564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->setMatrix(matrix); 2574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->INHERITED::setMatrix(matrix); 2584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::clipRect(const SkRect& rect, 2614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRegion::Op op, 2624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool doAntiAlias) { 2634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->clipRect(rect, op, doAntiAlias); 2644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::clipRect(rect, op, doAntiAlias); 2654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::clipPath(const SkPath& path, 2684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRegion::Op op, 2694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool doAntiAlias) { 2704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->clipPath(path, op, doAntiAlias); 2714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::clipPath(path, op, doAntiAlias); 2724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn, 2754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRegion::Op op) { 2764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->clipRegion(deviceRgn, op); 2774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return this->INHERITED::clipRegion(deviceRgn, op); 2784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::clear(SkColor color) { 2814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // purge pending commands 2824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing) { 2834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->contentsCleared(); 2844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 2854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->clear(color); 2874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawPaint(const SkPaint& paint) { 2904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing && isFullFrame(NULL, &paint) && 2914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isPaintOpaque(&paint)) { 2924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->contentsCleared(); 2934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 2944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawPaint(paint); 2964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 2974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawPoints(PointMode mode, size_t count, 2994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPoint pts[], const SkPaint& paint) { 3004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawPoints(mode, count, pts, paint); 3014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { 3044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing && isFullFrame(&rect, &paint) && 3054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isPaintOpaque(&paint)) { 3064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->contentsCleared(); 3074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 3084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawRect(rect, paint); 3104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 3134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawPath(path, paint); 3144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, 3174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkScalar top, const SkPaint* paint) { 3184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRect bitmapRect = SkRect::MakeXYWH(left, top, 3194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())); 3204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing && 3214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isFullFrame(&bitmapRect, paint) && 3224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isPaintOpaque(paint, &bitmap)) { 3234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->contentsCleared(); 3244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 3254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawBitmap(bitmap, left, top, paint); 3274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushIfNeeded(bitmap); 3284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawBitmapRect(const SkBitmap& bitmap, 3314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkIRect* src, 3324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkRect& dst, 3334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint* paint) { 3344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing && 3354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isFullFrame(&dst, paint) && 3364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isPaintOpaque(paint, &bitmap)) { 3374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->contentsCleared(); 3384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 3394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawBitmapRect(bitmap, src, 3414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger dst, paint); 3424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushIfNeeded(bitmap); 3434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawBitmapMatrix(const SkBitmap& bitmap, 3474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkMatrix& m, 3484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint* paint) { 3494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // TODO: reset recording canvas if paint+bitmap is opaque and clip rect 3504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // covers canvas entirely and transformed bitmap covers canvas entirely 3514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawBitmapMatrix(bitmap, m, paint); 3524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushIfNeeded(bitmap); 3534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawBitmapNine(const SkBitmap& bitmap, 3564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkIRect& center, const SkRect& dst, 3574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint* paint) { 3584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // TODO: reset recording canvas if paint+bitmap is opaque and clip rect 3594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // covers canvas entirely and dst covers canvas entirely 3604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawBitmapNine(bitmap, center, 3614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger dst, paint); 3624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushIfNeeded(bitmap); 3634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, 3664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint* paint) { 3674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRect bitmapRect = SkRect::MakeXYWH( 3684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIntToScalar(left), 3694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIntToScalar(top), 3704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIntToScalar(bitmap.width()), 3714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkIntToScalar(bitmap.height())); 3724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeferredDrawing && 3734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isFullFrame(&bitmapRect, paint) && 3744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isPaintOpaque(paint, &bitmap)) { 3754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger getDeferredDevice()->contentsCleared(); 3764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 3774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawSprite(bitmap, left, top, 3794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint); 3804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushIfNeeded(bitmap); 3814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawText(const void* text, size_t byteLength, 3844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkScalar x, SkScalar y, const SkPaint& paint) { 3854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawText(text, byteLength, x, y, paint); 3864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawPosText(const void* text, size_t byteLength, 3894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPoint pos[], const SkPaint& paint) { 3904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawPosText(text, byteLength, pos, paint); 3914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawPosTextH(const void* text, size_t byteLength, 3944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkScalar xpos[], SkScalar constY, 3954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint& paint) { 3964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawPosTextH(text, byteLength, xpos, constY, paint); 3974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 3984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 3994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawTextOnPath(const void* text, size_t byteLength, 4004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPath& path, 4014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkMatrix* matrix, 4024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint& paint) { 4034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawTextOnPath(text, byteLength, 4044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger path, matrix, 4054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint); 4064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawPicture(SkPicture& picture) { 4094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawPicture(picture); 4104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::drawVertices(VertexMode vmode, int vertexCount, 4134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPoint vertices[], 4144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPoint texs[], 4154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkColor colors[], SkXfermode* xmode, 4164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const uint16_t indices[], int indexCount, 4174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkPaint& paint) { 4184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->drawVertices(vmode, vertexCount, 4194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger vertices, texs, 4204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger colors, xmode, 4214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger indices, indexCount, 4224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint); 4234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4254f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkBounder* SkDeferredCanvas::setBounder(SkBounder* bounder) { 4264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->setBounder(bounder); 4274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return INHERITED::setBounder(bounder); 4284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4304f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { 4314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger drawingCanvas()->setDrawFilter(filter); 4324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return INHERITED::setDrawFilter(filter); 4334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4354f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkCanvas* SkDeferredCanvas::canvasForDrawIter() { 4364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return drawingCanvas(); 4374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger// SkDeferredCanvas::DeferredDevice 4404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger//------------------------------------ 4414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4424f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::DeferredDevice::DeferredDevice( 4434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkDevice* immediateDevice, DeviceContext* deviceContext) : 4444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkDevice(SkBitmap::kNo_Config, immediateDevice->width(), 4454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger immediateDevice->height(), immediateDevice->isOpaque()) 4464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger , fFreshFrame(true) { 4474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fDeviceContext = deviceContext; 4494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkSafeRef(fDeviceContext); 4504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateDevice = immediateDevice; // ref counted via fImmediateCanvas 4514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateCanvas = SkNEW_ARGS(SkCanvas, (fImmediateDevice)); 4524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fRecordingCanvas = fPicture.beginRecording(fImmediateDevice->width(), 4534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateDevice->height(), 0); 4544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4564f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDeferredCanvas::DeferredDevice::~DeferredDevice() { 4574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkSafeUnref(fImmediateCanvas); 4584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkSafeUnref(fDeviceContext); 4594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::DeferredDevice::setDeviceContext( 4624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger DeviceContext* deviceContext) { 4634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRefCnt_SafeAssign(fDeviceContext, deviceContext); 4644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 4654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::DeferredDevice::contentsCleared() { 4674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!fRecordingCanvas->isDrawingToLayer()) { 4684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fFreshFrame = true; 4694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // TODO: find a way to transfer the state stack and layers 4714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // to the new recording canvas. For now, purging only works 4724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // with an empty stack. 4734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fRecordingCanvas->getSaveCount() == 0) { 4744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Save state that is trashed by the purge 4764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkDrawFilter* drawFilter = fRecordingCanvas->getDrawFilter(); 4774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkSafeRef(drawFilter); // So that it survives the purge 4784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkMatrix matrix = fRecordingCanvas->getTotalMatrix(); 4794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRegion clipRegion = fRecordingCanvas->getTotalClip(); 4804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // beginRecording creates a new recording canvas and discards the 4824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // old one, hence purging deferred draw ops. 4834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fRecordingCanvas = fPicture.beginRecording( 4844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateDevice->width(), 4854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateDevice->height(), 0); 4864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 4874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Restore pre-purge state 4884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!clipRegion.isEmpty()) { 4894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fRecordingCanvas->clipRegion(clipRegion, 4904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkRegion::kReplace_Op); 4914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 4924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!matrix.isIdentity()) { 4934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fRecordingCanvas->setMatrix(matrix); 4944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 4954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (drawFilter) { 4964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fRecordingCanvas->setDrawFilter(drawFilter)->unref(); 4974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 4984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 4994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 5004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::DeferredDevice::isFreshFrame() { 5034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger bool ret = fFreshFrame; 5044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fFreshFrame = false; 5054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return ret; 5064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::DeferredDevice::flushPending() { 5094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (fDeviceContext) { 5104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fDeviceContext->prepareForDraw(); 5114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 5124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fPicture.draw(fImmediateCanvas); 5134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fRecordingCanvas = fPicture.beginRecording(fImmediateDevice->width(), 5144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateDevice->height(), 0); 5154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::DeferredDevice::flush() { 5184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushPending(); 5194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateCanvas->flush(); 5204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::DeferredDevice::flushIfNeeded(const SkBitmap& bitmap) { 5234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (bitmap.isImmutable()) { 5244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return; // safe to deffer without registering a dependency 5254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 5264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // For now, drawing a writable bitmap triggers a flush 5284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // TODO: implement read-only semantics and auto buffer duplication on write 5294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // in SkBitmap/SkPixelRef, which will make deferral possible in this case. 5304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushPending(); 5314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergeruint32_t SkDeferredCanvas::DeferredDevice::getDeviceCapabilities() { 5344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fImmediateDevice->getDeviceCapabilities(); 5354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerint SkDeferredCanvas::DeferredDevice::width() const { 5384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fImmediateDevice->width(); 5394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerint SkDeferredCanvas::DeferredDevice::height() const { 5424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fImmediateDevice->height(); 5434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5454f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkGpuRenderTarget* SkDeferredCanvas::DeferredDevice::accessRenderTarget() { 5464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushPending(); 5474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fImmediateDevice->accessRenderTarget(); 5484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkDeferredCanvas::DeferredDevice::writePixels(const SkBitmap& bitmap, 5514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int x, int y, SkCanvas::Config8888 config8888) { 5524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && 5544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger (y + bitmap.height()) >= height()) { 5554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger contentsCleared(); 5564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 5574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (SkBitmap::kARGB_8888_Config == bitmap.config() && 5594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkCanvas::kNative_Premul_Config8888 != config8888 && 5604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger kPMColorAlias != config8888) { 5614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger //Special case config: no deferral 5624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushPending(); 5634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateDevice->writePixels(bitmap, x, y, config8888); 5644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 5654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkPaint paint; 5674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger paint.setXfermodeMode(SkXfermode::kSrc_Mode); 5684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fRecordingCanvas->drawSprite(bitmap, x, y, &paint); 5694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushIfNeeded(bitmap); 5704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerconst SkBitmap& SkDeferredCanvas::DeferredDevice::onAccessBitmap(SkBitmap*) { 5734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushPending(); 5744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fImmediateDevice->accessBitmap(false); 5754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5774f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkDevice* SkDeferredCanvas::DeferredDevice::onCreateCompatibleDevice( 5784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkBitmap::Config config, int width, int height, bool isOpaque, 5794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger Usage usage) { 5804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Save layer usage not supported, and not required by SkDeferredCanvas. 5824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkASSERT(usage != kSaveLayer_Usage); 5834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Create a compatible non-deferred device. 5844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkDevice* compatibleDevice = 5854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fImmediateDevice->createCompatibleDevice(config, width, height, 5864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger isOpaque); 5874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkNEW_ARGS(DeferredDevice, (compatibleDevice, fDeviceContext)); 5884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 5894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 5904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDeferredCanvas::DeferredDevice::onReadPixels( 5914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { 5924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flushPending(); 5934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return fImmediateCanvas->readPixels(const_cast<SkBitmap*>(&bitmap), 5944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger x, y, config8888); 5954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 596