SkCanvas.cpp revision 343fe49b82d5b220d64c64f253bb362026006632
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" 310017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 32356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#include "SkRasterHandleAllocator.h" 334ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 344418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 352a475eae622adc1e8fa29206be1eaf862c23548eCary Clark#include "SkString.h" 3697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 377ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 39a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 408f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 41d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 43644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 447354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 45644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 463b65598bceb65736486db27ed49a56d787032747Brian Osman#include "SkGr.h" 47e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 48644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 49ebfce6d9b42198e04288a15953f40c395a7b6139Mike Reed#include "SkClipOpPriv.h" 50199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#include "SkVertices.h" 51644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 52e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 53e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 54139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedclass SkNoPixelsDevice : public SkBaseDevice { 55139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedpublic: 56139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props) 57139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed : SkBaseDevice(SkImageInfo::MakeUnknown(bounds.width(), bounds.height()), props) 58566e53c7003920ff45c72498754060804b657c68Mike Reed { 59e393a629491e9a52dd6662983d2bfd424541957eMike Reed // this fails if we enable this assert: DiscardableImageMapTest.GetDiscardableImagesInRectMaxImage 60e393a629491e9a52dd6662983d2bfd424541957eMike Reed //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0); 61566e53c7003920ff45c72498754060804b657c68Mike Reed } 62139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 63139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void resetForNextPicture(const SkIRect& bounds) { 64e393a629491e9a52dd6662983d2bfd424541957eMike Reed //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0); 65139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed this->privateResize(bounds.width(), bounds.height()); 66139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed } 67139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 68139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedprotected: 69139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed // We don't track the clip at all (for performance), but we have to respond to some queries. 70139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed // We pretend to be wide-open. We could pretend to always be empty, but that *seems* worse. 71139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onSave() override {} 72139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onRestore() override {} 73139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipRect(const SkRect& rect, SkClipOp, bool aa) override {} 74139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override {} 75139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipPath(const SkPath& path, SkClipOp, bool aa) override {} 76139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override {} 77139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override {} 78139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed bool onClipIsAA() const override { return false; } 79139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void onAsRgnClip(SkRegion* rgn) const override { 80139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed rgn->setRect(SkIRect::MakeWH(this->width(), this->height())); 81139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed } 82139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed ClipType onGetClipType() const override { 83139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed return kRect_ClipType; 84139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed } 85139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 86139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPaint(const SkPaint& paint) override {} 87139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&) override {} 88139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawRect(const SkRect&, const SkPaint&) override {} 89139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawOval(const SkRect&, const SkPaint&) override {} 90139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawRRect(const SkRRect&, const SkPaint&) override {} 91139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPath(const SkPath&, const SkPaint&, const SkMatrix*, bool) override {} 92139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) override {} 93139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawSprite(const SkBitmap&, int, int, const SkPaint&) override {} 94139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint&, 95139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed SkCanvas::SrcRectConstraint) override {} 96139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override {} 97139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawPosText(const void*, size_t, const SkScalar[], int, const SkPoint&, 98139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed const SkPaint&) override {} 99139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed void drawDevice(SkBaseDevice*, int, int, const SkPaint&) override {} 1002f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override {} 101139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 102139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reedprivate: 103139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed typedef SkBaseDevice INHERITED; 104139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed}; 105139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 106139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 107139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed 108c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 109c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 110c83a29759a5c2966da5ab973e4fd90763e4c962breed * 111c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 112c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 113c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 114c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 115c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 116c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 117c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 11899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 11999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 12099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 12199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 12299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 12399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 12499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 12599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 12699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 127c83a29759a5c2966da5ab973e4fd90763e4c962breed 128c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 129c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 130a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 131a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if we're clipped at all, we can't overwrite the entire surface 132a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed { 133a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* base = this->getDevice(); 134a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* top = this->getTopDevice(); 135a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (base != top) { 136a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return false; // we're in a saveLayer, so conservatively don't assume we'll overwrite 137a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 138a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (!base->clipIsWideOpen()) { 139a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return false; 140a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 141c83a29759a5c2966da5ab973e4fd90763e4c962breed } 142c83a29759a5c2966da5ab973e4fd90763e4c962breed 143c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 144c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!this->getTotalMatrix().isScaleTranslate()) { 145c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 146c83a29759a5c2966da5ab973e4fd90763e4c962breed } 147c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary 148c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary SkRect devRect; 149c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary this->getTotalMatrix().mapRectScaleTranslate(&devRect, *rect); 150c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!devRect.contains(bounds)) { 151c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 152c83a29759a5c2966da5ab973e4fd90763e4c962breed } 153c83a29759a5c2966da5ab973e4fd90763e4c962breed } 154c83a29759a5c2966da5ab973e4fd90763e4c962breed 155c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 156c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 157c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 158c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 159c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 160c83a29759a5c2966da5ab973e4fd90763e4c962breed } 161c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 162c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 163c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 164c83a29759a5c2966da5ab973e4fd90763e4c962breed } 165c83a29759a5c2966da5ab973e4fd90763e4c962breed } 166c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 167c83a29759a5c2966da5ab973e4fd90763e4c962breed} 168c83a29759a5c2966da5ab973e4fd90763e4c962breed 169c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 170c83a29759a5c2966da5ab973e4fd90763e4c962breed 171d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 172d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 173d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 174d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 175d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 176d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 177d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 178d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1790acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1800acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1810acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1820acf1b4b3645772d220c720313821bac389751b5reed} 1830acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1840acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1850acf1b4b3645772d220c720313821bac389751b5reed} 1860acf1b4b3645772d220c720313821bac389751b5reed 187da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2112c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 2122c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 213c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 21497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 215c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 216c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 217c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 218c83a29759a5c2966da5ab973e4fd90763e4c962breed } 219c83a29759a5c2966da5ab973e4fd90763e4c962breed} 220c83a29759a5c2966da5ab973e4fd90763e4c962breed 221c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 222c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 223c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 224c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 225c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 226c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 227c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 228c83a29759a5c2966da5ab973e4fd90763e4c962breed // 229c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 230c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 231c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 232c83a29759a5c2966da5ab973e4fd90763e4c962breed } 233c83a29759a5c2966da5ab973e4fd90763e4c962breed } 234c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 23597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 23697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 23797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2401f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 248713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita DeviceCM* fNext; 249713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita sk_sp<SkBaseDevice> fDevice; 250713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita SkRasterClip fClip; 251713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita std::unique_ptr<const SkPaint> fPaint; // may be null (in the future) 252713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer 25353f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita sk_sp<SkImage> fClipImage; 25453f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkMatrix fClipMatrix; 255713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita 25653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita DeviceCM(sk_sp<SkBaseDevice> device, const SkPaint* paint, const SkMatrix& stashed, 257b34ab04884f6219b93c1f143c83a1fc60fded40cMike Klein const SkImage* clipImage, const SkMatrix* clipMatrix) 25896fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 259713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita , fDevice(std::move(device)) 260713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita , fPaint(paint ? skstd::make_unique<SkPaint>(*paint) : nullptr) 2618c30a8196dd5903d2d23b4d0a5dc888e802bf698reed , fStashedMatrix(stashed) 262b34ab04884f6219b93c1f143c83a1fc60fded40cMike Klein , fClipImage(sk_ref_sp(const_cast<SkImage*>(clipImage))) 26353f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita , fClipMatrix(clipMatrix ? *clipMatrix : SkMatrix::I()) 264713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita {} 2654b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 266feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 267feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 268feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 269feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 270feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 271feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2831f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 284d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 291a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed DeviceCM* fTopLayer; 292a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkConservativeClip fRasterClip; 293a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkMatrix fMatrix; 294a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed int fDeferredSaveCount; 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 296a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed MCRec() { 29796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 29896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 29996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 3002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 3012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 302b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 303d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 304d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 305d954498c01ccf0417feacf89e45d0c62a06a813breed } 306343fe49b82d5b220d64c64f253bb362026006632Jim Van Verth MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 307d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 30896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 309d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 311b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 31682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 317385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 320feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 321feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 322feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 323feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 324feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 325feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 326feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 327feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 328feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 331a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedclass SkDrawIter { 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 333a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkDrawIter(SkCanvas* canvas) 334a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed : fDevice(nullptr), fCurrLayer(canvas->fMCRec->fTopLayer), fPaint(nullptr) 335a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed {} 3364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 338f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 339f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 340713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita fDevice = rec->fDevice.get(); 341713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita fPaint = rec->fPaint.get(); 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 34396fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3484b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3496f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3506f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3526f8f292aa768869a9e85c314b124875f57504f2creed@google.com 35399330ba6227137866a0dbd63478d36f335203ebdMike Reed SkBaseDevice* fDevice; 35499330ba6227137866a0dbd63478d36f335203ebdMike Reed 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 360713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita#define FOR_EACH_TOP_DEVICE( code ) \ 361713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita do { \ 362713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita DeviceCM* layer = fMCRec->fTopLayer; \ 363713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita while (layer) { \ 364713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita SkBaseDevice* device = layer->fDevice.get(); \ 365713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita if (device) { \ 366713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita code; \ 367713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita } \ 368713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita layer = layer->fNext; \ 369713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita } \ 3707627fa51044e35dc21251f925b56f6dd6887df97Mike Reed } while (0) 3717627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 374dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 375dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 376dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 377dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 378dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 379dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 38096fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 381dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 382d053ce9c54d4e5937a142278359e5a4cde18095ereedstatic sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) { 383dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 384dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 38596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 386dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 387dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 388d053ce9c54d4e5937a142278359e5a4cde18095ereed SkColorFilter* imgCFPtr; 389d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!imgf->asAColorFilter(&imgCFPtr)) { 39096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 391dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 392d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> imgCF(imgCFPtr); 393dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 394dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 39596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 396dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 398dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 399dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 401dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 402d053ce9c54d4e5937a142278359e5a4cde18095ereed return SkColorFilter::MakeComposeFilter(std::move(imgCF), sk_ref_sp(paintCF)); 403dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 404dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 40587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 40687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 40787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 40887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 40987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 41087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 41187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 41287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 41387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 41487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 41587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 41687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 41787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 41887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 41987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 42087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 42187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 42287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 42387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 42487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 42987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 43087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4323aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, bool skipLayerForImageFilter = false, 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4344e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 43553d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4377765000709dc64eb23be7df47d1f995d1f787115fmalita#else 4387765000709dc64eb23be7df47d1f995d1f787115fmalita fFilter = nullptr; 4397765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 4404a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4414e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4425c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4434e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 445d053ce9c54d4e5937a142278359e5a4cde18095ereed auto simplifiedCF = image_to_color_filter(fOrigPaint); 446dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 447dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 448d053ce9c54d4e5937a142278359e5a4cde18095ereed paint->setColorFilter(std::move(simplifiedCF)); 44996fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 450dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 451dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 452dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 453dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4545c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4555c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4565c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4575c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4585c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4595c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4605c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4615c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4625c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4635c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4645c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4655c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4665c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4675c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4685c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4698926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 470693fdbd6b81a860657612e7604430dd55d6e721bMike Reed tmp.setImageFilter(fPaint->refImageFilter()); 471374772bd61951f01bf84fe17bf53d8867681c9aereed tmp.setBlendMode(fPaint->getBlendMode()); 47287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 47387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 47487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 47587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 47687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 477bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), 47876033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4795c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 4805c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 4818926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4828926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 48379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 48473fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby fLooperContext = looper->makeContext(canvas, &fAlloc); 485129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 486129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 48796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 488129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 4895c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 49274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 4934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 4945c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 4958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 4968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4974e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 49974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 50474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 505129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 506129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 507129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 508129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 509129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 510129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 511129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 512129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 513129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 514fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 51574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 51773fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 518dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5192c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5202c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5212c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5222c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5232c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5245c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5252c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 526129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 52779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 52873fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby char fStorage[48]; 52973fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby SkArenaAlloc fAlloc {fStorage}; 530129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 531129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 534129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 53596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 536129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5375c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 538632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 539dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 540dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5418926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5425c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 54396fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 544374772bd61951f01bf84fe17bf53d8867681c9aereed paint->setBlendMode(SkBlendMode::kSrcOver); 545129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5468926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 54779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 548129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 549129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 550129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 551129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 552971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 553971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 554971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 555971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 55696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 557129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 558632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 559632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 560129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 561129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5628926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 563129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 56479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5664e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5674e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 568632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 569632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 57096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5724e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5754e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5783aafe111b6cc388400092851cc53bbbdfcb8a81creed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 5793aafe111b6cc388400092851cc53bbbdfcb8a81creed this->predrawNotify(); \ 5803aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \ 5813aafe111b6cc388400092851cc53bbbdfcb8a81creed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 582262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 583262a71b7f95ce98ff3dd8dba845afbd724470903reed 584262a71b7f95ce98ff3dd8dba845afbd724470903reed 5858926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 58697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5873aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, true); \ 5888926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 5898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 5908926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 59178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 59297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5933aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 5944e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 5964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 597c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 598c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 5993aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 600c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 601c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 602c83a29759a5c2966da5ab973e4fd90763e4c962breed 6034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 607fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline SkRect qr_clip_bounds(const SkIRect& bounds) { 608fbfa25802709139c2f14e304319c9541da65ca27msarett if (bounds.isEmpty()) { 609fbfa25802709139c2f14e304319c9541da65ca27msarett return SkRect::MakeEmpty(); 610fbfa25802709139c2f14e304319c9541da65ca27msarett } 611fbfa25802709139c2f14e304319c9541da65ca27msarett 612fbfa25802709139c2f14e304319c9541da65ca27msarett // Expand bounds out by 1 in case we are anti-aliasing. We store the 613fbfa25802709139c2f14e304319c9541da65ca27msarett // bounds as floats to enable a faster quick reject implementation. 614fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect dst; 615fbfa25802709139c2f14e304319c9541da65ca27msarett SkNx_cast<float>(Sk4i::Load(&bounds.fLeft) + Sk4i(-1,-1,1,1)).store(&dst.fLeft); 616fbfa25802709139c2f14e304319c9541da65ca27msarett return dst; 617fbfa25802709139c2f14e304319c9541da65ca27msarett} 618fbfa25802709139c2f14e304319c9541da65ca27msarett 619feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 620feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 621feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 622feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 623feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 624139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed // know that the device is a SkNoPixelsDevice. 625713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita static_cast<SkNoPixelsDevice*>(fMCRec->fLayer->fDevice.get())->resetForNextPicture(bounds); 626fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(bounds); 6279637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 628feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 629feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 630d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 63142b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 63242b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 63342b73eb00367c8315974b1c374308d20efa78897reed } 63442b73eb00367c8315974b1c374308d20efa78897reed 63545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 6362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 63796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 640a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed new (fMCRec) MCRec; 6415f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect); 6429637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 644a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 645a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 64653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita new (fDeviceCMStorage) DeviceCM(sk_ref_sp(device), nullptr, fMCRec->fMatrix, nullptr, nullptr); 647b679ca8926a832274b14fdb512f88f64b61d32eareed 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 65096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 651f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 652f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 653efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 654efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 65578e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 656fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds()); 657c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 658c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 659f92c86642a1875da54d54b447f006cb9dfbbb35creed } 660fbfa25802709139c2f14e304319c9541da65ca27msarett 661f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 664cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 665e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6664a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 667e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6688d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 669ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 67096fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6718d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6728d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 67396a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 674e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 67596a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 676e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 677e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 678b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 679566e53c7003920ff45c72498754060804b657c68Mike Reed this->init(new SkNoPixelsDevice(SkIRect::MakeWH(SkTMax(width, 0), SkTMax(height, 0)), fProps), 680385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 681d954498c01ccf0417feacf89e45d0c62a06a813breed} 682e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 68378e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 684d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6854a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 686d954498c01ccf0417feacf89e45d0c62a06a813breed{ 687d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 688b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 689566e53c7003920ff45c72498754060804b657c68Mike Reed SkIRect r = bounds.isEmpty() ? SkIRect::MakeEmpty() : bounds; 690566e53c7003920ff45c72498754060804b657c68Mike Reed this->init(new SkNoPixelsDevice(r, fProps), flags)->unref(); 69127a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 693d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 694d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6957b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 696d954498c01ccf0417feacf89e45d0c62a06a813breed{ 697d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 698b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 699d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 702fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 703fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7047b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 705fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 706fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 707fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 708fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 709fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 710fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7114a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7123716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7134a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 7143716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7153716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 716b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 717704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 718704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7194a8126e7f81384526629b1e21bf89b632ea13cd9reed} 72029c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 721356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocator> alloc, 722356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle hndl) 7234a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7244a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 725356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed , fAllocator(std::move(alloc)) 7264a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7274a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 728b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 729356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl)); 730704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 733356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap) : SkCanvas(bitmap, nullptr, nullptr) {} 734356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 73531f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 73631f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt SarettSkCanvas::SkCanvas(const SkBitmap& bitmap, ColorBehavior) 73731f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 73831f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 73931f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett , fAllocator(nullptr) 74031f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett{ 74131f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett inc_canvas(); 74231f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett 74331f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett SkBitmap tmp(bitmap); 74431f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett *const_cast<SkImageInfo*>(&tmp.info()) = tmp.info().makeColorSpace(nullptr); 74531f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett sk_sp<SkBaseDevice> device(new SkBitmapDevice(tmp, fProps, nullptr)); 74631f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett this->init(device.get(), kDefault_InitFlags); 74731f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett} 74831f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett#endif 74931f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7537c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 756385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 757b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 76153d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 76751985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7717765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 77374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 77474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 77574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 77696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 77774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 77874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 77974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 78074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 78174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 784bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 785ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed this->onFlush(); 786ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 787ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 788ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedvoid SkCanvas::onFlush() { 7891f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 790bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 791bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 792bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 793bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 794bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 795afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 796afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 7974ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 7984ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 7994ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 800afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8014ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 802afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 803afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 804afc7cce5d68663934128d76963cd501f771d71desenorblanco } 805afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 806210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 807210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8081f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 810c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 812713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita return rec->fLayer->fDevice.get(); 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8150ed3b640c9da71fbbd73c65a4ec1992f85596271Florin MalitaSkBaseDevice* SkCanvas::getTopDevice() const { 816713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita return fMCRec->fTopLayer->fDevice.get(); 8179266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8189266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 81996472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 820a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 821a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 822a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 823a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 824db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 82503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->readPixels(dstInfo, dstP, rowBytes, x, y); 82651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 82751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 82812e946b4bfdf598bffb276776ea6e25439e25265Mike Reedbool SkCanvas::readPixels(const SkPixmap& pm, int x, int y) { 82912e946b4bfdf598bffb276776ea6e25439e25265Mike Reed return pm.addr() && this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y); 83012e946b4bfdf598bffb276776ea6e25439e25265Mike Reed} 83112e946b4bfdf598bffb276776ea6e25439e25265Mike Reed 83212e946b4bfdf598bffb276776ea6e25439e25265Mike Reedbool SkCanvas::readPixels(const SkBitmap& bm, int x, int y) { 83312e946b4bfdf598bffb276776ea6e25439e25265Mike Reed SkPixmap pm; 83412e946b4bfdf598bffb276776ea6e25439e25265Mike Reed return bm.peekPixels(&pm) && this->readPixels(pm, x, y); 83512e946b4bfdf598bffb276776ea6e25439e25265Mike Reed} 83612e946b4bfdf598bffb276776ea6e25439e25265Mike Reed 8374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 8384edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed SkPixmap pm; 8394edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed if (bitmap.peekPixels(&pm)) { 840cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 8414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 8444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 84503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarettbool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_t rowBytes, 8464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 8474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 8484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 8494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 85203dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This check gives us an early out and prevents generation ID churn on the surface. 85303dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This is purely optional: it is a subset of the checks performed by SkWritePixelsRec. 85403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett SkIRect srcRect = SkIRect::MakeXYWH(x, y, srcInfo.width(), srcInfo.height()); 85503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett if (!srcRect.intersect(0, 0, device->width(), device->height())) { 85603dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return false; 8574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8584cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 85903dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // Tell our owning surface to bump its generation ID. 86003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett const bool completeOverwrite = 86103dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett srcRect.size() == SkISize::Make(device->width(), device->height()); 862c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 8634af35f348b2e2f6c428819118eb7a2f2fff53a74reed 86403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This can still fail, most notably in the case of a invalid color type or alpha type 86503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // conversion. We could pull those checks into this function and avoid the unnecessary 86603dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // generation ID bump. But then we would be performing those checks twice, since they 86703dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // are also necessary at the bitmap/pixmap entry points. 86803dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->writePixels(srcInfo, pixels, rowBytes, x, y); 8694cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 87051df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 8742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 8752ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 8762ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8772ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 879f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 8802ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 8812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 8822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 8832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 8842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 8852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 8862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 8872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 8892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 8912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 8922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 893f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 894f0090cb80ab10a49e511aa5450ae38917fa058d9reed 895f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 8962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 8972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 8982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 8992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 9012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 902f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 903a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 904a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 905a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 9062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 907f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 908f0090cb80ab10a49e511aa5450ae38917fa058d9reed 909f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 9102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9112ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 9122ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 9132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 9142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 9152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 9162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 9172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 9182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 919a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 9202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 9212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 9222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 923f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 924f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 925f0090cb80ab10a49e511aa5450ae38917fa058d9reed 926f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 927f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 928f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 929f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 930f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 931f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 932f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 933f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 934f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 935f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 936f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 937f0090cb80ab10a49e511aa5450ae38917fa058d9reed 9382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 9398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 940d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 9424b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 943c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->save()); 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9464960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 9474960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 9488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9504960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 9519b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 952918e144408ba218df919528f8b48c544f4767883Mike Reed SkIRect clipBounds = this->getDeviceClipBounds(); 953918e144408ba218df919528f8b48c544f4767883Mike Reed if (clipBounds.isEmpty()) { 954a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 955f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 956c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 95796e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 95896e657d0e103b8358a77ecd913f6086929f792b8reed 959c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 960e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 961db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 962db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 963db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 964c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 965bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 96649f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 9684b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 96996e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 9734960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 974a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty 9751f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 976fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 977bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 978a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 983180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9854960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 986180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 987180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 988fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(ir); 989a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 990a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 991a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 992a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 993a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 994a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 995a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 996a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 9974960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 9984960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 9994960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1000d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1001d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 10024960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 10034960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 10044960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 10054960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 10064960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 100753f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkTCopyOnFirstWrite<SaveLayerRec> rec(origRec); 1008d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 100953f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita rec.writable()->fBounds = nullptr; 1010d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 101153f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita 101253f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SaveLayerStrategy strategy = this->getSaveLayerStrategy(*rec); 1013a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 101453f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita this->internalSaveLayer(*rec, strategy); 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 10168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 10178926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1018a2217ef965e57fdbbf989989e7ec1f2c04f62d39reedvoid SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, 1019c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkBaseDevice* dst, const SkIPoint& dstOrigin, 1020a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed const SkMatrix& ctm) { 1021a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkDraw draw; 1022a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkRasterClip rc; 1023a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed rc.setRect(SkIRect::MakeWH(dst->width(), dst->height())); 1024a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!dst->accessPixels(&draw.fDst)) { 1025a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDst.reset(dst->imageInfo(), nullptr, 0); 1026a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1027a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fMatrix = &SkMatrix::I(); 1028a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fRC = &rc; 10297354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 10307354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1031c61abeed8958a757c6b49937f28b63066148dd67Mike Reed if (filter) { 1032c61abeed8958a757c6b49937f28b63066148dd67Mike Reed p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1033c61abeed8958a757c6b49937f28b63066148dd67Mike Reed } 1034a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1035c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int x = src->getOrigin().x() - dstOrigin.x(); 1036c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int y = src->getOrigin().y() - dstOrigin.y(); 1037a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed auto special = src->snapSpecial(); 1038a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 103953f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita dst->drawSpecial(special.get(), x, y, p, nullptr, SkMatrix::I()); 1040a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 10417354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 104270ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1043129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1044129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1045129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1046129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 104752ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman // SRGBTODO: Can we remove this check now? 1048129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1049129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1050129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1051129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1052129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1053129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1054129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1055129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 1056693fdbd6b81a860657612e7604430dd55d6e721bMike Reed return SkImageInfo::Make(w, h, prev.colorType(), alphaType, prev.refColorSpace()); 1057129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1058129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1059129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 10604960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 10614960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 10624960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 10634960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 10644960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 10658c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 10668c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 10678c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 10688c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 10698c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 10708c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 10718c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 10728c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 10738c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 10748c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 10758c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 10768c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 10778c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 10788c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 10798c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 10808c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 10818c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 10828c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 10838c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 10848c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 10858c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 108696a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 10878c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 10888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 10898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 10908c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 10918c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 10928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 10938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 10948c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 10958c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 10968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 10978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 10988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1099a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1100a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 11012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1102a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1103a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 11048c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 11052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 11068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1108e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1109e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1110e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 11112ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1112e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1113e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 11144960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 11158dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 11168dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 111776033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1118daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 111976033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 11208dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1121b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1122b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 11238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11245139e501c5ac3a511e35c78395c907a176113451robertphillips SkBaseDevice* priorDevice = this->getTopDevice(); 1125c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (nullptr == priorDevice) { // Do we still need this check??? 1126b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 11272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1128b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1129b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 11305139e501c5ac3a511e35c78395c907a176113451robertphillips SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir.height(), isOpaque, 1131129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1132129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1133704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> newDevice; 113461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 113570ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 11364960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1137daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 113870ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 1139356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed preserveLCDText, 1140356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator.get()); 11415139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice.reset(priorDevice->onCreateDevice(createInfo, paint)); 11425139e501c5ac3a511e35c78395c907a176113451robertphillips if (!newDevice) { 11437503d60847c4ad22df87458aecd917772b23d293reed return; 114461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 1145e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 114653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix, rec.fClipMask, rec.fClipMatrix); 11478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1148b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed // only have a "next" if this new layer doesn't affect the clip (rare) 1149b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer; 11508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 11518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1152a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1153c61abeed8958a757c6b49937f28b63066148dd67Mike Reed if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) { 1154c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop }, 1155a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fMCRec->fMatrix); 1156a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1157c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1158c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop); 1159c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1160c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 1161c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (layer->fNext) { 1162c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // need to punch a hole in the previous device, so we don't draw there, given that 1163c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // the new top-layer will allow drawing to happen "below" it. 1164c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkRegion hole(ir); 1165c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed do { 1166c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer = layer->fNext; 1167c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer->fDevice->clipRegion(hole, SkClipOp::kDifference); 1168c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } while (layer->fNext); 1169c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 11708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1172d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1173bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1174bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1175bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1176bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1177bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1178bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1179bada1885da479d948f065182d6dfa85a1140bda5reed } 1180d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1181d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 11848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 11878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 118896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 11918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 11948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1195c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (fMCRec) { 1196c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix)); 1197c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 1198c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 12008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 12018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 12028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 120349f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 1204b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed if (fMCRec) { 12056f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 1206713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita this->internalDrawDevice(layer->fDevice.get(), origin.x(), origin.y(), 120753f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita layer->fPaint.get(), 120853f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita layer->fClipImage.get(), layer->fClipMatrix); 12098c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 12108c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 12118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 1212385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1213b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1214b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1215a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1216b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 12178c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 12188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 121988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1220fbfa25802709139c2f14e304319c9541da65ca27msarett 1221fbfa25802709139c2f14e304319c9541da65ca27msarett if (fMCRec) { 12229637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 1223fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1224fbfa25802709139c2f14e304319c9541da65ca27msarett } 12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1227e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 122896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 12294a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 12304a8126e7f81384526629b1e21bf89b632ea13cd9reed } 12314a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 123276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 123376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1234e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 123576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1236e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 123776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 123876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1239c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1240ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onImageInfo(); 1241ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1242ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1243ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedSkImageInfo SkCanvas::onImageInfo() const { 1244c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1245c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1246c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1247c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1248900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1249c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1250c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1251c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1252898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1253ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onGetProps(props); 1254ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1255ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1256ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedbool SkCanvas::onGetProps(SkSurfaceProps* props) const { 1257898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1258898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1259898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1260898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1261898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1262898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1263898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1264898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1265898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1266898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1267898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 12686ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 12696ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1270c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1271c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1272884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1273c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1274884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1275c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1276c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 12776b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1278884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1279884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 128096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1281884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1282884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1283884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1284884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1285884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1286884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1287884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1288884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 12890ed3b640c9da71fbbd73c65a4ec1992f85596271Florin Malita *origin = this->getTopDevice()->getOrigin(); 12906b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1291884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 12929c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 12939c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1294884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 12959c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1296884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 12979c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 12989c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1299520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 130153f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malitavoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint, 130253f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkImage* clipImage, const SkMatrix& clipMatrix) { 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 130496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13074b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13088926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1309a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 13111f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 131276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 131376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 131476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 131553f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita if (filter || clipImage) { 1316833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial(); 1317833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips if (specialImage) { 131853f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint, 131953f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita clipImage, clipMatrix); 1320833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips } 132176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1322a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint); 132376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 13248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1325a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 13264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 132932704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1330da420b976e61071cfe5de10556b4b23e519091d6reed 133192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1332fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed if (dx || dy) { 1333fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->checkForDeferredSave(); 1334fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fMCRec->fMatrix.preTranslate(dx,dy); 1335cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1336fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed // Translate shouldn't affect the is-scale-translateness of the matrix. 1337fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1338cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1339c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 1340c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1341fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->didTranslate(dx,dy); 1342fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed } 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134592362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1346d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1347d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1348d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1352d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1353d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1354d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13577438bfc0804d021aa92cdd5ea644994a4248f3dbbungemanvoid SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) { 13587438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman SkMatrix m; 13597438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman m.setRotate(degrees, px, py); 13607438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman this->concat(m); 13617438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman} 13627438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman 136392362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1364d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1365d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1366d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 136744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 136844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 136992362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1370d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1371d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1372d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1373d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 13742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13751f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 13769637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 13777627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 13787627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 13797627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 138044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 138144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 138244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 13838c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 13841f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 13859da5a5a198e5dc9148f7f30a6089377590eee55bmsarett fIsScaleTranslate = matrix.isScaleTranslate(); 1386c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1387c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 13888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 13898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 13908c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 13918c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 13928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 139344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 13948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 13978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 13988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 14018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1402c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) { 14032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 14068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14078f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1408c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1409a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14107627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14117627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA)); 14127627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 1413c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1414a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1415a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1416fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14195f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Ilievvoid SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) { 14205f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fClipRestrictionRect = rect; 1421d519d484949161df6d4b2ecadc282427cab532cfMike Reed if (fClipRestrictionRect.isEmpty()) { 1422d519d484949161df6d4b2ecadc282427cab532cfMike Reed // we notify the device, but we *dont* resolve deferred saves (since we're just 1423d519d484949161df6d4b2ecadc282427cab532cfMike Reed // removing the restriction if the rect is empty. how I hate this api. 1424d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 1425d519d484949161df6d4b2ecadc282427cab532cfMike Reed } else { 14265f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev this->checkForDeferredSave(); 1427d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 14285f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev AutoValidateClip avc(this); 14295f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.op(fClipRestrictionRect, SkRegion::kIntersect_Op); 14305f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14315f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev } 14325f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev} 14335f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev 1434c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) { 14352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14368f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14374ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 14388f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 14398f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 14414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 14428f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 144314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1444c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1445a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon AutoValidateClip avc(this); 144614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1447a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14487627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14497627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA)); 1450a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1451a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1452a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1453a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14544ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 14554ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1456c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) { 14572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14588f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 145939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 146039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 146139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 146239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 146339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 146439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 146539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 146639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 146739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 146839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 146939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 147039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 147139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 147239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 147339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 147439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 147539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 14768f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 147739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 147839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 14798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1481c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) { 14825c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14835c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1484a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14857627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14867627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA)); 14875c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1488a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkPath* rasterClipPath = &path; 1489a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkMatrix* matrix = &fMCRec->fMatrix; 1490a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1491a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1492fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1495c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) { 14962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14978f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 14988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1500c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) { 15017627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op)); 150227d07f0acb85eea4062075dfbe9148ce12d92c66Mike Reed 1503a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed AutoValidateClip avc(this); 150427d07f0acb85eea4062075dfbe9148ce12d92c66Mike Reed 150573603f3c52ffd89fe9d035be827b566a0e7d3b79reed fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op); 1506fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1509819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1510819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1511819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 15121f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1513ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 15145c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1515ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1516ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1517819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1518819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1519819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1520a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedbool SkCanvas::androidFramework_isClipAA() const { 1521a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed bool containsAA = false; 1522a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1523a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed FOR_EACH_TOP_DEVICE(containsAA |= device->onClipIsAA()); 1524a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1525a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return containsAA; 1526a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed} 1527a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1528a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedclass RgnAccumulator { 1529a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkRegion* fRgn; 1530a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedpublic: 1531a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed RgnAccumulator(SkRegion* total) : fRgn(total) {} 1532a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed void accumulate(SkBaseDevice* device, SkRegion* rgn) { 1533a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkIPoint origin = device->getOrigin(); 1534a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (origin.x() | origin.y()) { 1535a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed rgn->translate(origin.x(), origin.y()); 1536a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 1537a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fRgn->op(*rgn, SkRegion::kUnion_Op); 1538a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 1539a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed}; 1540a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1541a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) { 1542a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed RgnAccumulator accum(rgn); 1543a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkRegion tmp; 1544a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1545a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed rgn->setEmpty(); 1546a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed FOR_EACH_TOP_DEVICE(device->onAsRgnClip(&tmp); accum.accumulate(device, &tmp)); 154790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 154890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 15495c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 15505c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1551754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 155202be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed return fMCRec->fRasterClip.isEmpty(); 155302be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed 155402be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed // TODO: should we only use the conservative answer in a recording canvas? 155502be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed#if 0 1556a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* dev = this->getTopDevice(); 1557a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if no device we return true 1558a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return !dev || dev->onGetClipType() == SkBaseDevice::kEmpty_ClipType; 155902be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed#endif 1560754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1561754de5f65b466f721d952a379194cc94de376f42reed@google.com 15625c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 1563a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* dev = this->getTopDevice(); 1564a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if no device we return false 1565a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return dev && dev->onGetClipType() == SkBaseDevice::kRect_ClipType; 15665c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 15675c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1568fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) { 1569fbfa25802709139c2f14e304319c9541da65ca27msarett#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 1570fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 lLtT = _mm_unpacklo_ps(devRect.fVec, devClip.fVec); 1571fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 RrBb = _mm_unpackhi_ps(devClip.fVec, devRect.fVec); 1572fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 mask = _mm_cmplt_ps(lLtT, RrBb); 1573fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xF != _mm_movemask_ps(mask); 1574fbfa25802709139c2f14e304319c9541da65ca27msarett#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON) 1575fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t lLtT = vzipq_f32(devRect.fVec, devClip.fVec).val[0]; 1576fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t RrBb = vzipq_f32(devClip.fVec, devRect.fVec).val[1]; 1577fbfa25802709139c2f14e304319c9541da65ca27msarett uint32x4_t mask = vcltq_f32(lLtT, RrBb); 1578fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xFFFFFFFFFFFFFFFF != (uint64_t) vmovn_u32(mask); 1579fbfa25802709139c2f14e304319c9541da65ca27msarett#else 1580fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devRectAsRect; 1581fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devClipAsRect; 1582fbfa25802709139c2f14e304319c9541da65ca27msarett devRect.store(&devRectAsRect.fLeft); 1583fbfa25802709139c2f14e304319c9541da65ca27msarett devClip.store(&devClipAsRect.fLeft); 1584fbfa25802709139c2f14e304319c9541da65ca27msarett return !devRectAsRect.isFinite() || !devRectAsRect.intersect(devClipAsRect); 1585fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1586fbfa25802709139c2f14e304319c9541da65ca27msarett} 1587fbfa25802709139c2f14e304319c9541da65ca27msarett 1588fbfa25802709139c2f14e304319c9541da65ca27msarett// It's important for this function to not be inlined. Otherwise the compiler will share code 1589fbfa25802709139c2f14e304319c9541da65ca27msarett// between the fast path and the slow path, resulting in two slow paths. 1590fbfa25802709139c2f14e304319c9541da65ca27msarettstatic SK_NEVER_INLINE bool quick_reject_slow_path(const SkRect& src, const SkRect& deviceClip, 1591fbfa25802709139c2f14e304319c9541da65ca27msarett const SkMatrix& matrix) { 1592fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect deviceRect; 1593fbfa25802709139c2f14e304319c9541da65ca27msarett matrix.mapRect(&deviceRect, src); 1594fbfa25802709139c2f14e304319c9541da65ca27msarett return !deviceRect.isFinite() || !deviceRect.intersect(deviceClip); 1595fbfa25802709139c2f14e304319c9541da65ca27msarett} 1596d22a817ff57986407facd16af36320fc86ce02damsarett 1597fbfa25802709139c2f14e304319c9541da65ca27msarettbool SkCanvas::quickReject(const SkRect& src) const { 1598fbfa25802709139c2f14e304319c9541da65ca27msarett#ifdef SK_DEBUG 1599fbfa25802709139c2f14e304319c9541da65ca27msarett // Verify that fDeviceClipBounds are set properly. 1600fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect tmp = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16011f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 16020c685ee188a5e500df25a34fa6edfceb4cbb795cmsarett SkASSERT(fDeviceClipBounds.isEmpty()); 1603fbfa25802709139c2f14e304319c9541da65ca27msarett } else { 1604fbfa25802709139c2f14e304319c9541da65ca27msarett SkASSERT(tmp == fDeviceClipBounds); 16058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16079637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett // Verify that fIsScaleTranslate is set properly. 16089637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1609fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1610d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 16119637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett if (!fIsScaleTranslate) { 1612fbfa25802709139c2f14e304319c9541da65ca27msarett return quick_reject_slow_path(src, fDeviceClipBounds, fMCRec->fMatrix); 16138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1614fbfa25802709139c2f14e304319c9541da65ca27msarett 1615fbfa25802709139c2f14e304319c9541da65ca27msarett // We inline the implementation of mapScaleTranslate() for the fast path. 1616fbfa25802709139c2f14e304319c9541da65ca27msarett float sx = fMCRec->fMatrix.getScaleX(); 1617fbfa25802709139c2f14e304319c9541da65ca27msarett float sy = fMCRec->fMatrix.getScaleY(); 1618fbfa25802709139c2f14e304319c9541da65ca27msarett float tx = fMCRec->fMatrix.getTranslateX(); 1619fbfa25802709139c2f14e304319c9541da65ca27msarett float ty = fMCRec->fMatrix.getTranslateY(); 1620fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f scale(sx, sy, sx, sy); 1621fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f trans(tx, ty, tx, ty); 1622fbfa25802709139c2f14e304319c9541da65ca27msarett 1623fbfa25802709139c2f14e304319c9541da65ca27msarett // Apply matrix. 1624fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans; 1625fbfa25802709139c2f14e304319c9541da65ca27msarett 1626fbfa25802709139c2f14e304319c9541da65ca27msarett // Make sure left < right, top < bottom. 1627fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]); 1628fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f min = Sk4f::Min(ltrb, rblt); 1629fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f max = Sk4f::Max(ltrb, rblt); 1630fbfa25802709139c2f14e304319c9541da65ca27msarett // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on 1631fbfa25802709139c2f14e304319c9541da65ca27msarett // ARM this sequence generates the fastest (a single instruction). 1632fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f devRect = Sk4f(min[2], min[3], max[0], max[1]); 1633fbfa25802709139c2f14e304319c9541da65ca27msarett 1634fbfa25802709139c2f14e304319c9541da65ca27msarett // Check if the device rect is NaN or outside the clip. 1635fbfa25802709139c2f14e304319c9541da65ca27msarett return is_nan_or_clipped(devRect, Sk4f::Load(&fDeviceClipBounds.fLeft)); 16368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16383b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 16393b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 16408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 164242e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkRect SkCanvas::onGetLocalClipBounds() const { 164342e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkIRect ibounds = this->onGetDeviceClipBounds(); 1644918e144408ba218df919528f8b48c544f4767883Mike Reed if (ibounds.isEmpty()) { 164542e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 16468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1648d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1649d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 16501f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 165142e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 1652d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1653d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 165442e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect bounds; 165542e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect r; 165642e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed // adjust it outwards in case we are antialiasing 165742e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed const int inset = 1; 1658fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 165942e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 166042e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed ibounds.fRight + inset, ibounds.fBottom + inset); 166142e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed inverse.mapRect(&bounds, r); 166242e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return bounds; 16638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 166542e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkIRect SkCanvas::onGetDeviceClipBounds() const { 1666a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fMCRec->fRasterClip.getBounds(); 1667bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1668bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 16698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 16701f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 16718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16731105224f9701e57ec5ce0354d6a380b664f5c638Brian OsmanGrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() { 16749c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 16751105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman return dev ? dev->accessRenderTargetContext() : nullptr; 16769c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 16779c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1678644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1679644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 168086ae3d161412961c27a406465b0ec5749cc2e753reed return device ? device->context() : nullptr; 1681644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1682e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1683ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1684ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 16859881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1686ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1687ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1688ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1689ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1690ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1691ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1692ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1693ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1694ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1695e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark // be able to return ... 1696e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark // if (!outer.contains(inner))) { 1697ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1698ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1699e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark if (!outer.getBounds().contains(inner.getBounds())) { 1700e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark return; 1701e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark } 1702ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1703ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1704ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1705ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 170641af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 170741af966ab338e95eee81ab618ab28195075338f7reed 170841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 170941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 171041af966ab338e95eee81ab618ab28195075338f7reed} 171141af966ab338e95eee81ab618ab28195075338f7reed 171241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 171341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 171441af966ab338e95eee81ab618ab28195075338f7reed} 171541af966ab338e95eee81ab618ab28195075338f7reed 1716dca352e2d42cfe698573947b3d11abc1eaade160msarettvoid SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { 1717dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isEmpty()) { 1718dca352e2d42cfe698573947b3d11abc1eaade160msarett return; 1719dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1720dca352e2d42cfe698573947b3d11abc1eaade160msarett 1721dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isRect()) { 1722dca352e2d42cfe698573947b3d11abc1eaade160msarett return this->drawIRect(region.getBounds(), paint); 1723dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1724dca352e2d42cfe698573947b3d11abc1eaade160msarett 1725dca352e2d42cfe698573947b3d11abc1eaade160msarett this->onDrawRegion(region, paint); 1726dca352e2d42cfe698573947b3d11abc1eaade160msarett} 1727dca352e2d42cfe698573947b3d11abc1eaade160msarett 172841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 172941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 173041af966ab338e95eee81ab618ab28195075338f7reed} 173141af966ab338e95eee81ab618ab28195075338f7reed 173241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 173341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 173441af966ab338e95eee81ab618ab28195075338f7reed} 173541af966ab338e95eee81ab618ab28195075338f7reed 173641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 173741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 173841af966ab338e95eee81ab618ab28195075338f7reed} 173941af966ab338e95eee81ab618ab28195075338f7reed 1740e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, 1741e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed const SkPaint& paint) { 1742e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed RETURN_ON_NULL(vertices); 1743e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed this->onDrawVerticesObject(vertices.get(), mode, paint); 1744e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed} 1745e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed 1746e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) { 1747199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon RETURN_ON_NULL(vertices); 1748e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed this->onDrawVerticesObject(vertices, mode, paint); 174941af966ab338e95eee81ab618ab28195075338f7reed} 175041af966ab338e95eee81ab618ab28195075338f7reed 175141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 175241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 175341af966ab338e95eee81ab618ab28195075338f7reed} 175441af966ab338e95eee81ab618ab28195075338f7reed 1755a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1756e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1757a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 175841af966ab338e95eee81ab618ab28195075338f7reed} 175941af966ab338e95eee81ab618ab28195075338f7reed 1760e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1761e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1762e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1763e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1764e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1765e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1766e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1767e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 176841af966ab338e95eee81ab618ab28195075338f7reed 176984984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 177084984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1771e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1772e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 177384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 177484984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1775e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1776e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1777e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1778e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1779e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1780e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1781e47829b6b1eeb6b0c97ccb3df3016d197046824creed 17824c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 17834c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 1784e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 17854c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 17864c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 17874c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 1788552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(image->width(), image->height(), center)) { 1789552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawImageNine(image, center, dst, paint); 1790552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1791e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 17924c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 17934c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 17944c21dc5ddf3b482293ed34eead876d8d61a662c3reed 1795168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 1796168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 1797168820625c35a8c19f66c661efcbce7a5e334837msarett RETURN_ON_NULL(image); 1798168820625c35a8c19f66c661efcbce7a5e334837msarett if (dst.isEmpty()) { 1799168820625c35a8c19f66c661efcbce7a5e334837msarett return; 1800168820625c35a8c19f66c661efcbce7a5e334837msarett } 180171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 180271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 180371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 180471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 180571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(image->width(), image->height()); 180671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 180771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 180871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 180971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) { 181071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawImageLattice(image, latticePlusBounds, dst, paint); 1811168820625c35a8c19f66c661efcbce7a5e334837msarett } else { 1812168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawImageRect(image, dst, paint); 1813168820625c35a8c19f66c661efcbce7a5e334837msarett } 1814168820625c35a8c19f66c661efcbce7a5e334837msarett} 1815168820625c35a8c19f66c661efcbce7a5e334837msarett 181641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 18174c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 18182df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 18192df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 182041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 182141af966ab338e95eee81ab618ab28195075338f7reed} 182241af966ab338e95eee81ab618ab28195075338f7reed 1823e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1824a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1825e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1826a5517e2b190a8083b38964972b031c13e99f1012reed return; 1827a5517e2b190a8083b38964972b031c13e99f1012reed } 1828e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 182941af966ab338e95eee81ab618ab28195075338f7reed} 183041af966ab338e95eee81ab618ab28195075338f7reed 183184984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 183284984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1833e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1834e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1835e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1836e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1837e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1838e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1839e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 184084984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 184184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 184241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 184341af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 18444c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 18452df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 18462df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 1847552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) { 1848552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawBitmapNine(bitmap, center, dst, paint); 1849552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1850a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 18514c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 185241af966ab338e95eee81ab618ab28195075338f7reed} 185341af966ab338e95eee81ab618ab28195075338f7reed 1854c573a40ed5024b463e47088d307e3164a486dba5msarettvoid SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, 1855c573a40ed5024b463e47088d307e3164a486dba5msarett const SkPaint* paint) { 1856168820625c35a8c19f66c661efcbce7a5e334837msarett if (bitmap.drawsNothing() || dst.isEmpty()) { 1857c573a40ed5024b463e47088d307e3164a486dba5msarett return; 1858c573a40ed5024b463e47088d307e3164a486dba5msarett } 185971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 186071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 186171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 186271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 186371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 186471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 186571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 186671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 186771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) { 186871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, paint); 1869552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1870168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawBitmapRect(bitmap, dst, paint); 1871c573a40ed5024b463e47088d307e3164a486dba5msarett } 1872c573a40ed5024b463e47088d307e3164a486dba5msarett} 1873c573a40ed5024b463e47088d307e3164a486dba5msarett 187471c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 18757d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkColor colors[], int count, SkBlendMode mode, 187671c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 1877e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 187871c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 187971c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 188071c3c760a83123ee0b3127b8c65c6394ce541c50reed } 1881c485907f0420e5f9cf8223e9ba53812cd8dd5368Joe Gregorio SkASSERT(atlas); 188271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 1883faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 188471c3c760a83123ee0b3127b8c65c6394ce541c50reed} 188571c3c760a83123ee0b3127b8c65c6394ce541c50reed 1886f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 1887f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 1888f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 1889f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 1890f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 1891f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 1892e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 1893e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1894e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1895e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 1896e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1897e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 1898e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1899e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1900e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1901e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 1902e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1903e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1904e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 1905e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1906e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 1907e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1908e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1909e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1910e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 19138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 191528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 191649f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 191728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 191828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 191928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 192028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 192141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 19229881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1923fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1924fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1925fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1926fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 192796fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 19288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 1930a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPaint(looper.paint()); 19318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19334e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 193641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 193741af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 19389881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 19398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 19408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1943822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect r; 194496fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 1945a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1946a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1947a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1948a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1949a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1950a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1951a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1952822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 195387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 195487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 195587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 195687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 1957fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1958a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 195996fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 19608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 196178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 19624b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 1964a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPoints(mode, count, pts, looper.paint()); 19658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19664b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19674e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19704a16717bc7aa471fad10ec3157774771a76e5106reedstatic bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) { 19714a16717bc7aa471fad10ec3157774771a76e5106reed return ((intptr_t)paint.getImageFilter() | 19724a16717bc7aa471fad10ec3157774771a76e5106reed#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 19734a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)canvas->getDrawFilter() | 19744a16717bc7aa471fad10ec3157774771a76e5106reed#endif 19754a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)paint.getLooper() ) != 0; 19764a16717bc7aa471fad10ec3157774771a76e5106reed} 19774a16717bc7aa471fad10ec3157774771a76e5106reed 197841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 19799881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 19808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 19818432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 19828432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 19838432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 19848432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 19858432808ad8898ac7137bc7ce1d9df6005e866401reed 1986822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 198787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 198887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 198987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 19908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19914b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19924a16717bc7aa471fad10ec3157774771a76e5106reed if (needs_autodrawlooper(this, paint)) { 1993822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, &r, false) 19948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19954a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 1996a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRect(r, looper.paint()); 19974a16717bc7aa471fad10ec3157774771a76e5106reed } 19988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19994a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_END 20004a16717bc7aa471fad10ec3157774771a76e5106reed } else { 2001822128b475c1782788f96e7a1a848d0affb878b1Mike Reed this->predrawNotify(&r, &paint, false); 20024a16717bc7aa471fad10ec3157774771a76e5106reed SkDrawIter iter(this); 20034a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 2004a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRect(r, paint); 20054a16717bc7aa471fad10ec3157774771a76e5106reed } 20064a16717bc7aa471fad10ec3157774771a76e5106reed } 20078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 200944df651ebefc284acc2f66425dff3ea0b0e14b36msarettvoid SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 201044df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect regionRect = SkRect::Make(region.getBounds()); 201144df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (paint.canComputeFastBounds()) { 2012822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 201344df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (this->quickReject(paint.computeFastBounds(regionRect, &storage))) { 201444df651ebefc284acc2f66425dff3ea0b0e14b36msarett return; 201544df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 201644df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 201744df651ebefc284acc2f66425dff3ea0b0e14b36msarett 2018822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, ®ionRect) 201944df651ebefc284acc2f66425dff3ea0b0e14b36msarett 202044df651ebefc284acc2f66425dff3ea0b0e14b36msarett while (iter.next()) { 2021a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRegion(region, looper.paint()); 202244df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 202344df651ebefc284acc2f66425dff3ea0b0e14b36msarett 202444df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_END 202544df651ebefc284acc2f66425dff3ea0b0e14b36msarett} 202644df651ebefc284acc2f66425dff3ea0b0e14b36msarett 202741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 20289881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 20294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 2030822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 203187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 203287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 203387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 20344ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2035306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 2036822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval) 203746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 203846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 2039a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawOval(oval, looper.paint()); 204046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 204146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 204246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 20434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2045ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomonvoid SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, 2046ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkScalar sweepAngle, bool useCenter, 2047ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkPaint& paint) { 2048ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 2049ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (paint.canComputeFastBounds()) { 2050ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkRect storage; 2051ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon // Note we're using the entire oval as the bounds. 2052ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 2053ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon return; 2054ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2055ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2056ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2057822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval) 2058ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2059ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon while (iter.next()) { 2060a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint()); 2061ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2062ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2063ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_END 2064ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon} 2065ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 206641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 20679881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 20684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 2069822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 207087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 207187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 207287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 20734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 20754ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 20764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 20774ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2078f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2079f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 20804ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2081f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2082f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 20834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2084f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2085822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &rrect.getBounds()) 2086f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2087f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2088a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRRect(rrect, looper.paint()); 2089f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2090f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2091f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 20924ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2094822128b475c1782788f96e7a1a848d0affb878b1Mike Reedvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { 2095ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 2096822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 209787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 209887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 209987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2100ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 210125c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2102822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &outer.getBounds()) 210325c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2104ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2105a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawDRRect(outer, inner, looper.paint()); 2106ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 210725c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2108ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2109ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 21104ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 211141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 21129881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 21139364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 21149364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 21159364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 21169364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 2117822128b475c1782788f96e7a1a848d0affb878b1Mike Reed const SkRect& pathBounds = path.getBounds(); 2118fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 2119822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 212087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 212187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 212287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 21238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21240b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 2125822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (pathBounds.width() <= 0 && pathBounds.height() <= 0) { 21266803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2127fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 21286651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2129fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2130fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 21318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2132822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds) 21338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 2135a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPath(path, looper.paint()); 21368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2141262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2142262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2143262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2144262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2145262a71b7f95ce98ff3dd8dba845afbd724470903reed 2146262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2147c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2148262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2149262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2150262a71b7f95ce98ff3dd8dba845afbd724470903reed 2151262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2152262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2153262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2154262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2155262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2156262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2157262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2158262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2159262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2160262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2161262a71b7f95ce98ff3dd8dba845afbd724470903reed 2162a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 21639881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2164a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2165a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 216696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 216787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 216887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 216987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 217087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 217187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 217287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 217387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2174a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 21759d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2176a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 217796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2178a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2179a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2180262a71b7f95ce98ff3dd8dba845afbd724470903reed 2181a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2182129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2183129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2184129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2185a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(image); 2186a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2187129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2188129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2189129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2190129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2191262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2192262a71b7f95ce98ff3dd8dba845afbd724470903reed 2193a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2194262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2195a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2196a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkPoint pt; 2197a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->ctm().mapXY(x, y, &pt); 2198a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawSpecial(special.get(), 2199a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 220053f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkScalarRoundToInt(pt.fY), pnt, 220153f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita nullptr, SkMatrix::I()); 2202262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2203a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImage(image, x, y, pnt); 2204262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2205a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22069d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2207a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2208b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2209b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 221041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2211562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 22129881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 221396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2214c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 221587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 221687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 221787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 221887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 221987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 222087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2221a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2222a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 222396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2224a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2225a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22269d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2227c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2228c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 22299d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2230a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2231a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint); 2232a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22339d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2234a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2235b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2236b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 223741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 22389881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 22398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 22408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 224133366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 224233366974d43eae80e22284a2e445225c343859dareed return; 224333366974d43eae80e22284a2e445225c343859dareed } 224433366974d43eae80e22284a2e445225c343859dareed 224533366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 224633366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 224733366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 224833366974d43eae80e22284a2e445225c343859dareed } 224933366974d43eae80e22284a2e445225c343859dareed 2250822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect bounds; 2251822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bitmap.getBounds(&bounds); 2252822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bounds.offset(x, y); 2253822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bool canFastBounds = paint->canComputeFastBounds(); 2254822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (canFastBounds) { 2255822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 2256822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (this->quickReject(paint->computeFastBounds(bounds, &storage))) { 225787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 225887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 22598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22604b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2261a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2262822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bool drawAsSprite = canFastBounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), 2263822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bitmap.height(), *paint); 2264129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2265a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(bitmap); 2266a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2267129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2268129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2269129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2270129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2271822128b475c1782788f96e7a1a848d0affb878b1Mike Reed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2272822128b475c1782788f96e7a1a848d0affb878b1Mike Reed 2273822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 227433366974d43eae80e22284a2e445225c343859dareed 227533366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2276262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2277a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2278262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2279a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->ctm().mapXY(x, y, &pt); 2280a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawSpecial(special.get(), 2281a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 228253f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkScalarRoundToInt(pt.fY), pnt, 228353f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita nullptr, SkMatrix::I()); 2284262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2285a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmap(bitmap, matrix, looper.paint()); 2286262a71b7f95ce98ff3dd8dba845afbd724470903reed } 228733366974d43eae80e22284a2e445225c343859dareed } 2288fbfa25802709139c2f14e304319c9541da65ca27msarett 228933366974d43eae80e22284a2e445225c343859dareed LOOPER_END 22908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22929987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 22937112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2294eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2295a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 229650b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 22978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 22988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 229974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 230096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2301c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 230287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 230387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 230487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23063d60812865bb034851da777a91413ab584929887reed@google.com 230733535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 230896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 230933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 23108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23117064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2312c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2313c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 23147064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 231533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2316a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint); 2317f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 23187064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 231933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 23208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 232241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2323562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 23249881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 23259987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2326562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 23279987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23289987ec3791336bad6af5cbe513564786b2df55aareed@google.com 23294c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 23304c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 23314c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 23329d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 233396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2334c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 233587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 233687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 233787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23383d60812865bb034851da777a91413ab584929887reed@google.com } 23399d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23404c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 234196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23424c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23434c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23449d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2345c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 23469d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23474c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 2348a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageNine(image, center, dst, looper.paint()); 23499987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 23509d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23514c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23529987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23539987ec3791336bad6af5cbe513564786b2df55aareed@google.com 235441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 235541af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 23569881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 23579987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 23589987ec3791336bad6af5cbe513564786b2df55aareed@google.com 235996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2360c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 236187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 236287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 236387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23644c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23659d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23664c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 236796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23684c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23694c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23709d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2371c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 23729d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23734c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 2374a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint()); 23754c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23769d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23774c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23789987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23799987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2380168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2381168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2382168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2383168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2384168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2385168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2386168820625c35a8c19f66c661efcbce7a5e334837msarett } 2387168820625c35a8c19f66c661efcbce7a5e334837msarett } 2388168820625c35a8c19f66c661efcbce7a5e334837msarett 2389168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2390168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2391168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2392168820625c35a8c19f66c661efcbce7a5e334837msarett } 2393168820625c35a8c19f66c661efcbce7a5e334837msarett 2394168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2395168820625c35a8c19f66c661efcbce7a5e334837msarett 2396168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2397a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint()); 2398168820625c35a8c19f66c661efcbce7a5e334837msarett } 2399168820625c35a8c19f66c661efcbce7a5e334837msarett 2400168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2401168820625c35a8c19f66c661efcbce7a5e334837msarett} 2402168820625c35a8c19f66c661efcbce7a5e334837msarett 2403168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, 2404168820625c35a8c19f66c661efcbce7a5e334837msarett const SkRect& dst, const SkPaint* paint) { 2405168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2406168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2407168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2408168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2409168820625c35a8c19f66c661efcbce7a5e334837msarett } 2410168820625c35a8c19f66c661efcbce7a5e334837msarett } 2411168820625c35a8c19f66c661efcbce7a5e334837msarett 2412168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2413168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2414168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2415168820625c35a8c19f66c661efcbce7a5e334837msarett } 2416168820625c35a8c19f66c661efcbce7a5e334837msarett 2417168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2418168820625c35a8c19f66c661efcbce7a5e334837msarett 2419168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2420a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint()); 2421168820625c35a8c19f66c661efcbce7a5e334837msarett } 2422168820625c35a8c19f66c661efcbce7a5e334837msarett 2423168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2424168820625c35a8c19f66c661efcbce7a5e334837msarett} 2425168820625c35a8c19f66c661efcbce7a5e334837msarett 2426f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2427f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 24281f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2429112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2430112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2431a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2432112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2433f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2434f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2435f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2436f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2437f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2438f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2439f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2440f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2441f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 24422c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 24432c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2444f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2445f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2446e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2447e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 244896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 24498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2452a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawText(text, byteLength, x, y, dfp.paint()); 24538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2458e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2459e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 246005c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 246105c4a4322e7d4f3417b7df33825bab8603d52051fmalita 246296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 246387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2466a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset, 2467f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2469b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 24704e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2473e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2474e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 247505c4a4322e7d4f3417b7df33825bab8603d52051fmalita 247605c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 247705c4a4322e7d4f3417b7df33825bab8603d52051fmalita 247896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 247987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2482a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset, 2483f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2485b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 24864e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2489e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2490e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 249196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 249287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 2494a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextOnPath(text, byteLength, path, 24954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 24968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2497b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2498945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 24994325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 25004325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 250145561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 250245561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 250345561a0b15fe045ba272c328684c3f7ae290785areed if (cullRect && this->quickReject(*cullRect)) { 250445561a0b15fe045ba272c328684c3f7ae290785areed return; 250545561a0b15fe045ba272c328684c3f7ae290785areed } 250645561a0b15fe045ba272c328684c3f7ae290785areed 250745561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 250845561a0b15fe045ba272c328684c3f7ae290785areed 250945561a0b15fe045ba272c328684c3f7ae290785areed while (iter.next()) { 2510a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextRSXform(text, byteLength, xform, looper.paint()); 251145561a0b15fe045ba272c328684c3f7ae290785areed } 251245561a0b15fe045ba272c328684c3f7ae290785areed 251345561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_END 251445561a0b15fe045ba272c328684c3f7ae290785areed} 251545561a0b15fe045ba272c328684c3f7ae290785areed 251600d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 251700d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 25187ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 251985d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 252096fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 252119653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 252285d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 252387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 252487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 252587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 252687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 252787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 25287ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 25297ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2530024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2531024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2532024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 253396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2534024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 253585d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 253600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2537aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2538aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2539a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextBlob(blob, x, y, dfp.paint(), drawFilter); 254000d5c2c6523321d25b32905ff4822f083a4173eefmalita } 254100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2542aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2543024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2544024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 254500d5c2c6523321d25b32905ff4822f083a4173eefmalita} 254600d5c2c6523321d25b32905ff4822f083a4173eefmalita 25472a475eae622adc1e8fa29206be1eaf862c23548eCary Clarkvoid SkCanvas::drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint) { 25482a475eae622adc1e8fa29206be1eaf862c23548eCary Clark this->drawText(string.c_str(), string.size(), x, y, paint); 25492a475eae622adc1e8fa29206be1eaf862c23548eCary Clark} 25502a475eae622adc1e8fa29206be1eaf862c23548eCary Clark 2551e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2552e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2553e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25549881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2555ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2556ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawText(text, byteLength, x, y, paint); 2557ac09554dce518e9d4496771f648f3ae17eca857creed } 2558e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2559e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2560e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25619881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2562ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2563ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosText(text, byteLength, pos, paint); 2564ac09554dce518e9d4496771f648f3ae17eca857creed } 2565e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2566e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2567e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 25689881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2569ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2570ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2571ac09554dce518e9d4496771f648f3ae17eca857creed } 2572e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2573e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2574e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 25759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2576ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2577ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2578ac09554dce518e9d4496771f648f3ae17eca857creed } 2579e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 258045561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 258145561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 258245561a0b15fe045ba272c328684c3f7ae290785areed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextRSXform()"); 258345561a0b15fe045ba272c328684c3f7ae290785areed if (byteLength) { 258445561a0b15fe045ba272c328684c3f7ae290785areed this->onDrawTextRSXform(text, byteLength, xform, cullRect, paint); 258545561a0b15fe045ba272c328684c3f7ae290785areed } 258645561a0b15fe045ba272c328684c3f7ae290785areed} 258700d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 258800d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2589e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 25909881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2591e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 259200d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2593e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 2594e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, 2595e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed const SkPaint& paint) { 2596199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 2597199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 2598199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2599199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon while (iter.next()) { 2600199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon // In the common case of one iteration we could std::move vertices here. 26012f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed iter.fDevice->drawVertices(vertices, bmode, looper.paint()); 2602199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon } 2603199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2604199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_END 2605199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon} 2606199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2607b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 26087d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 26097d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 26109881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 261196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2612b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2613b3c9d1c33caf325aada244204215eb790c228c12dandov } 26146cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2615faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawPatch(cubics, colors, texCoords, bmode, paint); 26169340c2685c0bb0e1e70008acaaf3d1448f074c38msarett} 26179340c2685c0bb0e1e70008acaaf3d1448f074c38msarett 26189340c2685c0bb0e1e70008acaaf3d1448f074c38msarettvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2619faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 26207d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 2621ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2622ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2623ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2624b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2625ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2626ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2627ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26286cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 262996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 26306cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2631ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2632a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, paint); 2633ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26346cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2635ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2636ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2637ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2638a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2639e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2640e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2641e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2642e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2643e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2644e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2645a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2646a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2647a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2648a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2649e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2650e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2651e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 26526a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2653e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 26546a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26556a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2656a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 26572a62e853c27cfacafd5c15ac1077cc13140589bareed // drawable bounds are no longer reliable (e.g. android displaylist) 26582a62e853c27cfacafd5c15ac1077cc13140589bareed // so don't use them for quick-reject 2659a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 26606a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26616a070dc06af4e9f305f9d08a69e34d18ade473cbreed 266271c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 2663faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkColor colors[], int count, SkBlendMode bmode, 266471c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 266571c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 266671c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 266771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 266871c3c760a83123ee0b3127b8c65c6394ce541c50reed 266971c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 267071c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 267171c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 267271c3c760a83123ee0b3127b8c65c6394ce541c50reed } 26739d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 267496fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 267571c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 2676a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt); 267771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 267871c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 267971c3c760a83123ee0b3127b8c65c6394ce541c50reed} 268071c3c760a83123ee0b3127b8c65c6394ce541c50reed 2681f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2682f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 2683f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2684f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 2685f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 2686f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 2687a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawAnnotation(rect, key, value); 2688f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2689f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 2690f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2691f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 26928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 26938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 26948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 26958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 26968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2697374772bd61951f01bf84fe17bf53d8867681c9aereedvoid SkCanvas::drawColor(SkColor c, SkBlendMode mode) { 26989881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 26998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 27008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2702374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(mode); 27038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 27048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 27079881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 27083661bc997620899695041010a750d11dbe8a972dMike Reed const SkPoint pt = { x, y }; 27098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 27108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27123661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint) { 27139881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 27148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 27154b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 27178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 27188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 27198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27213661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint) { 27229881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 27238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 27248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 27258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 27288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 27294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 27308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 27338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27349881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 27358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 27364ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 27374ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 27384ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 27398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 27408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 27418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 27458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 27468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27479881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 274821af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon if (oval.isEmpty() || !sweepAngle) { 274921af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon return; 27508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 275121af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint); 27528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 27558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 27568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 27579881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 27588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 27594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 27618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 27628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2764f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 27651c2c441fede0ae9573afc098017011e3439624a9reed 27661c2c441fede0ae9573afc098017011e3439624a9reed/** 27671c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 27681c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 27691c2c441fede0ae9573afc098017011e3439624a9reed * 27701c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 27711c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 27721c2c441fede0ae9573afc098017011e3439624a9reed */ 27731c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 27749b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2775d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 2776e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 2777e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 27781c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 2779e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2780e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 2781e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 2782e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 2783e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2784e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 2785e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2786e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 2787d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2788d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 27899b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2790d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2791d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2792d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 2793d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 2794d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 2795d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 2796d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2797d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 2798d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 2799d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2800d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 2801d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 2802d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2803d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2804d028180f0310cf2b23f9744256a41697b0683e67fmalita 2805a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2806c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 28078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28123aafe111b6cc388400092851cc53bbbdfcb8a81creedSkCanvas::LayerIter::LayerIter(SkCanvas* canvas) { 281399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 28148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 28168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28173aafe111b6cc388400092851cc53bbbdfcb8a81creed fImpl = new (fStorage) SkDrawIter(canvas); 28188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 28228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 28238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 28268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28291f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 283099330ba6227137866a0dbd63478d36f335203ebdMike Reed return fImpl->fDevice; 28318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 2834a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fImpl->fDevice->ctm(); 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 28388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 283996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 28418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 28438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2845a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkCanvas::LayerIter::clip(SkRegion* rgn) const { 2846a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fImpl->fDevice->onAsRgnClip(rgn); 2847a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed} 2848a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 28508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 285120a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 285220a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 285320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 28543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 28553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 28563107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 28573107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 28583107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28593107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28603107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28613107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 28623107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28633107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 28643107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 28653107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 286628fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 28679e3dbdff53f2d9957626a17a279730cda70f17bajunov case kRGBA_F16_SkColorType: 28683107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28693107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28703107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28713107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 28723107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28733107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 28743107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 28753107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28765df4934b3e40cdc378e225d1dda39f015cae9baeMike Reedstd::unique_ptr<SkCanvas> SkCanvas::MakeRasterDirect(const SkImageInfo& info, void* pixels, 28775df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed size_t rowBytes) { 287842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 287996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 288042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2881eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 288242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 288342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 288496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 288542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 28865df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed return skstd::make_unique<SkCanvas>(bitmap); 288742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2888d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2889d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2890d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2891d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2892a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2893d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2894d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2895d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 289649f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2897a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2898d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2899a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2900d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2901a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 290249f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2903d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2904d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 29056cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 290649f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2907d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2908d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2909d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2910d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2911d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2912d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2913d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2914e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 2915ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 2916ee424acbb87bf999be132a437527e656e37541d7Florin Malita 2917ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkNoDrawCanvas::SkNoDrawCanvas(int width, int height) 2918ee424acbb87bf999be132a437527e656e37541d7Florin Malita : INHERITED(SkIRect::MakeWH(width, height), kConservativeRasterClip_InitFlag) {} 2919ee424acbb87bf999be132a437527e656e37541d7Florin Malita 2920439ace939b6aaa58408ece0e9e89b633353571aeFlorin MalitaSkNoDrawCanvas::SkNoDrawCanvas(const SkIRect& bounds) 2921439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita : INHERITED(bounds, kConservativeRasterClip_InitFlag) {} 2922439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita 2923ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkCanvas::SaveLayerStrategy SkNoDrawCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { 2924ee424acbb87bf999be132a437527e656e37541d7Florin Malita (void)this->INHERITED::getSaveLayerStrategy(rec); 2925ee424acbb87bf999be132a437527e656e37541d7Florin Malita return kNoLayer_SaveLayerStrategy; 2926ee424acbb87bf999be132a437527e656e37541d7Florin Malita} 2927ee424acbb87bf999be132a437527e656e37541d7Florin Malita 2928ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 292973603f3c52ffd89fe9d035be827b566a0e7d3b79reed 293073603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kDifference_Op == (int)kDifference_SkClipOp, ""); 293173603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kIntersect_Op == (int)kIntersect_SkClipOp, ""); 293273603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kUnion_Op == (int)kUnion_SkClipOp, ""); 293373603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kXOR_Op == (int)kXOR_SkClipOp, ""); 293473603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReverseDifference_Op == (int)kReverseDifference_SkClipOp, ""); 293573603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReplace_Op == (int)kReplace_SkClipOp, ""); 2936356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2937356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 2938356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2939356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkCanvas::accessTopRasterHandle() const { 2940356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (fAllocator && fMCRec->fTopLayer->fDevice) { 2941713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita const auto& dev = fMCRec->fTopLayer->fDevice; 2942356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle handle = dev->getRasterHandle(); 2943356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIPoint origin = dev->getOrigin(); 2944356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkMatrix ctm = this->getTotalMatrix(); 2945356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed ctm.preTranslate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y())); 2946356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2947356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIRect clip = fMCRec->fRasterClip.getBounds(); 2948356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.offset(-origin.x(), -origin.y()); 2949108f55ed5d0b63baf653e4e443cc469df887c811Mike Reed if (!clip.intersect(0, 0, dev->width(), dev->height())) { 2950356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.setEmpty(); 2951356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2952356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2953356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator->updateHandle(handle, ctm, clip); 2954356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return handle; 2955356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2956356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 2957356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 2958356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2959356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstatic bool install(SkBitmap* bm, const SkImageInfo& info, 2960356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkRasterHandleAllocator::Rec& rec) { 2961356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return bm->installPixels(info, rec.fPixels, rec.fRowBytes, nullptr, 2962356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed rec.fReleaseProc, rec.fReleaseCtx); 2963356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 2964356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2965356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkRasterHandleAllocator::allocBitmap(const SkImageInfo& info, 2966356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap* bm) { 2967356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Rec rec; 2968356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!this->allocHandle(info, &rec) || !install(bm, info, rec)) { 2969356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 2970356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2971356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return rec.fHandle; 2972356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 2973356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2974356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstd::unique_ptr<SkCanvas> 2975356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::MakeCanvas(std::unique_ptr<SkRasterHandleAllocator> alloc, 2976356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkImageInfo& info, const Rec* rec) { 2977356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!alloc || !supported_for_raster_canvas(info)) { 2978356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 2979356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2980356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2981356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap bm; 2982356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed Handle hndl; 2983356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2984356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (rec) { 2985356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = install(&bm, info, *rec) ? rec->fHandle : nullptr; 2986356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } else { 2987356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = alloc->allocBitmap(info, &bm); 2988356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2989356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return hndl ? std::unique_ptr<SkCanvas>(new SkCanvas(bm, std::move(alloc), hndl)) : nullptr; 2990356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 2991