SkCanvas.cpp revision 3661bc997620899695041010a750d11dbe8a972d
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 873fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby#include "SkArenaAlloc.h" 9986480a71f4e860663ced7ad90a1fe346a164afbMike Reed#include "SkBitmapDevice.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 11d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 12d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkClipStack.h" 13dbc3cefb0b624808ddb86d444e6103f216e12fa5reed#include "SkColorFilter.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 153cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 18b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 19262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkImage_Base.h" 20900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilter.h" 21900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilterCache.h" 22c573a40ed5024b463e47088d307e3164a486dba5msarett#include "SkLatticeIter.h" 235df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed#include "SkMakeUnique.h" 24262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 26ee424acbb87bf999be132a437527e656e37541d7Florin Malita#include "SkNoDrawCanvas.h" 27fbfa25802709139c2f14e304319c9541da65ca27msarett#include "SkNx.h" 28c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 29b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 31b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack#include "SkRadialShadowMapShader.h" 320017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 33356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed#include "SkRasterHandleAllocator.h" 344ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 35904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowPaintFilterCanvas.h" 36904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowShader.h" 374418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 3897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 397ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 4052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 41a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 428f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 43d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 467354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 47644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 48614d8f9a3c44e22d77fa909e82119e8a6746e1b1bsalomon#include "SkGrPriv.h" 49e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 50644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 51ebfce6d9b42198e04288a15953f40c395a7b6139Mike Reed#include "SkClipOpPriv.h" 52199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon#include "SkVertices.h" 53644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 54e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 55e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 56c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 57c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 58c83a29759a5c2966da5ab973e4fd90763e4c962breed * 59c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 60c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 61c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 62c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 63c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 64c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 65c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 6699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 6799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 6899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 6999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 7099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 7199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 7299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 7399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 7499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 75c83a29759a5c2966da5ab973e4fd90763e4c962breed 76c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 77c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 78c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 79c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 80c83a29759a5c2966da5ab973e4fd90763e4c962breed } 81c83a29759a5c2966da5ab973e4fd90763e4c962breed 82c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 83c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!this->getTotalMatrix().isScaleTranslate()) { 84c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 85c83a29759a5c2966da5ab973e4fd90763e4c962breed } 86c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary 87c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary SkRect devRect; 88c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary this->getTotalMatrix().mapRectScaleTranslate(&devRect, *rect); 89c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!devRect.contains(bounds)) { 90c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 91c83a29759a5c2966da5ab973e4fd90763e4c962breed } 92c83a29759a5c2966da5ab973e4fd90763e4c962breed } 93c83a29759a5c2966da5ab973e4fd90763e4c962breed 94c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 95c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 96c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 97c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 98c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 99c83a29759a5c2966da5ab973e4fd90763e4c962breed } 100c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 101c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 102c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 103c83a29759a5c2966da5ab973e4fd90763e4c962breed } 104c83a29759a5c2966da5ab973e4fd90763e4c962breed } 105c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 106c83a29759a5c2966da5ab973e4fd90763e4c962breed} 107c83a29759a5c2966da5ab973e4fd90763e4c962breed 108c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 109c83a29759a5c2966da5ab973e4fd90763e4c962breed 110d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 111d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 112d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 113d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 114d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 115d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 116d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 117d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1180acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1190acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1200acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1210acf1b4b3645772d220c720313821bac389751b5reed} 1220acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1230acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1240acf1b4b3645772d220c720313821bac389751b5reed} 1250acf1b4b3645772d220c720313821bac389751b5reed 126da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1502c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1512c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 152c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 15397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 154c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 155c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 156c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 157c83a29759a5c2966da5ab973e4fd90763e4c962breed } 158c83a29759a5c2966da5ab973e4fd90763e4c962breed} 159c83a29759a5c2966da5ab973e4fd90763e4c962breed 160c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 161c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 162c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 163c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 164c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 165c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 166c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 167c83a29759a5c2966da5ab973e4fd90763e4c962breed // 168c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 169c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 170c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 171c83a29759a5c2966da5ab973e4fd90763e4c962breed } 172c83a29759a5c2966da5ab973e4fd90763e4c962breed } 173c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 17497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 17597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 17697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1791f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1881f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 189045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1906f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 19161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 19261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 1938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19596e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 1967503d60847c4ad22df87458aecd917772b23d293reed bool conservativeRasterClip, const SkMatrix& stashed) 19796fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 198d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 1998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed , fStashedMatrix(stashed) 200d954498c01ccf0417feacf89e45d0c62a06a813breed { 2012c9e20055be772feb3f44986c1af0c0a979eff49reed SkSafeRef(device); 2024b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 20396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = paint ? new SkPaint(*paint) : nullptr; 20488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 2072c9e20055be772feb3f44986c1af0c0a979eff49reed SkSafeUnref(fDevice); 208385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fPaint; 20988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2104b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 211feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 212feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 213feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 214feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 215feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 216feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 217feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 218045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 219de6c531e468197bb7746f1217a8ccb2ab175e0b8reed SkRasterClip* updateClip) { 2206f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2216f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2244b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 236045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 239c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkASSERT(*fMatrix == fDevice->ctm()); 240c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // TODO: debug tiles-rt-8888 so we can enable this all the time 241c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed// fDevice->validateDevBounds(fClip.getBounds()); 242c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 243c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2454b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 247045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2504b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 258f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2701f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 271d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2792ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2802ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 283e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack // This is the current cumulative depth (aggregate of all done translateZ calls) 284e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack SkScalar fCurDrawDepth; 285e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 286d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 28796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 28896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 28996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 2902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 292e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth = 0; 293b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 294d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 295d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 296d954498c01ccf0417feacf89e45d0c62a06a813breed } 297e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix), 298e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth(prev.fCurDrawDepth) { 299d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 30096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 301d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 303b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 30882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 309385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 312feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 313feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 314feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 315feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 316feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 317feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 318feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 319feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 320feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32302f9ed74ead11fcb01a24faa7d93f853e869f1abreedstatic SkIRect compute_device_bounds(SkBaseDevice* device) { 32402f9ed74ead11fcb01a24faa7d93f853e869f1abreed return SkIRect::MakeXYWH(device->getOrigin().x(), device->getOrigin().y(), 32502f9ed74ead11fcb01a24faa7d93f853e869f1abreed device->width(), device->height()); 32602f9ed74ead11fcb01a24faa7d93f853e869f1abreed} 32702f9ed74ead11fcb01a24faa7d93f853e869f1abreed 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 33099330ba6227137866a0dbd63478d36f335203ebdMike Reed SkDrawIter(SkCanvas* canvas) : fDevice(nullptr) { 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3336bd5284415bd983b0628c4941dff5def40018f5abungeman fClipStack = canvas->getClipStack(); 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 33502f9ed74ead11fcb01a24faa7d93f853e869f1abreed 33602f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS = nullptr; 33702f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fCurrLayer->fNext) { 3386bd5284415bd983b0628c4941dff5def40018f5abungeman fMultiDeviceCS = canvas->fClipStack.get(); 33902f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS->save(); 34002f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 341d519d484949161df6d4b2ecadc282427cab532cfMike Reed#ifdef SK_USE_DEVICE_CLIPPING 342d519d484949161df6d4b2ecadc282427cab532cfMike Reed fClipStack = nullptr; // for testing 343d519d484949161df6d4b2ecadc282427cab532cfMike Reed#endif 34402f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 34502f9ed74ead11fcb01a24faa7d93f853e869f1abreed 34602f9ed74ead11fcb01a24faa7d93f853e869f1abreed ~SkDrawIter() { 34702f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fMultiDeviceCS) { 34802f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS->restore(); 34902f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3514b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 35302f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fMultiDeviceCS && fDevice) { 35402f9ed74ead11fcb01a24faa7d93f853e869f1abreed // remove the previous device's bounds 355c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed fMultiDeviceCS->clipDevRect(compute_device_bounds(fDevice), kDifference_SkClipOp); 35602f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 35702f9ed74ead11fcb01a24faa7d93f853e869f1abreed 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3593aafe111b6cc388400092851cc53bbbdfcb8a81creed while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3603aafe111b6cc388400092851cc53bbbdfcb8a81creed fCurrLayer = fCurrLayer->fNext; 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 363f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 364f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 367045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 36941e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 37096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDst.reset(fDevice->imageInfo(), nullptr, 0); 37141e010cb901c0da9066c4df562030808c9ccd7f8reed } 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 373f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 37696fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 377199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3824b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3831e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed const SkRasterClip& getClip() const { return *fRC; } 3846f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3856f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3886f8f292aa768869a9e85c314b124875f57504f2creed@google.com 38999330ba6227137866a0dbd63478d36f335203ebdMike Reed SkBaseDevice* fDevice; 39099330ba6227137866a0dbd63478d36f335203ebdMike Reed 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 39402f9ed74ead11fcb01a24faa7d93f853e869f1abreed SkClipStack* fMultiDeviceCS; 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3997627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#define FOR_EACH_TOP_DEVICE( code ) \ 4007627fa51044e35dc21251f925b56f6dd6887df97Mike Reed do { \ 4017627fa51044e35dc21251f925b56f6dd6887df97Mike Reed DeviceCM* layer = fMCRec->fTopLayer; \ 4027627fa51044e35dc21251f925b56f6dd6887df97Mike Reed while (layer) { \ 4037627fa51044e35dc21251f925b56f6dd6887df97Mike Reed SkBaseDevice* device = layer->fDevice; \ 404c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (device) { \ 405c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed code; \ 406c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } \ 4077627fa51044e35dc21251f925b56f6dd6887df97Mike Reed layer = layer->fNext; \ 4087627fa51044e35dc21251f925b56f6dd6887df97Mike Reed } \ 4097627fa51044e35dc21251f925b56f6dd6887df97Mike Reed } while (0) 4107627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 413dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 414dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 415dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 416dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 417dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 418dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 41996fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 420dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 421d053ce9c54d4e5937a142278359e5a4cde18095ereedstatic sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) { 422dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 423dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 42496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 425dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 426dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 427d053ce9c54d4e5937a142278359e5a4cde18095ereed SkColorFilter* imgCFPtr; 428d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!imgf->asAColorFilter(&imgCFPtr)) { 42996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 430dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 431d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> imgCF(imgCFPtr); 432dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 433dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 43496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 435dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 436dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 437dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 438dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 439dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 440dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 441d053ce9c54d4e5937a142278359e5a4cde18095ereed return SkColorFilter::MakeComposeFilter(std::move(imgCF), sk_ref_sp(paintCF)); 442dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 443dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 44487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 44587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 44687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 44787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 44887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 44987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 45087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 45187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 45287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 45387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 45487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 45587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 45687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 45787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 45887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 45987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 46087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 46187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 46287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 46387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 46487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 46587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 46887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 46987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 47087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4713aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, bool skipLayerForImageFilter = false, 47287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 47453d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4767765000709dc64eb23be7df47d1f995d1f787115fmalita#else 4777765000709dc64eb23be7df47d1f995d1f787115fmalita fFilter = nullptr; 4787765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 4794a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4804e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4815c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 484d053ce9c54d4e5937a142278359e5a4cde18095ereed auto simplifiedCF = image_to_color_filter(fOrigPaint); 485dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 486dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 487d053ce9c54d4e5937a142278359e5a4cde18095ereed paint->setColorFilter(std::move(simplifiedCF)); 48896fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 489dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 490dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 491dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 492dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4935c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4945c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4955c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4965c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4975c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4985c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4995c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 5005c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 5015c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 5025c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 5035c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 5045c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 5055c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 5065c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 5075c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 5088926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 509693fdbd6b81a860657612e7604430dd55d6e721bMike Reed tmp.setImageFilter(fPaint->refImageFilter()); 510374772bd61951f01bf84fe17bf53d8867681c9aereed tmp.setBlendMode(fPaint->getBlendMode()); 51187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 51287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 51387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 51487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 51587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 516bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), 51776033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 5185c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 5195c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 5208926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 52279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 52373fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby fLooperContext = looper->makeContext(canvas, &fAlloc); 524129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 525129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 52696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 527129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 5285c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 53174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5324e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 5335c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 5348926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 5358926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 53874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5394e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5404e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5414e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5424e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 54374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 544129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 545129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 546129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 547129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 548129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 549129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 550129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 551129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 552129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 553fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 55474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 55673fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 557dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5582c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5592c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5602c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5612c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5622c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5635c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5642c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 565129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 56679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 56773fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby char fStorage[48]; 56873fe7b07e6391da81dfc48d600d7b3141be1f471Herb Derby SkArenaAlloc fAlloc {fStorage}; 569129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 570129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 573129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 57496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 575129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5765c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 577632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 578dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 579dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5808926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5815c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 58296fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 583374772bd61951f01bf84fe17bf53d8867681c9aereed paint->setBlendMode(SkBlendMode::kSrcOver); 584129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5858926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 58679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 587129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 588129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 589129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 590129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 591971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 592971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 593971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 594971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 59596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 596129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 597632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 598632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 599129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 600129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 6018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 602129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 60379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 6044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 6054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 6064e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 607632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 608632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 60996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 6104e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 6114e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 6124e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 6134e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 6144e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6173aafe111b6cc388400092851cc53bbbdfcb8a81creed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 6183aafe111b6cc388400092851cc53bbbdfcb8a81creed this->predrawNotify(); \ 6193aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \ 6203aafe111b6cc388400092851cc53bbbdfcb8a81creed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 621262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 622262a71b7f95ce98ff3dd8dba845afbd724470903reed 623262a71b7f95ce98ff3dd8dba845afbd724470903reed 6248926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 62597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6263aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, true); \ 6278926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 6288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 6298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 63078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 63197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6323aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 6334e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 6354b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 636c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 637c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 6383aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 639c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 640c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 641c83a29759a5c2966da5ab973e4fd90763e4c962breed 6424e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 646fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline SkRect qr_clip_bounds(const SkIRect& bounds) { 647fbfa25802709139c2f14e304319c9541da65ca27msarett if (bounds.isEmpty()) { 648fbfa25802709139c2f14e304319c9541da65ca27msarett return SkRect::MakeEmpty(); 649fbfa25802709139c2f14e304319c9541da65ca27msarett } 650fbfa25802709139c2f14e304319c9541da65ca27msarett 651fbfa25802709139c2f14e304319c9541da65ca27msarett // Expand bounds out by 1 in case we are anti-aliasing. We store the 652fbfa25802709139c2f14e304319c9541da65ca27msarett // bounds as floats to enable a faster quick reject implementation. 653fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect dst; 654fbfa25802709139c2f14e304319c9541da65ca27msarett SkNx_cast<float>(Sk4i::Load(&bounds.fLeft) + Sk4i(-1,-1,1,1)).store(&dst.fLeft); 655fbfa25802709139c2f14e304319c9541da65ca27msarett return dst; 656fbfa25802709139c2f14e304319c9541da65ca27msarett} 657fbfa25802709139c2f14e304319c9541da65ca27msarett 658feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 659feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 660feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 661feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 662feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 663feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 664feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 665feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 666fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(bounds); 6679637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 668feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 669feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 670d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 67142b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 67242b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 67342b73eb00367c8315974b1c374308d20efa78897reed } 67442b73eb00367c8315974b1c374308d20efa78897reed // Since init() is only called once by our constructors, it is safe to perform this 67542b73eb00367c8315974b1c374308d20efa78897reed // const-cast. 67642b73eb00367c8315974b1c374308d20efa78897reed *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag); 67742b73eb00367c8315974b1c374308d20efa78897reed 67845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 679f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6802ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 68196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 68295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 68395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack fLights = nullptr; 68495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 686385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fClipStack.reset(new SkClipStack); 687687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 689d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6905f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect); 6919637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 693a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 694a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 6957503d60847c4ad22df87458aecd917772b23d293reed new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip, 6968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix); 697b679ca8926a832274b14fdb512f88f64b61d32eareed 6988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 70096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 701f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 702f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 703efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 704efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 705f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 70678e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 707fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds()); 708c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 709c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 710c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 711c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 712f92c86642a1875da54d54b447f006cb9dfbbb35creed } 713fbfa25802709139c2f14e304319c9541da65ca27msarett 714f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 717cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 718e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7194a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 72042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 721e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 7228d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 723ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 72496fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 7258d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 7268d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 727d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 728d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 729d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 730d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 731d954498c01ccf0417feacf89e45d0c62a06a813breed} 732d954498c01ccf0417feacf89e45d0c62a06a813breed 733d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 734d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 735fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 736fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 73778e276889795454891cbba48ab11927968114953reed { 738c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed this->setOrigin(SkMatrix::I(), bounds.x(), bounds.y()); 73978e276889795454891cbba48ab11927968114953reed } 740d954498c01ccf0417feacf89e45d0c62a06a813breed 741d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 742b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 743d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 744d954498c01ccf0417feacf89e45d0c62a06a813breed}; 745d954498c01ccf0417feacf89e45d0c62a06a813breed 74696a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 747e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 74896a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 74942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 750e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 751e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 752b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 753385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps), 754385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 755d954498c01ccf0417feacf89e45d0c62a06a813breed} 756e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 75778e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 758d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7594a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 76042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 761d954498c01ccf0417feacf89e45d0c62a06a813breed{ 762d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 763b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 764385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref(); 76527a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 767d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 768d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7697b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 77042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 771d954498c01ccf0417feacf89e45d0c62a06a813breed{ 772d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 773b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 774d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 777fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 778fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7797b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 78042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 781fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 782fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 783fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 784fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 785fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 786fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7874a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7883716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7894a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 79042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7913716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7923716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 793b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 794704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 795704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7964a8126e7f81384526629b1e21bf89b632ea13cd9reed} 79729c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 798356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocator> alloc, 799356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle hndl) 8004a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 8014a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 802356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed , fAllocator(std::move(alloc)) 80342b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 8044a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 8054a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 806b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 807356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl)); 808704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 811356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkCanvas::SkCanvas(const SkBitmap& bitmap) : SkCanvas(bitmap, nullptr, nullptr) {} 812356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 8167c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 819385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 820b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 82453d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 83051985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8347765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 83674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 83774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 83874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 83996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 84074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 84174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 84274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 84374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 84474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 847bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 848ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed this->onFlush(); 849ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 850ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 851ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedvoid SkCanvas::onFlush() { 8521f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 853bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 854bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 855bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 856bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 857bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 858afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 859afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 8604ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8614ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8624ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 863afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8644ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 865afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 866afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 867afc7cce5d68663934128d76963cd501f771d71desenorblanco } 868afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 869210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 870210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8711f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 873c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 8758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8780ed3b640c9da71fbbd73c65a4ec1992f85596271Florin MalitaSkBaseDevice* SkCanvas::getTopDevice() const { 8799266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 8809266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8819266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 882a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 883a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 88496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap->pixelRef()) { 885848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 886a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 887a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 888a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 889a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 890a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 891cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 892cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 893cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 894cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 895cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 896cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 897a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 898a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 899a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 9001b3387b5cfef150c3237c6a8700b2d6f3730e4ceHal Canary bitmap->setPixelRef(nullptr, 0, 0); 901a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 902a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 903a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 90451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 905c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 906a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 907a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 908a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 909a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 910ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 911ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 91274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 913848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 914a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 915a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 916a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 917a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 918a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 919daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 920c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 921a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 922a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 923c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 92496472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 925a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 926a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 927a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 928a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 929db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 93003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->readPixels(dstInfo, dstP, rowBytes, x, y); 93151df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 93251df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 934cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 935cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 936cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 937cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 9384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 9414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 94203dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarettbool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_t rowBytes, 9434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 9444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 9454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 9464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 94903dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This check gives us an early out and prevents generation ID churn on the surface. 95003dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This is purely optional: it is a subset of the checks performed by SkWritePixelsRec. 95103dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett SkIRect srcRect = SkIRect::MakeXYWH(x, y, srcInfo.width(), srcInfo.height()); 95203dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett if (!srcRect.intersect(0, 0, device->width(), device->height())) { 95303dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return false; 9544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 95603dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // Tell our owning surface to bump its generation ID. 95703dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett const bool completeOverwrite = 95803dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett srcRect.size() == SkISize::Make(device->width(), device->height()); 959c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9604af35f348b2e2f6c428819118eb7a2f2fff53a74reed 96103dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // This can still fail, most notably in the case of a invalid color type or alpha type 96203dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // conversion. We could pull those checks into this function and avoid the unnecessary 96303dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // generation ID bump. But then we would be performing those checks twice, since they 96403dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett // are also necessary at the bitmap/pixmap entry points. 96503dd6d5208a6e3d92190e7020300e4399178ae4bMatt Sarett return device->writePixels(srcInfo, pixels, rowBytes, x, y); 9664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 96751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9731f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9754b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 97696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == layer->fNext) { // only one layer 977de6c531e468197bb7746f1217a8ccb2ab175e0b8reed layer->updateMC(totalMatrix, totalClip, nullptr); 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 979045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 981de6c531e468197bb7746f1217a8ccb2ab175e0b8reed layer->updateMC(totalMatrix, clip, &clip); 98296fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((layer = layer->fNext) != nullptr); 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 9912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 9932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 996f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 9972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 9982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 9992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 10002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 10012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 10032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 10042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 10062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 10082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 10092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 1010f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1011f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1012f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 10132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 10162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 10182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 1019f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 1020a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 1021a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 1022a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 10232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1024f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1025f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1026f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 10272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 10292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 10302ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 10312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 10322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 10332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 10342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 10352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 1036a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 10372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 10382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 10392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 1040f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1041f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1042f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1043f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 1044f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 1045f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 1046f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 1047f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1048f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 1049f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 1050f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 1051f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 1052f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1053f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1054f0090cb80ab10a49e511aa5450ae38917fa058d9reed 10552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 1057d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1060687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 1061c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 1062c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->save()); 1063c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 10648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10664960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 10674960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 10688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10704960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 10719b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1072918e144408ba218df919528f8b48c544f4767883Mike Reed SkIRect clipBounds = this->getDeviceClipBounds(); 1073918e144408ba218df919528f8b48c544f4767883Mike Reed if (clipBounds.isEmpty()) { 1074a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1075f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1076c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 107796e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 107896e657d0e103b8358a77ecd913f6086929f792b8reed 1079c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 1080e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 1081db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 1082db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 1083db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 1084c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1085bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 108649f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10884b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 108996e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 10928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 10934960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 10941f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1095fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 1096bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1097a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1102180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11044960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 1105180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 1106c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed fClipStack->clipDevRect(ir, kReplace_SkClipOp); 1107180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1108fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(ir); 1109a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1110a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1111a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1112a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1113a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1114a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1115a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1116a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 11174960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11184960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 11194960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1120d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1121d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11224960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 11234960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 11244960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 11254960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11264960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 11274960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerRec rec(origRec); 1128d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 11294960eeec4a1f2a772654883d7f3615d47bcd5dc3reed rec.fBounds = nullptr; 1130d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 11314960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1132a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 11334960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->internalSaveLayer(rec, strategy); 11342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 11358926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 11368926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1137a2217ef965e57fdbbf989989e7ec1f2c04f62d39reedvoid SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, 1138c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkBaseDevice* dst, const SkIPoint& dstOrigin, 1139c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed const SkMatrix& ctm, const SkClipStack* clipStack) { 1140a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkDraw draw; 1141a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkRasterClip rc; 1142a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed rc.setRect(SkIRect::MakeWH(dst->width(), dst->height())); 1143a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!dst->accessPixels(&draw.fDst)) { 1144a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDst.reset(dst->imageInfo(), nullptr, 0); 1145a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1146a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fMatrix = &SkMatrix::I(); 1147a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fRC = &rc; 1148a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fClipStack = clipStack; 11497354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11507354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1151372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1152a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1153c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int x = src->getOrigin().x() - dstOrigin.x(); 1154c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed int y = src->getOrigin().y() - dstOrigin.y(); 1155a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed auto special = src->snapSpecial(); 1156a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 1157a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed dst->drawSpecial(draw, special.get(), x, y, p); 1158a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 11597354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 116070ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1161129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1162129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1163129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1164129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 116552ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman // SRGBTODO: Can we remove this check now? 1166129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1167129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1168129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1169129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1170129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1171129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1172129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1173129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 1174693fdbd6b81a860657612e7604430dd55d6e721bMike Reed return SkImageInfo::Make(w, h, prev.colorType(), alphaType, prev.refColorSpace()); 1175129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1176129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1177129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 11784960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 11794960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 11804960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 11814960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 11824960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11838c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 11848c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 11858c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 11868c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 11878c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 11888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 11898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 11908c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 11918c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 11928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 11938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 11948c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 11958c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 11968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 11978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 11988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 11998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 12008c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 12018c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 12028c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 12038c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 120496a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 12058c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 12068c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 12078c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 12088c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 12098c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 12108c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 12118c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 12128c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 12138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 12148c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 12158c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 12168c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1217a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1218a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 12192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1220a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1221a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1222a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1223a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 12248c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 12252ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 12268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1228e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1229e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1230e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 12312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1232e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1233e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 12344960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 12358dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 12368dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 123776033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1238daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 123976033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 12408dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1241b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1242b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 12438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12445139e501c5ac3a511e35c78395c907a176113451robertphillips SkBaseDevice* priorDevice = this->getTopDevice(); 1245c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (nullptr == priorDevice) { // Do we still need this check??? 1246b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 12472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1248b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1249b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 12505139e501c5ac3a511e35c78395c907a176113451robertphillips SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir.height(), isOpaque, 1251129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1252129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1253704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> newDevice; 125461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 125570ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 12564960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1257daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 125870ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 1259356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed preserveLCDText, 1260356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator.get()); 12615139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice.reset(priorDevice->onCreateDevice(createInfo, paint)); 12625139e501c5ac3a511e35c78395c907a176113451robertphillips if (!newDevice) { 12637503d60847c4ad22df87458aecd917772b23d293reed return; 126461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 1265e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 1266c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifndef SK_USE_DEVICE_CLIPPING 1267c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop); 1268c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 12697354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 1270704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary DeviceCM* layer = 1271704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary new DeviceCM(newDevice.get(), paint, this, fConservativeRasterClip, stashedMatrix); 12728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1273b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed // only have a "next" if this new layer doesn't affect the clip (rare) 1274b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer; 12758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1277a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1278a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (rec.fBackdrop) { 1279c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop }, 1280a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed fMCRec->fMatrix, this->getClipStack()); 1281a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1282c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1283c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 1284c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop); 1285c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1286c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect); 1287c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (layer->fNext) { 1288c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // need to punch a hole in the previous device, so we don't draw there, given that 1289c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed // the new top-layer will allow drawing to happen "below" it. 1290c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed SkRegion hole(ir); 1291c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed do { 1292c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer = layer->fNext; 1293c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed layer->fDevice->clipRegion(hole, SkClipOp::kDifference); 1294c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } while (layer->fNext); 1295c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 1296c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 12978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1299d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1300bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1301bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1302bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1303bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1304bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1305bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1306bada1885da479d948f065182d6dfa85a1140bda5reed } 1307d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1308d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 13138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1314687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 13156c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 131688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 131996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 13248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1326c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 1327c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed if (fMCRec) { 1328c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix)); 1329c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed } 1330c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 1331c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 13348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 13358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 133649f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 1337b43a3e0160b3854a04305decd1d9e766a3889b3aMike Reed if (fMCRec) { 13386f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 13397503d60847c4ad22df87458aecd917772b23d293reed this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), layer->fPaint); 13408c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 13418c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 13428926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1344385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1345b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1346b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1347a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1348b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 13498c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 13508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 135188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1352fbfa25802709139c2f14e304319c9541da65ca27msarett 1353fbfa25802709139c2f14e304319c9541da65ca27msarett if (fMCRec) { 13549637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 1355fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1356fbfa25802709139c2f14e304319c9541da65ca27msarett } 13578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1359e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 136096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 13614a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 13624a8126e7f81384526629b1e21bf89b632ea13cd9reed } 13634a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 136476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 136576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1366e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 136776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1368e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 136976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 137076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1371c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1372ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onImageInfo(); 1373ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1374ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1375ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedSkImageInfo SkCanvas::onImageInfo() const { 1376c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1377c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1378c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1379c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1380900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1381c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1382c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1383c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1384898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1385ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onGetProps(props); 1386ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1387ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1388ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedbool SkCanvas::onGetProps(SkSurfaceProps* props) const { 1389898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1390898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1391898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1392898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1393898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1394898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1395898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1396898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1397898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1398898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1399898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 14006ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 14016ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1402c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1403c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1404884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1405c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1406884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1407c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1408c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 14096b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1410884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1411884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 141296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1413884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1414884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1415884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1416884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1417884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1418884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1419884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1420884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 14210ed3b640c9da71fbbd73c65a4ec1992f85596271Florin Malita *origin = this->getTopDevice()->getOrigin(); 14226b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1423884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 14249c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14259c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1426884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 14279c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1428884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 14299c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14309c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1431520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 14328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14337503d60847c4ad22df87458aecd917772b23d293reedvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint) { 14348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 143596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 14368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 14378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14384b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14398926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1440a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 14418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 14421f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 144376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 144476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 144576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 1446833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips if (filter) { 1447833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial(); 1448833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips if (specialImage) { 1449833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips dstDev->drawSpecial(iter, specialImage.get(), pos.x(), pos.y(), *paint); 1450833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips } 145176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1452b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 145376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 14548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1455a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 14564e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 14578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145932704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1460da420b976e61071cfe5de10556b4b23e519091d6reed 146192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1462fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed if (dx || dy) { 1463fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->checkForDeferredSave(); 1464fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fDeviceCMDirty = true; 1465fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fMCRec->fMatrix.preTranslate(dx,dy); 1466cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1467fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed // Translate shouldn't affect the is-scale-translateness of the matrix. 1468fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1469cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1470c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 1471c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 1472c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 1473c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1474fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->didTranslate(dx,dy); 1475fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed } 14768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 147892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1479d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1480d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1481d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1485d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1486d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1487d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14907438bfc0804d021aa92cdd5ea644994a4248f3dbbungemanvoid SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) { 14917438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman SkMatrix m; 14927438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman m.setRotate(degrees, px, py); 14937438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman this->concat(m); 14947438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman} 14957438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman 149692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1497d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1498d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1499d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 150044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 150144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 150292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1503d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1504d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1505d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1506d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 15072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 15091f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 15109637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 15117627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 15127627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 15137627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 15147627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#endif 15157627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 151644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 151744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 151844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 15198c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 15208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 15211f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 15229da5a5a198e5dc9148f7f30a6089377590eee55bmsarett fIsScaleTranslate = matrix.isScaleTranslate(); 1523c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed 1524c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 1525c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix)); 1526c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 15278c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 15288c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 15298c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 15308c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 15318c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 153244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 15338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 15368c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 15378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 153995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 1540e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackvoid SkCanvas::translateZ(SkScalar z) { 1541e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->checkForDeferredSave(); 1542e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->fMCRec->fCurDrawDepth += z; 1543e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->didTranslateZ(z); 1544e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1545e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 1546e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackSkScalar SkCanvas::getZ() const { 1547e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack return this->fMCRec->fCurDrawDepth; 1548e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1549e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 155095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::setLights(sk_sp<SkLights> lights) { 155195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack this->fLights = lights; 155295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 155395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 155495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblacksk_sp<SkLights> SkCanvas::getLights() const { 155595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack return this->fLights; 155695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 155795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 155895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 15598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 15608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1561c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) { 15622ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15648f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 15658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1567c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1568a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 15697627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 15707627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 15717627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA)); 15727627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#endif 15737627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 1574c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1575a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA); 1576a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1577a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1578c64eff55049b1192052b791549a32a03be1c43e3reed fDeviceCMDirty = true; 1579fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 15808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15825f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Ilievvoid SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) { 15835f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fClipRestrictionRect = rect; 15845f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fClipStack->setDeviceClipRestriction(fClipRestrictionRect); 1585d519d484949161df6d4b2ecadc282427cab532cfMike Reed if (fClipRestrictionRect.isEmpty()) { 1586d519d484949161df6d4b2ecadc282427cab532cfMike Reed // we notify the device, but we *dont* resolve deferred saves (since we're just 1587d519d484949161df6d4b2ecadc282427cab532cfMike Reed // removing the restriction if the rect is empty. how I hate this api. 1588d519d484949161df6d4b2ecadc282427cab532cfMike Reed#ifdef SK_USE_DEVICE_CLIPPING 1589d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 1590d519d484949161df6d4b2ecadc282427cab532cfMike Reed#endif 1591d519d484949161df6d4b2ecadc282427cab532cfMike Reed } else { 15925f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev this->checkForDeferredSave(); 1593c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 1594d519d484949161df6d4b2ecadc282427cab532cfMike Reed FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect)); 1595c42a1cdd1de7a3cf57a9a5fd7363f5fb660e97d0Mike Reed#endif 15965f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev AutoValidateClip avc(this); 15975f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fClipStack->clipDevRect(fClipRestrictionRect, kIntersect_SkClipOp); 15985f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fMCRec->fRasterClip.op(fClipRestrictionRect, SkRegion::kIntersect_Op); 15995f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fDeviceCMDirty = true; 16005f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16015f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev } 16025f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev} 16035f1bb0a7c5186e797aa0f0d447a68fc3fbf3c2feStan Iliev 1604c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) { 16052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 16074ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 16088f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 16098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 16108f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 16114ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 16128f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 161314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1614c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) { 1615a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon AutoValidateClip avc(this); 161614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1617a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fDeviceCMDirty = true; 161814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1619a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 16207627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 16217627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 16227627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA)); 16237627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#endif 16247627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 1625a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA); 1626a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1627a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1628a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1629a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon return; 16304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 16314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1632c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) { 16332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16348f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 163539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 163639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 163739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 163839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 163939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 164039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 164139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 164239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 164339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 164439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 164539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 164639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 164739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 164839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 164939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 165039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 165139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 16528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 165339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 165439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 16558f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1657c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) { 16585c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16595c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1661a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 16627627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 16637627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 16647627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA)); 16657627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#endif 16667627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 1667a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA); 16685c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1669a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkPath* rasterClipPath = &path; 1670a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkMatrix* matrix = &fMCRec->fMatrix; 1671a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon SkPath tempPath; 167245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 1673a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA = getClipStack()->asPath(&tempPath); 1674a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon rasterClipPath = &tempPath; 1675a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon matrix = &SkMatrix::I(); 1676c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reed op = kReplace_SkClipOp; 167745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 1678a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1679a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1680fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1683c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) { 16842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16858f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 16868f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 1688c1f7774e8d327e3c98b4094c9c01d26e27013f71Mike Reedvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) { 16897627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#ifdef SK_USE_DEVICE_CLIPPING 16907627fa51044e35dc21251f925b56f6dd6887df97Mike Reed FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op)); 16917627fa51044e35dc21251f925b56f6dd6887df97Mike Reed#endif 16927627fa51044e35dc21251f925b56f6dd6887df97Mike Reed 16935c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16945c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 16968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16975c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 16985c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1699687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 17005c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 170173603f3c52ffd89fe9d035be827b566a0e7d3b79reed fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op); 1702fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 17038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1705819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1706819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1707819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 17081f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1709ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 17105c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1711ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1712ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1713ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1714819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1715819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1716d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1717819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1718687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17198182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 172096fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 17218182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 17228182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 17238182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 172473603f3c52ffd89fe9d035be827b566a0e7d3b79reed tmpClip.op(ir, (SkRegion::Op)element->getOp()); 17258182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17268182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 17278182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 17288182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17299cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 17309cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 17319cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 1732a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon tmpClip.op(path, SkMatrix::I(), this->getTopLayerBounds(), 1733a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon (SkRegion::Op)element->getOp(), element->isAA()); 17349cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 17359cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1736819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1737819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1738819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1739819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1740819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 174190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1742687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 17448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 174596fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 1746c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 174790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 174890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 174990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 17505c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 17515c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1752754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 17531f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1754754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1755754de5f65b466f721d952a379194cc94de376f42reed@google.com 17565c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 17571f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 17585c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17595c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1760fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) { 1761fbfa25802709139c2f14e304319c9541da65ca27msarett#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 1762fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 lLtT = _mm_unpacklo_ps(devRect.fVec, devClip.fVec); 1763fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 RrBb = _mm_unpackhi_ps(devClip.fVec, devRect.fVec); 1764fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 mask = _mm_cmplt_ps(lLtT, RrBb); 1765fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xF != _mm_movemask_ps(mask); 1766fbfa25802709139c2f14e304319c9541da65ca27msarett#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON) 1767fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t lLtT = vzipq_f32(devRect.fVec, devClip.fVec).val[0]; 1768fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t RrBb = vzipq_f32(devClip.fVec, devRect.fVec).val[1]; 1769fbfa25802709139c2f14e304319c9541da65ca27msarett uint32x4_t mask = vcltq_f32(lLtT, RrBb); 1770fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xFFFFFFFFFFFFFFFF != (uint64_t) vmovn_u32(mask); 1771fbfa25802709139c2f14e304319c9541da65ca27msarett#else 1772fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devRectAsRect; 1773fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devClipAsRect; 1774fbfa25802709139c2f14e304319c9541da65ca27msarett devRect.store(&devRectAsRect.fLeft); 1775fbfa25802709139c2f14e304319c9541da65ca27msarett devClip.store(&devClipAsRect.fLeft); 1776fbfa25802709139c2f14e304319c9541da65ca27msarett return !devRectAsRect.isFinite() || !devRectAsRect.intersect(devClipAsRect); 1777fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1778fbfa25802709139c2f14e304319c9541da65ca27msarett} 1779fbfa25802709139c2f14e304319c9541da65ca27msarett 1780fbfa25802709139c2f14e304319c9541da65ca27msarett// It's important for this function to not be inlined. Otherwise the compiler will share code 1781fbfa25802709139c2f14e304319c9541da65ca27msarett// between the fast path and the slow path, resulting in two slow paths. 1782fbfa25802709139c2f14e304319c9541da65ca27msarettstatic SK_NEVER_INLINE bool quick_reject_slow_path(const SkRect& src, const SkRect& deviceClip, 1783fbfa25802709139c2f14e304319c9541da65ca27msarett const SkMatrix& matrix) { 1784fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect deviceRect; 1785fbfa25802709139c2f14e304319c9541da65ca27msarett matrix.mapRect(&deviceRect, src); 1786fbfa25802709139c2f14e304319c9541da65ca27msarett return !deviceRect.isFinite() || !deviceRect.intersect(deviceClip); 1787fbfa25802709139c2f14e304319c9541da65ca27msarett} 1788d22a817ff57986407facd16af36320fc86ce02damsarett 1789fbfa25802709139c2f14e304319c9541da65ca27msarettbool SkCanvas::quickReject(const SkRect& src) const { 1790fbfa25802709139c2f14e304319c9541da65ca27msarett#ifdef SK_DEBUG 1791fbfa25802709139c2f14e304319c9541da65ca27msarett // Verify that fDeviceClipBounds are set properly. 1792fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect tmp = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 17931f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 17940c685ee188a5e500df25a34fa6edfceb4cbb795cmsarett SkASSERT(fDeviceClipBounds.isEmpty()); 1795fbfa25802709139c2f14e304319c9541da65ca27msarett } else { 1796fbfa25802709139c2f14e304319c9541da65ca27msarett SkASSERT(tmp == fDeviceClipBounds); 17978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17999637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett // Verify that fIsScaleTranslate is set properly. 18009637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1801fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1802d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 18039637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett if (!fIsScaleTranslate) { 1804fbfa25802709139c2f14e304319c9541da65ca27msarett return quick_reject_slow_path(src, fDeviceClipBounds, fMCRec->fMatrix); 18058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1806fbfa25802709139c2f14e304319c9541da65ca27msarett 1807fbfa25802709139c2f14e304319c9541da65ca27msarett // We inline the implementation of mapScaleTranslate() for the fast path. 1808fbfa25802709139c2f14e304319c9541da65ca27msarett float sx = fMCRec->fMatrix.getScaleX(); 1809fbfa25802709139c2f14e304319c9541da65ca27msarett float sy = fMCRec->fMatrix.getScaleY(); 1810fbfa25802709139c2f14e304319c9541da65ca27msarett float tx = fMCRec->fMatrix.getTranslateX(); 1811fbfa25802709139c2f14e304319c9541da65ca27msarett float ty = fMCRec->fMatrix.getTranslateY(); 1812fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f scale(sx, sy, sx, sy); 1813fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f trans(tx, ty, tx, ty); 1814fbfa25802709139c2f14e304319c9541da65ca27msarett 1815fbfa25802709139c2f14e304319c9541da65ca27msarett // Apply matrix. 1816fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans; 1817fbfa25802709139c2f14e304319c9541da65ca27msarett 1818fbfa25802709139c2f14e304319c9541da65ca27msarett // Make sure left < right, top < bottom. 1819fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]); 1820fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f min = Sk4f::Min(ltrb, rblt); 1821fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f max = Sk4f::Max(ltrb, rblt); 1822fbfa25802709139c2f14e304319c9541da65ca27msarett // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on 1823fbfa25802709139c2f14e304319c9541da65ca27msarett // ARM this sequence generates the fastest (a single instruction). 1824fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f devRect = Sk4f(min[2], min[3], max[0], max[1]); 1825fbfa25802709139c2f14e304319c9541da65ca27msarett 1826fbfa25802709139c2f14e304319c9541da65ca27msarett // Check if the device rect is NaN or outside the clip. 1827fbfa25802709139c2f14e304319c9541da65ca27msarett return is_nan_or_clipped(devRect, Sk4f::Load(&fDeviceClipBounds.fLeft)); 18288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18303b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 18313b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 183442e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkRect SkCanvas::onGetLocalClipBounds() const { 183542e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkIRect ibounds = this->onGetDeviceClipBounds(); 1836918e144408ba218df919528f8b48c544f4767883Mike Reed if (ibounds.isEmpty()) { 183742e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1840d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1841d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 18421f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 184342e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkRect::MakeEmpty(); 1844d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1845d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 184642e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect bounds; 184742e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed SkRect r; 184842e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed // adjust it outwards in case we are antialiasing 184942e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed const int inset = 1; 1850fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 185142e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 185242e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed ibounds.fRight + inset, ibounds.fBottom + inset); 185342e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed inverse.mapRect(&bounds, r); 185442e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return bounds; 18558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 185742e8c53b3ef58f887a623b410d9783b4d4ab4921Mike ReedSkIRect SkCanvas::onGetDeviceClipBounds() const { 18581f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1859bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 186042e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return SkIRect::MakeEmpty(); 1861bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 186242e8c53b3ef58f887a623b410d9783b4d4ab4921Mike Reed return clip.getBounds(); 1863bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1864bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 18658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 18661f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 18678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18693726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reedvoid SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) { 18703726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed // we know that ganesh doesn't track the rgn, so ask for its clipstack 18713726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed if (this->getGrContext()) { 18724eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev const SkClipStack* cs = this->getClipStack(); 18734eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev SkClipStack::BoundsType boundType; 18744eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev bool isIntersectionOfRects; 18754eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev SkRect bounds; 18764eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev cs->getBounds(&bounds, &boundType, &isIntersectionOfRects); 18774eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) { 18784eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev rgn->setRect(bounds.round()); 18794eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev return; 18804eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev } 18813726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed SkPath path; 18824eabd5d88aec712f5d0643a2f814aea7403d2119Stan Iliev cs->asPath(&path); 18833726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed SkISize size = this->getBaseLayerSize(); 18843726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed rgn->setPath(path, SkRegion(SkIRect::MakeWH(size.width(), size.height()))); 18853726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed } else { 18863726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed *rgn = fMCRec->fRasterClip.forceGetBW(); 18873726a4ac68821deea7ef4d5472a42f7d35ec4b4eMike Reed } 18885c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18895c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18901105224f9701e57ec5ce0354d6a380b664f5c638Brian OsmanGrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() { 18919c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 18921105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman return dev ? dev->accessRenderTargetContext() : nullptr; 18939c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18949c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1895644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1896644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 189786ae3d161412961c27a406465b0ec5749cc2e753reed return device ? device->context() : nullptr; 1898644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1899e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1900ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1901ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 19029881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1903ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1904ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1905ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1906ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1907ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1908ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1909ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1910ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1911ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1912ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1913ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1914ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1915ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1916ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1917ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1918ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1919ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1920ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 192141af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 192241af966ab338e95eee81ab618ab28195075338f7reed 192341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 192441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 192541af966ab338e95eee81ab618ab28195075338f7reed} 192641af966ab338e95eee81ab618ab28195075338f7reed 192741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 192841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 192941af966ab338e95eee81ab618ab28195075338f7reed} 193041af966ab338e95eee81ab618ab28195075338f7reed 1931dca352e2d42cfe698573947b3d11abc1eaade160msarettvoid SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { 1932dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isEmpty()) { 1933dca352e2d42cfe698573947b3d11abc1eaade160msarett return; 1934dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1935dca352e2d42cfe698573947b3d11abc1eaade160msarett 1936dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isRect()) { 1937dca352e2d42cfe698573947b3d11abc1eaade160msarett return this->drawIRect(region.getBounds(), paint); 1938dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1939dca352e2d42cfe698573947b3d11abc1eaade160msarett 1940dca352e2d42cfe698573947b3d11abc1eaade160msarett this->onDrawRegion(region, paint); 1941dca352e2d42cfe698573947b3d11abc1eaade160msarett} 1942dca352e2d42cfe698573947b3d11abc1eaade160msarett 194341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 194441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 194541af966ab338e95eee81ab618ab28195075338f7reed} 194641af966ab338e95eee81ab618ab28195075338f7reed 194741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 194841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 194941af966ab338e95eee81ab618ab28195075338f7reed} 195041af966ab338e95eee81ab618ab28195075338f7reed 195141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 195241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 195341af966ab338e95eee81ab618ab28195075338f7reed} 195441af966ab338e95eee81ab618ab28195075338f7reed 195541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 19567d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPoint texs[], const SkColor colors[], SkBlendMode bmode, 195741af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 1958199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon this->onDrawVertices(vmode, vertexCount, std::move(vertices), texs, colors, bmode, indices, 1959199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon indexCount, paint); 1960199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon} 1961199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 1962199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomonvoid SkCanvas::drawVertices(sk_sp<SkVertices> vertices, SkBlendMode mode, const SkPaint& paint, 1963199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon uint32_t flags) { 1964199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon RETURN_ON_NULL(vertices); 1965199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon this->onDrawVerticesObject(std::move(vertices), mode, paint, flags); 196641af966ab338e95eee81ab618ab28195075338f7reed} 196741af966ab338e95eee81ab618ab28195075338f7reed 196841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 196941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 197041af966ab338e95eee81ab618ab28195075338f7reed} 197141af966ab338e95eee81ab618ab28195075338f7reed 1972a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1973e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1974a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 197541af966ab338e95eee81ab618ab28195075338f7reed} 197641af966ab338e95eee81ab618ab28195075338f7reed 1977e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1978e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1979e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1980e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1981e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1982e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1983e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1984e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 198541af966ab338e95eee81ab618ab28195075338f7reed 198684984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 198784984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1988e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1989e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 199084984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 199184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1992e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1993e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1994e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1995e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1996e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1997e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1998e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19994c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 20004c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 2001e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 20024c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 20034c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 20044c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 2005552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(image->width(), image->height(), center)) { 2006552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawImageNine(image, center, dst, paint); 2007552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 2008e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 20094c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 20104c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 20114c21dc5ddf3b482293ed34eead876d8d61a662c3reed 2012168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2013168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2014168820625c35a8c19f66c661efcbce7a5e334837msarett RETURN_ON_NULL(image); 2015168820625c35a8c19f66c661efcbce7a5e334837msarett if (dst.isEmpty()) { 2016168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2017168820625c35a8c19f66c661efcbce7a5e334837msarett } 201871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 201971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 202071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 202171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 202271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(image->width(), image->height()); 202371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 202471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 202571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 202671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) { 202771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawImageLattice(image, latticePlusBounds, dst, paint); 2028168820625c35a8c19f66c661efcbce7a5e334837msarett } else { 2029168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawImageRect(image, dst, paint); 2030168820625c35a8c19f66c661efcbce7a5e334837msarett } 2031168820625c35a8c19f66c661efcbce7a5e334837msarett} 2032168820625c35a8c19f66c661efcbce7a5e334837msarett 203341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 20344c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 20352df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 20362df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 203741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 203841af966ab338e95eee81ab618ab28195075338f7reed} 203941af966ab338e95eee81ab618ab28195075338f7reed 2040e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 2041a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 2042e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 2043a5517e2b190a8083b38964972b031c13e99f1012reed return; 2044a5517e2b190a8083b38964972b031c13e99f1012reed } 2045e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 204641af966ab338e95eee81ab618ab28195075338f7reed} 204741af966ab338e95eee81ab618ab28195075338f7reed 204884984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 204984984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 2050e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 2051e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2052e47829b6b1eeb6b0c97ccb3df3016d197046824creed 2053e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 2054e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 2055e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 2056e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 205784984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 205884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 205941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 206041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 20614c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 20622df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 20632df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 2064552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) { 2065552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawBitmapNine(bitmap, center, dst, paint); 2066552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 2067a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 20684c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 206941af966ab338e95eee81ab618ab28195075338f7reed} 207041af966ab338e95eee81ab618ab28195075338f7reed 2071c573a40ed5024b463e47088d307e3164a486dba5msarettvoid SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, 2072c573a40ed5024b463e47088d307e3164a486dba5msarett const SkPaint* paint) { 2073168820625c35a8c19f66c661efcbce7a5e334837msarett if (bitmap.drawsNothing() || dst.isEmpty()) { 2074c573a40ed5024b463e47088d307e3164a486dba5msarett return; 2075c573a40ed5024b463e47088d307e3164a486dba5msarett } 207671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 207771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 207871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 207971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 208071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 208171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 208271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 208371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 208471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) { 208571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, paint); 2086552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 2087168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawBitmapRect(bitmap, dst, paint); 2088c573a40ed5024b463e47088d307e3164a486dba5msarett } 2089c573a40ed5024b463e47088d307e3164a486dba5msarett} 2090c573a40ed5024b463e47088d307e3164a486dba5msarett 209171c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 20927d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkColor colors[], int count, SkBlendMode mode, 209371c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 2094e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 209571c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 209671c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 209771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 2098c485907f0420e5f9cf8223e9ba53812cd8dd5368Joe Gregorio SkASSERT(atlas); 209971c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 2100faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 210171c3c760a83123ee0b3127b8c65c6394ce541c50reed} 210271c3c760a83123ee0b3127b8c65c6394ce541c50reed 2103f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2104f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 2105f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 2106f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2107f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2108f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2109e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2110e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2111e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2112e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 2113e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2114e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 2115e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2116e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2117e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2118e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2119e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2120e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2121e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 2122e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2123e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 2124e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2125e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2126e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2127e47829b6b1eeb6b0c97ccb3df3016d197046824creed 2128cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudsonvoid SkCanvas::temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds) { 2129cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson SkIRect layer_bounds = this->getTopLayerBounds(); 2130cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (matrix) { 2131cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson *matrix = this->getTotalMatrix(); 2132cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson matrix->preTranslate(-layer_bounds.left(), -layer_bounds.top()); 2133cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2134cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (clip_bounds) { 2135918e144408ba218df919528f8b48c544f4767883Mike Reed *clip_bounds = this->getDeviceClipBounds(); 2136cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson clip_bounds->offset(-layer_bounds.left(), -layer_bounds.top()); 2137cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2138cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson} 2139cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson 21408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 21418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 21428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 21438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 214428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 214549f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 214628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 214728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 214828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 214928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 215041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 21519881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 2152fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2153fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 2154fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 2155fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 215696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 21578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21594e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 21608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21624e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 216541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 216641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 21679881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 21688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 21698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 21708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 217278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 217396fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2174a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2175a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2176a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2177a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2178a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2179a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2180a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 218187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 218287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 218387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 218487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 2185fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2186a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 218796fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 21888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 218978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 21904b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21924e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 21938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21944b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21984a16717bc7aa471fad10ec3157774771a76e5106reedstatic bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) { 21994a16717bc7aa471fad10ec3157774771a76e5106reed return ((intptr_t)paint.getImageFilter() | 22004a16717bc7aa471fad10ec3157774771a76e5106reed#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 22014a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)canvas->getDrawFilter() | 22024a16717bc7aa471fad10ec3157774771a76e5106reed#endif 22034a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)paint.getLooper() ) != 0; 22044a16717bc7aa471fad10ec3157774771a76e5106reed} 22054a16717bc7aa471fad10ec3157774771a76e5106reed 220641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 22079881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 220878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 220996fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 22108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 22118432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 22128432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 22138432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 22148432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 22158432808ad8898ac7137bc7ce1d9df6005e866401reed 221687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 221787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 221887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 221987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 22208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22214b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22224a16717bc7aa471fad10ec3157774771a76e5106reed if (needs_autodrawlooper(this, paint)) { 22234a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 22248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22254a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 22264a16717bc7aa471fad10ec3157774771a76e5106reed iter.fDevice->drawRect(iter, r, looper.paint()); 22274a16717bc7aa471fad10ec3157774771a76e5106reed } 22288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22294a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_END 22304a16717bc7aa471fad10ec3157774771a76e5106reed } else { 22314a16717bc7aa471fad10ec3157774771a76e5106reed this->predrawNotify(bounds, &paint, false); 22324a16717bc7aa471fad10ec3157774771a76e5106reed SkDrawIter iter(this); 22334a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 22344a16717bc7aa471fad10ec3157774771a76e5106reed iter.fDevice->drawRect(iter, r, paint); 22354a16717bc7aa471fad10ec3157774771a76e5106reed } 22364a16717bc7aa471fad10ec3157774771a76e5106reed } 22378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 223944df651ebefc284acc2f66425dff3ea0b0e14b36msarettvoid SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 224044df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect storage; 224144df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect regionRect = SkRect::Make(region.getBounds()); 224244df651ebefc284acc2f66425dff3ea0b0e14b36msarett const SkRect* bounds = nullptr; 224344df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (paint.canComputeFastBounds()) { 224444df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (this->quickReject(paint.computeFastBounds(regionRect, &storage))) { 224544df651ebefc284acc2f66425dff3ea0b0e14b36msarett return; 224644df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 224744df651ebefc284acc2f66425dff3ea0b0e14b36msarett bounds = ®ionRect; 224844df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 224944df651ebefc284acc2f66425dff3ea0b0e14b36msarett 225044df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 225144df651ebefc284acc2f66425dff3ea0b0e14b36msarett 225244df651ebefc284acc2f66425dff3ea0b0e14b36msarett while (iter.next()) { 225344df651ebefc284acc2f66425dff3ea0b0e14b36msarett iter.fDevice->drawRegion(iter, region, looper.paint()); 225444df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 225544df651ebefc284acc2f66425dff3ea0b0e14b36msarett 225644df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_END 225744df651ebefc284acc2f66425dff3ea0b0e14b36msarett} 225844df651ebefc284acc2f66425dff3ea0b0e14b36msarett 225941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 22609881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 226178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 226296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 22634ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 226487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 226587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 226687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 226787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &oval; 22684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2269306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 227078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 227146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 227246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 227346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 227446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 227546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 227646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 22774ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 22784ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2279ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomonvoid SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, 2280ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkScalar sweepAngle, bool useCenter, 2281ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkPaint& paint) { 2282ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 2283ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkRect* bounds = nullptr; 2284ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (paint.canComputeFastBounds()) { 2285ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkRect storage; 2286ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon // Note we're using the entire oval as the bounds. 2287ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 2288ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon return; 2289ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2290ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon bounds = &oval; 2291ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2292ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2293ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 2294ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2295ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon while (iter.next()) { 2296ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint()); 2297ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2298ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2299ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_END 2300ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon} 2301ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 230241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 23039881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 230478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 230596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 23064ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 230787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 230887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 230987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 231087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &rrect.getBounds(); 23114ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 23124ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 23134ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 23144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 23154ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2316f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2317f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 23184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2319f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2320f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 23214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2322f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 232378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2324f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2325f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2326f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2327f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2328f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2329f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 23304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 23314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2332ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2333ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2334ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 233596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2336ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 233787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 233887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 233987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 234087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &outer.getBounds(); 2341ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 234225c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2343ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 234425c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2345ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2346ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2347ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 234825c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2349ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2350ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 23514ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 235241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 23539881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 23549364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 23559364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 23569364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 23579364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 235878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 235996fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2360fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 236178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 236287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 236387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 236487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 236587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &pathBounds; 23668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23670b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 23680b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 23690b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 23706803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2371fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 23726651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2373fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2374fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 23758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 237678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 23778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 23808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2385262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2386262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2387262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2388262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2389262a71b7f95ce98ff3dd8dba845afbd724470903reed 2390262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2391c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2392262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2393262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2394262a71b7f95ce98ff3dd8dba845afbd724470903reed 2395262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2396262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2397262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2398262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2399262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2400262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2401262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2402262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2403262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2404262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2405262a71b7f95ce98ff3dd8dba845afbd724470903reed 2406a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 24079881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2408a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2409a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 241096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 241187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 241287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 241387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 241487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 241587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 241687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 241787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2418a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 24199d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2420a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 242196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2422a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2423a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2424262a71b7f95ce98ff3dd8dba845afbd724470903reed 2425a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2426129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2427129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2428129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2429a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(image); 2430a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2431129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2432129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2433129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2434129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2435262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2436262a71b7f95ce98ff3dd8dba845afbd724470903reed 2437a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2438262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2439a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2440a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkPoint pt; 2441a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fMatrix->mapXY(x, y, &pt); 2442a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fDevice->drawSpecial(iter, special.get(), 2443a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2444a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2445262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2446262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawImage(iter, image, x, y, pnt); 2447262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2448a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 24499d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2450a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2451b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2452b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 245341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2454562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 24559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 245696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2457c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 245887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 245987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 246087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 246187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 246287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 246387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2464a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2465a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 246696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2467a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2468a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 24699d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2470c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2471c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 24729d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2473a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2474a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2475a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 24769d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2477a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2478b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2479b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 248041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 24819881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 24828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 24838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248433366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 248533366974d43eae80e22284a2e445225c343859dareed return; 248633366974d43eae80e22284a2e445225c343859dareed } 248733366974d43eae80e22284a2e445225c343859dareed 248833366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 248933366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 249033366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 249133366974d43eae80e22284a2e445225c343859dareed } 249233366974d43eae80e22284a2e445225c343859dareed 249333366974d43eae80e22284a2e445225c343859dareed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 249433366974d43eae80e22284a2e445225c343859dareed 249533366974d43eae80e22284a2e445225c343859dareed SkRect storage; 249633366974d43eae80e22284a2e445225c343859dareed const SkRect* bounds = nullptr; 249733366974d43eae80e22284a2e445225c343859dareed if (paint->canComputeFastBounds()) { 249833366974d43eae80e22284a2e445225c343859dareed bitmap.getBounds(&storage); 249933366974d43eae80e22284a2e445225c343859dareed matrix.mapRect(&storage); 250087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = storage; 250187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 250287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 250387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 250487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 25058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25064b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2507a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2508129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), bitmap.height(), 2509129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2510129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2511a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(bitmap); 2512a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2513129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2514129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2515129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2516129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2517262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds) 251833366974d43eae80e22284a2e445225c343859dareed 251933366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2520262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2521a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2522262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2523262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 2524a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fDevice->drawSpecial(iter, special.get(), 2525a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2526a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2527262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2528262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 2529262a71b7f95ce98ff3dd8dba845afbd724470903reed } 253033366974d43eae80e22284a2e445225c343859dareed } 2531fbfa25802709139c2f14e304319c9541da65ca27msarett 253233366974d43eae80e22284a2e445225c343859dareed LOOPER_END 25338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25359987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 25367112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2537eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2538a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 253950b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 25408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 25418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 254274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 254396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2544c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 254587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 254687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 254787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 25488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25493d60812865bb034851da777a91413ab584929887reed@google.com 255033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 255196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 255233535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 25538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25547064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2555c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2556c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 25577064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 255833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2559562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2560f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 25617064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 256233535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 25638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 256541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2566562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 25679881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 25689987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2569562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 25709987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 25719987ec3791336bad6af5cbe513564786b2df55aareed@google.com 25724c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 25734c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 25744c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 25759d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 257696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2577c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 257887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 257987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 258087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 25813d60812865bb034851da777a91413ab584929887reed@google.com } 25829d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 25834c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 258496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 25854c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 25864c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 25879d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2588c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 25899d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 25904c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 25914c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 25929987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 25939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 25944c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 25959987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 25969987ec3791336bad6af5cbe513564786b2df55aareed@google.com 259741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 259841af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 25999881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 26009987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 26019987ec3791336bad6af5cbe513564786b2df55aareed@google.com 260296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2603c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 260487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 260587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 260687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 26074c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 26089d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26094c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 261096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 26114c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 26124c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 26139d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2614c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 26159d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26164c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 26174c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 26184c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 26199d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26204c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 26219987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 26229987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2623168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2624168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2625168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2626168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2627168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2628168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2629168820625c35a8c19f66c661efcbce7a5e334837msarett } 2630168820625c35a8c19f66c661efcbce7a5e334837msarett } 2631168820625c35a8c19f66c661efcbce7a5e334837msarett 2632168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2633168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2634168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2635168820625c35a8c19f66c661efcbce7a5e334837msarett } 2636168820625c35a8c19f66c661efcbce7a5e334837msarett 2637168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2638168820625c35a8c19f66c661efcbce7a5e334837msarett 2639168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2640168820625c35a8c19f66c661efcbce7a5e334837msarett iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint()); 2641168820625c35a8c19f66c661efcbce7a5e334837msarett } 2642168820625c35a8c19f66c661efcbce7a5e334837msarett 2643168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2644168820625c35a8c19f66c661efcbce7a5e334837msarett} 2645168820625c35a8c19f66c661efcbce7a5e334837msarett 2646168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, 2647168820625c35a8c19f66c661efcbce7a5e334837msarett const SkRect& dst, const SkPaint* paint) { 2648168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2649168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2650168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2651168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2652168820625c35a8c19f66c661efcbce7a5e334837msarett } 2653168820625c35a8c19f66c661efcbce7a5e334837msarett } 2654168820625c35a8c19f66c661efcbce7a5e334837msarett 2655168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2656168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2657168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2658168820625c35a8c19f66c661efcbce7a5e334837msarett } 2659168820625c35a8c19f66c661efcbce7a5e334837msarett 2660168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2661168820625c35a8c19f66c661efcbce7a5e334837msarett 2662168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2663168820625c35a8c19f66c661efcbce7a5e334837msarett iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint()); 2664168820625c35a8c19f66c661efcbce7a5e334837msarett } 2665168820625c35a8c19f66c661efcbce7a5e334837msarett 2666168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2667168820625c35a8c19f66c661efcbce7a5e334837msarett} 2668168820625c35a8c19f66c661efcbce7a5e334837msarett 2669f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2670f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 26711f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2672112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2673112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2674a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2675112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2676f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2677f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2678f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2679f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2680f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2681f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2682f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2683f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2684f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 26852c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 26862c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2687f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2688f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2689e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2690e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 269196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 26928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26944e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2695f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 26968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2701e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2702e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 270305c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 270405c4a4322e7d4f3417b7df33825bab8603d52051fmalita 270596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 270687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 27078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 27084e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 270905c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2710f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 27118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2712b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 27134e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 27148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2716e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2717e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 271805c4a4322e7d4f3417b7df33825bab8603d52051fmalita 271905c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 272005c4a4322e7d4f3417b7df33825bab8603d52051fmalita 272196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 272287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 27238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 27244e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 272505c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2726f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 27278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2728b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 27294e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 27308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2732e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2733e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 273496fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 273587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 27368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 27378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 27384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 27398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2740b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2741945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 27424325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 27434325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 274445561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 274545561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 274645561a0b15fe045ba272c328684c3f7ae290785areed if (cullRect && this->quickReject(*cullRect)) { 274745561a0b15fe045ba272c328684c3f7ae290785areed return; 274845561a0b15fe045ba272c328684c3f7ae290785areed } 274945561a0b15fe045ba272c328684c3f7ae290785areed 275045561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 275145561a0b15fe045ba272c328684c3f7ae290785areed 275245561a0b15fe045ba272c328684c3f7ae290785areed while (iter.next()) { 275345561a0b15fe045ba272c328684c3f7ae290785areed iter.fDevice->drawTextRSXform(iter, text, byteLength, xform, looper.paint()); 275445561a0b15fe045ba272c328684c3f7ae290785areed } 275545561a0b15fe045ba272c328684c3f7ae290785areed 275645561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_END 275745561a0b15fe045ba272c328684c3f7ae290785areed} 275845561a0b15fe045ba272c328684c3f7ae290785areed 275900d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 276000d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 27617ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 276285d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 276396fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 276419653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 276585d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 276687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 276787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 276887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 276987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 277087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 27717ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 27727ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2773024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2774024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2775024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 277696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2777024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 277885d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 277900d5c2c6523321d25b32905ff4822f083a4173eefmalita 2780aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2781aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2782024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 278300d5c2c6523321d25b32905ff4822f083a4173eefmalita } 278400d5c2c6523321d25b32905ff4822f083a4173eefmalita 2785aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2786024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2787024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 278800d5c2c6523321d25b32905ff4822f083a4173eefmalita} 278900d5c2c6523321d25b32905ff4822f083a4173eefmalita 2790e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2791e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2792e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 27939881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2794ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2795ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawText(text, byteLength, x, y, paint); 2796ac09554dce518e9d4496771f648f3ae17eca857creed } 2797e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2798e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2799e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 28009881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2801ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2802ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosText(text, byteLength, pos, paint); 2803ac09554dce518e9d4496771f648f3ae17eca857creed } 2804e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2805e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2806e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 28079881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2808ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2809ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2810ac09554dce518e9d4496771f648f3ae17eca857creed } 2811e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2812e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2813e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 28149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2815ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2816ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2817ac09554dce518e9d4496771f648f3ae17eca857creed } 2818e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 281945561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 282045561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 282145561a0b15fe045ba272c328684c3f7ae290785areed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextRSXform()"); 282245561a0b15fe045ba272c328684c3f7ae290785areed if (byteLength) { 282345561a0b15fe045ba272c328684c3f7ae290785areed this->onDrawTextRSXform(text, byteLength, xform, cullRect, paint); 282445561a0b15fe045ba272c328684c3f7ae290785areed } 282545561a0b15fe045ba272c328684c3f7ae290785areed} 282600d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 282700d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2828e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 28299881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2830e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 283100d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2832e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 283341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 283441af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 2835faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkColor colors[], SkBlendMode bmode, 283641af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 283741af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 28389881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 283996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 28404b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 2843faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed colors, bmode, indices, indexCount, 28444e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 28458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28474e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2850199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomonvoid SkCanvas::onDrawVerticesObject(sk_sp<SkVertices> vertices, SkBlendMode bmode, 2851199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon const SkPaint& paint, uint32_t flags) { 2852199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 2853199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 2854199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2855199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon while (iter.next()) { 2856199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon // In the common case of one iteration we could std::move vertices here. 2857199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon iter.fDevice->drawVerticesObject(iter, vertices, bmode, looper.paint(), flags); 2858199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon } 2859199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2860199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon LOOPER_END 2861199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon} 2862199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2863199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomonvoid SkCanvas::onDrawVerticesObjectFallback(sk_sp<SkVertices> vertices, SkBlendMode mode, 2864199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon const SkPaint& paint, uint32_t flags) { 2865199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon const SkPoint* texs = 2866199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon (flags & SkCanvas::kIgnoreTexCoords_VerticesFlag) ? nullptr : vertices->texCoords(); 2867199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon const SkColor* colors = (flags & kIgnoreColors_VerticesFlag) ? nullptr : vertices->colors(); 2868199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon this->onDrawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(), texs, 2869199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon colors, mode, vertices->indices(), vertices->indexCount(), paint); 2870199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon} 2871199fb875c5e63c13233209e89b943c7ac7ab6665Brian Salomon 2872b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 28737d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 28747d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 28759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 287696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2877b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2878b3c9d1c33caf325aada244204215eb790c228c12dandov } 28796cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2880faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawPatch(cubics, colors, texCoords, bmode, paint); 28819340c2685c0bb0e1e70008acaaf3d1448f074c38msarett} 28829340c2685c0bb0e1e70008acaaf3d1448f074c38msarett 28839340c2685c0bb0e1e70008acaaf3d1448f074c38msarettvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2884faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 28857d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 2886ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2887ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2888ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2889b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2890ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2891ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2892ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 28936cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 289496fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 28956cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2896ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2897faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed iter.fDevice->drawPatch(iter, cubics, colors, texCoords, bmode, paint); 2898ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 28996cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2900ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2901ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2902ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2903a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2904e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2905e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2906e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2907e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2908e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2909e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2910a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2911a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2912a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2913a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2914e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2915e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2916e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 29176a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2918e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 29196a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 29206a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2921a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 29222a62e853c27cfacafd5c15ac1077cc13140589bareed // drawable bounds are no longer reliable (e.g. android displaylist) 29232a62e853c27cfacafd5c15ac1077cc13140589bareed // so don't use them for quick-reject 2924a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 29256a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 29266a070dc06af4e9f305f9d08a69e34d18ade473cbreed 292771c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 2928faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkColor colors[], int count, SkBlendMode bmode, 292971c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 293071c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 293171c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 293271c3c760a83123ee0b3127b8c65c6394ce541c50reed } 293371c3c760a83123ee0b3127b8c65c6394ce541c50reed 293471c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 293571c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 293671c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 293771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 29389d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 293996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 294071c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 2941faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, bmode, pnt); 294271c3c760a83123ee0b3127b8c65c6394ce541c50reed } 294371c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 294471c3c760a83123ee0b3127b8c65c6394ce541c50reed} 294571c3c760a83123ee0b3127b8c65c6394ce541c50reed 2946f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2947f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 2948f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2949f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 2950f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 2951f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 2952f70b531daaf47db1ee95c70da9843f1dd1f418d3reed iter.fDevice->drawAnnotation(iter, rect, key, value); 2953f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2954f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 2955f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2956f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 29578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 29588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 29598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 29608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 29618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29623661bc997620899695041010a750d11dbe8a972dMike Reed#ifdef SK_SUPPORT_LEGACY_CANVAS_HELPERS 2963374772bd61951f01bf84fe17bf53d8867681c9aereedvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode) { 29649881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 29658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 29668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2968374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(mode); 29698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 29708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29713661bc997620899695041010a750d11dbe8a972dMike Reed#endif 29728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2973374772bd61951f01bf84fe17bf53d8867681c9aereedvoid SkCanvas::drawColor(SkColor c, SkBlendMode mode) { 29749881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 29758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 29768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2978374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(mode); 29798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 29808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 29839881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 29843661bc997620899695041010a750d11dbe8a972dMike Reed const SkPoint pt = { x, y }; 29858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 29868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29883661bc997620899695041010a750d11dbe8a972dMike Reed#ifdef SK_SUPPORT_LEGACY_CANVAS_HELPERS 29898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 29909881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 29918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 29928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 29934b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 29958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 29968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 29978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29983661bc997620899695041010a750d11dbe8a972dMike Reed#endif 29998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30003661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint) { 30019881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 30028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 30034b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 30048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 30058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 30068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 30078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30093661bc997620899695041010a750d11dbe8a972dMike Reed#ifdef SK_SUPPORT_LEGACY_CANVAS_HELPERS 30108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 30118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 30128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 30139881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 30148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 30158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 30178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 30188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30193661bc997620899695041010a750d11dbe8a972dMike Reed#endif 30208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30213661bc997620899695041010a750d11dbe8a972dMike Reedvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint) { 30229881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 30238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 30248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 30258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 30288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 30294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 30308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 30338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 30349881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 30358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 30364ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 30374ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 30384ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 30398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 30408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 30418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 30458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 30468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 30479881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 304821af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon if (oval.isEmpty() || !sweepAngle) { 304921af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon return; 30508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 305121af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint); 30528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 30558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 30568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 30579881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 30588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 30594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 30608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 30618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 30628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3064f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 30651c2c441fede0ae9573afc098017011e3439624a9reed 30661c2c441fede0ae9573afc098017011e3439624a9reed/** 30671c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 30681c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 30691c2c441fede0ae9573afc098017011e3439624a9reed * 30701c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 30711c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 30721c2c441fede0ae9573afc098017011e3439624a9reed */ 30731c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 30749b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 3075d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 3076e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 3077e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 30781c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 3079e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 3080e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 3081e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 3082e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 3083e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3084e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 3085e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 3086e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 3087d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3088d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 30899b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 3090d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 3091d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 3092d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 3093d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 3094d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 3095d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 3096d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3097d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 3098d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 3099d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3100d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 3101d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 3102d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3103d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3104d028180f0310cf2b23f9744256a41697b0683e67fmalita 3105a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3106c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 31078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 310995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 311095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::drawShadowedPicture(const SkPicture* picture, 311195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 3112e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 3113e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 311495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack RETURN_ON_NULL(picture); 311595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 311695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); 311795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 3118e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack this->onDrawShadowedPicture(picture, matrix, paint, params); 311995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 312095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 312195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::onDrawShadowedPicture(const SkPicture* picture, 312295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 3123e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 3124e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 3125904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (!paint || paint->canComputeFastBounds()) { 3126904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkRect bounds = picture->cullRect(); 3127904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (paint) { 3128904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack paint->computeFastBounds(bounds, &bounds); 3129904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3130904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (matrix) { 3131904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack matrix->mapRect(&bounds); 3132904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3133904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (this->quickReject(bounds)) { 3134904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack return; 3135904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3136904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3137904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3138904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3139904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3140e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> povDepthMap; 3141e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> diffuseMap; 3142e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 3143904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // povDepthMap 3144904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 3145904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkLights::Builder builder; 3146772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), 3147772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack SkVector3::Make(0.0f, 0.0f, 1.0f))); 3148904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkLights> povLight = builder.finish(); 3149904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3150904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3151904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 3152904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 3153904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 3154904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3155904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Create a new surface (that matches the backend of canvas) 3156904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // to create the povDepthMap 3157904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3158904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3159904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Wrap another SPFCanvas around the surface 3160904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3161904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3162904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3163904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // set the depth map canvas to have the light as the user's POV 3164904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->setLights(std::move(povLight)); 3165904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3166904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->drawPicture(picture); 3167904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack povDepthMap = surf->makeImageSnapshot(); 3168904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3169904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3170904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // diffuseMap 3171904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 3172904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3173904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 3174904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 3175904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 3176904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3177904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3178904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack surf->getCanvas()->drawPicture(picture); 3179904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3180904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap = surf->makeImageSnapshot(); 3181904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3182904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3183904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_TileMode, 3184904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 3185904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_TileMode, 3186904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 3187b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3188b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: pass the depth to the shader in vertices, or uniforms 3189b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // so we don't have to render depth and color separately 3190b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack for (int i = 0; i < fLights->numLights(); ++i) { 3191b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // skip over ambient lights; they don't cast shadows 3192b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // lights that have shadow maps do not need updating (because lights are immutable) 3193b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkImage> depthMap; 3194b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkISize shMapSize; 3195b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3196b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).getShadowMap() != nullptr) { 3197b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack continue; 3198b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3199b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3200b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).isRadial()) { 3201b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fHeight = 1; 3202b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fWidth = (int) picture->cullRect().width(); 3203b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3204b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(diffuseMap->width(), 1, 3205b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3206b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3207b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3208b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create new surface (that matches the backend of canvas) 3209b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 3210b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3211b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3212b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 3213b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkCanvas* depthMapCanvas = surf->getCanvas(); 3214b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3215b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 3216b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 3217b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 3218b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3219b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShader> shadowMapShader; 3220b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapShader = SkRadialShadowMapShader::Make( 3221b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack povDepthShader, curLight, 3222b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 3223b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 3224b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3225b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowMapPaint; 3226b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint.setShader(std::move(shadowMapShader)); 3227b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3228b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(curLight); 3229b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3230b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawRect(SkRect::MakeIWH(diffuseMap->width(), 3231b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack diffuseMap->height()), 3232b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint); 3233b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3234b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 3235b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3236b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else { 3237b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: compute the correct size of the depth map from the light properties 3238b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: maybe add a kDepth_8_SkColorType 3239b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: find actual max depth of picture 3240b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( 3241b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i), 255, 3242b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 3243b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 3244b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3245b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 3246b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3247b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3248b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3249b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create a new surface (that matches the backend of canvas) 3250b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 3251b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3252b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3253b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 3254b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3255b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3256b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setShadowParams(params); 3257b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3258b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // set the depth map canvas to have the light we're drawing. 3259b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 3260b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 3261b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 3262b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(std::move(curLight)); 3263b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3264b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawPicture(picture); 3265b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 3266b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3267b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3268b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (params.fType == SkShadowParams::kNoBlur_ShadowType) { 3269b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(std::move(depthMap)); 3270b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else if (params.fType == SkShadowParams::kVariance_ShadowType) { 3271b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // we blur the variance map 3272b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint blurPaint; 3273b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurPaint.setImageFilter(SkImageFilter::MakeBlur(params.fShadowRadius, 3274b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack params.fShadowRadius, nullptr)); 3275b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3276b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 3277b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3278b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3279b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3280b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); 3281b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3282b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); 3283b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3284b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); 3285b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3286b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3287b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3288b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowPaint; 3289904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader), 3290904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack std::move(diffuseShader), 3291b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights, 3292904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap->width(), 3293e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack diffuseMap->height(), 3294e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack params); 3295904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3296904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack shadowPaint.setShader(shadowShader); 3297904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3298904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), shadowPaint); 329995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 330095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 330195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 33028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 33038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 33048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33053aafe111b6cc388400092851cc53bbbdfcb8a81creedSkCanvas::LayerIter::LayerIter(SkCanvas* canvas) { 330699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 33078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 33098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33103aafe111b6cc388400092851cc53bbbdfcb8a81creed fImpl = new (fStorage) SkDrawIter(canvas); 33118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 33128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 33138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 33158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 33168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 33178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 33198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 33208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 33218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33221f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 332399330ba6227137866a0dbd63478d36f335203ebdMike Reed return fImpl->fDevice; 33248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 33258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 33278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 33288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 33298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 33318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 333296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 33338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 33348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 33358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 33368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 33378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33381e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreedconst SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 33398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 33408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 334120a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 334220a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 334320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 3344c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 33453107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33463107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 33473107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33483107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 33493107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 33503107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 33513107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 33523107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 33533107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 33543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 33553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 33563107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33573107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 33583107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 33593107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 336028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 33619e3dbdff53f2d9957626a17a279730cda70f17bajunov case kRGBA_F16_SkColorType: 33623107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 33633107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 33643107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 33653107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 33663107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33673107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 33683107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 33693107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33705df4934b3e40cdc378e225d1dda39f015cae9baeMike Reedstd::unique_ptr<SkCanvas> SkCanvas::MakeRasterDirect(const SkImageInfo& info, void* pixels, 33715df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed size_t rowBytes) { 337242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 337396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 337442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3375eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 337642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 337742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 337896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 337942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 33805df4934b3e40cdc378e225d1dda39f015cae9baeMike Reed return skstd::make_unique<SkCanvas>(bitmap); 338142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 3382d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3383d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 3384d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3385d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 3386a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 3387d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 3388d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 3389d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 339049f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 3391a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 3392d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 3393a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 3394d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3395a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 339649f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 3397d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 3398d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 33996cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 340049f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 3401d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 3402d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3403d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3404d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3405d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3406d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 3407d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3408e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 3409ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 3410ee424acbb87bf999be132a437527e656e37541d7Florin Malita 3411ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkNoDrawCanvas::SkNoDrawCanvas(int width, int height) 3412ee424acbb87bf999be132a437527e656e37541d7Florin Malita : INHERITED(SkIRect::MakeWH(width, height), kConservativeRasterClip_InitFlag) {} 3413ee424acbb87bf999be132a437527e656e37541d7Florin Malita 3414439ace939b6aaa58408ece0e9e89b633353571aeFlorin MalitaSkNoDrawCanvas::SkNoDrawCanvas(const SkIRect& bounds) 3415439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita : INHERITED(bounds, kConservativeRasterClip_InitFlag) {} 3416439ace939b6aaa58408ece0e9e89b633353571aeFlorin Malita 3417ee424acbb87bf999be132a437527e656e37541d7Florin MalitaSkCanvas::SaveLayerStrategy SkNoDrawCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { 3418ee424acbb87bf999be132a437527e656e37541d7Florin Malita (void)this->INHERITED::getSaveLayerStrategy(rec); 3419ee424acbb87bf999be132a437527e656e37541d7Florin Malita return kNoLayer_SaveLayerStrategy; 3420ee424acbb87bf999be132a437527e656e37541d7Florin Malita} 3421ee424acbb87bf999be132a437527e656e37541d7Florin Malita 3422ee424acbb87bf999be132a437527e656e37541d7Florin Malita/////////////////////////////////////////////////////////////////////////////// 342373603f3c52ffd89fe9d035be827b566a0e7d3b79reed 342473603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kDifference_Op == (int)kDifference_SkClipOp, ""); 342573603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kIntersect_Op == (int)kIntersect_SkClipOp, ""); 342673603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kUnion_Op == (int)kUnion_SkClipOp, ""); 342773603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kXOR_Op == (int)kXOR_SkClipOp, ""); 342873603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReverseDifference_Op == (int)kReverseDifference_SkClipOp, ""); 342973603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReplace_Op == (int)kReplace_SkClipOp, ""); 3430356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3431356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 3432356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3433356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkCanvas::accessTopRasterHandle() const { 3434356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (fAllocator && fMCRec->fTopLayer->fDevice) { 3435356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkBaseDevice* dev = fMCRec->fTopLayer->fDevice; 3436356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Handle handle = dev->getRasterHandle(); 3437356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIPoint origin = dev->getOrigin(); 3438356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkMatrix ctm = this->getTotalMatrix(); 3439356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed ctm.preTranslate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y())); 3440356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3441356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkIRect clip = fMCRec->fRasterClip.getBounds(); 3442356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.offset(-origin.x(), -origin.y()); 3443108f55ed5d0b63baf653e4e443cc469df887c811Mike Reed if (!clip.intersect(0, 0, dev->width(), dev->height())) { 3444356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed clip.setEmpty(); 3445356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3446356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3447356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed fAllocator->updateHandle(handle, ctm, clip); 3448356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return handle; 3449356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3450356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 3451356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3452356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3453356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstatic bool install(SkBitmap* bm, const SkImageInfo& info, 3454356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkRasterHandleAllocator::Rec& rec) { 3455356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return bm->installPixels(info, rec.fPixels, rec.fRowBytes, nullptr, 3456356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed rec.fReleaseProc, rec.fReleaseCtx); 3457356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3458356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3459356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::Handle SkRasterHandleAllocator::allocBitmap(const SkImageInfo& info, 3460356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap* bm) { 3461356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkRasterHandleAllocator::Rec rec; 3462356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!this->allocHandle(info, &rec) || !install(bm, info, rec)) { 3463356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 3464356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3465356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return rec.fHandle; 3466356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3467356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3468356f7c2600ef54237fb8678cf63d5953f065b7daMike Reedstd::unique_ptr<SkCanvas> 3469356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedSkRasterHandleAllocator::MakeCanvas(std::unique_ptr<SkRasterHandleAllocator> alloc, 3470356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed const SkImageInfo& info, const Rec* rec) { 3471356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (!alloc || !supported_for_raster_canvas(info)) { 3472356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; 3473356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3474356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3475356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed SkBitmap bm; 3476356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed Handle hndl; 3477356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 3478356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed if (rec) { 3479356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = install(&bm, info, *rec) ? rec->fHandle : nullptr; 3480356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } else { 3481356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed hndl = alloc->allocBitmap(info, &bm); 3482356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 3483356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return hndl ? std::unique_ptr<SkCanvas>(new SkCanvas(bm, std::move(alloc), hndl)) : nullptr; 3484356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 3485