SkCanvas.cpp revision 713b8ef3748609ee20f6005a66d6aafd02aab4b6
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 873fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby#include "SkArenaAlloc.h" 9986480a71f4e860663ced7ad90a1fe346a164afbMike Reed#include "SkBitmapDevice.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 11d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 12d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkClipStack.h" 13dbc3cefb0b624808ddb86d444e6103f216e12fa5reed#include "SkColorFilter.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 153cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 18b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 19262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkImage_Base.h" 20900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilter.h" 21900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilterCache.h" 22c573a40ed5024b463e47088d307e3164a486dba5msarett#include "SkLatticeIter.h" 235df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed#include "SkMakeUnique.h" 24262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 26ee424acbb87bf999be132a437527e656e37541d7Florin Malita#include "SkNoDrawCanvas.h" 27fbfa25802709139c2f14e304319c9541da65ca27msarett#include "SkNx.h" 28c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 29b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 31b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack#include "SkRadialShadowMapShader.h" 320017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 33356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#include "SkRasterHandleAllocator.h" 344ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 35904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowPaintFilterCanvas.h" 36904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowShader.h" 374418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 3897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 397ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 4052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 41a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 428f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 43d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 467354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 47644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 483b65598bceb65736486db27ed49a56d787032747Brian Osman#include "SkGr.h" 49e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 50644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 51ebfce6d9b42198e04288a15953f40c395a7b6139Mike Reed#include "SkClipOpPriv.h" 52199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#include "SkVertices.h" 53644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 54e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 55e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 56139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedclass SkNoPixelsDevice : public SkBaseDevice { 57139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedpublic: 58139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props) 59139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed : SkBaseDevice(SkImageInfo::MakeUnknown(bounds.width(), bounds.height()), props) 60566e53c7003920ff45c72498754060804b657c68Mike Reed { 61e393a629491e9a52dd6662983d2bfd424541957eMike Reed // this fails if we enable this assert: DiscardableImageMapTest.GetDiscardableImagesInRectMaxImage 62e393a629491e9a52dd6662983d2bfd424541957eMike Reed //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0); 63566e53c7003920ff45c72498754060804b657c68Mike Reed } 64139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 65139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void resetForNextPicture(const SkIRect& bounds) { 66e393a629491e9a52dd6662983d2bfd424541957eMike Reed //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0); 67139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed this->privateResize(bounds.width(), bounds.height()); 68139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed } 69139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 70139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedprotected: 71139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed // We don't track the clip at all (for performance), but we have to respond to some queries. 72139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed // We pretend to be wide-open. We could pretend to always be empty, but that *seems* worse. 73139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onSave() override {} 74139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onRestore() override {} 75139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipRect(const SkRect& rect, SkClipOp, bool aa) override {} 76139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override {} 77139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipPath(const SkPath& path, SkClipOp, bool aa) override {} 78139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override {} 79139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override {} 80139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed bool onClipIsAA() const override { return false; } 81139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onAsRgnClip(SkRegion* rgn) const override { 82139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed rgn->setRect(SkIRect::MakeWH(this->width(), this->height())); 83139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed } 84139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed ClipType onGetClipType() const override { 85139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed return kRect_ClipType; 86139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed } 87139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 88139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPaint(const SkPaint& paint) override {} 89139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&) override {} 90139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawRect(const SkRect&, const SkPaint&) override {} 91139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawOval(const SkRect&, const SkPaint&) override {} 92139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawRRect(const SkRRect&, const SkPaint&) override {} 93139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPath(const SkPath&, const SkPaint&, const SkMatrix*, bool) override {} 94139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) override {} 95139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawSprite(const SkBitmap&, int, int, const SkPaint&) override {} 96139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint&, 97139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed SkCanvas::SrcRectConstraint) override {} 98139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override {} 99139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPosText(const void*, size_t, const SkScalar[], int, const SkPoint&, 100139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed const SkPaint&) override {} 101139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawDevice(SkBaseDevice*, int, int, const SkPaint&) override {} 1022f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override {} 103139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 104139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedprivate: 105139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed typedef SkBaseDevice INHERITED; 106139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed}; 107139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 108139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 109139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 110c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 111c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 112c83a29759a5c2966da5ab973e4fd90763e4c962breed * 113c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 114c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 115c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 116c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 117c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 118c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 119c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 12099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 12199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 12299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 12399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 12499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 12599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 12699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 12799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 12899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 129c83a29759a5c2966da5ab973e4fd90763e4c962breed 130c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 131c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 132a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 133a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if we're clipped at all, we can't overwrite the entire surface 134a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed { 135a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* base = this->getDevice(); 136a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* top = this->getTopDevice(); 137a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (base != top) { 138a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return false; // we're in a saveLayer, so conservatively don't assume we'll overwrite 139a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 140a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (!base->clipIsWideOpen()) { 141a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return false; 142a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 143c83a29759a5c2966da5ab973e4fd90763e4c962breed } 144c83a29759a5c2966da5ab973e4fd90763e4c962breed 145c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 146c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!this->getTotalMatrix().isScaleTranslate()) { 147c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 148c83a29759a5c2966da5ab973e4fd90763e4c962breed } 149c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary 150c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary SkRect devRect; 151c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary this->getTotalMatrix().mapRectScaleTranslate(&devRect, *rect); 152c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!devRect.contains(bounds)) { 153c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 154c83a29759a5c2966da5ab973e4fd90763e4c962breed } 155c83a29759a5c2966da5ab973e4fd90763e4c962breed } 156c83a29759a5c2966da5ab973e4fd90763e4c962breed 157c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 158c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 159c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 160c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 161c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 162c83a29759a5c2966da5ab973e4fd90763e4c962breed } 163c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 164c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 165c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 166c83a29759a5c2966da5ab973e4fd90763e4c962breed } 167c83a29759a5c2966da5ab973e4fd90763e4c962breed } 168c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 169c83a29759a5c2966da5ab973e4fd90763e4c962breed} 170c83a29759a5c2966da5ab973e4fd90763e4c962breed 171c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 172c83a29759a5c2966da5ab973e4fd90763e4c962breed 173d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 174d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 175d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 176d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 177d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 178d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 179d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 180d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1810acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1820acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1830acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1840acf1b4b3645772d220c720313821bac389751b5reed} 1850acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1860acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1870acf1b4b3645772d220c720313821bac389751b5reed} 1880acf1b4b3645772d220c720313821bac389751b5reed 189da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2132c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 2142c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 215c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 21697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 217c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 218c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 219c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 220c83a29759a5c2966da5ab973e4fd90763e4c962breed } 221c83a29759a5c2966da5ab973e4fd90763e4c962breed} 222c83a29759a5c2966da5ab973e4fd90763e4c962breed 223c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 224c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 225c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 226c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 227c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 228c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 229c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 230c83a29759a5c2966da5ab973e4fd90763e4c962breed // 231c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 232c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 233c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 234c83a29759a5c2966da5ab973e4fd90763e4c962breed } 235c83a29759a5c2966da5ab973e4fd90763e4c962breed } 236c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 23797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 23897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 23997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2421f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 250713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita DeviceCM* fNext; 251713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita sk_sp<SkBaseDevice> fDevice; 252713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita SkRasterClip fClip; 253713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita std::unique_ptr<const SkPaint> fPaint; // may be null (in the future) 254713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer 255713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita 256713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita DeviceCM(sk_sp<SkBaseDevice> device, const SkPaint* paint, const SkMatrix& stashed) 25796fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 258713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita , fDevice(std::move(device)) 259713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita , fPaint(paint ? skstd::make_unique<SkPaint>(*paint) : nullptr) 2608c30a8196dd5903d2d23b4d0a5dc888e802bf698reed , fStashedMatrix(stashed) 261713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita {} 2624b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 263feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 264feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 265feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 266feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 267feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 268feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2801f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 281d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 288a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed DeviceCM* fTopLayer; 289a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkConservativeClip fRasterClip; 290a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkMatrix fMatrix; 291a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed int fDeferredSaveCount; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 293e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack // This is the current cumulative depth (aggregate of all done translateZ calls) 294e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack SkScalar fCurDrawDepth; 295e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 296a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed MCRec() { 29796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 29896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 29996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 3002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 3012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 302e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth = 0; 303b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 304d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 305d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 306d954498c01ccf0417feacf89e45d0c62a06a813breed } 307e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix), 308e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth(prev.fCurDrawDepth) { 309d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 31096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 311d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3122ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 313b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 31882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 319385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 322feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 323feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 324feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 325feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 326feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 327feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 328feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 329feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 330feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 333a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedclass SkDrawIter { 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 335a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkDrawIter(SkCanvas* canvas) 336a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed : fDevice(nullptr), fCurrLayer(canvas->fMCRec->fTopLayer), fPaint(nullptr) 337a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed {} 3384b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 340f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 341f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 342713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita fDevice = rec->fDevice.get(); 343713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita fPaint = rec->fPaint.get(); 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 34596fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3504b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3516f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3526f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3546f8f292aa768869a9e85c314b124875f57504f2creed@google.com 35599330ba6227137866a0dbd63478d36f335203ebdMike Reed SkBaseDevice* fDevice; 35699330ba6227137866a0dbd63478d36f335203ebdMike Reed 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 362713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita#define FOR_EACH_TOP_DEVICE( code ) \ 363713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita do { \ 364713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita DeviceCM* layer = fMCRec->fTopLayer; \ 365713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita while (layer) { \ 366713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita SkBaseDevice* device = layer->fDevice.get(); \ 367713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita if (device) { \ 368713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita code; \ 369713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita } \ 370713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita layer = layer->fNext; \ 371713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita } \ 3727627fa51044e35dc21251f925b56f6dd6887df97Mike Reed } while (0) 3737627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 376dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 377dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 378dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 379dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 380dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 381dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 38296fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 383dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 384d053ce9c54d4e5937a142278359e5a4cde18095ereedstatic sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) { 385dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 386dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 38796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 388dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 389dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 390d053ce9c54d4e5937a142278359e5a4cde18095ereed SkColorFilter* imgCFPtr; 391d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!imgf->asAColorFilter(&imgCFPtr)) { 39296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 393dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 394d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> imgCF(imgCFPtr); 395dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 396dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 39796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 398dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 399dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 401dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 402dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 403dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 404d053ce9c54d4e5937a142278359e5a4cde18095ereed return SkColorFilter::MakeComposeFilter(std::move(imgCF), sk_ref_sp(paintCF)); 405dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 406dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 40787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 40887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 40987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 41087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 41187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 41287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 41387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 41487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 41587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 41687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 41787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 41887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 41987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 42087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 42187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 42287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 42387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 42487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 42787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 42887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 43287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4343aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, bool skipLayerForImageFilter = false, 43587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 43753d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4397765000709dc64eb23be7df47d1f995d1f787115fmalita#else 4407765000709dc64eb23be7df47d1f995d1f787115fmalita fFilter = nullptr; 4417765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 4424a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4434e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4445c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4454e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 447d053ce9c54d4e5937a142278359e5a4cde18095ereed auto simplifiedCF = image_to_color_filter(fOrigPaint); 448dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 449dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 450d053ce9c54d4e5937a142278359e5a4cde18095ereed paint->setColorFilter(std::move(simplifiedCF)); 45196fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 452dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 453dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 454dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 455dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4565c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4575c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4585c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4595c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4605c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4615c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4625c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4635c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4645c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4655c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4665c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4675c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4685c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4695c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4705c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4718926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 472693fdbd6b81a860657612e7604430dd55d6e721bMike Reed tmp.setImageFilter(fPaint->refImageFilter()); 473374772bd61951f01bf84fe17bf53d8867681c9aereed tmp.setBlendMode(fPaint->getBlendMode()); 47487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 47587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 47687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 47787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 47887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 479bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), 48076033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4815c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 4825c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 4838926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4848926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 48579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 48673fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby fLooperContext = looper->makeContext(canvas, &fAlloc); 487129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 488129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 48996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 490129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 4915c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 49474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 4954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 4965c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 4978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 4988926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 50174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 50674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 507129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 508129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 509129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 510129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 511129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 512129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 513129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 514129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 515129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 516fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 51774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 51973fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 520dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5212c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5222c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5232c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5242c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5252c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5265c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5272c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 528129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 52979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 53073fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby char fStorage[48]; 53173fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby SkArenaAlloc fAlloc {fStorage}; 532129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 533129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 536129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 53796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 538129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5395c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 540632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 541dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 542dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5438926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5445c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 54596fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 546374772bd61951f01bf84fe17bf53d8867681c9aereed paint->setBlendMode(SkBlendMode::kSrcOver); 547129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5488926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 54979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 550129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 551129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 552129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 553129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 554971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 555971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 556971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 557971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 55896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 559129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 560632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 561632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 562129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 563129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5648926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 565129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 56679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5674e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5684e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5694e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 570632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 571632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 57296fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5754e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5764e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5774e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5803aafe111b6cc388400092851cc53bbbdfcb8a81creed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 5813aafe111b6cc388400092851cc53bbbdfcb8a81creed this->predrawNotify(); \ 5823aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \ 5833aafe111b6cc388400092851cc53bbbdfcb8a81creed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 584262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 585262a71b7f95ce98ff3dd8dba845afbd724470903reed 586262a71b7f95ce98ff3dd8dba845afbd724470903reed 5878926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 58897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5893aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, true); \ 5908926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 5918926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 5928926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 59378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 59497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5953aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 5964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 5984b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 599c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 600c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 6013aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 602c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 603c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 604c83a29759a5c2966da5ab973e4fd90763e4c962breed 6054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 609fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline SkRect qr_clip_bounds(const SkIRect& bounds) { 610fbfa25802709139c2f14e304319c9541da65ca27msarett if (bounds.isEmpty()) { 611fbfa25802709139c2f14e304319c9541da65ca27msarett return SkRect::MakeEmpty(); 612fbfa25802709139c2f14e304319c9541da65ca27msarett } 613fbfa25802709139c2f14e304319c9541da65ca27msarett 614fbfa25802709139c2f14e304319c9541da65ca27msarett // Expand bounds out by 1 in case we are anti-aliasing. We store the 615fbfa25802709139c2f14e304319c9541da65ca27msarett // bounds as floats to enable a faster quick reject implementation. 616fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect dst; 617fbfa25802709139c2f14e304319c9541da65ca27msarett SkNx_cast<float>(Sk4i::Load(&bounds.fLeft) + Sk4i(-1,-1,1,1)).store(&dst.fLeft); 618fbfa25802709139c2f14e304319c9541da65ca27msarett return dst; 619fbfa25802709139c2f14e304319c9541da65ca27msarett} 620fbfa25802709139c2f14e304319c9541da65ca27msarett 621feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 622feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 623feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 624feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 625feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 626139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed // know that the device is a SkNoPixelsDevice. 627713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita static_cast<SkNoPixelsDevice*>(fMCRec->fLayer->fDevice.get())->resetForNextPicture(bounds); 628fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(bounds); 6299637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 630feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 631feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 632d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 63342b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 63442b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 63542b73eb00367c8315974b1c374308d20efa78897reed } 63642b73eb00367c8315974b1c374308d20efa78897reed 63745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 6382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 63996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 64095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 64195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack fLights = nullptr; 64295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 645a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed new (fMCRec) MCRec; 6465f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect); 6479637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 649a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 650a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 651713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita new (fDeviceCMStorage) DeviceCM(sk_ref_sp(device), nullptr, fMCRec->fMatrix); 652b679ca8926a832274b14fdb512f88f64b61d32eareed 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 65596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 656f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 657f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 658efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 659efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 66078e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 661fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds()); 662c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 663c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 664f92c86642a1875da54d54b447f006cb9dfbbb35creed } 665fbfa25802709139c2f14e304319c9541da65ca27msarett 666f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 669cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 670e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6714a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 672e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6738d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 674ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 67596fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6768d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6778d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 67896a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 679e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 68096a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 681e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 682e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 683b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 684566e53c7003920ff45c72498754060804b657c68Mike Reed this->init(new SkNoPixelsDevice(SkIRect::MakeWH(SkTMax(width, 0), SkTMax(height, 0)), fProps), 685385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 686d954498c01ccf0417feacf89e45d0c62a06a813breed} 687e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 68878e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 689d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6904a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 691d954498c01ccf0417feacf89e45d0c62a06a813breed{ 692d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 693b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 694566e53c7003920ff45c72498754060804b657c68Mike Reed SkIRect r = bounds.isEmpty() ? SkIRect::MakeEmpty() : bounds; 695566e53c7003920ff45c72498754060804b657c68Mike Reed this->init(new SkNoPixelsDevice(r, fProps), flags)->unref(); 69627a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 6978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 699d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7007b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 701d954498c01ccf0417feacf89e45d0c62a06a813breed{ 702d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 703b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 704d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 707fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 708fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7097b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 710fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 711fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 712fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 713fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 714fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 715fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7164a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7173716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7184a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 7193716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7203716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 721b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 722704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 723704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7244a8126e7f81384526629b1e21bf89b632ea13cd9reed} 72529c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 726356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocator> alloc, 727356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle hndl) 7284a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7294a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 730356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed , fAllocator(std::move(alloc)) 7314a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7324a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 733b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 734356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl)); 735704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap) : SkCanvas(bitmap, nullptr, nullptr) {} 739356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 74031f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 74131f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt SarettSkCanvas::SkCanvas(const SkBitmap& bitmap, ColorBehavior) 74231f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 74331f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 74431f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett , fAllocator(nullptr) 74531f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett{ 74631f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett inc_canvas(); 74731f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett 74831f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett SkBitmap tmp(bitmap); 74931f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett *const_cast<SkImageInfo*>(&tmp.info()) = tmp.info().makeColorSpace(nullptr); 75031f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett sk_sp<SkBaseDevice> device(new SkBitmapDevice(tmp, fProps, nullptr)); 75131f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett this->init(device.get(), kDefault_InitFlags); 75231f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett} 75331f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett#endif 75431f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett 7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7587c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 761385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 762b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 76653d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 77251985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7767765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 77874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 77974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 78074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 78196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 78274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 78374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 78474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 78574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 78674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 789bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 790ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed this->onFlush(); 791ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 792ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 793ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedvoid SkCanvas::onFlush() { 7941f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 795bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 796bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 797bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 798bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 799bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 800afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 801afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 8024ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8034ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8044ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 805afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8064ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 807afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 808afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 809afc7cce5d68663934128d76963cd501f771d71desenorblanco } 810afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 811210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 812210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8131f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 815c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 817713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita return rec->fLayer->fDevice.get(); 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8200ed3b640c9da71fbbd73c65a4ec1992f85596271Florin MalitaSkBaseDevice* SkCanvas::getTopDevice() const { 821713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita return fMCRec->fTopLayer->fDevice.get(); 8229266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8239266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 82496472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 825a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 826a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 827a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 828a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 829db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 83003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->readPixels(dstInfo, dstP, rowBytes, x, y); 83151df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 83251df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 83312e946b4bfdf598bffb276776ea6e25439e25265Mike Reedbool SkCanvas::readPixels(const SkPixmap& pm, int x, int y) { 83412e946b4bfdf598bffb276776ea6e25439e25265Mike Reed return pm.addr() && this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y); 83512e946b4bfdf598bffb276776ea6e25439e25265Mike Reed} 83612e946b4bfdf598bffb276776ea6e25439e25265Mike Reed 83712e946b4bfdf598bffb276776ea6e25439e25265Mike Reedbool SkCanvas::readPixels(const SkBitmap& bm, int x, int y) { 83812e946b4bfdf598bffb276776ea6e25439e25265Mike Reed SkPixmap pm; 83912e946b4bfdf598bffb276776ea6e25439e25265Mike Reed return bm.peekPixels(&pm) && this->readPixels(pm, x, y); 84012e946b4bfdf598bffb276776ea6e25439e25265Mike Reed} 84112e946b4bfdf598bffb276776ea6e25439e25265Mike Reed 8424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 8434edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed SkPixmap pm; 8444edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed if (bitmap.peekPixels(&pm)) { 845cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 8464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 8494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 85003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarettbool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_t rowBytes, 8514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 8524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 8534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 8544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 85703dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This check gives us an early out and prevents generation ID churn on the surface. 85803dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This is purely optional: it is a subset of the checks performed by SkWritePixelsRec. 85903dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett SkIRect srcRect = SkIRect::MakeXYWH(x, y, srcInfo.width(), srcInfo.height()); 86003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett if (!srcRect.intersect(0, 0, device->width(), device->height())) { 86103dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return false; 8624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 86403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // Tell our owning surface to bump its generation ID. 86503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett const bool completeOverwrite = 86603dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett srcRect.size() == SkISize::Make(device->width(), device->height()); 867c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 8684af35f348b2e2f6c428819118eb7a2f2fff53a74reed 86903dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This can still fail, most notably in the case of a invalid color type or alpha type 87003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // conversion. We could pull those checks into this function and avoid the unnecessary 87103dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // generation ID bump. But then we would be performing those checks twice, since they 87203dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // are also necessary at the bitmap/pixmap entry points. 87303dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->writePixels(srcInfo, pixels, rowBytes, x, y); 8744cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 87551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 8792ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 8802ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 8812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 884f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 8852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 8862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 8872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 8882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 8892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 8902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 8912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 8922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 8942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 8962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 8972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 898f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 899f0090cb80ab10a49e511aa5450ae38917fa058d9reed 900f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 9012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 9022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 9032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 9042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 9062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 907f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 908a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 909a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 910a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 9112ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 912f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 913f0090cb80ab10a49e511aa5450ae38917fa058d9reed 914f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 9152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 9172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 9182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 9192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 9202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 9212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 9222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 9232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 924a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 9252ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 9262ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 9272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 928f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 929f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 930f0090cb80ab10a49e511aa5450ae38917fa058d9reed 931f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 932f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 933f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 934f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 935f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 936f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 937f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 938f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 939f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 940f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 941f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 942f0090cb80ab10a49e511aa5450ae38917fa058d9reed 9432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 945d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 9468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 9474b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 948c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->save()); 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9514960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 9524960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9554960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 9569b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 957918e144408ba218df919528f8b48c544f4767883Mike Reed SkIRect clipBounds = this->getDeviceClipBounds(); 958918e144408ba218df919528f8b48c544f4767883Mike Reed if (clipBounds.isEmpty()) { 959a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 960f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 961c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 96296e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 96396e657d0e103b8358a77ecd913f6086929f792b8reed 964c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 965e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 966db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 967db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 968db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 969c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 970bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 97149f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 9734b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 97496e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 9778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 9784960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 979a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty 9801f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 981fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 982bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 983a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 988180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9904960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 991180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 992180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 993fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(ir); 994a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 995a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 996a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 997a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 998a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 999a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1000a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1001a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 10024960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 10034960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 10044960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1005d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1006d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 10074960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 10084960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 10094960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 10104960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 10114960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 10124960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerRec rec(origRec); 1013d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 10144960eeec4a1f2a772654883d7f3615d47bcd5dc3reed rec.fBounds = nullptr; 1015d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 10164960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1017a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 10184960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->internalSaveLayer(rec, strategy); 10192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 10208926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 10218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1022a2217ef965e57fdbbf989989e7ec1f2c04f62d39reedvoid SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, 1023c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkBaseDevice* dst, const SkIPoint& dstOrigin, 1024a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed const SkMatrix& ctm) { 1025a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkDraw draw; 1026a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkRasterClip rc; 1027a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed rc.setRect(SkIRect::MakeWH(dst->width(), dst->height())); 1028a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!dst->accessPixels(&draw.fDst)) { 1029a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDst.reset(dst->imageInfo(), nullptr, 0); 1030a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1031a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fMatrix = &SkMatrix::I(); 1032a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fRC = &rc; 10337354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 10347354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1035c61abeed8958a757c6b49937f28b63066148dd67Mike Reed if (filter) { 1036c61abeed8958a757c6b49937f28b63066148dd67Mike Reed p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1037c61abeed8958a757c6b49937f28b63066148dd67Mike Reed } 1038a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1039c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int x = src->getOrigin().x() - dstOrigin.x(); 1040c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int y = src->getOrigin().y() - dstOrigin.y(); 1041a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed auto special = src->snapSpecial(); 1042a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 1043a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed dst->drawSpecial(special.get(), x, y, p); 1044a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 10457354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 104670ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1047129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1048129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1049129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1050129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 105152ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman // SRGBTODO: Can we remove this check now? 1052129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1053129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1054129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1055129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1056129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1057129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1058129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1059129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 1060693fdbd6b81a860657612e7604430dd55d6e721bMike Reed return SkImageInfo::Make(w, h, prev.colorType(), alphaType, prev.refColorSpace()); 1061129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1062129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1063129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 10644960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 10654960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 10664960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 10674960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 10684960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 10698c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 10708c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 10718c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 10728c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 10738c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 10748c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 10758c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 10768c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 10778c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 10788c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 10798c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 10808c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 10818c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 10828c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 10838c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 10848c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 10858c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 10868c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 10878c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 10888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 10898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 109096a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 10918c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 10928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 10938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 10948c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 10958c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 10968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 10978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 10988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 10998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 11008c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 11018c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 11028c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1103a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1104a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 11052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1106a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1107a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 11088c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 11092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 11108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1112e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1113e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1114e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 11152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1116e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1117e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 11184960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 11198dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 11208dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 112176033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1122daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 112376033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 11248dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1125b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1126b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 11278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11285139e501c5ac3a511e35c78395c907a176113451robertphillips SkBaseDevice* priorDevice = this->getTopDevice(); 1129c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (nullptr == priorDevice) { // Do we still need this check??? 1130b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 11312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1132b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1133b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 11345139e501c5ac3a511e35c78395c907a176113451robertphillips SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir.height(), isOpaque, 1135129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1136129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1137704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> newDevice; 113861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 113970ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 11404960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1141daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 114270ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 1143356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed preserveLCDText, 1144356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator.get()); 11455139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice.reset(priorDevice->onCreateDevice(createInfo, paint)); 11465139e501c5ac3a511e35c78395c907a176113451robertphillips if (!newDevice) { 11477503d60847c4ad22df87458aecd917772b23d293reed return; 114861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 1149e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 1150713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix); 11518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1152b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed // only have a "next" if this new layer doesn't affect the clip (rare) 1153b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer; 11548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1156a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1157c61abeed8958a757c6b49937f28b63066148dd67Mike Reed if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) { 1158c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop }, 1159a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fMCRec->fMatrix); 1160a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1161c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1162c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop); 1163c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1164c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 1165c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (layer->fNext) { 1166c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // need to punch a hole in the previous device, so we don't draw there, given that 1167c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // the new top-layer will allow drawing to happen "below" it. 1168c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkRegion hole(ir); 1169c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed do { 1170c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer = layer->fNext; 1171c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer->fDevice->clipRegion(hole, SkClipOp::kDifference); 1172c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } while (layer->fNext); 1173c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 11748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1176d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1177bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1178bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1179bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1180bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1181bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1182bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1183bada1885da479d948f065182d6dfa85a1140bda5reed } 1184d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1185d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 11878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 11888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 11918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 119296fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 11958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 11968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 11978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1199c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (fMCRec) { 1200c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix)); 1201c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 1202c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 12038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 12048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 12058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 12068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 120749f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 1208b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed if (fMCRec) { 12096f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 1210713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita this->internalDrawDevice(layer->fDevice.get(), origin.x(), origin.y(), 1211713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita layer->fPaint.get()); 12128c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 12138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 12148926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 1215385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1216b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1217b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1218a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1219b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 12208c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 12218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 122288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1223fbfa25802709139c2f14e304319c9541da65ca27msarett 1224fbfa25802709139c2f14e304319c9541da65ca27msarett if (fMCRec) { 12259637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 1226fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1227fbfa25802709139c2f14e304319c9541da65ca27msarett } 12288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1230e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 123196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 12324a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 12334a8126e7f81384526629b1e21bf89b632ea13cd9reed } 12344a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 123576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 123676f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1237e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 123876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1239e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 124076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 124176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1242c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1243ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onImageInfo(); 1244ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1245ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1246ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedSkImageInfo SkCanvas::onImageInfo() const { 1247c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1248c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1249c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1250c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1251900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1252c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1253c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1254c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1255898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1256ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onGetProps(props); 1257ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1258ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1259ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedbool SkCanvas::onGetProps(SkSurfaceProps* props) const { 1260898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1261898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1262898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1263898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1264898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1265898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1266898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1267898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1268898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1269898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1270898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 12716ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 12726ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1273c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1274c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1275884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1276c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1277884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1278c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1279c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 12806b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1281884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1282884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 128396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1284884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1285884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1286884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1287884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1288884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1289884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1290884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1291884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 12920ed3b640c9da71fbbd73c65a4ec1992f85596271Florin Malita *origin = this->getTopDevice()->getOrigin(); 12936b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1294884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 12959c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 12969c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1297884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 12989c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1299884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 13009c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 13019c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1302520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13047503d60847c4ad22df87458aecd917772b23d293reedvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint) { 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 130696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13094b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1311a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 13131f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 131476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 131576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 131676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 1317833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips if (filter) { 1318833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial(); 1319833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips if (specialImage) { 1320a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint); 1321833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips } 132276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1323a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint); 132476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1326a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 13274e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 133032704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1331da420b976e61071cfe5de10556b4b23e519091d6reed 133292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1333fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed if (dx || dy) { 1334fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->checkForDeferredSave(); 1335fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fMCRec->fMatrix.preTranslate(dx,dy); 1336cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1337fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed // Translate shouldn't affect the is-scale-translateness of the matrix. 1338fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1339cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1340c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 1341c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1342fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->didTranslate(dx,dy); 1343fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed } 13448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1347d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1348d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1349d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1353d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1354d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1355d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13587438bfc0804d021aa92cdd5ea644994a4248f3dbbungemanvoid SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) { 13597438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman SkMatrix m; 13607438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman m.setRotate(degrees, px, py); 13617438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman this->concat(m); 13627438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman} 13637438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman 136492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1365d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1366d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1367d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 136844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 136944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 137092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1371d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1372d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1373d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1374d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 13752ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13761f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 13779637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 13787627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 13797627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 13807627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 138144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 138244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 138344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 13848c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 13851f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 13869da5a5a198e5dc9148f7f30a6089377590eee55bmsarett fIsScaleTranslate = matrix.isScaleTranslate(); 1387c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1388c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 13898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 13908c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 13918c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 13928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 13938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 139444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 13958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 13988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 13998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 140195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 1402e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackvoid SkCanvas::translateZ(SkScalar z) { 1403e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->checkForDeferredSave(); 1404e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->fMCRec->fCurDrawDepth += z; 1405e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->didTranslateZ(z); 1406e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1407e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 1408e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackSkScalar SkCanvas::getZ() const { 1409e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack return this->fMCRec->fCurDrawDepth; 1410e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1411e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 141295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::setLights(sk_sp<SkLights> lights) { 141395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack this->fLights = lights; 141495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 141595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 141695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblacksk_sp<SkLights> SkCanvas::getLights() const { 141795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack return this->fLights; 141895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 141995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 142095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 14218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 14228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1423c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) { 14242ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14258f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 14278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1429c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1430a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14317627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14327627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA)); 14337627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 1434c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1435a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1436a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1437fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14405f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Ilievvoid SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) { 14415f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fClipRestrictionRect = rect; 1442d519d484949161df6d4b2ecadc282427cab532cfMike Reed if (fClipRestrictionRect.isEmpty()) { 1443d519d484949161df6d4b2ecadc282427cab532cfMike Reed // we notify the device, but we *dont* resolve deferred saves (since we're just 1444d519d484949161df6d4b2ecadc282427cab532cfMike Reed // removing the restriction if the rect is empty. how I hate this api. 1445d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 1446d519d484949161df6d4b2ecadc282427cab532cfMike Reed } else { 14475f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev this->checkForDeferredSave(); 1448d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 14495f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev AutoValidateClip avc(this); 14505f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.op(fClipRestrictionRect, SkRegion::kIntersect_Op); 14515f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14525f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev } 14535f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev} 14545f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev 1455c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) { 14562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 14598f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 14608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 14624ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 14638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 146414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1465c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1466a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon AutoValidateClip avc(this); 146714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1468a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14697627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14707627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA)); 1471a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1472a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1473a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1474a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14754ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 14764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1477c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) { 14782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 148039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 148139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 148239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 148339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 148439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 148539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 148639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 148739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 148839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 148939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 149039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 149139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 149239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 149339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 149439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 149539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 149639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 14978f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 149839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 149939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 15008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15018f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1502c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) { 15035c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15045c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1505a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 15067627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 15077627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA)); 15085c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1509a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkPath* rasterClipPath = &path; 1510a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkMatrix* matrix = &fMCRec->fMatrix; 1511a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1512a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1513fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 15148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1516c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) { 15172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15188f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 15198f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1521c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) { 15227627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op)); 152327d07f0acb85eea4062075dfbe9148ce12d92c66Mike Reed 1524a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed AutoValidateClip avc(this); 152527d07f0acb85eea4062075dfbe9148ce12d92c66Mike Reed 152673603f3c52ffd89fe9d035be827b566a0e7d3b79reed fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op); 1527fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 15288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1530819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1531819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1532819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 15331f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1534ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 15355c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1536ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1537ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1538819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1539819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1540819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1541a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedbool SkCanvas::androidFramework_isClipAA() const { 1542a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed bool containsAA = false; 1543a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1544a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed FOR_EACH_TOP_DEVICE(containsAA |= device->onClipIsAA()); 1545a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1546a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return containsAA; 1547a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed} 1548a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1549a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedclass RgnAccumulator { 1550a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkRegion* fRgn; 1551a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedpublic: 1552a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed RgnAccumulator(SkRegion* total) : fRgn(total) {} 1553a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed void accumulate(SkBaseDevice* device, SkRegion* rgn) { 1554a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkIPoint origin = device->getOrigin(); 1555a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (origin.x() | origin.y()) { 1556a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed rgn->translate(origin.x(), origin.y()); 1557a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 1558a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fRgn->op(*rgn, SkRegion::kUnion_Op); 1559a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 1560a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed}; 1561a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1562a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) { 1563a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed RgnAccumulator accum(rgn); 1564a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkRegion tmp; 1565a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1566a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed rgn->setEmpty(); 1567a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed FOR_EACH_TOP_DEVICE(device->onAsRgnClip(&tmp); accum.accumulate(device, &tmp)); 156890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 156990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 15705c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 15715c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1572754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 157302be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed return fMCRec->fRasterClip.isEmpty(); 157402be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed 157502be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed // TODO: should we only use the conservative answer in a recording canvas? 157602be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed#if 0 1577a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* dev = this->getTopDevice(); 1578a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if no device we return true 1579a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return !dev || dev->onGetClipType() == SkBaseDevice::kEmpty_ClipType; 158002be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed#endif 1581754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1582754de5f65b466f721d952a379194cc94de376f42reed@google.com 15835c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 1584a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* dev = this->getTopDevice(); 1585a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if no device we return false 1586a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return dev && dev->onGetClipType() == SkBaseDevice::kRect_ClipType; 15875c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 15885c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1589fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) { 1590fbfa25802709139c2f14e304319c9541da65ca27msarett#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 1591fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 lLtT = _mm_unpacklo_ps(devRect.fVec, devClip.fVec); 1592fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 RrBb = _mm_unpackhi_ps(devClip.fVec, devRect.fVec); 1593fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 mask = _mm_cmplt_ps(lLtT, RrBb); 1594fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xF != _mm_movemask_ps(mask); 1595fbfa25802709139c2f14e304319c9541da65ca27msarett#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON) 1596fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t lLtT = vzipq_f32(devRect.fVec, devClip.fVec).val[0]; 1597fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t RrBb = vzipq_f32(devClip.fVec, devRect.fVec).val[1]; 1598fbfa25802709139c2f14e304319c9541da65ca27msarett uint32x4_t mask = vcltq_f32(lLtT, RrBb); 1599fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xFFFFFFFFFFFFFFFF != (uint64_t) vmovn_u32(mask); 1600fbfa25802709139c2f14e304319c9541da65ca27msarett#else 1601fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devRectAsRect; 1602fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devClipAsRect; 1603fbfa25802709139c2f14e304319c9541da65ca27msarett devRect.store(&devRectAsRect.fLeft); 1604fbfa25802709139c2f14e304319c9541da65ca27msarett devClip.store(&devClipAsRect.fLeft); 1605fbfa25802709139c2f14e304319c9541da65ca27msarett return !devRectAsRect.isFinite() || !devRectAsRect.intersect(devClipAsRect); 1606fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1607fbfa25802709139c2f14e304319c9541da65ca27msarett} 1608fbfa25802709139c2f14e304319c9541da65ca27msarett 1609fbfa25802709139c2f14e304319c9541da65ca27msarett// It's important for this function to not be inlined. Otherwise the compiler will share code 1610fbfa25802709139c2f14e304319c9541da65ca27msarett// between the fast path and the slow path, resulting in two slow paths. 1611fbfa25802709139c2f14e304319c9541da65ca27msarettstatic SK_NEVER_INLINE bool quick_reject_slow_path(const SkRect& src, const SkRect& deviceClip, 1612fbfa25802709139c2f14e304319c9541da65ca27msarett const SkMatrix& matrix) { 1613fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect deviceRect; 1614fbfa25802709139c2f14e304319c9541da65ca27msarett matrix.mapRect(&deviceRect, src); 1615fbfa25802709139c2f14e304319c9541da65ca27msarett return !deviceRect.isFinite() || !deviceRect.intersect(deviceClip); 1616fbfa25802709139c2f14e304319c9541da65ca27msarett} 1617d22a817ff57986407facd16af36320fc86ce02damsarett 1618fbfa25802709139c2f14e304319c9541da65ca27msarettbool SkCanvas::quickReject(const SkRect& src) const { 1619fbfa25802709139c2f14e304319c9541da65ca27msarett#ifdef SK_DEBUG 1620fbfa25802709139c2f14e304319c9541da65ca27msarett // Verify that fDeviceClipBounds are set properly. 1621fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect tmp = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16221f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 16230c685ee188a5e500df25a34fa6edfceb4cbb795cmsarett SkASSERT(fDeviceClipBounds.isEmpty()); 1624fbfa25802709139c2f14e304319c9541da65ca27msarett } else { 1625fbfa25802709139c2f14e304319c9541da65ca27msarett SkASSERT(tmp == fDeviceClipBounds); 16268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16289637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett // Verify that fIsScaleTranslate is set properly. 16299637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1630fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1631d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 16329637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett if (!fIsScaleTranslate) { 1633fbfa25802709139c2f14e304319c9541da65ca27msarett return quick_reject_slow_path(src, fDeviceClipBounds, fMCRec->fMatrix); 16348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1635fbfa25802709139c2f14e304319c9541da65ca27msarett 1636fbfa25802709139c2f14e304319c9541da65ca27msarett // We inline the implementation of mapScaleTranslate() for the fast path. 1637fbfa25802709139c2f14e304319c9541da65ca27msarett float sx = fMCRec->fMatrix.getScaleX(); 1638fbfa25802709139c2f14e304319c9541da65ca27msarett float sy = fMCRec->fMatrix.getScaleY(); 1639fbfa25802709139c2f14e304319c9541da65ca27msarett float tx = fMCRec->fMatrix.getTranslateX(); 1640fbfa25802709139c2f14e304319c9541da65ca27msarett float ty = fMCRec->fMatrix.getTranslateY(); 1641fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f scale(sx, sy, sx, sy); 1642fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f trans(tx, ty, tx, ty); 1643fbfa25802709139c2f14e304319c9541da65ca27msarett 1644fbfa25802709139c2f14e304319c9541da65ca27msarett // Apply matrix. 1645fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans; 1646fbfa25802709139c2f14e304319c9541da65ca27msarett 1647fbfa25802709139c2f14e304319c9541da65ca27msarett // Make sure left < right, top < bottom. 1648fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]); 1649fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f min = Sk4f::Min(ltrb, rblt); 1650fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f max = Sk4f::Max(ltrb, rblt); 1651fbfa25802709139c2f14e304319c9541da65ca27msarett // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on 1652fbfa25802709139c2f14e304319c9541da65ca27msarett // ARM this sequence generates the fastest (a single instruction). 1653fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f devRect = Sk4f(min[2], min[3], max[0], max[1]); 1654fbfa25802709139c2f14e304319c9541da65ca27msarett 1655fbfa25802709139c2f14e304319c9541da65ca27msarett // Check if the device rect is NaN or outside the clip. 1656fbfa25802709139c2f14e304319c9541da65ca27msarett return is_nan_or_clipped(devRect, Sk4f::Load(&fDeviceClipBounds.fLeft)); 16578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16593b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 16603b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 16618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 166342e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkRect SkCanvas::onGetLocalClipBounds() const { 166442e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkIRect ibounds = this->onGetDeviceClipBounds(); 1665918e144408ba218df919528f8b48c544f4767883Mike Reed if (ibounds.isEmpty()) { 166642e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 16678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1669d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1670d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 16711f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 167242e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 1673d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1674d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 167542e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect bounds; 167642e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect r; 167742e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed // adjust it outwards in case we are antialiasing 167842e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed const int inset = 1; 1679fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 168042e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 168142e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed ibounds.fRight + inset, ibounds.fBottom + inset); 168242e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed inverse.mapRect(&bounds, r); 168342e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return bounds; 16848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168642e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkIRect SkCanvas::onGetDeviceClipBounds() const { 1687a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fMCRec->fRasterClip.getBounds(); 1688bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1689bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 16908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 16911f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16941105224f9701e57ec5ce0354d6a380b664f5c638Brian OsmanGrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() { 16959c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 16961105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman return dev ? dev->accessRenderTargetContext() : nullptr; 16979c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 16989c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1699644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1700644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 170186ae3d161412961c27a406465b0ec5749cc2e753reed return device ? device->context() : nullptr; 1702644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1703e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1704ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1705ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 17069881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1707ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1708ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1709ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1710ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1711ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1712ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1713ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1714ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1715ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1716e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark // be able to return ... 1717e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark // if (!outer.contains(inner))) { 1718ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1719ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1720e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark if (!outer.getBounds().contains(inner.getBounds())) { 1721e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark return; 1722e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark } 1723ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1724ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1725ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1726ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 172741af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 172841af966ab338e95eee81ab618ab28195075338f7reed 172941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 173041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 173141af966ab338e95eee81ab618ab28195075338f7reed} 173241af966ab338e95eee81ab618ab28195075338f7reed 173341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 173441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 173541af966ab338e95eee81ab618ab28195075338f7reed} 173641af966ab338e95eee81ab618ab28195075338f7reed 1737dca352e2d42cfe698573947b3d11abc1eaade160msarettvoid SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { 1738dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isEmpty()) { 1739dca352e2d42cfe698573947b3d11abc1eaade160msarett return; 1740dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1741dca352e2d42cfe698573947b3d11abc1eaade160msarett 1742dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isRect()) { 1743dca352e2d42cfe698573947b3d11abc1eaade160msarett return this->drawIRect(region.getBounds(), paint); 1744dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1745dca352e2d42cfe698573947b3d11abc1eaade160msarett 1746dca352e2d42cfe698573947b3d11abc1eaade160msarett this->onDrawRegion(region, paint); 1747dca352e2d42cfe698573947b3d11abc1eaade160msarett} 1748dca352e2d42cfe698573947b3d11abc1eaade160msarett 174941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 175041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 175141af966ab338e95eee81ab618ab28195075338f7reed} 175241af966ab338e95eee81ab618ab28195075338f7reed 175341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 175441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 175541af966ab338e95eee81ab618ab28195075338f7reed} 175641af966ab338e95eee81ab618ab28195075338f7reed 175741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 175841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 175941af966ab338e95eee81ab618ab28195075338f7reed} 176041af966ab338e95eee81ab618ab28195075338f7reed 1761e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, 1762e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed const SkPaint& paint) { 1763e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed RETURN_ON_NULL(vertices); 1764e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed this->onDrawVerticesObject(vertices.get(), mode, paint); 1765e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed} 1766e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed 1767e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) { 1768199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon RETURN_ON_NULL(vertices); 1769e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed this->onDrawVerticesObject(vertices, mode, paint); 177041af966ab338e95eee81ab618ab28195075338f7reed} 177141af966ab338e95eee81ab618ab28195075338f7reed 177241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 177341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 177441af966ab338e95eee81ab618ab28195075338f7reed} 177541af966ab338e95eee81ab618ab28195075338f7reed 1776a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1777e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1778a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 177941af966ab338e95eee81ab618ab28195075338f7reed} 178041af966ab338e95eee81ab618ab28195075338f7reed 1781e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1782e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1783e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1784e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1785e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1786e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1787e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1788e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 178941af966ab338e95eee81ab618ab28195075338f7reed 179084984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 179184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1792e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1793e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 179484984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 179584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1796e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1797e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1798e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1799e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1800e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1801e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1802e47829b6b1eeb6b0c97ccb3df3016d197046824creed 18034c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 18044c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 1805e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 18064c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 18074c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 18084c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 1809552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(image->width(), image->height(), center)) { 1810552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawImageNine(image, center, dst, paint); 1811552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1812e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 18134c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 18144c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 18154c21dc5ddf3b482293ed34eead876d8d61a662c3reed 1816168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 1817168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 1818168820625c35a8c19f66c661efcbce7a5e334837msarett RETURN_ON_NULL(image); 1819168820625c35a8c19f66c661efcbce7a5e334837msarett if (dst.isEmpty()) { 1820168820625c35a8c19f66c661efcbce7a5e334837msarett return; 1821168820625c35a8c19f66c661efcbce7a5e334837msarett } 182271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 182371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 182471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 182571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 182671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(image->width(), image->height()); 182771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 182871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 182971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 183071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) { 183171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawImageLattice(image, latticePlusBounds, dst, paint); 1832168820625c35a8c19f66c661efcbce7a5e334837msarett } else { 1833168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawImageRect(image, dst, paint); 1834168820625c35a8c19f66c661efcbce7a5e334837msarett } 1835168820625c35a8c19f66c661efcbce7a5e334837msarett} 1836168820625c35a8c19f66c661efcbce7a5e334837msarett 183741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 18384c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 18392df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 18402df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 184141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 184241af966ab338e95eee81ab618ab28195075338f7reed} 184341af966ab338e95eee81ab618ab28195075338f7reed 1844e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1845a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1846e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1847a5517e2b190a8083b38964972b031c13e99f1012reed return; 1848a5517e2b190a8083b38964972b031c13e99f1012reed } 1849e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 185041af966ab338e95eee81ab618ab28195075338f7reed} 185141af966ab338e95eee81ab618ab28195075338f7reed 185284984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 185384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1854e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1855e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1856e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1857e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1858e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1859e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1860e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 186184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 186284984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 186341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 186441af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 18654c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 18662df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 18672df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 1868552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) { 1869552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawBitmapNine(bitmap, center, dst, paint); 1870552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1871a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 18724c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 187341af966ab338e95eee81ab618ab28195075338f7reed} 187441af966ab338e95eee81ab618ab28195075338f7reed 1875c573a40ed5024b463e47088d307e3164a486dba5msarettvoid SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, 1876c573a40ed5024b463e47088d307e3164a486dba5msarett const SkPaint* paint) { 1877168820625c35a8c19f66c661efcbce7a5e334837msarett if (bitmap.drawsNothing() || dst.isEmpty()) { 1878c573a40ed5024b463e47088d307e3164a486dba5msarett return; 1879c573a40ed5024b463e47088d307e3164a486dba5msarett } 188071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 188171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 188271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 188371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 188471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 188571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 188671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 188771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 188871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) { 188971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, paint); 1890552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1891168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawBitmapRect(bitmap, dst, paint); 1892c573a40ed5024b463e47088d307e3164a486dba5msarett } 1893c573a40ed5024b463e47088d307e3164a486dba5msarett} 1894c573a40ed5024b463e47088d307e3164a486dba5msarett 189571c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 18967d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkColor colors[], int count, SkBlendMode mode, 189771c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 1898e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 189971c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 190071c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 190171c3c760a83123ee0b3127b8c65c6394ce541c50reed } 1902c485907f0420e5f9cf8223e9ba53812cd8dd5368Joe Gregorio SkASSERT(atlas); 190371c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 1904faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 190571c3c760a83123ee0b3127b8c65c6394ce541c50reed} 190671c3c760a83123ee0b3127b8c65c6394ce541c50reed 1907f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 1908f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 1909f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 1910f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 1911f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 1912f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 1913e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 1914e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1915e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1916e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 1917e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1918e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 1919e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1920e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1921e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1922e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 1923e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1924e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1925e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 1926e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1927e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 1928e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1929e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1930e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1931e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1932cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudsonvoid SkCanvas::temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds) { 1933cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson SkIRect layer_bounds = this->getTopLayerBounds(); 1934cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (matrix) { 1935cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson *matrix = this->getTotalMatrix(); 1936cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson matrix->preTranslate(-layer_bounds.left(), -layer_bounds.top()); 1937cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 1938cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (clip_bounds) { 1939918e144408ba218df919528f8b48c544f4767883Mike Reed *clip_bounds = this->getDeviceClipBounds(); 1940cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson clip_bounds->offset(-layer_bounds.left(), -layer_bounds.top()); 1941cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 1942cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson} 1943cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson 19448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 19468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 194828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 194949f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 195028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 195128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 195228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 195328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 195441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 19559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1956fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1957fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1958fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1959fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 196096fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 19618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 1963a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPaint(looper.paint()); 19648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19664e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 196941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 197041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 19719881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 19728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 19738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1976822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect r; 197796fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 1978a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1979a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1980a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1981a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1982a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1983a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1984a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1985822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 198687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 198787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 198887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 198987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 1990fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1991a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 199296fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 19938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 199478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 19954b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 1997a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPoints(mode, count, pts, looper.paint()); 19988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19994b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20034a16717bc7aa471fad10ec3157774771a76e5106reedstatic bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) { 20044a16717bc7aa471fad10ec3157774771a76e5106reed return ((intptr_t)paint.getImageFilter() | 20054a16717bc7aa471fad10ec3157774771a76e5106reed#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 20064a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)canvas->getDrawFilter() | 20074a16717bc7aa471fad10ec3157774771a76e5106reed#endif 20084a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)paint.getLooper() ) != 0; 20094a16717bc7aa471fad10ec3157774771a76e5106reed} 20104a16717bc7aa471fad10ec3157774771a76e5106reed 201141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 20129881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 20138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 20148432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 20158432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 20168432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 20178432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 20188432808ad8898ac7137bc7ce1d9df6005e866401reed 2019822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 202087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 202187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 202287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 20238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20244b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20254a16717bc7aa471fad10ec3157774771a76e5106reed if (needs_autodrawlooper(this, paint)) { 2026822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, &r, false) 20278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20284a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 2029a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRect(r, looper.paint()); 20304a16717bc7aa471fad10ec3157774771a76e5106reed } 20318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20324a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_END 20334a16717bc7aa471fad10ec3157774771a76e5106reed } else { 2034822128b475c1782788f96e7a1a848d0affb878b1Mike Reed this->predrawNotify(&r, &paint, false); 20354a16717bc7aa471fad10ec3157774771a76e5106reed SkDrawIter iter(this); 20364a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 2037a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRect(r, paint); 20384a16717bc7aa471fad10ec3157774771a76e5106reed } 20394a16717bc7aa471fad10ec3157774771a76e5106reed } 20408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 204244df651ebefc284acc2f66425dff3ea0b0e14b36msarettvoid SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 204344df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect regionRect = SkRect::Make(region.getBounds()); 204444df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (paint.canComputeFastBounds()) { 2045822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 204644df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (this->quickReject(paint.computeFastBounds(regionRect, &storage))) { 204744df651ebefc284acc2f66425dff3ea0b0e14b36msarett return; 204844df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 204944df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 205044df651ebefc284acc2f66425dff3ea0b0e14b36msarett 2051822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, ®ionRect) 205244df651ebefc284acc2f66425dff3ea0b0e14b36msarett 205344df651ebefc284acc2f66425dff3ea0b0e14b36msarett while (iter.next()) { 2054a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRegion(region, looper.paint()); 205544df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 205644df651ebefc284acc2f66425dff3ea0b0e14b36msarett 205744df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_END 205844df651ebefc284acc2f66425dff3ea0b0e14b36msarett} 205944df651ebefc284acc2f66425dff3ea0b0e14b36msarett 206041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 20619881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 20624ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 2063822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 206487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 206587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 206687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 20674ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2068306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 2069822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval) 207046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 207146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 2072a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawOval(oval, looper.paint()); 207346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 207446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 207546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 20764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20774ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2078ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomonvoid SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, 2079ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkScalar sweepAngle, bool useCenter, 2080ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkPaint& paint) { 2081ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 2082ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (paint.canComputeFastBounds()) { 2083ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkRect storage; 2084ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon // Note we're using the entire oval as the bounds. 2085ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 2086ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon return; 2087ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2088ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2089ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2090822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval) 2091ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2092ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon while (iter.next()) { 2093a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint()); 2094ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2095ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2096ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_END 2097ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon} 2098ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 209941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 21009881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 21014ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 2102822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 210387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 210487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 210587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 21064ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 21074ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 21084ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 21094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 21104ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2111f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2112f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 21134ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2114f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2115f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 21164ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2117f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2118822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &rrect.getBounds()) 2119f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2120f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2121a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRRect(rrect, looper.paint()); 2122f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2123f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2124f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 21254ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21264ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2127822128b475c1782788f96e7a1a848d0affb878b1Mike Reedvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { 2128ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 2129822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 213087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 213187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 213287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2133ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 213425c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2135822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &outer.getBounds()) 213625c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2137ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2138a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawDRRect(outer, inner, looper.paint()); 2139ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 214025c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2141ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2142ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 21434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 214441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 21459881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 21469364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 21479364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 21489364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 21499364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 2150822128b475c1782788f96e7a1a848d0affb878b1Mike Reed const SkRect& pathBounds = path.getBounds(); 2151fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 2152822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 215387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 215487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 215587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 21568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21570b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 2158822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (pathBounds.width() <= 0 && pathBounds.height() <= 0) { 21596803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2160fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 21616651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2162fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2163fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 21648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2165822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds) 21668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 2168a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPath(path, looper.paint()); 21698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2174262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2175262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2176262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2177262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2178262a71b7f95ce98ff3dd8dba845afbd724470903reed 2179262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2180c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2181262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2182262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2183262a71b7f95ce98ff3dd8dba845afbd724470903reed 2184262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2185262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2186262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2187262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2188262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2189262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2190262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2191262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2192262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2193262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2194262a71b7f95ce98ff3dd8dba845afbd724470903reed 2195a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 21969881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2197a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2198a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 219996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 220087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 220187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 220287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 220387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 220487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 220587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 220687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2207a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22089d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2209a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 221096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2211a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2212a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2213262a71b7f95ce98ff3dd8dba845afbd724470903reed 2214a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2215129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2216129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2217129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2218a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(image); 2219a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2220129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2221129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2222129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2223129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2224262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2225262a71b7f95ce98ff3dd8dba845afbd724470903reed 2226a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2227262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2228a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2229a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkPoint pt; 2230a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->ctm().mapXY(x, y, &pt); 2231a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawSpecial(special.get(), 2232a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2233a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2234262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2235a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImage(image, x, y, pnt); 2236262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2237a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22389d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2239a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2240b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2241b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 224241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2243562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 22449881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 224596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2246c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 224787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 224887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 224987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 225087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 225187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 225287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2253a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2254a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 225596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2256a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2257a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22589d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2259c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2260c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 22619d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2262a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2263a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint); 2264a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22659d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2266a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2267b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2268b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 226941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 22709881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 22718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 22728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 227333366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 227433366974d43eae80e22284a2e445225c343859dareed return; 227533366974d43eae80e22284a2e445225c343859dareed } 227633366974d43eae80e22284a2e445225c343859dareed 227733366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 227833366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 227933366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 228033366974d43eae80e22284a2e445225c343859dareed } 228133366974d43eae80e22284a2e445225c343859dareed 2282822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect bounds; 2283822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bitmap.getBounds(&bounds); 2284822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bounds.offset(x, y); 2285822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bool canFastBounds = paint->canComputeFastBounds(); 2286822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (canFastBounds) { 2287822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 2288822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (this->quickReject(paint->computeFastBounds(bounds, &storage))) { 228987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 229087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 22918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22924b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2293a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2294822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bool drawAsSprite = canFastBounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), 2295822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bitmap.height(), *paint); 2296129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2297a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(bitmap); 2298a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2299129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2300129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2301129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2302129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2303822128b475c1782788f96e7a1a848d0affb878b1Mike Reed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2304822128b475c1782788f96e7a1a848d0affb878b1Mike Reed 2305822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 230633366974d43eae80e22284a2e445225c343859dareed 230733366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2308262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2309a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2310262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2311a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->ctm().mapXY(x, y, &pt); 2312a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawSpecial(special.get(), 2313a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2314a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2315262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2316a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmap(bitmap, matrix, looper.paint()); 2317262a71b7f95ce98ff3dd8dba845afbd724470903reed } 231833366974d43eae80e22284a2e445225c343859dareed } 2319fbfa25802709139c2f14e304319c9541da65ca27msarett 232033366974d43eae80e22284a2e445225c343859dareed LOOPER_END 23218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23239987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 23247112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2325eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2326a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 232750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 23288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 23298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 233074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 233196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2332c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 233387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 233487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 233587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23373d60812865bb034851da777a91413ab584929887reed@google.com 233833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 233996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 234033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 23418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23427064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2343c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2344c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 23457064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 234633535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2347a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint); 2348f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 23497064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 235033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 23518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 235341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2354562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 23559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 23569987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2357562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 23589987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23599987ec3791336bad6af5cbe513564786b2df55aareed@google.com 23604c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 23614c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 23624c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 23639d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 236496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2365c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 236687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 236787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 236887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23693d60812865bb034851da777a91413ab584929887reed@google.com } 23709d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23714c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 237296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23734c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23744c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23759d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2376c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 23779d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23784c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 2379a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageNine(image, center, dst, looper.paint()); 23809987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 23819d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23824c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23839987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23849987ec3791336bad6af5cbe513564786b2df55aareed@google.com 238541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 238641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 23879881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 23889987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 23899987ec3791336bad6af5cbe513564786b2df55aareed@google.com 239096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2391c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 239287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 239387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 239487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23954c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23969d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23974c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 239896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23994c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24004c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24019d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2402c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24039d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24044c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 2405a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint()); 24064c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24079d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24084c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 24099987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24109987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2411168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2412168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2413168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2414168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2415168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2416168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2417168820625c35a8c19f66c661efcbce7a5e334837msarett } 2418168820625c35a8c19f66c661efcbce7a5e334837msarett } 2419168820625c35a8c19f66c661efcbce7a5e334837msarett 2420168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2421168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2422168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2423168820625c35a8c19f66c661efcbce7a5e334837msarett } 2424168820625c35a8c19f66c661efcbce7a5e334837msarett 2425168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2426168820625c35a8c19f66c661efcbce7a5e334837msarett 2427168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2428a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint()); 2429168820625c35a8c19f66c661efcbce7a5e334837msarett } 2430168820625c35a8c19f66c661efcbce7a5e334837msarett 2431168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2432168820625c35a8c19f66c661efcbce7a5e334837msarett} 2433168820625c35a8c19f66c661efcbce7a5e334837msarett 2434168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, 2435168820625c35a8c19f66c661efcbce7a5e334837msarett const SkRect& dst, const SkPaint* paint) { 2436168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2437168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2438168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2439168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2440168820625c35a8c19f66c661efcbce7a5e334837msarett } 2441168820625c35a8c19f66c661efcbce7a5e334837msarett } 2442168820625c35a8c19f66c661efcbce7a5e334837msarett 2443168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2444168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2445168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2446168820625c35a8c19f66c661efcbce7a5e334837msarett } 2447168820625c35a8c19f66c661efcbce7a5e334837msarett 2448168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2449168820625c35a8c19f66c661efcbce7a5e334837msarett 2450168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2451a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint()); 2452168820625c35a8c19f66c661efcbce7a5e334837msarett } 2453168820625c35a8c19f66c661efcbce7a5e334837msarett 2454168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2455168820625c35a8c19f66c661efcbce7a5e334837msarett} 2456168820625c35a8c19f66c661efcbce7a5e334837msarett 2457f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2458f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 24591f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2460112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2461112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2462a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2463112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2464f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2465f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2466f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2467f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2468f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2469f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2470f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2471f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2472f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 24732c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 24742c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2475f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2476f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2477e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2478e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 247996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 24808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2483a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawText(text, byteLength, x, y, dfp.paint()); 24848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24864e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2489e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2490e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 249105c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 249205c4a4322e7d4f3417b7df33825bab8603d52051fmalita 249396fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 249487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2497a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset, 2498f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2500b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 25014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2504e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2505e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 250605c4a4322e7d4f3417b7df33825bab8603d52051fmalita 250705c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 250805c4a4322e7d4f3417b7df33825bab8603d52051fmalita 250996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 251087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 25118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25124e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2513a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset, 2514f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 25158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2516b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 25174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2520e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2521e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 252296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 252387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 25248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 2525a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextOnPath(text, byteLength, path, 25264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 25278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2528b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2529945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 25304325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 25314325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 253245561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 253345561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 253445561a0b15fe045ba272c328684c3f7ae290785areed if (cullRect && this->quickReject(*cullRect)) { 253545561a0b15fe045ba272c328684c3f7ae290785areed return; 253645561a0b15fe045ba272c328684c3f7ae290785areed } 253745561a0b15fe045ba272c328684c3f7ae290785areed 253845561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 253945561a0b15fe045ba272c328684c3f7ae290785areed 254045561a0b15fe045ba272c328684c3f7ae290785areed while (iter.next()) { 2541a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextRSXform(text, byteLength, xform, looper.paint()); 254245561a0b15fe045ba272c328684c3f7ae290785areed } 254345561a0b15fe045ba272c328684c3f7ae290785areed 254445561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_END 254545561a0b15fe045ba272c328684c3f7ae290785areed} 254645561a0b15fe045ba272c328684c3f7ae290785areed 254700d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 254800d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 25497ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 255085d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 255196fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 255219653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 255385d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 255487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 255587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 255687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 255787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 255887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 25597ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 25607ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2561024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2562024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2563024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 256496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2565024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 256685d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 256700d5c2c6523321d25b32905ff4822f083a4173eefmalita 2568aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2569aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2570a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextBlob(blob, x, y, dfp.paint(), drawFilter); 257100d5c2c6523321d25b32905ff4822f083a4173eefmalita } 257200d5c2c6523321d25b32905ff4822f083a4173eefmalita 2573aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2574024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2575024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 257600d5c2c6523321d25b32905ff4822f083a4173eefmalita} 257700d5c2c6523321d25b32905ff4822f083a4173eefmalita 2578e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2579e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2580e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25819881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2582ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2583ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawText(text, byteLength, x, y, paint); 2584ac09554dce518e9d4496771f648f3ae17eca857creed } 2585e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2586e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2587e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25889881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2589ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2590ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosText(text, byteLength, pos, paint); 2591ac09554dce518e9d4496771f648f3ae17eca857creed } 2592e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2593e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2594e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 25959881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2596ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2597ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2598ac09554dce518e9d4496771f648f3ae17eca857creed } 2599e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2600e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2601e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 26029881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2603ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2604ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2605ac09554dce518e9d4496771f648f3ae17eca857creed } 2606e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 260745561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 260845561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 260945561a0b15fe045ba272c328684c3f7ae290785areed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextRSXform()"); 261045561a0b15fe045ba272c328684c3f7ae290785areed if (byteLength) { 261145561a0b15fe045ba272c328684c3f7ae290785areed this->onDrawTextRSXform(text, byteLength, xform, cullRect, paint); 261245561a0b15fe045ba272c328684c3f7ae290785areed } 261345561a0b15fe045ba272c328684c3f7ae290785areed} 261400d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 261500d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2616e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 26179881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2618e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 261900d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2620e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 2621e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, 2622e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed const SkPaint& paint) { 2623199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 2624199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 2625199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2626199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon while (iter.next()) { 2627199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon // In the common case of one iteration we could std::move vertices here. 26282f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed iter.fDevice->drawVertices(vertices, bmode, looper.paint()); 2629199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon } 2630199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2631199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_END 2632199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon} 2633199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2634b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 26357d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 26367d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 26379881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 263896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2639b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2640b3c9d1c33caf325aada244204215eb790c228c12dandov } 26416cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2642faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawPatch(cubics, colors, texCoords, bmode, paint); 26439340c2685c0bb0e1e70008acaaf3d1448f074c38msarett} 26449340c2685c0bb0e1e70008acaaf3d1448f074c38msarett 26459340c2685c0bb0e1e70008acaaf3d1448f074c38msarettvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2646faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 26477d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 2648ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2649ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2650ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2651b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2652ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2653ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2654ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26556cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 265696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 26576cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2658ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2659a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, paint); 2660ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26616cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2662ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2663ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2664ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2665a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2666e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2667e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2668e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2669e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2670e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2671e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2672a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2673a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2674a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2675a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2676e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2677e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2678e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 26796a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2680e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 26816a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26826a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2683a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 26842a62e853c27cfacafd5c15ac1077cc13140589bareed // drawable bounds are no longer reliable (e.g. android displaylist) 26852a62e853c27cfacafd5c15ac1077cc13140589bareed // so don't use them for quick-reject 2686a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 26876a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26886a070dc06af4e9f305f9d08a69e34d18ade473cbreed 268971c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 2690faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkColor colors[], int count, SkBlendMode bmode, 269171c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 269271c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 269371c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 269471c3c760a83123ee0b3127b8c65c6394ce541c50reed } 269571c3c760a83123ee0b3127b8c65c6394ce541c50reed 269671c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 269771c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 269871c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 269971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 27009d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 270196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 270271c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 2703a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt); 270471c3c760a83123ee0b3127b8c65c6394ce541c50reed } 270571c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 270671c3c760a83123ee0b3127b8c65c6394ce541c50reed} 270771c3c760a83123ee0b3127b8c65c6394ce541c50reed 2708f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2709f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 2710f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2711f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 2712f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 2713f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 2714a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawAnnotation(rect, key, value); 2715f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2716f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 2717f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2718f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 27198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 27208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 27218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 27228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 27238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2724374772bd61951f01bf84fe17bf53d8867681c9aereedvoid SkCanvas::drawColor(SkColor c, SkBlendMode mode) { 27259881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 27268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 27278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2729374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(mode); 27308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 27318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 27349881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 27353661bc997620899695041010a750d11dbe8a972dMike Reed const SkPoint pt = { x, y }; 27368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 27378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27393661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint) { 27409881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 27418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 27424b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 27448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 27458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 27468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27483661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint) { 27499881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 27508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 27518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 27528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 27558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 27564ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 27578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 27608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27619881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 27628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 27634ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 27644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 27654ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 27668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 27678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 27688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 27728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 27738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27749881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 277521af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon if (oval.isEmpty() || !sweepAngle) { 277621af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon return; 27778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 277821af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint); 27798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 27828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 27838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 27849881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 27858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 27864b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 27888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 27898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2791f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 27921c2c441fede0ae9573afc098017011e3439624a9reed 27931c2c441fede0ae9573afc098017011e3439624a9reed/** 27941c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 27951c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 27961c2c441fede0ae9573afc098017011e3439624a9reed * 27971c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 27981c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 27991c2c441fede0ae9573afc098017011e3439624a9reed */ 28001c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 28019b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2802d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 2803e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 2804e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 28051c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 2806e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2807e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 2808e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 2809e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 2810e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2811e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 2812e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2813e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 2814d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2815d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 28169b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2817d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2818d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2819d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 2820d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 2821d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 2822d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 2823d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2824d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 2825d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 2826d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2827d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 2828d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 2829d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2830d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2831d028180f0310cf2b23f9744256a41697b0683e67fmalita 2832a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2833c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 28348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 283695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 283795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::drawShadowedPicture(const SkPicture* picture, 283895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 2839e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 2840e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 284195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack RETURN_ON_NULL(picture); 284295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 284395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); 284495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 2845e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack this->onDrawShadowedPicture(picture, matrix, paint, params); 284695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 284795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 284895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::onDrawShadowedPicture(const SkPicture* picture, 284995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 2850e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 2851e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 2852904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (!paint || paint->canComputeFastBounds()) { 2853904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkRect bounds = picture->cullRect(); 2854904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (paint) { 2855904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack paint->computeFastBounds(bounds, &bounds); 2856904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 2857904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (matrix) { 2858904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack matrix->mapRect(&bounds); 2859904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 2860904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (this->quickReject(bounds)) { 2861904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack return; 2862904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 2863904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 2864904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2865904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2866904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2867e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> povDepthMap; 2868e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> diffuseMap; 2869e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 2870904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // povDepthMap 2871904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 2872904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkLights::Builder builder; 2873772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), 2874772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack SkVector3::Make(0.0f, 0.0f, 1.0f))); 2875904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkLights> povLight = builder.finish(); 2876904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2877904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 2878904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 2879904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 2880904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 2881904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2882904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Create a new surface (that matches the backend of canvas) 2883904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // to create the povDepthMap 2884904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 2885904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2886904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Wrap another SPFCanvas around the surface 2887904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 2888904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 2889904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2890904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // set the depth map canvas to have the light as the user's POV 2891904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->setLights(std::move(povLight)); 2892904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2893904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->drawPicture(picture); 2894904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack povDepthMap = surf->makeImageSnapshot(); 2895904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 2896904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2897904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // diffuseMap 2898904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 2899904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 2900904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 2901904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 2902904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 2903904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2904904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 2905904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack surf->getCanvas()->drawPicture(picture); 2906904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2907904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap = surf->makeImageSnapshot(); 2908904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 2909904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 2910904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_TileMode, 2911904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 2912904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_TileMode, 2913904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 2914b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2915b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: pass the depth to the shader in vertices, or uniforms 2916b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // so we don't have to render depth and color separately 2917b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack for (int i = 0; i < fLights->numLights(); ++i) { 2918b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // skip over ambient lights; they don't cast shadows 2919b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // lights that have shadow maps do not need updating (because lights are immutable) 2920b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkImage> depthMap; 2921b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkISize shMapSize; 2922b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2923b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).getShadowMap() != nullptr) { 2924b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack continue; 2925b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 2926b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2927b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).isRadial()) { 2928b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fHeight = 1; 2929b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fWidth = (int) picture->cullRect().width(); 2930b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2931b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(diffuseMap->width(), 1, 2932b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 2933b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 2934b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2935b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create new surface (that matches the backend of canvas) 2936b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 2937b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 2938b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2939b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 2940b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkCanvas* depthMapCanvas = surf->getCanvas(); 2941b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2942b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 2943b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 2944b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 2945b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2946b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShader> shadowMapShader; 2947b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapShader = SkRadialShadowMapShader::Make( 2948b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack povDepthShader, curLight, 2949b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 2950b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 2951b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2952b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowMapPaint; 2953b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint.setShader(std::move(shadowMapShader)); 2954b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2955b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(curLight); 2956b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2957b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawRect(SkRect::MakeIWH(diffuseMap->width(), 2958b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack diffuseMap->height()), 2959b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint); 2960b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2961b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 2962b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2963b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else { 2964b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: compute the correct size of the depth map from the light properties 2965b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: maybe add a kDepth_8_SkColorType 2966b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: find actual max depth of picture 2967b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( 2968b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i), 255, 2969b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 2970b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 2971b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2972b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 2973b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 2974b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 2975b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2976b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create a new surface (that matches the backend of canvas) 2977b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 2978b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 2979b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2980b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 2981b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 2982b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 2983b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setShadowParams(params); 2984b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2985b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // set the depth map canvas to have the light we're drawing. 2986b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 2987b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 2988b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 2989b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(std::move(curLight)); 2990b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2991b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawPicture(picture); 2992b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 2993b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 2994b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 2995b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (params.fType == SkShadowParams::kNoBlur_ShadowType) { 2996b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(std::move(depthMap)); 2997b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else if (params.fType == SkShadowParams::kVariance_ShadowType) { 2998b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // we blur the variance map 2999b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint blurPaint; 3000b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurPaint.setImageFilter(SkImageFilter::MakeBlur(params.fShadowRadius, 3001b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack params.fShadowRadius, nullptr)); 3002b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3003b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 3004b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3005b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3006b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3007b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); 3008b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3009b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); 3010b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3011b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); 3012b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3013b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3014b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3015b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowPaint; 3016904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader), 3017904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack std::move(diffuseShader), 3018b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights, 3019904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap->width(), 3020e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack diffuseMap->height(), 3021e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack params); 3022904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3023904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack shadowPaint.setShader(shadowShader); 3024904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3025904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), shadowPaint); 302695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 302795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 302895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 30298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 30308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 30318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30323aafe111b6cc388400092851cc53bbbdfcb8a81creedSkCanvas::LayerIter::LayerIter(SkCanvas* canvas) { 303399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 30348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 30368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30373aafe111b6cc388400092851cc53bbbdfcb8a81creed fImpl = new (fStorage) SkDrawIter(canvas); 30388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 30398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 30428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 30438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 30468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 30478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30491f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 305099330ba6227137866a0dbd63478d36f335203ebdMike Reed return fImpl->fDevice; 30518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 3054a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fImpl->fDevice->ctm(); 30558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 30588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 305996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 30608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 30618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 30638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3065a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkCanvas::LayerIter::clip(SkRegion* rgn) const { 3066a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fImpl->fDevice->onAsRgnClip(rgn); 3067a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed} 3068a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 30698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 30708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 307120a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 307220a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 307320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 30743107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 30753107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 30763107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 30773107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 30783107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 30793107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 30803107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 30813107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 30823107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30833107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 30843107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 30853107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 308628fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 30879e3dbdff53f2d9957626a17a279730cda70f17bajunov case kRGBA_F16_SkColorType: 30883107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 30893107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 30903107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 30913107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 30923107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30933107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 30943107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 30953107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30965df4934b3e40cdc378e225d1dda39f015cae9baeMike Reedstd::unique_ptr<SkCanvas> SkCanvas::MakeRasterDirect(const SkImageInfo& info, void* pixels, 30975df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed size_t rowBytes) { 309842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 309996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 310042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3101eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 310242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 310342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 310496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 310542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 31065df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed return skstd::make_unique<SkCanvas>(bitmap); 310742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 3108d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3109d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 3110d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3111d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 3112a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 3113d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 3114d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 3115d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 311649f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 3117a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 3118d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 3119a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 3120d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3121a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 312249f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 3123d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 3124d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 31256cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 312649f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 3127d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 3128d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3129d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3130d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3131d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3132d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 3133d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3134e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 3135ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 3136ee424acbb87bf999be132a437527e656e37541d7Florin Malita 3137ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkNoDrawCanvas::SkNoDrawCanvas(int width, int height) 3138ee424acbb87bf999be132a437527e656e37541d7Florin Malita : INHERITED(SkIRect::MakeWH(width, height), kConservativeRasterClip_InitFlag) {} 3139ee424acbb87bf999be132a437527e656e37541d7Florin Malita 3140439ace939b6aaa58408ece0e9e89b633353571aeFlorin MalitaSkNoDrawCanvas::SkNoDrawCanvas(const SkIRect& bounds) 3141439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita : INHERITED(bounds, kConservativeRasterClip_InitFlag) {} 3142439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita 3143ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkCanvas::SaveLayerStrategy SkNoDrawCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { 3144ee424acbb87bf999be132a437527e656e37541d7Florin Malita (void)this->INHERITED::getSaveLayerStrategy(rec); 3145ee424acbb87bf999be132a437527e656e37541d7Florin Malita return kNoLayer_SaveLayerStrategy; 3146ee424acbb87bf999be132a437527e656e37541d7Florin Malita} 3147ee424acbb87bf999be132a437527e656e37541d7Florin Malita 3148ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 314973603f3c52ffd89fe9d035be827b566a0e7d3b79reed 315073603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kDifference_Op == (int)kDifference_SkClipOp, ""); 315173603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kIntersect_Op == (int)kIntersect_SkClipOp, ""); 315273603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kUnion_Op == (int)kUnion_SkClipOp, ""); 315373603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kXOR_Op == (int)kXOR_SkClipOp, ""); 315473603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReverseDifference_Op == (int)kReverseDifference_SkClipOp, ""); 315573603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReplace_Op == (int)kReplace_SkClipOp, ""); 3156356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3157356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 3158356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3159356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkCanvas::accessTopRasterHandle() const { 3160356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (fAllocator && fMCRec->fTopLayer->fDevice) { 3161713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita const auto& dev = fMCRec->fTopLayer->fDevice; 3162356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle handle = dev->getRasterHandle(); 3163356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIPoint origin = dev->getOrigin(); 3164356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkMatrix ctm = this->getTotalMatrix(); 3165356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed ctm.preTranslate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y())); 3166356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3167356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIRect clip = fMCRec->fRasterClip.getBounds(); 3168356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.offset(-origin.x(), -origin.y()); 3169108f55ed5d0b63baf653e4e443cc469df887c811Mike Reed if (!clip.intersect(0, 0, dev->width(), dev->height())) { 3170356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.setEmpty(); 3171356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3172356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3173356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator->updateHandle(handle, ctm, clip); 3174356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return handle; 3175356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3176356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 3177356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3178356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3179356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstatic bool install(SkBitmap* bm, const SkImageInfo& info, 3180356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkRasterHandleAllocator::Rec& rec) { 3181356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return bm->installPixels(info, rec.fPixels, rec.fRowBytes, nullptr, 3182356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed rec.fReleaseProc, rec.fReleaseCtx); 3183356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3184356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3185356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkRasterHandleAllocator::allocBitmap(const SkImageInfo& info, 3186356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap* bm) { 3187356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Rec rec; 3188356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!this->allocHandle(info, &rec) || !install(bm, info, rec)) { 3189356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 3190356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3191356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return rec.fHandle; 3192356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3193356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3194356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstd::unique_ptr<SkCanvas> 3195356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::MakeCanvas(std::unique_ptr<SkRasterHandleAllocator> alloc, 3196356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkImageInfo& info, const Rec* rec) { 3197356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!alloc || !supported_for_raster_canvas(info)) { 3198356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 3199356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3200356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3201356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap bm; 3202356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed Handle hndl; 3203356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3204356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (rec) { 3205356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = install(&bm, info, *rec) ? rec->fHandle : nullptr; 3206356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } else { 3207356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = alloc->allocBitmap(info, &bm); 3208356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3209356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return hndl ? std::unique_ptr<SkCanvas>(new SkCanvas(bm, std::move(alloc), hndl)) : nullptr; 3210356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3211