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" 23ab244f045a0740fa6106ed21a4e5824cd09f84f3Florin Malita#include "SkLights.h" 245df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed#include "SkMakeUnique.h" 25262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 27ee424acbb87bf999be132a437527e656e37541d7Florin Malita#include "SkNoDrawCanvas.h" 28fbfa25802709139c2f14e304319c9541da65ca27msarett#include "SkNx.h" 29c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 30b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 320017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 33356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#include "SkRasterHandleAllocator.h" 344ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 354418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 362a475eae622adc1e8fa29206be1eaf862c23548eCary Clark#include "SkString.h" 3797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 387ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 40a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 418f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 42d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 44644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 457354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.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 {} 92b964238f0bded00bae59c26c5f366a7780a0ef5fHal Canary void drawBitmap(const SkBitmap&, SkScalar x, SkScalar y, 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; 52814a6430b7bcf92bcabf4aef18805969d1335aab1Florin Malita SkSTArenaAlloc<48> fAlloc; 529129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 530129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 533129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 53496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 535129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5365c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 537632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 538dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 539dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5408926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5415c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 54296fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 543374772bd61951f01bf84fe17bf53d8867681c9aereed paint->setBlendMode(SkBlendMode::kSrcOver); 544129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5458926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 54679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 547129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 548129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 549129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 550129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 551971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 552971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 553971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 554971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 55596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 556129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 557632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 558632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 559129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 560129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5618926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 562129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 56379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5644e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5664e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 567632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 568632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 56996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5704e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5724e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5773aafe111b6cc388400092851cc53bbbdfcb8a81creed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 5783aafe111b6cc388400092851cc53bbbdfcb8a81creed this->predrawNotify(); \ 5793aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \ 5803aafe111b6cc388400092851cc53bbbdfcb8a81creed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 581262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 582262a71b7f95ce98ff3dd8dba845afbd724470903reed 583262a71b7f95ce98ff3dd8dba845afbd724470903reed 5848926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 58597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5863aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, true); \ 5878926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 5888926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 5898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 59078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 59197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5923aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 5934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 5954b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 596c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 597c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 5983aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 599c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 600c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 601c83a29759a5c2966da5ab973e4fd90763e4c962breed 6024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 606fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline SkRect qr_clip_bounds(const SkIRect& bounds) { 607fbfa25802709139c2f14e304319c9541da65ca27msarett if (bounds.isEmpty()) { 608fbfa25802709139c2f14e304319c9541da65ca27msarett return SkRect::MakeEmpty(); 609fbfa25802709139c2f14e304319c9541da65ca27msarett } 610fbfa25802709139c2f14e304319c9541da65ca27msarett 611fbfa25802709139c2f14e304319c9541da65ca27msarett // Expand bounds out by 1 in case we are anti-aliasing. We store the 612fbfa25802709139c2f14e304319c9541da65ca27msarett // bounds as floats to enable a faster quick reject implementation. 613fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect dst; 614fbfa25802709139c2f14e304319c9541da65ca27msarett SkNx_cast<float>(Sk4i::Load(&bounds.fLeft) + Sk4i(-1,-1,1,1)).store(&dst.fLeft); 615fbfa25802709139c2f14e304319c9541da65ca27msarett return dst; 616fbfa25802709139c2f14e304319c9541da65ca27msarett} 617fbfa25802709139c2f14e304319c9541da65ca27msarett 618feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 619feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 620feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 621feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 622feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 623139e5e08a5d276b8dc988f7dee1b9c0467fcf607Mike Reed // know that the device is a SkNoPixelsDevice. 624713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita static_cast<SkNoPixelsDevice*>(fMCRec->fLayer->fDevice.get())->resetForNextPicture(bounds); 625fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(bounds); 6269637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 627feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 628feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 629d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 63042b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 63142b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 63242b73eb00367c8315974b1c374308d20efa78897reed } 63342b73eb00367c8315974b1c374308d20efa78897reed 63445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 6352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 63696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 639a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed new (fMCRec) MCRec; 6405f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect); 6419637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 643a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 644a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 64553f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita new (fDeviceCMStorage) DeviceCM(sk_ref_sp(device), nullptr, fMCRec->fMatrix, nullptr, nullptr); 646b679ca8926a832274b14fdb512f88f64b61d32eareed 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 650f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 651f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 652efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 653efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 65478e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 655fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds()); 656c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 657c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 658f92c86642a1875da54d54b447f006cb9dfbbb35creed } 659fbfa25802709139c2f14e304319c9541da65ca27msarett 660f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 663cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 664e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6654a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 666e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6678d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 668ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 66996fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6708d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6718d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 67296a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 673e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 67496a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 675e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 676e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 677b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 678566e53c7003920ff45c72498754060804b657c68Mike Reed this->init(new SkNoPixelsDevice(SkIRect::MakeWH(SkTMax(width, 0), SkTMax(height, 0)), fProps), 679385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 680d954498c01ccf0417feacf89e45d0c62a06a813breed} 681e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 68278e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 683d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6844a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 685d954498c01ccf0417feacf89e45d0c62a06a813breed{ 686d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 687b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 688566e53c7003920ff45c72498754060804b657c68Mike Reed SkIRect r = bounds.isEmpty() ? SkIRect::MakeEmpty() : bounds; 689566e53c7003920ff45c72498754060804b657c68Mike Reed this->init(new SkNoPixelsDevice(r, fProps), flags)->unref(); 69027a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 692d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 693d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6947b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 695d954498c01ccf0417feacf89e45d0c62a06a813breed{ 696d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 697b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 698d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 701fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 702fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7037b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 704fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 705fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 706fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 707fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 708fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 709fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7104a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7113716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7124a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 7133716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7143716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 715b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 716704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 717704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7184a8126e7f81384526629b1e21bf89b632ea13cd9reed} 71929c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 720356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocator> alloc, 721356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle hndl) 7224a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7234a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 724356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed , fAllocator(std::move(alloc)) 7254a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7264a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 727b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 728356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl)); 729704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 732356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap) : SkCanvas(bitmap, nullptr, nullptr) {} 733356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 73431f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 73531f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt SarettSkCanvas::SkCanvas(const SkBitmap& bitmap, ColorBehavior) 73631f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 73731f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 73831f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett , fAllocator(nullptr) 73931f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett{ 74031f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett inc_canvas(); 74131f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett 74231f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett SkBitmap tmp(bitmap); 74331f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett *const_cast<SkImageInfo*>(&tmp.info()) = tmp.info().makeColorSpace(nullptr); 74431f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett sk_sp<SkBaseDevice> device(new SkBitmapDevice(tmp, fProps, nullptr)); 74531f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett this->init(device.get(), kDefault_InitFlags); 74631f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett} 74731f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett#endif 74831f99ce7d2f3c2b61742d07ab92b6dac6a928ef9Matt Sarett 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7527c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 755385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 756b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 76053d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 76651985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7707765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 77274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 77374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 77474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 77596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 77674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 77774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 77874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 77974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 78074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 783bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 784ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed this->onFlush(); 785ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 786ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 787ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedvoid SkCanvas::onFlush() { 7881f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 789bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 790bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 791bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 792bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 793bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 794afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 795afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 7964ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 7974ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 7984ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 799afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8004ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 801afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 802afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 803afc7cce5d68663934128d76963cd501f771d71desenorblanco } 804afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 805210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 806210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8071f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 809c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 811713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita return rec->fLayer->fDevice.get(); 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8140ed3b640c9da71fbbd73c65a4ec1992f85596271Florin MalitaSkBaseDevice* SkCanvas::getTopDevice() const { 815713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita return fMCRec->fTopLayer->fDevice.get(); 8169266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8179266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 81896472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 819a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 820a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 821a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 822a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 823db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 82403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->readPixels(dstInfo, dstP, rowBytes, x, y); 82551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 82651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 82712e946b4bfdf598bffb276776ea6e25439e25265Mike Reedbool SkCanvas::readPixels(const SkPixmap& pm, int x, int y) { 82812e946b4bfdf598bffb276776ea6e25439e25265Mike Reed return pm.addr() && this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y); 82912e946b4bfdf598bffb276776ea6e25439e25265Mike Reed} 83012e946b4bfdf598bffb276776ea6e25439e25265Mike Reed 83112e946b4bfdf598bffb276776ea6e25439e25265Mike Reedbool SkCanvas::readPixels(const SkBitmap& bm, int x, int y) { 83212e946b4bfdf598bffb276776ea6e25439e25265Mike Reed SkPixmap pm; 83312e946b4bfdf598bffb276776ea6e25439e25265Mike Reed return bm.peekPixels(&pm) && this->readPixels(pm, x, y); 83412e946b4bfdf598bffb276776ea6e25439e25265Mike Reed} 83512e946b4bfdf598bffb276776ea6e25439e25265Mike Reed 8364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 8374edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed SkPixmap pm; 8384edb5d219eb99aa1e8fbe5e37260d3b34314e54bMike Reed if (bitmap.peekPixels(&pm)) { 839cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 8404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 8434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 84403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarettbool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_t rowBytes, 8454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 8464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 8474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 8484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 85103dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This check gives us an early out and prevents generation ID churn on the surface. 85203dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This is purely optional: it is a subset of the checks performed by SkWritePixelsRec. 85303dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett SkIRect srcRect = SkIRect::MakeXYWH(x, y, srcInfo.width(), srcInfo.height()); 85403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett if (!srcRect.intersect(0, 0, device->width(), device->height())) { 85503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return false; 8564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 85803dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // Tell our owning surface to bump its generation ID. 85903dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett const bool completeOverwrite = 86003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett srcRect.size() == SkISize::Make(device->width(), device->height()); 861c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 8624af35f348b2e2f6c428819118eb7a2f2fff53a74reed 86303dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This can still fail, most notably in the case of a invalid color type or alpha type 86403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // conversion. We could pull those checks into this function and avoid the unnecessary 86503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // generation ID bump. But then we would be performing those checks twice, since they 86603dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // are also necessary at the bitmap/pixmap entry points. 86703dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->writePixels(srcInfo, pixels, rowBytes, x, y); 8684cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 86951df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8722ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 8732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 8742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 8752ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8762ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8772ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 878f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 8792ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 8802ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 8812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 8822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 8832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 8842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 8852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 8862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 8882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 8902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 8912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 892f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 893f0090cb80ab10a49e511aa5450ae38917fa058d9reed 894f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 8952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 8962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 8972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 8982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 9002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 901f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 902a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 903a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 904a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 9052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 906f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 907f0090cb80ab10a49e511aa5450ae38917fa058d9reed 908f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 9092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 9112ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 9122ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 9132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 9142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 9152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 9162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 9172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 918a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 9192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 9202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 9212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 922f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 923f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 924f0090cb80ab10a49e511aa5450ae38917fa058d9reed 925f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 926f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 927f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 928f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 929f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 930f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 931f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 932f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 933f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 934f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 935f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 936f0090cb80ab10a49e511aa5450ae38917fa058d9reed 9372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 939d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 9414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 942c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->save()); 9438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9454960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 9464960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 9478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9494960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 9509b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 951918e144408ba218df919528f8b48c544f4767883Mike Reed SkIRect clipBounds = this->getDeviceClipBounds(); 952918e144408ba218df919528f8b48c544f4767883Mike Reed if (clipBounds.isEmpty()) { 953a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 954f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 955c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 95696e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 95796e657d0e103b8358a77ecd913f6086929f792b8reed 958c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 959e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 960db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 961db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 962db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 963c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 964bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 96549f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 9674b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 96896e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 9724960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 973a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty 9741f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 975fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 976bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 977a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 982180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9844960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 985180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 986180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 987fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(ir); 988a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 989a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 990a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 991a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 992a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 993a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 994a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 995a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 9964960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 9974960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 9984960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 999d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1000d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 10014960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 10024960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 10034960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 10044960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 10054960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 100653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkTCopyOnFirstWrite<SaveLayerRec> rec(origRec); 1007d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 100853f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita rec.writable()->fBounds = nullptr; 1009d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 101053f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita 101153f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SaveLayerStrategy strategy = this->getSaveLayerStrategy(*rec); 1012a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 101353f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita this->internalSaveLayer(*rec, strategy); 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 10158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 10168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1017a2217ef965e57fdbbf989989e7ec1f2c04f62d39reedvoid SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, 1018c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkBaseDevice* dst, const SkIPoint& dstOrigin, 1019a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed const SkMatrix& ctm) { 1020a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkDraw draw; 1021a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkRasterClip rc; 1022a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed rc.setRect(SkIRect::MakeWH(dst->width(), dst->height())); 1023a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!dst->accessPixels(&draw.fDst)) { 1024a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDst.reset(dst->imageInfo(), nullptr, 0); 1025a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1026a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fMatrix = &SkMatrix::I(); 1027a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fRC = &rc; 10287354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 10297354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1030c61abeed8958a757c6b49937f28b63066148dd67Mike Reed if (filter) { 1031c61abeed8958a757c6b49937f28b63066148dd67Mike Reed p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1032c61abeed8958a757c6b49937f28b63066148dd67Mike Reed } 1033a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1034c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int x = src->getOrigin().x() - dstOrigin.x(); 1035c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int y = src->getOrigin().y() - dstOrigin.y(); 1036a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed auto special = src->snapSpecial(); 1037a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 103853f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita dst->drawSpecial(special.get(), x, y, p, nullptr, SkMatrix::I()); 1039a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 10407354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 104170ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1042129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1043129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1044129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1045129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 104652ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman // SRGBTODO: Can we remove this check now? 1047129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1048129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1049129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1050129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1051129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1052129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1053129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1054129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 1055693fdbd6b81a860657612e7604430dd55d6e721bMike Reed return SkImageInfo::Make(w, h, prev.colorType(), alphaType, prev.refColorSpace()); 1056129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1057129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1058129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 10594960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 10604960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 10614960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 10624960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 10634960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 10648c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 10658c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 10668c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 10678c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 10688c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 10698c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 10708c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 10718c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 10728c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 10738c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 10748c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 10758c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 10768c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 10778c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 10788c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 10798c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 10808c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 10818c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 10828c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 10838c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 10848c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 108596a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 10868c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 10878c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 10888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 10898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 10908c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 10918c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 10928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 10938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 10948c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 10958c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 10968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 10978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1098a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1099a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 11002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1101a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1102a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 11038c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 11042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1107e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1108e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1109e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 11102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1111e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1112e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 11134960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 11148dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 11158dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 111676033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1117daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 111876033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 11198dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1120b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1121b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 11228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11235139e501c5ac3a511e35c78395c907a176113451robertphillips SkBaseDevice* priorDevice = this->getTopDevice(); 1124c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (nullptr == priorDevice) { // Do we still need this check??? 1125b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 11262ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1127b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1128b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 11295139e501c5ac3a511e35c78395c907a176113451robertphillips SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir.height(), isOpaque, 1130129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1131129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1132704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> newDevice; 113361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 113470ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 11354960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1136daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 113770ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 1138356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed preserveLCDText, 1139356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator.get()); 11405139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice.reset(priorDevice->onCreateDevice(createInfo, paint)); 11415139e501c5ac3a511e35c78395c907a176113451robertphillips if (!newDevice) { 11427503d60847c4ad22df87458aecd917772b23d293reed return; 114361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 1144e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 114553f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix, rec.fClipMask, rec.fClipMatrix); 11468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1147b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed // only have a "next" if this new layer doesn't affect the clip (rare) 1148b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer; 11498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 11508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1151a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1152c61abeed8958a757c6b49937f28b63066148dd67Mike Reed if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) { 1153c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop }, 1154a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fMCRec->fMatrix); 1155a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1156c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1157c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop); 1158c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1159c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 1160c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (layer->fNext) { 1161c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // need to punch a hole in the previous device, so we don't draw there, given that 1162c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // the new top-layer will allow drawing to happen "below" it. 1163c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkRegion hole(ir); 1164c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed do { 1165c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer = layer->fNext; 1166c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer->fDevice->clipRegion(hole, SkClipOp::kDifference); 1167c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } while (layer->fNext); 1168c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 11698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1171d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1172bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1173bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1174bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1175bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1176bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1177bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1178bada1885da479d948f065182d6dfa85a1140bda5reed } 1179d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1180d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 11858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 118796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 11888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 11918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1194c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (fMCRec) { 1195c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix)); 1196c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 1197c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 12008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 12018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 120249f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 1203b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed if (fMCRec) { 12046f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 1205713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita this->internalDrawDevice(layer->fDevice.get(), origin.x(), origin.y(), 120653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita layer->fPaint.get(), 120753f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita layer->fClipImage.get(), layer->fClipMatrix); 12088c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 12098c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 12108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 1211385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1212b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1213b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1214a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1215b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 12168c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 12178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 121888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1219fbfa25802709139c2f14e304319c9541da65ca27msarett 1220fbfa25802709139c2f14e304319c9541da65ca27msarett if (fMCRec) { 12219637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 1222fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1223fbfa25802709139c2f14e304319c9541da65ca27msarett } 12248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1226e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 122796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 12284a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 12294a8126e7f81384526629b1e21bf89b632ea13cd9reed } 12304a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 123176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 123276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1233e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 123476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1235e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 123676f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 123776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1238c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1239ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onImageInfo(); 1240ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1241ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1242ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedSkImageInfo SkCanvas::onImageInfo() const { 1243c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1244c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1245c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1246c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1247900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1248c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1249c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1250c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1251898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1252ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onGetProps(props); 1253ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1254ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1255ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedbool SkCanvas::onGetProps(SkSurfaceProps* props) const { 1256898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1257898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1258898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1259898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1260898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1261898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1262898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1263898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1264898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1265898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1266898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 12676ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 12686ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1269c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1270c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1271884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1272c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1273884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1274c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1275c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 12766b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1277884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1278884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 127996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1280884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1281884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1282884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1283884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1284884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1285884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1286884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1287884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 12880ed3b640c9da71fbbd73c65a4ec1992f85596271Florin Malita *origin = this->getTopDevice()->getOrigin(); 12896b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1290884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 12919c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 12929c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1293884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 12949c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1295884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 12969c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 12979c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1298520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 130053f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malitavoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint, 130153f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkImage* clipImage, const SkMatrix& clipMatrix) { 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 130396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13064b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13078926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1308a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 13101f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 131176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 131276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 131376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 131453f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita if (filter || clipImage) { 1315833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial(); 1316833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips if (specialImage) { 131753f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint, 131853f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita clipImage, clipMatrix); 1319833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips } 132076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1321a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint); 132276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1324a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 13254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 132832704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1329da420b976e61071cfe5de10556b4b23e519091d6reed 133092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1331fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed if (dx || dy) { 1332fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->checkForDeferredSave(); 1333fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fMCRec->fMatrix.preTranslate(dx,dy); 1334cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1335fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed // Translate shouldn't affect the is-scale-translateness of the matrix. 1336fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1337cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1338c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 1339c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1340fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->didTranslate(dx,dy); 1341fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed } 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1345d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1346d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1347d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1351d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1352d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1353d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13567438bfc0804d021aa92cdd5ea644994a4248f3dbbungemanvoid SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) { 13577438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman SkMatrix m; 13587438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman m.setRotate(degrees, px, py); 13597438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman this->concat(m); 13607438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman} 13617438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman 136292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1363d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1364d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1365d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 136644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 136744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 136892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1369d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1370d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1371d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1372d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 13732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13741f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 13759637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 13767627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 13777627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 13787627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 137944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 138044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 138144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 13828c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 13831f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 13849da5a5a198e5dc9148f7f30a6089377590eee55bmsarett fIsScaleTranslate = matrix.isScaleTranslate(); 1385c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1386c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 13878c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 13888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 13898c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 13908c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 13918c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 139244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 13938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 13968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 13978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 14008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1401c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) { 14022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14038f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 14058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1407c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1408a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14097627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14107627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA)); 14117627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 1412c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1413a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1414a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1415fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14185f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Ilievvoid SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) { 14195f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fClipRestrictionRect = rect; 1420d519d484949161df6d4b2ecadc282427cab532cfMike Reed if (fClipRestrictionRect.isEmpty()) { 1421d519d484949161df6d4b2ecadc282427cab532cfMike Reed // we notify the device, but we *dont* resolve deferred saves (since we're just 1422d519d484949161df6d4b2ecadc282427cab532cfMike Reed // removing the restriction if the rect is empty. how I hate this api. 1423d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 1424d519d484949161df6d4b2ecadc282427cab532cfMike Reed } else { 14255f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev this->checkForDeferredSave(); 1426d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 14275f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev AutoValidateClip avc(this); 14285f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.op(fClipRestrictionRect, SkRegion::kIntersect_Op); 14295f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14305f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev } 14315f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev} 14325f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev 1433c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) { 14342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14364ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 14378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 14388f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14398f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 14404ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 14418f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 144214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1443c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1444a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon AutoValidateClip avc(this); 144514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1446a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14477627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14487627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA)); 1449a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1450a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1451a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1452a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14534ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 14544ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1455c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) { 14562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 145839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 145939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 146039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 146139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 146239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 146339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 146439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 146539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 146639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 146739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 146839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 146939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 147039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 147139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 147239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 147339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 147439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 14758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 147639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 147739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 14788f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1480c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) { 14815c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14825c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1483a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 14847627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 14857627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA)); 14865c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1487a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkPath* rasterClipPath = &path; 1488a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkMatrix* matrix = &fMCRec->fMatrix; 1489a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1490a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1491fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 14928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1494c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) { 14952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14968f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 14978f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1499c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) { 15007627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op)); 150127d07f0acb85eea4062075dfbe9148ce12d92c66Mike Reed 1502a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed AutoValidateClip avc(this); 150327d07f0acb85eea4062075dfbe9148ce12d92c66Mike Reed 150473603f3c52ffd89fe9d035be827b566a0e7d3b79reed fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op); 1505fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 15068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1508819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1509819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1510819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 15111f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1512ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 15135c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1514ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1515ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1516819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1517819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1518819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1519a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedbool SkCanvas::androidFramework_isClipAA() const { 1520a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed bool containsAA = false; 1521a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1522a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed FOR_EACH_TOP_DEVICE(containsAA |= device->onClipIsAA()); 1523a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1524a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return containsAA; 1525a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed} 1526a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1527a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedclass RgnAccumulator { 1528a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkRegion* fRgn; 1529a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedpublic: 1530a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed RgnAccumulator(SkRegion* total) : fRgn(total) {} 1531a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed void accumulate(SkBaseDevice* device, SkRegion* rgn) { 1532a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkIPoint origin = device->getOrigin(); 1533a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (origin.x() | origin.y()) { 1534a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed rgn->translate(origin.x(), origin.y()); 1535a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 1536a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed fRgn->op(*rgn, SkRegion::kUnion_Op); 1537a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed } 1538a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed}; 1539a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1540a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) { 1541a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed RgnAccumulator accum(rgn); 1542a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkRegion tmp; 1543a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1544a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed rgn->setEmpty(); 1545a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed FOR_EACH_TOP_DEVICE(device->onAsRgnClip(&tmp); accum.accumulate(device, &tmp)); 154690c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 154790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 15485c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 15495c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1550754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 155102be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed return fMCRec->fRasterClip.isEmpty(); 155202be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed 155302be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed // TODO: should we only use the conservative answer in a recording canvas? 155402be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed#if 0 1555a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* dev = this->getTopDevice(); 1556a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if no device we return true 1557a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return !dev || dev->onGetClipType() == SkBaseDevice::kEmpty_ClipType; 155802be3c1c3f53858263df82b1db466b5bb7059ab0Mike Reed#endif 1559754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1560754de5f65b466f721d952a379194cc94de376f42reed@google.com 15615c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 1562a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkBaseDevice* dev = this->getTopDevice(); 1563a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // if no device we return false 1564a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return dev && dev->onGetClipType() == SkBaseDevice::kRect_ClipType; 15655c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 15665c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1567fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) { 1568fbfa25802709139c2f14e304319c9541da65ca27msarett#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 1569fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 lLtT = _mm_unpacklo_ps(devRect.fVec, devClip.fVec); 1570fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 RrBb = _mm_unpackhi_ps(devClip.fVec, devRect.fVec); 1571fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 mask = _mm_cmplt_ps(lLtT, RrBb); 1572fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xF != _mm_movemask_ps(mask); 1573fbfa25802709139c2f14e304319c9541da65ca27msarett#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON) 1574fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t lLtT = vzipq_f32(devRect.fVec, devClip.fVec).val[0]; 1575fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t RrBb = vzipq_f32(devClip.fVec, devRect.fVec).val[1]; 1576fbfa25802709139c2f14e304319c9541da65ca27msarett uint32x4_t mask = vcltq_f32(lLtT, RrBb); 1577fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xFFFFFFFFFFFFFFFF != (uint64_t) vmovn_u32(mask); 1578fbfa25802709139c2f14e304319c9541da65ca27msarett#else 1579fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devRectAsRect; 1580fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devClipAsRect; 1581fbfa25802709139c2f14e304319c9541da65ca27msarett devRect.store(&devRectAsRect.fLeft); 1582fbfa25802709139c2f14e304319c9541da65ca27msarett devClip.store(&devClipAsRect.fLeft); 1583fbfa25802709139c2f14e304319c9541da65ca27msarett return !devRectAsRect.isFinite() || !devRectAsRect.intersect(devClipAsRect); 1584fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1585fbfa25802709139c2f14e304319c9541da65ca27msarett} 1586fbfa25802709139c2f14e304319c9541da65ca27msarett 1587fbfa25802709139c2f14e304319c9541da65ca27msarett// It's important for this function to not be inlined. Otherwise the compiler will share code 1588fbfa25802709139c2f14e304319c9541da65ca27msarett// between the fast path and the slow path, resulting in two slow paths. 1589fbfa25802709139c2f14e304319c9541da65ca27msarettstatic SK_NEVER_INLINE bool quick_reject_slow_path(const SkRect& src, const SkRect& deviceClip, 1590fbfa25802709139c2f14e304319c9541da65ca27msarett const SkMatrix& matrix) { 1591fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect deviceRect; 1592fbfa25802709139c2f14e304319c9541da65ca27msarett matrix.mapRect(&deviceRect, src); 1593fbfa25802709139c2f14e304319c9541da65ca27msarett return !deviceRect.isFinite() || !deviceRect.intersect(deviceClip); 1594fbfa25802709139c2f14e304319c9541da65ca27msarett} 1595d22a817ff57986407facd16af36320fc86ce02damsarett 1596fbfa25802709139c2f14e304319c9541da65ca27msarettbool SkCanvas::quickReject(const SkRect& src) const { 1597fbfa25802709139c2f14e304319c9541da65ca27msarett#ifdef SK_DEBUG 1598fbfa25802709139c2f14e304319c9541da65ca27msarett // Verify that fDeviceClipBounds are set properly. 1599fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect tmp = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16001f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 16010c685ee188a5e500df25a34fa6edfceb4cbb795cmsarett SkASSERT(fDeviceClipBounds.isEmpty()); 1602fbfa25802709139c2f14e304319c9541da65ca27msarett } else { 1603fbfa25802709139c2f14e304319c9541da65ca27msarett SkASSERT(tmp == fDeviceClipBounds); 16048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16069637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett // Verify that fIsScaleTranslate is set properly. 16079637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1608fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1609d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 16109637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett if (!fIsScaleTranslate) { 1611fbfa25802709139c2f14e304319c9541da65ca27msarett return quick_reject_slow_path(src, fDeviceClipBounds, fMCRec->fMatrix); 16128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1613fbfa25802709139c2f14e304319c9541da65ca27msarett 1614fbfa25802709139c2f14e304319c9541da65ca27msarett // We inline the implementation of mapScaleTranslate() for the fast path. 1615fbfa25802709139c2f14e304319c9541da65ca27msarett float sx = fMCRec->fMatrix.getScaleX(); 1616fbfa25802709139c2f14e304319c9541da65ca27msarett float sy = fMCRec->fMatrix.getScaleY(); 1617fbfa25802709139c2f14e304319c9541da65ca27msarett float tx = fMCRec->fMatrix.getTranslateX(); 1618fbfa25802709139c2f14e304319c9541da65ca27msarett float ty = fMCRec->fMatrix.getTranslateY(); 1619fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f scale(sx, sy, sx, sy); 1620fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f trans(tx, ty, tx, ty); 1621fbfa25802709139c2f14e304319c9541da65ca27msarett 1622fbfa25802709139c2f14e304319c9541da65ca27msarett // Apply matrix. 1623fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans; 1624fbfa25802709139c2f14e304319c9541da65ca27msarett 1625fbfa25802709139c2f14e304319c9541da65ca27msarett // Make sure left < right, top < bottom. 1626fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]); 1627fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f min = Sk4f::Min(ltrb, rblt); 1628fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f max = Sk4f::Max(ltrb, rblt); 1629fbfa25802709139c2f14e304319c9541da65ca27msarett // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on 1630fbfa25802709139c2f14e304319c9541da65ca27msarett // ARM this sequence generates the fastest (a single instruction). 1631fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f devRect = Sk4f(min[2], min[3], max[0], max[1]); 1632fbfa25802709139c2f14e304319c9541da65ca27msarett 1633fbfa25802709139c2f14e304319c9541da65ca27msarett // Check if the device rect is NaN or outside the clip. 1634fbfa25802709139c2f14e304319c9541da65ca27msarett return is_nan_or_clipped(devRect, Sk4f::Load(&fDeviceClipBounds.fLeft)); 16358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16373b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 16383b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 16398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 164142e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkRect SkCanvas::onGetLocalClipBounds() const { 164242e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkIRect ibounds = this->onGetDeviceClipBounds(); 1643918e144408ba218df919528f8b48c544f4767883Mike Reed if (ibounds.isEmpty()) { 164442e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 16458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1647d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1648d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 16491f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 165042e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 1651d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1652d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 165342e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect bounds; 165442e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect r; 165542e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed // adjust it outwards in case we are antialiasing 165642e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed const int inset = 1; 1657fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 165842e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 165942e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed ibounds.fRight + inset, ibounds.fBottom + inset); 166042e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed inverse.mapRect(&bounds, r); 166142e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return bounds; 16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 166442e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkIRect SkCanvas::onGetDeviceClipBounds() const { 1665a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fMCRec->fRasterClip.getBounds(); 1666bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1667bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 16688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 16691f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 16708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16721105224f9701e57ec5ce0354d6a380b664f5c638Brian OsmanGrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() { 16739c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 16741105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman return dev ? dev->accessRenderTargetContext() : nullptr; 16759c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 16769c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1677644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1678644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 167986ae3d161412961c27a406465b0ec5749cc2e753reed return device ? device->context() : nullptr; 1680644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1681e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1682ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1683ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 16849881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1685ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1686ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1687ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1688ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1689ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1690ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1691ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1692ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1693ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1694e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark // be able to return ... 1695e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark // if (!outer.contains(inner))) { 1696ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1697ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1698e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark if (!outer.getBounds().contains(inner.getBounds())) { 1699e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark return; 1700e0b728726d3b44bf18219b8c5bc5599332be7c34Cary Clark } 1701ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1702ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1703ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1704ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 170541af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 170641af966ab338e95eee81ab618ab28195075338f7reed 170741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 170841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 170941af966ab338e95eee81ab618ab28195075338f7reed} 171041af966ab338e95eee81ab618ab28195075338f7reed 171141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 17126e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman // To avoid redundant logic in our culling code and various backends, we always sort rects 17136e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman // before passing them along. 17146e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman this->onDrawRect(r.makeSorted(), paint); 171541af966ab338e95eee81ab618ab28195075338f7reed} 171641af966ab338e95eee81ab618ab28195075338f7reed 1717dca352e2d42cfe698573947b3d11abc1eaade160msarettvoid SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { 1718dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isEmpty()) { 1719dca352e2d42cfe698573947b3d11abc1eaade160msarett return; 1720dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1721dca352e2d42cfe698573947b3d11abc1eaade160msarett 1722dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isRect()) { 1723dca352e2d42cfe698573947b3d11abc1eaade160msarett return this->drawIRect(region.getBounds(), paint); 1724dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1725dca352e2d42cfe698573947b3d11abc1eaade160msarett 1726dca352e2d42cfe698573947b3d11abc1eaade160msarett this->onDrawRegion(region, paint); 1727dca352e2d42cfe698573947b3d11abc1eaade160msarett} 1728dca352e2d42cfe698573947b3d11abc1eaade160msarett 172941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 17306e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman // To avoid redundant logic in our culling code and various backends, we always sort rects 17316e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman // before passing them along. 17326e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman this->onDrawOval(r.makeSorted(), paint); 173341af966ab338e95eee81ab618ab28195075338f7reed} 173441af966ab338e95eee81ab618ab28195075338f7reed 173541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 173641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 173741af966ab338e95eee81ab618ab28195075338f7reed} 173841af966ab338e95eee81ab618ab28195075338f7reed 173941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 174041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 174141af966ab338e95eee81ab618ab28195075338f7reed} 174241af966ab338e95eee81ab618ab28195075338f7reed 1743e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, 1744e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed const SkPaint& paint) { 1745e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed RETURN_ON_NULL(vertices); 1746e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed this->onDrawVerticesObject(vertices.get(), mode, paint); 1747e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed} 1748e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed 1749e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) { 1750199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon RETURN_ON_NULL(vertices); 1751e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed this->onDrawVerticesObject(vertices, mode, paint); 175241af966ab338e95eee81ab618ab28195075338f7reed} 175341af966ab338e95eee81ab618ab28195075338f7reed 175441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 175541af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 175641af966ab338e95eee81ab618ab28195075338f7reed} 175741af966ab338e95eee81ab618ab28195075338f7reed 1758a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1759e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1760a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 176141af966ab338e95eee81ab618ab28195075338f7reed} 176241af966ab338e95eee81ab618ab28195075338f7reed 1763e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1764e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1765e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1766e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1767e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1768e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1769e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1770e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 177141af966ab338e95eee81ab618ab28195075338f7reed 177284984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 177384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1774e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1775e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 177684984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 177784984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1778e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1779e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1780e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1781e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1782e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1783e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1784e47829b6b1eeb6b0c97ccb3df3016d197046824creed 17854c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 17864c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 1787e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 17884c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 17894c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 17904c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 1791552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(image->width(), image->height(), center)) { 1792552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawImageNine(image, center, dst, paint); 1793552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1794e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 17954c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 17964c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 17974c21dc5ddf3b482293ed34eead876d8d61a662c3reed 1798168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 1799168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 1800168820625c35a8c19f66c661efcbce7a5e334837msarett RETURN_ON_NULL(image); 1801168820625c35a8c19f66c661efcbce7a5e334837msarett if (dst.isEmpty()) { 1802168820625c35a8c19f66c661efcbce7a5e334837msarett return; 1803168820625c35a8c19f66c661efcbce7a5e334837msarett } 180471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 180571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 180671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 180771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 180871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(image->width(), image->height()); 180971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 181071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 181171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 181271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) { 181371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawImageLattice(image, latticePlusBounds, dst, paint); 1814168820625c35a8c19f66c661efcbce7a5e334837msarett } else { 1815168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawImageRect(image, dst, paint); 1816168820625c35a8c19f66c661efcbce7a5e334837msarett } 1817168820625c35a8c19f66c661efcbce7a5e334837msarett} 1818168820625c35a8c19f66c661efcbce7a5e334837msarett 181941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 18204c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 18212df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 18222df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 182341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 182441af966ab338e95eee81ab618ab28195075338f7reed} 182541af966ab338e95eee81ab618ab28195075338f7reed 1826e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1827a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1828e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1829a5517e2b190a8083b38964972b031c13e99f1012reed return; 1830a5517e2b190a8083b38964972b031c13e99f1012reed } 1831e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 183241af966ab338e95eee81ab618ab28195075338f7reed} 183341af966ab338e95eee81ab618ab28195075338f7reed 183484984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 183584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1836e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1837e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1838e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1839e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1840e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1841e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1842e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 184384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 184484984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 184541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 184641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 18474c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 18482df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 18492df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 1850552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) { 1851552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawBitmapNine(bitmap, center, dst, paint); 1852552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1853a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 18544c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 185541af966ab338e95eee81ab618ab28195075338f7reed} 185641af966ab338e95eee81ab618ab28195075338f7reed 1857c573a40ed5024b463e47088d307e3164a486dba5msarettvoid SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, 1858c573a40ed5024b463e47088d307e3164a486dba5msarett const SkPaint* paint) { 1859168820625c35a8c19f66c661efcbce7a5e334837msarett if (bitmap.drawsNothing() || dst.isEmpty()) { 1860c573a40ed5024b463e47088d307e3164a486dba5msarett return; 1861c573a40ed5024b463e47088d307e3164a486dba5msarett } 186271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 186371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 186471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 186571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 186671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 186771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 186871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 186971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 187071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) { 187171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, paint); 1872552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1873168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawBitmapRect(bitmap, dst, paint); 1874c573a40ed5024b463e47088d307e3164a486dba5msarett } 1875c573a40ed5024b463e47088d307e3164a486dba5msarett} 1876c573a40ed5024b463e47088d307e3164a486dba5msarett 187771c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 18787d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkColor colors[], int count, SkBlendMode mode, 187971c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 1880e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 188171c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 188271c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 188371c3c760a83123ee0b3127b8c65c6394ce541c50reed } 1884c485907f0420e5f9cf8223e9ba53812cd8dd5368Joe Gregorio SkASSERT(atlas); 188571c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 1886faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 188771c3c760a83123ee0b3127b8c65c6394ce541c50reed} 188871c3c760a83123ee0b3127b8c65c6394ce541c50reed 1889f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 1890f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 1891f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 1892f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 1893f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 1894f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 1895e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 1896e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1897e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1898e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 1899e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1900e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 1901e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1902e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1903e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1904e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 1905e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1906e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1907e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 1908e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1909e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 1910e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1911e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1912e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1913e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19144204da25aa4c6e0b321314aa32fd9affb4865563Mike Reedvoid SkCanvas::private_draw_shadow_rec(const SkPath& path, const SkDrawShadowRec& rec) { 19154204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed this->onDrawShadowRec(path, rec); 19164204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed} 19174204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed 19184204da25aa4c6e0b321314aa32fd9affb4865563Mike Reedvoid SkCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) { 19194204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed SkPaint paint; 19204204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed const SkRect& pathBounds = path.getBounds(); 19214204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed 19224204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds) 19234204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed while (iter.next()) { 19244204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed iter.fDevice->drawShadow(path, rec); 19254204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed } 19264204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed LOOPER_END 19274204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed} 19284204da25aa4c6e0b321314aa32fd9affb4865563Mike Reed 19298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 19318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 193328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 193449f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 193528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 193628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 193728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 193828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 193941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 19409881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1941fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1942fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1943fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1944fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 194596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 19468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 1948a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPaint(looper.paint()); 19498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 195441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 195541af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 19569881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 19578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 19588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1961822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect r; 196296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 1963a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1964a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1965a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1966a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1967a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1968a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1969a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1970822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 197187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 197287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 197387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 197487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 1975fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1976a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 197796fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 19788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 197978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 19804b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 1982a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPoints(mode, count, pts, looper.paint()); 19838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19844b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19884a16717bc7aa471fad10ec3157774771a76e5106reedstatic bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) { 19894a16717bc7aa471fad10ec3157774771a76e5106reed return ((intptr_t)paint.getImageFilter() | 19904a16717bc7aa471fad10ec3157774771a76e5106reed#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 19914a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)canvas->getDrawFilter() | 19924a16717bc7aa471fad10ec3157774771a76e5106reed#endif 19934a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)paint.getLooper() ) != 0; 19944a16717bc7aa471fad10ec3157774771a76e5106reed} 19954a16717bc7aa471fad10ec3157774771a76e5106reed 199641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 19979881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 19986e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman SkASSERT(r.isSorted()); 19998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 2000822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 20016e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman if (this->quickReject(paint.computeFastBounds(r, &storage))) { 200287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 200387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 20048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20054b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20064a16717bc7aa471fad10ec3157774771a76e5106reed if (needs_autodrawlooper(this, paint)) { 2007822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, &r, false) 20088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20094a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 2010a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRect(r, looper.paint()); 20114a16717bc7aa471fad10ec3157774771a76e5106reed } 20128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20134a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_END 20144a16717bc7aa471fad10ec3157774771a76e5106reed } else { 2015822128b475c1782788f96e7a1a848d0affb878b1Mike Reed this->predrawNotify(&r, &paint, false); 20164a16717bc7aa471fad10ec3157774771a76e5106reed SkDrawIter iter(this); 20174a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 2018a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRect(r, paint); 20194a16717bc7aa471fad10ec3157774771a76e5106reed } 20204a16717bc7aa471fad10ec3157774771a76e5106reed } 20218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 202344df651ebefc284acc2f66425dff3ea0b0e14b36msarettvoid SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 202444df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect regionRect = SkRect::Make(region.getBounds()); 202544df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (paint.canComputeFastBounds()) { 2026822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 202744df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (this->quickReject(paint.computeFastBounds(regionRect, &storage))) { 202844df651ebefc284acc2f66425dff3ea0b0e14b36msarett return; 202944df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 203044df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 203144df651ebefc284acc2f66425dff3ea0b0e14b36msarett 2032822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, ®ionRect) 203344df651ebefc284acc2f66425dff3ea0b0e14b36msarett 203444df651ebefc284acc2f66425dff3ea0b0e14b36msarett while (iter.next()) { 2035a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRegion(region, looper.paint()); 203644df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 203744df651ebefc284acc2f66425dff3ea0b0e14b36msarett 203844df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_END 203944df651ebefc284acc2f66425dff3ea0b0e14b36msarett} 204044df651ebefc284acc2f66425dff3ea0b0e14b36msarett 204141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 20429881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 20436e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman SkASSERT(oval.isSorted()); 20444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 2045822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 20466e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 204787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 204887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 20494ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2050306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 2051822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval) 205246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 205346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 2054a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawOval(oval, looper.paint()); 205546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 205646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 205746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 20584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2060ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomonvoid SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, 2061ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkScalar sweepAngle, bool useCenter, 2062ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkPaint& paint) { 2063ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 20646e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman SkASSERT(oval.isSorted()); 2065ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (paint.canComputeFastBounds()) { 2066ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkRect storage; 2067ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon // Note we're using the entire oval as the bounds. 20686e3ce40bd93e5de16b0086cb70320ff3283e72cfBrian Osman if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 2069ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon return; 2070ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2071ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2072ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2073822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval) 2074ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2075ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon while (iter.next()) { 2076a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint()); 2077ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2078ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2079ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_END 2080ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon} 2081ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 208241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 20839881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 20844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 2085822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 208687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 208787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 208887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 20894ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 20914ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 20924ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 20934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2094f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2095f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 20964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2097f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2098f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 20994ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2100f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2101822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &rrect.getBounds()) 2102f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2103f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2104a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawRRect(rrect, looper.paint()); 2105f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2106f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2107f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 21084ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2110822128b475c1782788f96e7a1a848d0affb878b1Mike Reedvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { 2111ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 2112822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 211387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 211487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 211587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2116ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 211725c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2118822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &outer.getBounds()) 211925c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2120ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2121a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawDRRect(outer, inner, looper.paint()); 2122ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 212325c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2124ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2125ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 21264ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 212741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 21289881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 21299364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 21309364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 21319364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 21329364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 2133822128b475c1782788f96e7a1a848d0affb878b1Mike Reed const SkRect& pathBounds = path.getBounds(); 2134fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 2135822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 213687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 213787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 213887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 21398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21400b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 2141822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (pathBounds.width() <= 0 && pathBounds.height() <= 0) { 21426803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2143fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 21446651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2145fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2146fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 21478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2148822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds) 21498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 2151a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPath(path, looper.paint()); 21528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21544e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2157262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2158262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2159262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2160262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2161262a71b7f95ce98ff3dd8dba845afbd724470903reed 2162262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2163c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2164262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2165262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2166262a71b7f95ce98ff3dd8dba845afbd724470903reed 2167262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2168262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2169262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2170262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2171262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2172262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2173262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2174262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2175262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2176262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2177262a71b7f95ce98ff3dd8dba845afbd724470903reed 2178a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 21799881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2180a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2181a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 218296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 218387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 218487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 218587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 218687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 218787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 218887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 218987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2190a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 21919d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2192a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 219396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2194a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2195a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2196262a71b7f95ce98ff3dd8dba845afbd724470903reed 2197a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2198129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2199129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2200129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2201a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(image); 2202a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2203129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2204129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2205129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2206129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2207262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2208262a71b7f95ce98ff3dd8dba845afbd724470903reed 2209a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2210262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2211a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2212a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkPoint pt; 2213a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->ctm().mapXY(x, y, &pt); 2214a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawSpecial(special.get(), 2215a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 221653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkScalarRoundToInt(pt.fY), pnt, 221753f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita nullptr, SkMatrix::I()); 2218262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2219a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImage(image, x, y, pnt); 2220262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2221a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22229d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2223a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2224b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2225b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 222641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2227562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 22289881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 222996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2230c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 223187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 223287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 223387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 223487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 223587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 223687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2237a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2238a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 223996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2240a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2241a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22429d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2243c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2244c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 22459d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2246a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2247a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint); 2248a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22499d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2250a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2251b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2252b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 225341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 22549881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 22558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 22568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 225733366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 225833366974d43eae80e22284a2e445225c343859dareed return; 225933366974d43eae80e22284a2e445225c343859dareed } 226033366974d43eae80e22284a2e445225c343859dareed 226133366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 226233366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 226333366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 226433366974d43eae80e22284a2e445225c343859dareed } 226533366974d43eae80e22284a2e445225c343859dareed 2266822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect bounds; 2267822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bitmap.getBounds(&bounds); 2268822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bounds.offset(x, y); 2269822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bool canFastBounds = paint->canComputeFastBounds(); 2270822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (canFastBounds) { 2271822128b475c1782788f96e7a1a848d0affb878b1Mike Reed SkRect storage; 2272822128b475c1782788f96e7a1a848d0affb878b1Mike Reed if (this->quickReject(paint->computeFastBounds(bounds, &storage))) { 227387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 227487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 22758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22764b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2277a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2278822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bool drawAsSprite = canFastBounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), 2279822128b475c1782788f96e7a1a848d0affb878b1Mike Reed bitmap.height(), *paint); 2280129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2281a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(bitmap); 2282a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2283129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2284129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2285129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2286129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2287822128b475c1782788f96e7a1a848d0affb878b1Mike Reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 228833366974d43eae80e22284a2e445225c343859dareed 228933366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2290262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2291a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2292262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2293a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->ctm().mapXY(x, y, &pt); 2294a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawSpecial(special.get(), 2295a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 229653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita SkScalarRoundToInt(pt.fY), pnt, 229753f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita nullptr, SkMatrix::I()); 2298262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2299b964238f0bded00bae59c26c5f366a7780a0ef5fHal Canary iter.fDevice->drawBitmap(bitmap, x, y, looper.paint()); 2300262a71b7f95ce98ff3dd8dba845afbd724470903reed } 230133366974d43eae80e22284a2e445225c343859dareed } 2302fbfa25802709139c2f14e304319c9541da65ca27msarett 230333366974d43eae80e22284a2e445225c343859dareed LOOPER_END 23048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23069987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 23077112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2308eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2309a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 231050b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 23118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 23128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 231374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 231496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2315c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 231687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 231787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 231887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23203d60812865bb034851da777a91413ab584929887reed@google.com 232133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 232296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 232333535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 23248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23257064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2326c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2327c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 23287064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 232933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2330a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint); 2331f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 23327064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 233333535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 23348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 233641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2337562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 23389881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 23399987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2340562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 23419987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23429987ec3791336bad6af5cbe513564786b2df55aareed@google.com 23434c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 23444c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 23454c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 23469d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 234796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2348c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 234987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 235087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 235187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23523d60812865bb034851da777a91413ab584929887reed@google.com } 23539d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23544c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 235596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23564c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23574c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23589d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2359c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 23609d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23614c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 2362a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageNine(image, center, dst, looper.paint()); 23639987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 23649d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23654c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23669987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23679987ec3791336bad6af5cbe513564786b2df55aareed@google.com 236841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 236941af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 23709881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 23719987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 23729987ec3791336bad6af5cbe513564786b2df55aareed@google.com 237396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2374c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 237587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 237687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 237787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23784c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23799d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23804c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 238196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23824c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23834c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23849d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2385c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 23869d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23874c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 2388a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint()); 23894c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23909d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 23914c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23929987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23939987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2394168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2395168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2396168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2397168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2398168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2399168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2400168820625c35a8c19f66c661efcbce7a5e334837msarett } 2401168820625c35a8c19f66c661efcbce7a5e334837msarett } 2402168820625c35a8c19f66c661efcbce7a5e334837msarett 2403168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2404168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2405168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2406168820625c35a8c19f66c661efcbce7a5e334837msarett } 2407168820625c35a8c19f66c661efcbce7a5e334837msarett 2408168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2409168820625c35a8c19f66c661efcbce7a5e334837msarett 2410168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2411a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint()); 2412168820625c35a8c19f66c661efcbce7a5e334837msarett } 2413168820625c35a8c19f66c661efcbce7a5e334837msarett 2414168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2415168820625c35a8c19f66c661efcbce7a5e334837msarett} 2416168820625c35a8c19f66c661efcbce7a5e334837msarett 2417168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, 2418168820625c35a8c19f66c661efcbce7a5e334837msarett const SkRect& dst, const SkPaint* paint) { 2419168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2420168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2421168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2422168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2423168820625c35a8c19f66c661efcbce7a5e334837msarett } 2424168820625c35a8c19f66c661efcbce7a5e334837msarett } 2425168820625c35a8c19f66c661efcbce7a5e334837msarett 2426168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2427168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2428168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2429168820625c35a8c19f66c661efcbce7a5e334837msarett } 2430168820625c35a8c19f66c661efcbce7a5e334837msarett 2431168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2432168820625c35a8c19f66c661efcbce7a5e334837msarett 2433168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2434a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint()); 2435168820625c35a8c19f66c661efcbce7a5e334837msarett } 2436168820625c35a8c19f66c661efcbce7a5e334837msarett 2437168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2438168820625c35a8c19f66c661efcbce7a5e334837msarett} 2439168820625c35a8c19f66c661efcbce7a5e334837msarett 2440f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2441f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 24421f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2443112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2444112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2445a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2446112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2447f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2448f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2449f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2450f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2451f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2452f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2453f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2454f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2455f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 24562c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 24572c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2458f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2459f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2460e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2461e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 246296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 24638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2466a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawText(text, byteLength, x, y, dfp.paint()); 24678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24694e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2472e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2473e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 247405c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 247505c4a4322e7d4f3417b7df33825bab8603d52051fmalita 247696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 247787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2480a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset, 2481f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2483b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 24844e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2487e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2488e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 248905c4a4322e7d4f3417b7df33825bab8603d52051fmalita 249005c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 249105c4a4322e7d4f3417b7df33825bab8603d52051fmalita 249296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 249387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2496a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset, 2497f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2499b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 25004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2503e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2504e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 250596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 250687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 25078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 2508a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextOnPath(text, byteLength, path, 25094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 25108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2511b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2512945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 25134325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 25144325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 251545561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 251645561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 251745561a0b15fe045ba272c328684c3f7ae290785areed if (cullRect && this->quickReject(*cullRect)) { 251845561a0b15fe045ba272c328684c3f7ae290785areed return; 251945561a0b15fe045ba272c328684c3f7ae290785areed } 252045561a0b15fe045ba272c328684c3f7ae290785areed 252145561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 252245561a0b15fe045ba272c328684c3f7ae290785areed 252345561a0b15fe045ba272c328684c3f7ae290785areed while (iter.next()) { 2524a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextRSXform(text, byteLength, xform, looper.paint()); 252545561a0b15fe045ba272c328684c3f7ae290785areed } 252645561a0b15fe045ba272c328684c3f7ae290785areed 252745561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_END 252845561a0b15fe045ba272c328684c3f7ae290785areed} 252945561a0b15fe045ba272c328684c3f7ae290785areed 253000d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 253100d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 25327ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 253385d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 253496fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 253519653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 253685d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 253787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 253887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 253987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 254087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 254187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 25427ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 25437ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2544024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2545024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2546024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 254796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2548024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 254985d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 255000d5c2c6523321d25b32905ff4822f083a4173eefmalita 2551aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2552aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2553a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawTextBlob(blob, x, y, dfp.paint(), drawFilter); 255400d5c2c6523321d25b32905ff4822f083a4173eefmalita } 255500d5c2c6523321d25b32905ff4822f083a4173eefmalita 2556aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2557024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2558024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 255900d5c2c6523321d25b32905ff4822f083a4173eefmalita} 256000d5c2c6523321d25b32905ff4822f083a4173eefmalita 25612a475eae622adc1e8fa29206be1eaf862c23548eCary Clarkvoid SkCanvas::drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint) { 25622a475eae622adc1e8fa29206be1eaf862c23548eCary Clark this->drawText(string.c_str(), string.size(), x, y, paint); 25632a475eae622adc1e8fa29206be1eaf862c23548eCary Clark} 25642a475eae622adc1e8fa29206be1eaf862c23548eCary Clark 2565e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2566e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2567e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25689881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2569ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2570ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawText(text, byteLength, x, y, paint); 2571ac09554dce518e9d4496771f648f3ae17eca857creed } 2572e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2573e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2574e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2576ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2577ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosText(text, byteLength, pos, paint); 2578ac09554dce518e9d4496771f648f3ae17eca857creed } 2579e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2580e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2581e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 25829881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2583ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2584ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2585ac09554dce518e9d4496771f648f3ae17eca857creed } 2586e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2587e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2588e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 25899881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2590ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2591ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2592ac09554dce518e9d4496771f648f3ae17eca857creed } 2593e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 259445561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 259545561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 259645561a0b15fe045ba272c328684c3f7ae290785areed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextRSXform()"); 259745561a0b15fe045ba272c328684c3f7ae290785areed if (byteLength) { 259845561a0b15fe045ba272c328684c3f7ae290785areed this->onDrawTextRSXform(text, byteLength, xform, cullRect, paint); 259945561a0b15fe045ba272c328684c3f7ae290785areed } 260045561a0b15fe045ba272c328684c3f7ae290785areed} 260100d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 260200d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2603e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 26049881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2605e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 260600d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2607e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 2608e88a1cb20e6b4c9f099070112225a88693a4630bMike Reedvoid SkCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, 2609e88a1cb20e6b4c9f099070112225a88693a4630bMike Reed const SkPaint& paint) { 2610199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 2611199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 2612199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2613199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon while (iter.next()) { 2614199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon // In the common case of one iteration we could std::move vertices here. 26152f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed iter.fDevice->drawVertices(vertices, bmode, looper.paint()); 2616199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon } 2617199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2618199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_END 2619199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon} 2620199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2621b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 26227d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 26237d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 26249881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 262596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2626b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2627b3c9d1c33caf325aada244204215eb790c228c12dandov } 26286cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2629faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawPatch(cubics, colors, texCoords, bmode, paint); 26309340c2685c0bb0e1e70008acaaf3d1448f074c38msarett} 26319340c2685c0bb0e1e70008acaaf3d1448f074c38msarett 26329340c2685c0bb0e1e70008acaaf3d1448f074c38msarettvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2633faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 26347d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 2635ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2636ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2637ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2638b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2639ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2640ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2641ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26426cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2643435071e8ab865e395bec34ef128a412ceb50f063Mike Reed const bool interpColorsLinearly = (this->imageInfo().colorSpace() != nullptr); 2644435071e8ab865e395bec34ef128a412ceb50f063Mike Reed 264596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 26466cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2647ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2648435071e8ab865e395bec34ef128a412ceb50f063Mike Reed iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, interpColorsLinearly, paint); 2649ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26506cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2651ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2652ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2653ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2654a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2655e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2656e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2657e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2658e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2659e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2660e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2661a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2662a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2663a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2664a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2665e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2666e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2667e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 26686a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2669e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 26706a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26716a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2672a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 26732a62e853c27cfacafd5c15ac1077cc13140589bareed // drawable bounds are no longer reliable (e.g. android displaylist) 26742a62e853c27cfacafd5c15ac1077cc13140589bareed // so don't use them for quick-reject 2675a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 26766a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26776a070dc06af4e9f305f9d08a69e34d18ade473cbreed 267871c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 2679faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkColor colors[], int count, SkBlendMode bmode, 268071c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 268171c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 268271c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 268371c3c760a83123ee0b3127b8c65c6394ce541c50reed } 268471c3c760a83123ee0b3127b8c65c6394ce541c50reed 268571c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 268671c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 268771c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 268871c3c760a83123ee0b3127b8c65c6394ce541c50reed } 26899d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 269096fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 269171c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 2692a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt); 269371c3c760a83123ee0b3127b8c65c6394ce541c50reed } 269471c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 269571c3c760a83123ee0b3127b8c65c6394ce541c50reed} 269671c3c760a83123ee0b3127b8c65c6394ce541c50reed 2697f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2698f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 2699f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2700f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 2701f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 2702f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 2703a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed iter.fDevice->drawAnnotation(rect, key, value); 2704f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2705f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 2706f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2707f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 27088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 27098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 27108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 27118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 27128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2713374772bd61951f01bf84fe17bf53d8867681c9aereedvoid SkCanvas::drawColor(SkColor c, SkBlendMode mode) { 27149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 27158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 27168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2718374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(mode); 27198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 27208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 27239881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 27243661bc997620899695041010a750d11dbe8a972dMike Reed const SkPoint pt = { x, y }; 27258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 27268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27283661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint) { 27299881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 27308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 27314b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 27338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 27348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 27358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27373661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint) { 27389881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 27398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 27408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 27418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 27448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 27454ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 27468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 27498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27509881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 27518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 27524ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 27534ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 27544ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 27558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 27568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 27578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 27618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 27628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27639881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 276421af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon if (oval.isEmpty() || !sweepAngle) { 276521af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon return; 27668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 276721af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint); 27688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 27718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 27728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 27739881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 27748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 27754b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 27778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 27788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2780f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 27811c2c441fede0ae9573afc098017011e3439624a9reed 27821c2c441fede0ae9573afc098017011e3439624a9reed/** 27831c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 27841c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 27851c2c441fede0ae9573afc098017011e3439624a9reed * 27861c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 27871c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 27881c2c441fede0ae9573afc098017011e3439624a9reed */ 27891c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 27909b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2791d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 2792e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 2793e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 27941c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 2795e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2796e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 2797e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 2798e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 2799e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2800e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 2801e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2802e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 2803d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2804d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 28059b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2806d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2807d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2808d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 2809d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 2810d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 2811d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 2812d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2813d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 2814d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 2815d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2816d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 2817d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 2818d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2819d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2820d028180f0310cf2b23f9744256a41697b0683e67fmalita 2821a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2822c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 28238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28283aafe111b6cc388400092851cc53bbbdfcb8a81creedSkCanvas::LayerIter::LayerIter(SkCanvas* canvas) { 282999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 28308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 28328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28333aafe111b6cc388400092851cc53bbbdfcb8a81creed fImpl = new (fStorage) SkDrawIter(canvas); 28348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 28388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 28398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28451f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 284699330ba6227137866a0dbd63478d36f335203ebdMike Reed return fImpl->fDevice; 28478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 2850a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fImpl->fDevice->ctm(); 28518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 28548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 285596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 28568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 28578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 28598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2861a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkCanvas::LayerIter::clip(SkRegion* rgn) const { 2862a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed return fImpl->fDevice->onAsRgnClip(rgn); 2863a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed} 2864a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 28658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 28668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 286720a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 286820a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 286920a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 28703107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 28713107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 28723107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 28733107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 28743107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28753107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28763107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28773107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 28783107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28793107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 28803107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 28813107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 288228fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 28839e3dbdff53f2d9957626a17a279730cda70f17bajunov case kRGBA_F16_SkColorType: 28843107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28853107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28863107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28873107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 28883107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28893107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 28903107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 28913107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28925df4934b3e40cdc378e225d1dda39f015cae9baeMike Reedstd::unique_ptr<SkCanvas> SkCanvas::MakeRasterDirect(const SkImageInfo& info, void* pixels, 28935df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed size_t rowBytes) { 289442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 289596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 289642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2897eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 289842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 289942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 290096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 290142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 29025df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed return skstd::make_unique<SkCanvas>(bitmap); 290342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2904d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2905d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2906d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2907d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2908a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2909d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2910d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2911d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 291249f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2913a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2914d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2915a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2916d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2917a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 291849f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2919d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2920d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 29216cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 292249f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2923d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2924d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2925d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2926d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2927d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2928d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2929d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2930e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 2931ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 2932ee424acbb87bf999be132a437527e656e37541d7Florin Malita 2933ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkNoDrawCanvas::SkNoDrawCanvas(int width, int height) 2934ee424acbb87bf999be132a437527e656e37541d7Florin Malita : INHERITED(SkIRect::MakeWH(width, height), kConservativeRasterClip_InitFlag) {} 2935ee424acbb87bf999be132a437527e656e37541d7Florin Malita 2936439ace939b6aaa58408ece0e9e89b633353571aeFlorin MalitaSkNoDrawCanvas::SkNoDrawCanvas(const SkIRect& bounds) 2937439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita : INHERITED(bounds, kConservativeRasterClip_InitFlag) {} 2938439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita 2939ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkCanvas::SaveLayerStrategy SkNoDrawCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { 2940ee424acbb87bf999be132a437527e656e37541d7Florin Malita (void)this->INHERITED::getSaveLayerStrategy(rec); 2941ee424acbb87bf999be132a437527e656e37541d7Florin Malita return kNoLayer_SaveLayerStrategy; 2942ee424acbb87bf999be132a437527e656e37541d7Florin Malita} 2943ee424acbb87bf999be132a437527e656e37541d7Florin Malita 2944ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 294573603f3c52ffd89fe9d035be827b566a0e7d3b79reed 294673603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kDifference_Op == (int)kDifference_SkClipOp, ""); 294773603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kIntersect_Op == (int)kIntersect_SkClipOp, ""); 294873603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kUnion_Op == (int)kUnion_SkClipOp, ""); 294973603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kXOR_Op == (int)kXOR_SkClipOp, ""); 295073603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReverseDifference_Op == (int)kReverseDifference_SkClipOp, ""); 295173603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReplace_Op == (int)kReplace_SkClipOp, ""); 2952356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2953356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 2954356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2955356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkCanvas::accessTopRasterHandle() const { 2956356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (fAllocator && fMCRec->fTopLayer->fDevice) { 2957713b8ef3748609ee20f6005a66d6aafd02aab4b6Florin Malita const auto& dev = fMCRec->fTopLayer->fDevice; 2958356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle handle = dev->getRasterHandle(); 2959356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIPoint origin = dev->getOrigin(); 2960356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkMatrix ctm = this->getTotalMatrix(); 2961356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed ctm.preTranslate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y())); 2962356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2963356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIRect clip = fMCRec->fRasterClip.getBounds(); 2964356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.offset(-origin.x(), -origin.y()); 2965108f55ed5d0b63baf653e4e443cc469df887c811Mike Reed if (!clip.intersect(0, 0, dev->width(), dev->height())) { 2966356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.setEmpty(); 2967356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2968356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2969356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator->updateHandle(handle, ctm, clip); 2970356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return handle; 2971356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2972356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 2973356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 2974356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2975356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstatic bool install(SkBitmap* bm, const SkImageInfo& info, 2976356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkRasterHandleAllocator::Rec& rec) { 2977086a427b0cee3862f25c492fc5082ff24105dc53Mike Reed return bm->installPixels(info, rec.fPixels, rec.fRowBytes, rec.fReleaseProc, rec.fReleaseCtx); 2978356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 2979356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2980356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkRasterHandleAllocator::allocBitmap(const SkImageInfo& info, 2981356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap* bm) { 2982356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Rec rec; 2983356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!this->allocHandle(info, &rec) || !install(bm, info, rec)) { 2984356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 2985356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2986356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return rec.fHandle; 2987356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 2988356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2989356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstd::unique_ptr<SkCanvas> 2990356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::MakeCanvas(std::unique_ptr<SkRasterHandleAllocator> alloc, 2991356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkImageInfo& info, const Rec* rec) { 2992356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!alloc || !supported_for_raster_canvas(info)) { 2993356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 2994356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 2995356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2996356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap bm; 2997356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed Handle hndl; 2998356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 2999356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (rec) { 3000356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = install(&bm, info, *rec) ? rec->fHandle : nullptr; 3001356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } else { 3002356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = alloc->allocBitmap(info, &bm); 3003356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3004356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return hndl ? std::unique_ptr<SkCanvas>(new SkCanvas(bm, std::move(alloc), hndl)) : nullptr; 3005356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3006