SkCanvas.cpp 104 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069
  1. /*
  2. * Copyright 2008 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkColorFilter.h"
  9. #include "include/core/SkDrawLooper.h"
  10. #include "include/core/SkImage.h"
  11. #include "include/core/SkImageFilter.h"
  12. #include "include/core/SkPathEffect.h"
  13. #include "include/core/SkPicture.h"
  14. #include "include/core/SkRRect.h"
  15. #include "include/core/SkRasterHandleAllocator.h"
  16. #include "include/core/SkString.h"
  17. #include "include/core/SkTextBlob.h"
  18. #include "include/core/SkVertices.h"
  19. #include "include/private/SkNx.h"
  20. #include "include/private/SkTo.h"
  21. #include "include/utils/SkNoDrawCanvas.h"
  22. #include "src/core/SkArenaAlloc.h"
  23. #include "src/core/SkBitmapDevice.h"
  24. #include "src/core/SkCanvasPriv.h"
  25. #include "src/core/SkClipOpPriv.h"
  26. #include "src/core/SkClipStack.h"
  27. #include "src/core/SkDraw.h"
  28. #include "src/core/SkGlyphRun.h"
  29. #include "src/core/SkImageFilterCache.h"
  30. #include "src/core/SkImageFilterPriv.h"
  31. #include "src/core/SkLatticeIter.h"
  32. #include "src/core/SkMSAN.h"
  33. #include "src/core/SkMakeUnique.h"
  34. #include "src/core/SkMatrixUtils.h"
  35. #include "src/core/SkPaintPriv.h"
  36. #include "src/core/SkRasterClip.h"
  37. #include "src/core/SkSpecialImage.h"
  38. #include "src/core/SkStrikeCache.h"
  39. #include "src/core/SkTLazy.h"
  40. #include "src/core/SkTextFormatParams.h"
  41. #include "src/core/SkTraceEvent.h"
  42. #include "src/image/SkImage_Base.h"
  43. #include "src/image/SkSurface_Base.h"
  44. #include "src/utils/SkPatchUtils.h"
  45. #include <new>
  46. #if SK_SUPPORT_GPU
  47. #include "include/gpu/GrContext.h"
  48. #include "src/gpu/SkGr.h"
  49. #endif
  50. #define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0)
  51. #define RETURN_ON_FALSE(pred) do { if (!(pred)) return; } while (0)
  52. ///////////////////////////////////////////////////////////////////////////////////////////////////
  53. /*
  54. * Return true if the drawing this rect would hit every pixels in the canvas.
  55. *
  56. * Returns false if
  57. * - rect does not contain the canvas' bounds
  58. * - paint is not fill
  59. * - paint would blur or otherwise change the coverage of the rect
  60. */
  61. bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint,
  62. ShaderOverrideOpacity overrideOpacity) const {
  63. static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity ==
  64. (int)kNone_ShaderOverrideOpacity,
  65. "need_matching_enums0");
  66. static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity ==
  67. (int)kOpaque_ShaderOverrideOpacity,
  68. "need_matching_enums1");
  69. static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity ==
  70. (int)kNotOpaque_ShaderOverrideOpacity,
  71. "need_matching_enums2");
  72. const SkISize size = this->getBaseLayerSize();
  73. const SkRect bounds = SkRect::MakeIWH(size.width(), size.height());
  74. // if we're clipped at all, we can't overwrite the entire surface
  75. {
  76. SkBaseDevice* base = this->getDevice();
  77. SkBaseDevice* top = this->getTopDevice();
  78. if (base != top) {
  79. return false; // we're in a saveLayer, so conservatively don't assume we'll overwrite
  80. }
  81. if (!base->clipIsWideOpen()) {
  82. return false;
  83. }
  84. }
  85. if (rect) {
  86. if (!this->getTotalMatrix().isScaleTranslate()) {
  87. return false; // conservative
  88. }
  89. SkRect devRect;
  90. this->getTotalMatrix().mapRectScaleTranslate(&devRect, *rect);
  91. if (!devRect.contains(bounds)) {
  92. return false;
  93. }
  94. }
  95. if (paint) {
  96. SkPaint::Style paintStyle = paint->getStyle();
  97. if (!(paintStyle == SkPaint::kFill_Style ||
  98. paintStyle == SkPaint::kStrokeAndFill_Style)) {
  99. return false;
  100. }
  101. if (paint->getMaskFilter()
  102. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  103. || paint->getLooper()
  104. #endif
  105. || paint->getPathEffect() || paint->getImageFilter()) {
  106. return false; // conservative
  107. }
  108. }
  109. return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity);
  110. }
  111. ///////////////////////////////////////////////////////////////////////////////////////////////////
  112. // experimental for faster tiled drawing...
  113. //#define SK_TRACE_SAVERESTORE
  114. #ifdef SK_TRACE_SAVERESTORE
  115. static int gLayerCounter;
  116. static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); }
  117. static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); }
  118. static int gRecCounter;
  119. static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); }
  120. static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); }
  121. static int gCanvasCounter;
  122. static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); }
  123. static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); }
  124. #else
  125. #define inc_layer()
  126. #define dec_layer()
  127. #define inc_rec()
  128. #define dec_rec()
  129. #define inc_canvas()
  130. #define dec_canvas()
  131. #endif
  132. typedef SkTLazy<SkPaint> SkLazyPaint;
  133. void SkCanvas::predrawNotify(bool willOverwritesEntireSurface) {
  134. if (fSurfaceBase) {
  135. fSurfaceBase->aboutToDraw(willOverwritesEntireSurface
  136. ? SkSurface::kDiscard_ContentChangeMode
  137. : SkSurface::kRetain_ContentChangeMode);
  138. }
  139. }
  140. void SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint,
  141. ShaderOverrideOpacity overrideOpacity) {
  142. if (fSurfaceBase) {
  143. SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode;
  144. // Since willOverwriteAllPixels() may not be complete free to call, we only do so if
  145. // there is an outstanding snapshot, since w/o that, there will be no copy-on-write
  146. // and therefore we don't care which mode we're in.
  147. //
  148. if (fSurfaceBase->outstandingImageSnapshot()) {
  149. if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) {
  150. mode = SkSurface::kDiscard_ContentChangeMode;
  151. }
  152. }
  153. fSurfaceBase->aboutToDraw(mode);
  154. }
  155. }
  156. ///////////////////////////////////////////////////////////////////////////////
  157. /* This is the record we keep for each SkBaseDevice that the user installs.
  158. The clip/matrix/proc are fields that reflect the top of the save/restore
  159. stack. Whenever the canvas changes, it marks a dirty flag, and then before
  160. these are used (assuming we're not on a layer) we rebuild these cache
  161. values: they reflect the top of the save stack, but translated and clipped
  162. by the device's XY offset and bitmap-bounds.
  163. */
  164. struct DeviceCM {
  165. DeviceCM* fNext;
  166. sk_sp<SkBaseDevice> fDevice;
  167. SkRasterClip fClip;
  168. std::unique_ptr<const SkPaint> fPaint; // may be null (in the future)
  169. SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer
  170. sk_sp<SkImage> fClipImage;
  171. SkMatrix fClipMatrix;
  172. DeviceCM(sk_sp<SkBaseDevice> device, const SkPaint* paint, const SkMatrix& stashed,
  173. const SkImage* clipImage, const SkMatrix* clipMatrix)
  174. : fNext(nullptr)
  175. , fDevice(std::move(device))
  176. , fPaint(paint ? skstd::make_unique<SkPaint>(*paint) : nullptr)
  177. , fStashedMatrix(stashed)
  178. , fClipImage(sk_ref_sp(const_cast<SkImage*>(clipImage)))
  179. , fClipMatrix(clipMatrix ? *clipMatrix : SkMatrix::I())
  180. {}
  181. void reset(const SkIRect& bounds) {
  182. SkASSERT(!fPaint);
  183. SkASSERT(!fNext);
  184. SkASSERT(fDevice);
  185. fClip.setRect(bounds);
  186. }
  187. };
  188. namespace {
  189. // Encapsulate state needed to restore from saveBehind()
  190. struct BackImage {
  191. sk_sp<SkSpecialImage> fImage;
  192. SkIPoint fLoc;
  193. };
  194. }
  195. /* This is the record we keep for each save/restore level in the stack.
  196. Since a level optionally copies the matrix and/or stack, we have pointers
  197. for these fields. If the value is copied for this level, the copy is
  198. stored in the ...Storage field, and the pointer points to that. If the
  199. value is not copied for this level, we ignore ...Storage, and just point
  200. at the corresponding value in the previous level in the stack.
  201. */
  202. class SkCanvas::MCRec {
  203. public:
  204. DeviceCM* fLayer;
  205. /* If there are any layers in the stack, this points to the top-most
  206. one that is at or below this level in the stack (so we know what
  207. bitmap/device to draw into from this level. This value is NOT
  208. reference counted, since the real owner is either our fLayer field,
  209. or a previous one in a lower level.)
  210. */
  211. DeviceCM* fTopLayer;
  212. std::unique_ptr<BackImage> fBackImage;
  213. SkConservativeClip fRasterClip;
  214. SkMatrix fMatrix;
  215. int fDeferredSaveCount;
  216. MCRec() {
  217. fLayer = nullptr;
  218. fTopLayer = nullptr;
  219. fMatrix.reset();
  220. fDeferredSaveCount = 0;
  221. // don't bother initializing fNext
  222. inc_rec();
  223. }
  224. MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) {
  225. fLayer = nullptr;
  226. fTopLayer = prev.fTopLayer;
  227. fDeferredSaveCount = 0;
  228. // don't bother initializing fNext
  229. inc_rec();
  230. }
  231. ~MCRec() {
  232. delete fLayer;
  233. dec_rec();
  234. }
  235. void reset(const SkIRect& bounds) {
  236. SkASSERT(fLayer);
  237. SkASSERT(fDeferredSaveCount == 0);
  238. fMatrix.reset();
  239. fRasterClip.setRect(bounds);
  240. fLayer->reset(bounds);
  241. }
  242. };
  243. class SkDrawIter {
  244. public:
  245. SkDrawIter(SkCanvas* canvas)
  246. : fDevice(nullptr), fCurrLayer(canvas->fMCRec->fTopLayer), fPaint(nullptr)
  247. {}
  248. bool next() {
  249. const DeviceCM* rec = fCurrLayer;
  250. if (rec && rec->fDevice) {
  251. fDevice = rec->fDevice.get();
  252. fPaint = rec->fPaint.get();
  253. fCurrLayer = rec->fNext;
  254. // fCurrLayer may be nullptr now
  255. return true;
  256. }
  257. return false;
  258. }
  259. int getX() const { return fDevice->getOrigin().x(); }
  260. int getY() const { return fDevice->getOrigin().y(); }
  261. const SkPaint* getPaint() const { return fPaint; }
  262. SkBaseDevice* fDevice;
  263. private:
  264. const DeviceCM* fCurrLayer;
  265. const SkPaint* fPaint; // May be null.
  266. };
  267. #define FOR_EACH_TOP_DEVICE( code ) \
  268. do { \
  269. DeviceCM* layer = fMCRec->fTopLayer; \
  270. while (layer) { \
  271. SkBaseDevice* device = layer->fDevice.get(); \
  272. if (device) { \
  273. code; \
  274. } \
  275. layer = layer->fNext; \
  276. } \
  277. } while (0)
  278. /////////////////////////////////////////////////////////////////////////////
  279. static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) {
  280. return lazy->isValid() ? lazy->get() : lazy->set(orig);
  281. }
  282. /**
  283. * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that
  284. * colorfilter, else return nullptr.
  285. */
  286. static sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) {
  287. SkImageFilter* imgf = paint.getImageFilter();
  288. if (!imgf) {
  289. return nullptr;
  290. }
  291. SkColorFilter* imgCFPtr;
  292. if (!imgf->asAColorFilter(&imgCFPtr)) {
  293. return nullptr;
  294. }
  295. sk_sp<SkColorFilter> imgCF(imgCFPtr);
  296. SkColorFilter* paintCF = paint.getColorFilter();
  297. if (nullptr == paintCF) {
  298. // there is no existing paint colorfilter, so we can just return the imagefilter's
  299. return imgCF;
  300. }
  301. // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF)
  302. // and we need to combine them into a single colorfilter.
  303. return imgCF->makeComposed(sk_ref_sp(paintCF));
  304. }
  305. /**
  306. * There are many bounds in skia. A circle's bounds is just its center extended by its radius.
  307. * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw
  308. * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional
  309. * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters,
  310. * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the
  311. * conservative "effective" bounds based on the settings in the paint... with one exception. This
  312. * function does *not* look at the imagefilter, which can also modify the effective bounds. It is
  313. * deliberately ignored.
  314. */
  315. static const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint,
  316. const SkRect& rawBounds,
  317. SkRect* storage) {
  318. SkPaint tmpUnfiltered(paint);
  319. tmpUnfiltered.setImageFilter(nullptr);
  320. if (tmpUnfiltered.canComputeFastBounds()) {
  321. return tmpUnfiltered.computeFastBounds(rawBounds, storage);
  322. } else {
  323. return rawBounds;
  324. }
  325. }
  326. class AutoDrawLooper {
  327. public:
  328. // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the
  329. // paint. It's used to determine the size of the offscreen layer for filters.
  330. // If null, the clip will be used instead.
  331. AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, bool skipLayerForImageFilter = false,
  332. const SkRect* rawBounds = nullptr) : fOrigPaint(paint) {
  333. fCanvas = canvas;
  334. fPaint = &fOrigPaint;
  335. fSaveCount = canvas->getSaveCount();
  336. fTempLayerForImageFilter = false;
  337. fDone = false;
  338. auto simplifiedCF = image_to_color_filter(fOrigPaint);
  339. if (simplifiedCF) {
  340. SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint);
  341. paint->setColorFilter(std::move(simplifiedCF));
  342. paint->setImageFilter(nullptr);
  343. fPaint = paint;
  344. }
  345. if (!skipLayerForImageFilter && fPaint->getImageFilter()) {
  346. /**
  347. * We implement ImageFilters for a given draw by creating a layer, then applying the
  348. * imagefilter to the pixels of that layer (its backing surface/image), and then
  349. * we call restore() to xfer that layer to the main canvas.
  350. *
  351. * 1. SaveLayer (with a paint containing the current imagefilter and xfermode)
  352. * 2. Generate the src pixels:
  353. * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper)
  354. * return (fPaint). We then draw the primitive (using srcover) into a cleared
  355. * buffer/surface.
  356. * 3. Restore the layer created in #1
  357. * The imagefilter is passed the buffer/surface from the layer (now filled with the
  358. * src pixels of the primitive). It returns a new "filtered" buffer, which we
  359. * draw onto the previous layer using the xfermode from the original paint.
  360. */
  361. SkPaint tmp;
  362. tmp.setImageFilter(fPaint->refImageFilter());
  363. tmp.setBlendMode(fPaint->getBlendMode());
  364. SkRect storage;
  365. if (rawBounds) {
  366. // Make rawBounds include all paint outsets except for those due to image filters.
  367. rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage);
  368. }
  369. (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp),
  370. SkCanvas::kFullLayer_SaveLayerStrategy);
  371. fTempLayerForImageFilter = true;
  372. // we remove the imagefilter/xfermode inside doNext()
  373. }
  374. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  375. if (SkDrawLooper* looper = paint.getLooper()) {
  376. fLooperContext = looper->makeContext(canvas, &fAlloc);
  377. fIsSimple = false;
  378. } else
  379. #endif
  380. {
  381. fLooperContext = nullptr;
  382. // can we be marked as simple?
  383. fIsSimple = !fTempLayerForImageFilter;
  384. }
  385. }
  386. ~AutoDrawLooper() {
  387. if (fTempLayerForImageFilter) {
  388. fCanvas->internalRestore();
  389. }
  390. SkASSERT(fCanvas->getSaveCount() == fSaveCount);
  391. }
  392. const SkPaint& paint() const {
  393. SkASSERT(fPaint);
  394. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  395. SkASSERT(fPaint->getDrawLooper() == nullptr); // we should have cleared this
  396. #endif
  397. return *fPaint;
  398. }
  399. bool next() {
  400. if (fDone) {
  401. return false;
  402. } else if (fIsSimple) {
  403. fDone = true;
  404. return !fPaint->nothingToDraw();
  405. } else {
  406. return this->doNext();
  407. }
  408. }
  409. private:
  410. SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it
  411. SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it
  412. SkCanvas* fCanvas;
  413. const SkPaint& fOrigPaint;
  414. const SkPaint* fPaint;
  415. int fSaveCount;
  416. bool fTempLayerForImageFilter;
  417. bool fDone;
  418. bool fIsSimple;
  419. SkDrawLooper::Context* fLooperContext;
  420. SkSTArenaAlloc<48> fAlloc;
  421. bool doNext();
  422. };
  423. bool AutoDrawLooper::doNext() {
  424. fPaint = nullptr;
  425. SkASSERT(!fIsSimple);
  426. SkASSERT(fLooperContext || fTempLayerForImageFilter);
  427. SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ?
  428. *fLazyPaintInit.get() : fOrigPaint);
  429. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  430. // never want our downstream clients (i.e. devices) to see loopers
  431. paint->setDrawLooper(nullptr);
  432. #endif
  433. if (fTempLayerForImageFilter) {
  434. paint->setImageFilter(nullptr);
  435. paint->setBlendMode(SkBlendMode::kSrcOver);
  436. }
  437. if (fLooperContext && !fLooperContext->next(fCanvas, paint)) {
  438. fDone = true;
  439. return false;
  440. }
  441. fPaint = paint;
  442. // if we only came in here for the imagefilter, mark us as done
  443. if (!fLooperContext) {
  444. fDone = true;
  445. }
  446. return true;
  447. }
  448. ////////// macros to place around the internal draw calls //////////////////
  449. #define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \
  450. this->predrawNotify(); \
  451. AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \
  452. while (looper.next()) { \
  453. SkDrawIter iter(this);
  454. #define LOOPER_BEGIN_DRAWDEVICE(paint) \
  455. this->predrawNotify(); \
  456. AutoDrawLooper looper(this, paint, true); \
  457. while (looper.next()) { \
  458. SkDrawIter iter(this);
  459. #define LOOPER_BEGIN(paint, bounds) \
  460. this->predrawNotify(); \
  461. AutoDrawLooper looper(this, paint, false, bounds); \
  462. while (looper.next()) { \
  463. SkDrawIter iter(this);
  464. #define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, bounds, auxOpaque) \
  465. this->predrawNotify(bounds, &paint, auxOpaque); \
  466. AutoDrawLooper looper(this, paint, false, bounds); \
  467. while (looper.next()) { \
  468. SkDrawIter iter(this);
  469. #define LOOPER_END }
  470. ////////////////////////////////////////////////////////////////////////////
  471. static inline SkRect qr_clip_bounds(const SkIRect& bounds) {
  472. if (bounds.isEmpty()) {
  473. return SkRect::MakeEmpty();
  474. }
  475. // Expand bounds out by 1 in case we are anti-aliasing. We store the
  476. // bounds as floats to enable a faster quick reject implementation.
  477. SkRect dst;
  478. SkNx_cast<float>(Sk4i::Load(&bounds.fLeft) + Sk4i(-1,-1,1,1)).store(&dst.fLeft);
  479. return dst;
  480. }
  481. void SkCanvas::resetForNextPicture(const SkIRect& bounds) {
  482. this->restoreToCount(1);
  483. fMCRec->reset(bounds);
  484. // We're peering through a lot of structs here. Only at this scope do we
  485. // know that the device is a SkNoPixelsDevice.
  486. static_cast<SkNoPixelsDevice*>(fMCRec->fLayer->fDevice.get())->resetForNextPicture(bounds);
  487. fDeviceClipBounds = qr_clip_bounds(bounds);
  488. fIsScaleTranslate = true;
  489. }
  490. void SkCanvas::init(sk_sp<SkBaseDevice> device) {
  491. fAllowSimplifyClip = false;
  492. fSaveCount = 1;
  493. fMCRec = (MCRec*)fMCStack.push_back();
  494. new (fMCRec) MCRec;
  495. fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect);
  496. fIsScaleTranslate = true;
  497. SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
  498. fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
  499. new (fDeviceCMStorage) DeviceCM(device, nullptr, fMCRec->fMatrix, nullptr, nullptr);
  500. fMCRec->fTopLayer = fMCRec->fLayer;
  501. fSurfaceBase = nullptr;
  502. if (device) {
  503. // The root device and the canvas should always have the same pixel geometry
  504. SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry());
  505. fMCRec->fRasterClip.setRect(device->getGlobalBounds());
  506. fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds());
  507. device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
  508. }
  509. fScratchGlyphRunBuilder = skstd::make_unique<SkGlyphRunBuilder>();
  510. }
  511. SkCanvas::SkCanvas()
  512. : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
  513. , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
  514. {
  515. inc_canvas();
  516. this->init(nullptr);
  517. }
  518. SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
  519. : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
  520. , fProps(SkSurfacePropsCopyOrDefault(props))
  521. {
  522. inc_canvas();
  523. this->init(sk_make_sp<SkNoPixelsDevice>(
  524. SkIRect::MakeWH(SkTMax(width, 0), SkTMax(height, 0)), fProps));
  525. }
  526. SkCanvas::SkCanvas(const SkIRect& bounds)
  527. : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
  528. , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
  529. {
  530. inc_canvas();
  531. SkIRect r = bounds.isEmpty() ? SkIRect::MakeEmpty() : bounds;
  532. this->init(sk_make_sp<SkNoPixelsDevice>(r, fProps));
  533. }
  534. SkCanvas::SkCanvas(sk_sp<SkBaseDevice> device)
  535. : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
  536. , fProps(device->surfaceProps())
  537. {
  538. inc_canvas();
  539. this->init(device);
  540. }
  541. SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
  542. : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
  543. , fProps(props)
  544. {
  545. inc_canvas();
  546. sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, nullptr, nullptr));
  547. this->init(device);
  548. }
  549. SkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocator> alloc,
  550. SkRasterHandleAllocator::Handle hndl)
  551. : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
  552. , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
  553. , fAllocator(std::move(alloc))
  554. {
  555. inc_canvas();
  556. sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps, hndl, nullptr));
  557. this->init(device);
  558. }
  559. SkCanvas::SkCanvas(const SkBitmap& bitmap) : SkCanvas(bitmap, nullptr, nullptr) {}
  560. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  561. SkCanvas::SkCanvas(const SkBitmap& bitmap, ColorBehavior)
  562. : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
  563. , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
  564. , fAllocator(nullptr)
  565. {
  566. inc_canvas();
  567. SkBitmap tmp(bitmap);
  568. *const_cast<SkImageInfo*>(&tmp.info()) = tmp.info().makeColorSpace(nullptr);
  569. sk_sp<SkBaseDevice> device(new SkBitmapDevice(tmp, fProps, nullptr, nullptr));
  570. this->init(device);
  571. }
  572. #endif
  573. SkCanvas::~SkCanvas() {
  574. // free up the contents of our deque
  575. this->restoreToCount(1); // restore everything but the last
  576. this->internalRestore(); // restore the last, since we're going away
  577. dec_canvas();
  578. }
  579. ///////////////////////////////////////////////////////////////////////////////
  580. void SkCanvas::flush() {
  581. this->onFlush();
  582. }
  583. void SkCanvas::onFlush() {
  584. SkBaseDevice* device = this->getDevice();
  585. if (device) {
  586. device->flush();
  587. }
  588. }
  589. SkISize SkCanvas::getBaseLayerSize() const {
  590. SkBaseDevice* d = this->getDevice();
  591. return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0);
  592. }
  593. SkIRect SkCanvas::getTopLayerBounds() const {
  594. SkBaseDevice* d = this->getTopDevice();
  595. if (!d) {
  596. return SkIRect::MakeEmpty();
  597. }
  598. return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height());
  599. }
  600. SkBaseDevice* SkCanvas::getDevice() const {
  601. // return root device
  602. MCRec* rec = (MCRec*) fMCStack.front();
  603. SkASSERT(rec && rec->fLayer);
  604. return rec->fLayer->fDevice.get();
  605. }
  606. SkBaseDevice* SkCanvas::getTopDevice() const {
  607. return fMCRec->fTopLayer->fDevice.get();
  608. }
  609. bool SkCanvas::readPixels(const SkPixmap& pm, int x, int y) {
  610. SkBaseDevice* device = this->getDevice();
  611. return device && pm.addr() && device->readPixels(pm, x, y);
  612. }
  613. bool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) {
  614. return this->readPixels({ dstInfo, dstP, rowBytes}, x, y);
  615. }
  616. bool SkCanvas::readPixels(const SkBitmap& bm, int x, int y) {
  617. SkPixmap pm;
  618. return bm.peekPixels(&pm) && this->readPixels(pm, x, y);
  619. }
  620. bool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) {
  621. SkPixmap pm;
  622. if (bitmap.peekPixels(&pm)) {
  623. return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y);
  624. }
  625. return false;
  626. }
  627. bool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_t rowBytes,
  628. int x, int y) {
  629. SkBaseDevice* device = this->getDevice();
  630. if (!device) {
  631. return false;
  632. }
  633. // This check gives us an early out and prevents generation ID churn on the surface.
  634. // This is purely optional: it is a subset of the checks performed by SkWritePixelsRec.
  635. SkIRect srcRect = SkIRect::MakeXYWH(x, y, srcInfo.width(), srcInfo.height());
  636. if (!srcRect.intersect(0, 0, device->width(), device->height())) {
  637. return false;
  638. }
  639. // Tell our owning surface to bump its generation ID.
  640. const bool completeOverwrite =
  641. srcRect.size() == SkISize::Make(device->width(), device->height());
  642. this->predrawNotify(completeOverwrite);
  643. // This can still fail, most notably in the case of a invalid color type or alpha type
  644. // conversion. We could pull those checks into this function and avoid the unnecessary
  645. // generation ID bump. But then we would be performing those checks twice, since they
  646. // are also necessary at the bitmap/pixmap entry points.
  647. return device->writePixels({srcInfo, pixels, rowBytes}, x, y);
  648. }
  649. //////////////////////////////////////////////////////////////////////////////
  650. void SkCanvas::checkForDeferredSave() {
  651. if (fMCRec->fDeferredSaveCount > 0) {
  652. this->doSave();
  653. }
  654. }
  655. int SkCanvas::getSaveCount() const {
  656. #ifdef SK_DEBUG
  657. int count = 0;
  658. SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart);
  659. for (;;) {
  660. const MCRec* rec = (const MCRec*)iter.next();
  661. if (!rec) {
  662. break;
  663. }
  664. count += 1 + rec->fDeferredSaveCount;
  665. }
  666. SkASSERT(count == fSaveCount);
  667. #endif
  668. return fSaveCount;
  669. }
  670. int SkCanvas::save() {
  671. fSaveCount += 1;
  672. fMCRec->fDeferredSaveCount += 1;
  673. return this->getSaveCount() - 1; // return our prev value
  674. }
  675. void SkCanvas::doSave() {
  676. this->willSave();
  677. SkASSERT(fMCRec->fDeferredSaveCount > 0);
  678. fMCRec->fDeferredSaveCount -= 1;
  679. this->internalSave();
  680. }
  681. void SkCanvas::restore() {
  682. if (fMCRec->fDeferredSaveCount > 0) {
  683. SkASSERT(fSaveCount > 1);
  684. fSaveCount -= 1;
  685. fMCRec->fDeferredSaveCount -= 1;
  686. } else {
  687. // check for underflow
  688. if (fMCStack.count() > 1) {
  689. this->willRestore();
  690. SkASSERT(fSaveCount > 1);
  691. fSaveCount -= 1;
  692. this->internalRestore();
  693. this->didRestore();
  694. }
  695. }
  696. }
  697. void SkCanvas::restoreToCount(int count) {
  698. // sanity check
  699. if (count < 1) {
  700. count = 1;
  701. }
  702. int n = this->getSaveCount() - count;
  703. for (int i = 0; i < n; ++i) {
  704. this->restore();
  705. }
  706. }
  707. void SkCanvas::internalSave() {
  708. MCRec* newTop = (MCRec*)fMCStack.push_back();
  709. new (newTop) MCRec(*fMCRec); // balanced in restore()
  710. fMCRec = newTop;
  711. FOR_EACH_TOP_DEVICE(device->save());
  712. }
  713. bool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) {
  714. return !(saveLayerFlags & SkCanvasPriv::kDontClipToLayer_SaveLayerFlag);
  715. }
  716. bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags,
  717. SkIRect* intersection, const SkImageFilter* imageFilter) {
  718. // clipRectBounds() is called to determine the input layer size needed for a given image filter.
  719. // The coordinate space of the rectangle passed to filterBounds(kReverse) is meant to be in the
  720. // filtering layer space. Here, 'clipBounds' is always in the true device space. When an image
  721. // filter does not require a decomposed CTM matrix, the filter space and device space are the
  722. // same. When it has been decomposed, we want the original image filter node to process the
  723. // bounds in the layer space represented by the decomposed scale matrix. 'imageFilter' is no
  724. // longer the original filter, but has the remainder matrix baked into it, and passing in the
  725. // the true device clip bounds ensures that the matrix image filter provides a layer clip bounds
  726. // to the original filter node (barring inflation from consecutive calls to mapRect). While
  727. // initially counter-intuitive given the apparent inconsistency of coordinate spaces, always
  728. // passing getDeviceClipBounds() to 'imageFilter' is correct.
  729. // FIXME (michaelludwig) - When the remainder matrix is instead applied as a final draw, it will
  730. // be important to more accurately calculate the clip bounds in the layer space for the original
  731. // image filter (similar to how matrix image filter does it, but ideally without the inflation).
  732. SkIRect clipBounds = this->getDeviceClipBounds();
  733. if (clipBounds.isEmpty()) {
  734. return false;
  735. }
  736. const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix()
  737. if (imageFilter && bounds && !imageFilter->canComputeFastBounds()) {
  738. // If the image filter DAG affects transparent black then we will need to render
  739. // out to the clip bounds
  740. bounds = nullptr;
  741. }
  742. SkIRect inputSaveLayerBounds;
  743. if (bounds) {
  744. SkRect r;
  745. ctm.mapRect(&r, *bounds);
  746. r.roundOut(&inputSaveLayerBounds);
  747. } else { // no user bounds, so just use the clip
  748. inputSaveLayerBounds = clipBounds;
  749. }
  750. if (imageFilter) {
  751. // expand the clip bounds by the image filter DAG to include extra content that might
  752. // be required by the image filters.
  753. clipBounds = imageFilter->filterBounds(clipBounds, ctm,
  754. SkImageFilter::kReverse_MapDirection,
  755. &inputSaveLayerBounds);
  756. }
  757. SkIRect clippedSaveLayerBounds;
  758. if (bounds) {
  759. // For better or for worse, user bounds currently act as a hard clip on the layer's
  760. // extent (i.e., they implement the CSS filter-effects 'filter region' feature).
  761. clippedSaveLayerBounds = inputSaveLayerBounds;
  762. } else {
  763. // If there are no user bounds, we don't want to artificially restrict the resulting
  764. // layer bounds, so allow the expanded clip bounds free reign.
  765. clippedSaveLayerBounds = clipBounds;
  766. }
  767. // early exit if the layer's bounds are clipped out
  768. if (!clippedSaveLayerBounds.intersect(clipBounds)) {
  769. if (BoundsAffectsClip(saveLayerFlags)) {
  770. fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty
  771. fMCRec->fRasterClip.setEmpty();
  772. fDeviceClipBounds.setEmpty();
  773. }
  774. return false;
  775. }
  776. SkASSERT(!clippedSaveLayerBounds.isEmpty());
  777. if (BoundsAffectsClip(saveLayerFlags)) {
  778. // Simplify the current clips since they will be applied properly during restore()
  779. fMCRec->fRasterClip.setRect(clippedSaveLayerBounds);
  780. fDeviceClipBounds = qr_clip_bounds(clippedSaveLayerBounds);
  781. }
  782. if (intersection) {
  783. *intersection = clippedSaveLayerBounds;
  784. }
  785. return true;
  786. }
  787. int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
  788. return this->saveLayer(SaveLayerRec(bounds, paint, 0));
  789. }
  790. int SkCanvas::saveLayer(const SaveLayerRec& rec) {
  791. TRACE_EVENT0("skia", TRACE_FUNC);
  792. if (rec.fPaint && rec.fPaint->nothingToDraw()) {
  793. // no need for the layer (or any of the draws until the matching restore()
  794. this->save();
  795. this->clipRect({0,0,0,0});
  796. } else {
  797. SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec);
  798. fSaveCount += 1;
  799. this->internalSaveLayer(rec, strategy);
  800. }
  801. return this->getSaveCount() - 1;
  802. }
  803. int SkCanvas::only_axis_aligned_saveBehind(const SkRect* bounds) {
  804. if (bounds && !this->getLocalClipBounds().intersects(*bounds)) {
  805. // Assuming clips never expand, if the request bounds is outside of the current clip
  806. // there is no need to copy/restore the area, so just devolve back to a regular save.
  807. this->save();
  808. } else {
  809. bool doTheWork = this->onDoSaveBehind(bounds);
  810. fSaveCount += 1;
  811. this->internalSave();
  812. if (doTheWork) {
  813. this->internalSaveBehind(bounds);
  814. }
  815. }
  816. return this->getSaveCount() - 1;
  817. }
  818. void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
  819. SkBaseDevice* dst, const SkIPoint& dstOrigin,
  820. const SkMatrix& ctm) {
  821. SkPaint p;
  822. SkIRect snapBounds = SkIRect::MakeXYWH(dstOrigin.x() - src->getOrigin().x(),
  823. dstOrigin.y() - src->getOrigin().y(),
  824. dst->width(), dst->height());
  825. int x = 0;
  826. int y = 0;
  827. if (filter) {
  828. // Calculate expanded snap bounds
  829. SkIRect newBounds = filter->filterBounds(
  830. snapBounds, ctm, SkImageFilter::kReverse_MapDirection, &snapBounds);
  831. // Must clamp to valid src since the filter or rotations may expand beyond what's readable
  832. SkIRect srcR = SkIRect::MakeWH(src->width(), src->height());
  833. if (!newBounds.intersect(srcR)) {
  834. return;
  835. }
  836. x = newBounds.fLeft - snapBounds.fLeft;
  837. y = newBounds.fTop - snapBounds.fTop;
  838. snapBounds = newBounds;
  839. SkMatrix localCTM;
  840. sk_sp<SkImageFilter> modifiedFilter = SkApplyCTMToBackdropFilter(filter, ctm, &localCTM);
  841. // Account for the origin offset in the CTM
  842. localCTM.postTranslate(-dstOrigin.x(), -dstOrigin.y());
  843. // In this case we always wrap the filter (even when it's the original) with 'localCTM'
  844. // since there's no device CTM stack that provides it to the image filter context.
  845. // FIXME skbug.com/9074 - once perspective is properly supported, drop the
  846. // localCTM.hasPerspective condition from assert.
  847. SkASSERT(localCTM.isScaleTranslate() || filter->canHandleComplexCTM() ||
  848. localCTM.hasPerspective());
  849. p.setImageFilter(modifiedFilter->makeWithLocalMatrix(localCTM));
  850. }
  851. auto special = src->snapBackImage(snapBounds);
  852. if (special) {
  853. dst->drawSpecial(special.get(), x, y, p, nullptr, SkMatrix::I());
  854. }
  855. }
  856. // This is shared by all backends, but contains raster-specific thoughts. Can we defer to the
  857. // device to perform this?
  858. static SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, const SkPaint* paint) {
  859. // Need to force L32 for now if we have an image filter.
  860. // If filters ever support other colortypes, e.g. F16, we can modify this check.
  861. if (paint && paint->getImageFilter()) {
  862. // TODO: can we query the imagefilter, to see if it can handle floats (so we don't always
  863. // use N32 when the layer itself was float)?
  864. return SkImageInfo::MakeN32Premul(w, h, prev.refColorSpace());
  865. }
  866. SkColorType ct = prev.colorType();
  867. if (prev.bytesPerPixel() <= 4) {
  868. // "Upgrade" A8, G8, 565, 4444, 1010102, 101010x, and 888x to 8888,
  869. // ensuring plenty of alpha bits for the layer, perhaps losing some color bits in return.
  870. ct = kN32_SkColorType;
  871. }
  872. return SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType, prev.refColorSpace());
  873. }
  874. void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) {
  875. TRACE_EVENT0("skia", TRACE_FUNC);
  876. const SkRect* bounds = rec.fBounds;
  877. const SkPaint* paint = rec.fPaint;
  878. SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags;
  879. // If we have a backdrop filter, then we must apply it to the entire layer (clip-bounds)
  880. // regardless of any hint-rect from the caller. skbug.com/8783
  881. if (rec.fBackdrop) {
  882. bounds = nullptr;
  883. }
  884. SkLazyPaint lazyP;
  885. SkImageFilter* imageFilter = paint ? paint->getImageFilter() : nullptr;
  886. SkMatrix stashedMatrix = fMCRec->fMatrix;
  887. MCRec* modifiedRec = nullptr;
  888. /*
  889. * Many ImageFilters (so far) do not (on their own) correctly handle matrices (CTM) that
  890. * contain rotation/skew/etc. We rely on applyCTM to create a new image filter DAG as needed to
  891. * accommodate this, but it requires update the CTM we use when drawing into the layer.
  892. *
  893. * 1. Stash off the current CTM
  894. * 2. Apply the CTM to imagefilter, which decomposes it into simple and complex transforms
  895. * if necessary.
  896. * 3. Wack the CTM to be the remaining scale matrix and use the modified imagefilter, which
  897. * is a MatrixImageFilter that contains the complex matrix.
  898. * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM)
  899. * 5. During restore, the MatrixImageFilter automatically applies complex stage to the output
  900. * of the original imagefilter, and draw that (via drawSprite)
  901. * 6. Unwack the CTM to its original state (i.e. stashedMatrix)
  902. *
  903. * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer
  904. * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter.
  905. */
  906. if (imageFilter) {
  907. SkMatrix modifiedCTM;
  908. sk_sp<SkImageFilter> modifiedFilter = SkApplyCTMToFilter(imageFilter, stashedMatrix,
  909. &modifiedCTM);
  910. if (!SkIsSameFilter(modifiedFilter.get(), imageFilter)) {
  911. // The original filter couldn't support the CTM entirely
  912. SkASSERT(modifiedCTM.isScaleTranslate() || imageFilter->canHandleComplexCTM());
  913. modifiedRec = fMCRec;
  914. this->internalSetMatrix(modifiedCTM);
  915. SkPaint* p = lazyP.set(*paint);
  916. p->setImageFilter(std::move(modifiedFilter));
  917. imageFilter = p->getImageFilter();
  918. paint = p;
  919. }
  920. // Else the filter didn't change, so modifiedCTM == stashedMatrix and there's nothing
  921. // left to do since the stack already has that as the CTM.
  922. }
  923. // do this before we create the layer. We don't call the public save() since
  924. // that would invoke a possibly overridden virtual
  925. this->internalSave();
  926. SkIRect ir;
  927. if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) {
  928. if (modifiedRec) {
  929. // In this case there will be no layer in which to stash the matrix so we need to
  930. // revert the prior MCRec to its earlier state.
  931. modifiedRec->fMatrix = stashedMatrix;
  932. }
  933. return;
  934. }
  935. // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about
  936. // the clipRectBounds() call above?
  937. if (kNoLayer_SaveLayerStrategy == strategy) {
  938. return;
  939. }
  940. SkPixelGeometry geo = fProps.pixelGeometry();
  941. if (paint) {
  942. // TODO: perhaps add a query to filters so we might preserve opaqueness...
  943. if (paint->getImageFilter() || paint->getColorFilter()) {
  944. geo = kUnknown_SkPixelGeometry;
  945. }
  946. }
  947. SkBaseDevice* priorDevice = this->getTopDevice();
  948. if (nullptr == priorDevice) { // Do we still need this check???
  949. SkDebugf("Unable to find device for layer.");
  950. return;
  951. }
  952. SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir.height(), paint);
  953. if (rec.fSaveLayerFlags & kF16ColorType) {
  954. info = info.makeColorType(kRGBA_F16_SkColorType);
  955. }
  956. sk_sp<SkBaseDevice> newDevice;
  957. {
  958. const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType();
  959. const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage;
  960. const bool trackCoverage =
  961. SkToBool(saveLayerFlags & kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag);
  962. const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo,
  963. preserveLCDText,
  964. trackCoverage,
  965. fAllocator.get());
  966. newDevice.reset(priorDevice->onCreateDevice(createInfo, paint));
  967. if (!newDevice) {
  968. return;
  969. }
  970. }
  971. DeviceCM* layer = new DeviceCM(newDevice, paint, stashedMatrix, rec.fClipMask, rec.fClipMatrix);
  972. // only have a "next" if this new layer doesn't affect the clip (rare)
  973. layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer;
  974. fMCRec->fLayer = layer;
  975. fMCRec->fTopLayer = layer; // this field is NOT an owner of layer
  976. if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) {
  977. DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop },
  978. fMCRec->fMatrix);
  979. }
  980. newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
  981. newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
  982. if (layer->fNext) {
  983. // need to punch a hole in the previous device, so we don't draw there, given that
  984. // the new top-layer will allow drawing to happen "below" it.
  985. SkRegion hole(ir);
  986. do {
  987. layer = layer->fNext;
  988. layer->fDevice->clipRegion(hole, SkClipOp::kDifference);
  989. } while (layer->fNext);
  990. }
  991. }
  992. int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
  993. if (0xFF == alpha) {
  994. return this->saveLayer(bounds, nullptr);
  995. } else {
  996. SkPaint tmpPaint;
  997. tmpPaint.setAlpha(alpha);
  998. return this->saveLayer(bounds, &tmpPaint);
  999. }
  1000. }
  1001. void SkCanvas::internalSaveBehind(const SkRect* localBounds) {
  1002. SkIRect devBounds;
  1003. if (localBounds) {
  1004. SkRect tmp;
  1005. fMCRec->fMatrix.mapRect(&tmp, *localBounds);
  1006. if (!devBounds.intersect(tmp.round(), this->getDeviceClipBounds())) {
  1007. devBounds.setEmpty();
  1008. }
  1009. } else {
  1010. devBounds = this->getDeviceClipBounds();
  1011. }
  1012. if (devBounds.isEmpty()) {
  1013. return;
  1014. }
  1015. SkBaseDevice* device = this->getTopDevice();
  1016. if (nullptr == device) { // Do we still need this check???
  1017. return;
  1018. }
  1019. // need the bounds relative to the device itself
  1020. devBounds.offset(-device->fOrigin.fX, -device->fOrigin.fY);
  1021. auto backImage = device->snapBackImage(devBounds);
  1022. if (!backImage) {
  1023. return;
  1024. }
  1025. // we really need the save, so we can wack the fMCRec
  1026. this->checkForDeferredSave();
  1027. fMCRec->fBackImage.reset(new BackImage{std::move(backImage), devBounds.topLeft()});
  1028. SkPaint paint;
  1029. paint.setBlendMode(SkBlendMode::kClear);
  1030. this->drawClippedToSaveBehind(paint);
  1031. }
  1032. void SkCanvas::internalRestore() {
  1033. SkASSERT(fMCStack.count() != 0);
  1034. // reserve our layer (if any)
  1035. DeviceCM* layer = fMCRec->fLayer; // may be null
  1036. // now detach it from fMCRec so we can pop(). Gets freed after its drawn
  1037. fMCRec->fLayer = nullptr;
  1038. // move this out before we do the actual restore
  1039. auto backImage = std::move(fMCRec->fBackImage);
  1040. // now do the normal restore()
  1041. fMCRec->~MCRec(); // balanced in save()
  1042. fMCStack.pop_back();
  1043. fMCRec = (MCRec*)fMCStack.back();
  1044. if (fMCRec) {
  1045. FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix));
  1046. }
  1047. if (backImage) {
  1048. SkPaint paint;
  1049. paint.setBlendMode(SkBlendMode::kDstOver);
  1050. const int x = backImage->fLoc.x();
  1051. const int y = backImage->fLoc.y();
  1052. this->getTopDevice()->drawSpecial(backImage->fImage.get(), x, y, paint,
  1053. nullptr, SkMatrix::I());
  1054. }
  1055. /* Time to draw the layer's offscreen. We can't call the public drawSprite,
  1056. since if we're being recorded, we don't want to record this (the
  1057. recorder will have already recorded the restore).
  1058. */
  1059. if (layer) {
  1060. if (fMCRec) {
  1061. const SkIPoint& origin = layer->fDevice->getOrigin();
  1062. layer->fDevice->setImmutable();
  1063. this->internalDrawDevice(layer->fDevice.get(), origin.x(), origin.y(),
  1064. layer->fPaint.get(),
  1065. layer->fClipImage.get(), layer->fClipMatrix);
  1066. // restore what we smashed in internalSaveLayer
  1067. this->internalSetMatrix(layer->fStashedMatrix);
  1068. // reset this, since internalDrawDevice will have set it to true
  1069. delete layer;
  1070. } else {
  1071. // we're at the root
  1072. SkASSERT(layer == (void*)fDeviceCMStorage);
  1073. layer->~DeviceCM();
  1074. // no need to update fMCRec, 'cause we're killing the canvas
  1075. }
  1076. }
  1077. if (fMCRec) {
  1078. fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
  1079. fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
  1080. }
  1081. }
  1082. sk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) {
  1083. if (nullptr == props) {
  1084. props = &fProps;
  1085. }
  1086. return this->onNewSurface(info, *props);
  1087. }
  1088. sk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
  1089. SkBaseDevice* dev = this->getDevice();
  1090. return dev ? dev->makeSurface(info, props) : nullptr;
  1091. }
  1092. SkImageInfo SkCanvas::imageInfo() const {
  1093. return this->onImageInfo();
  1094. }
  1095. SkImageInfo SkCanvas::onImageInfo() const {
  1096. SkBaseDevice* dev = this->getDevice();
  1097. if (dev) {
  1098. return dev->imageInfo();
  1099. } else {
  1100. return SkImageInfo::MakeUnknown(0, 0);
  1101. }
  1102. }
  1103. bool SkCanvas::getProps(SkSurfaceProps* props) const {
  1104. return this->onGetProps(props);
  1105. }
  1106. bool SkCanvas::onGetProps(SkSurfaceProps* props) const {
  1107. SkBaseDevice* dev = this->getDevice();
  1108. if (dev) {
  1109. if (props) {
  1110. *props = fProps;
  1111. }
  1112. return true;
  1113. } else {
  1114. return false;
  1115. }
  1116. }
  1117. bool SkCanvas::peekPixels(SkPixmap* pmap) {
  1118. return this->onPeekPixels(pmap);
  1119. }
  1120. bool SkCanvas::onPeekPixels(SkPixmap* pmap) {
  1121. SkBaseDevice* dev = this->getDevice();
  1122. return dev && dev->peekPixels(pmap);
  1123. }
  1124. void* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) {
  1125. SkPixmap pmap;
  1126. if (!this->onAccessTopLayerPixels(&pmap)) {
  1127. return nullptr;
  1128. }
  1129. if (info) {
  1130. *info = pmap.info();
  1131. }
  1132. if (rowBytes) {
  1133. *rowBytes = pmap.rowBytes();
  1134. }
  1135. if (origin) {
  1136. *origin = this->getTopDevice()->getOrigin();
  1137. }
  1138. return pmap.writable_addr();
  1139. }
  1140. bool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) {
  1141. SkBaseDevice* dev = this->getTopDevice();
  1142. return dev && dev->accessPixels(pmap);
  1143. }
  1144. /////////////////////////////////////////////////////////////////////////////
  1145. // In our current design/features, we should never have a layer (src) in a different colorspace
  1146. // than its parent (dst), so we assert that here. This is called out from other asserts, in case
  1147. // we add some feature in the future to allow a given layer/imagefilter to operate in a specific
  1148. // colorspace.
  1149. static void check_drawdevice_colorspaces(SkColorSpace* src, SkColorSpace* dst) {
  1150. SkASSERT(src == dst);
  1151. }
  1152. void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint,
  1153. SkImage* clipImage, const SkMatrix& clipMatrix) {
  1154. SkPaint tmp;
  1155. if (nullptr == paint) {
  1156. paint = &tmp;
  1157. }
  1158. LOOPER_BEGIN_DRAWDEVICE(*paint)
  1159. while (iter.next()) {
  1160. SkBaseDevice* dstDev = iter.fDevice;
  1161. check_drawdevice_colorspaces(dstDev->imageInfo().colorSpace(),
  1162. srcDev->imageInfo().colorSpace());
  1163. paint = &looper.paint();
  1164. SkImageFilter* filter = paint->getImageFilter();
  1165. SkIPoint pos = { x - iter.getX(), y - iter.getY() };
  1166. if (filter || clipImage) {
  1167. sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial();
  1168. if (specialImage) {
  1169. check_drawdevice_colorspaces(dstDev->imageInfo().colorSpace(),
  1170. specialImage->getColorSpace());
  1171. dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint,
  1172. clipImage, clipMatrix);
  1173. }
  1174. } else {
  1175. dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint);
  1176. }
  1177. }
  1178. LOOPER_END
  1179. }
  1180. /////////////////////////////////////////////////////////////////////////////
  1181. void SkCanvas::translate(SkScalar dx, SkScalar dy) {
  1182. if (dx || dy) {
  1183. this->checkForDeferredSave();
  1184. fMCRec->fMatrix.preTranslate(dx,dy);
  1185. // Translate shouldn't affect the is-scale-translateness of the matrix.
  1186. SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate());
  1187. FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
  1188. this->didTranslate(dx,dy);
  1189. }
  1190. }
  1191. void SkCanvas::scale(SkScalar sx, SkScalar sy) {
  1192. SkMatrix m;
  1193. m.setScale(sx, sy);
  1194. this->concat(m);
  1195. }
  1196. void SkCanvas::rotate(SkScalar degrees) {
  1197. SkMatrix m;
  1198. m.setRotate(degrees);
  1199. this->concat(m);
  1200. }
  1201. void SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) {
  1202. SkMatrix m;
  1203. m.setRotate(degrees, px, py);
  1204. this->concat(m);
  1205. }
  1206. void SkCanvas::skew(SkScalar sx, SkScalar sy) {
  1207. SkMatrix m;
  1208. m.setSkew(sx, sy);
  1209. this->concat(m);
  1210. }
  1211. void SkCanvas::concat(const SkMatrix& matrix) {
  1212. if (matrix.isIdentity()) {
  1213. return;
  1214. }
  1215. this->checkForDeferredSave();
  1216. fMCRec->fMatrix.preConcat(matrix);
  1217. fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
  1218. FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
  1219. this->didConcat(matrix);
  1220. }
  1221. void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
  1222. fMCRec->fMatrix = matrix;
  1223. fIsScaleTranslate = matrix.isScaleTranslate();
  1224. FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
  1225. }
  1226. void SkCanvas::setMatrix(const SkMatrix& matrix) {
  1227. this->checkForDeferredSave();
  1228. this->internalSetMatrix(matrix);
  1229. this->didSetMatrix(matrix);
  1230. }
  1231. void SkCanvas::resetMatrix() {
  1232. this->setMatrix(SkMatrix::I());
  1233. }
  1234. //////////////////////////////////////////////////////////////////////////////
  1235. void SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) {
  1236. if (!rect.isFinite()) {
  1237. return;
  1238. }
  1239. this->checkForDeferredSave();
  1240. ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
  1241. this->onClipRect(rect, op, edgeStyle);
  1242. }
  1243. void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
  1244. const bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
  1245. FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA));
  1246. AutoValidateClip avc(this);
  1247. fMCRec->fRasterClip.opRect(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
  1248. isAA);
  1249. fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
  1250. }
  1251. void SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) {
  1252. fClipRestrictionRect = rect;
  1253. if (fClipRestrictionRect.isEmpty()) {
  1254. // we notify the device, but we *dont* resolve deferred saves (since we're just
  1255. // removing the restriction if the rect is empty. how I hate this api.
  1256. FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
  1257. } else {
  1258. this->checkForDeferredSave();
  1259. FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
  1260. AutoValidateClip avc(this);
  1261. fMCRec->fRasterClip.opIRect(fClipRestrictionRect, SkRegion::kIntersect_Op);
  1262. fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
  1263. }
  1264. }
  1265. void SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) {
  1266. this->checkForDeferredSave();
  1267. ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
  1268. if (rrect.isRect()) {
  1269. this->onClipRect(rrect.getBounds(), op, edgeStyle);
  1270. } else {
  1271. this->onClipRRect(rrect, op, edgeStyle);
  1272. }
  1273. }
  1274. void SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
  1275. AutoValidateClip avc(this);
  1276. bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
  1277. FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA));
  1278. fMCRec->fRasterClip.opRRect(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
  1279. isAA);
  1280. fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
  1281. }
  1282. void SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) {
  1283. this->checkForDeferredSave();
  1284. ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle;
  1285. if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) {
  1286. SkRect r;
  1287. if (path.isRect(&r)) {
  1288. this->onClipRect(r, op, edgeStyle);
  1289. return;
  1290. }
  1291. SkRRect rrect;
  1292. if (path.isOval(&r)) {
  1293. rrect.setOval(r);
  1294. this->onClipRRect(rrect, op, edgeStyle);
  1295. return;
  1296. }
  1297. if (path.isRRect(&rrect)) {
  1298. this->onClipRRect(rrect, op, edgeStyle);
  1299. return;
  1300. }
  1301. }
  1302. this->onClipPath(path, op, edgeStyle);
  1303. }
  1304. void SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
  1305. AutoValidateClip avc(this);
  1306. bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
  1307. FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA));
  1308. const SkPath* rasterClipPath = &path;
  1309. const SkMatrix* matrix = &fMCRec->fMatrix;
  1310. fMCRec->fRasterClip.opPath(*rasterClipPath, *matrix, this->getTopLayerBounds(),
  1311. (SkRegion::Op)op, isAA);
  1312. fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
  1313. }
  1314. void SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) {
  1315. this->checkForDeferredSave();
  1316. this->onClipRegion(rgn, op);
  1317. }
  1318. void SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) {
  1319. FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op));
  1320. AutoValidateClip avc(this);
  1321. fMCRec->fRasterClip.opRegion(rgn, (SkRegion::Op)op);
  1322. fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
  1323. }
  1324. #ifdef SK_DEBUG
  1325. void SkCanvas::validateClip() const {
  1326. // construct clipRgn from the clipstack
  1327. const SkBaseDevice* device = this->getDevice();
  1328. if (!device) {
  1329. SkASSERT(this->isClipEmpty());
  1330. return;
  1331. }
  1332. }
  1333. #endif
  1334. bool SkCanvas::androidFramework_isClipAA() const {
  1335. bool containsAA = false;
  1336. FOR_EACH_TOP_DEVICE(containsAA |= device->onClipIsAA());
  1337. return containsAA;
  1338. }
  1339. class RgnAccumulator {
  1340. SkRegion* fRgn;
  1341. public:
  1342. RgnAccumulator(SkRegion* total) : fRgn(total) {}
  1343. void accumulate(SkBaseDevice* device, SkRegion* rgn) {
  1344. SkIPoint origin = device->getOrigin();
  1345. if (origin.x() | origin.y()) {
  1346. rgn->translate(origin.x(), origin.y());
  1347. }
  1348. fRgn->op(*rgn, SkRegion::kUnion_Op);
  1349. }
  1350. };
  1351. void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) {
  1352. RgnAccumulator accum(rgn);
  1353. SkRegion tmp;
  1354. rgn->setEmpty();
  1355. FOR_EACH_TOP_DEVICE(device->onAsRgnClip(&tmp); accum.accumulate(device, &tmp));
  1356. }
  1357. ///////////////////////////////////////////////////////////////////////////////
  1358. bool SkCanvas::isClipEmpty() const {
  1359. return fMCRec->fRasterClip.isEmpty();
  1360. // TODO: should we only use the conservative answer in a recording canvas?
  1361. #if 0
  1362. SkBaseDevice* dev = this->getTopDevice();
  1363. // if no device we return true
  1364. return !dev || dev->onGetClipType() == SkBaseDevice::kEmpty_ClipType;
  1365. #endif
  1366. }
  1367. bool SkCanvas::isClipRect() const {
  1368. SkBaseDevice* dev = this->getTopDevice();
  1369. // if no device we return false
  1370. return dev && dev->onGetClipType() == SkBaseDevice::kRect_ClipType;
  1371. }
  1372. static inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) {
  1373. #if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
  1374. __m128 lLtT = _mm_unpacklo_ps(devRect.fVec, devClip.fVec);
  1375. __m128 RrBb = _mm_unpackhi_ps(devClip.fVec, devRect.fVec);
  1376. __m128 mask = _mm_cmplt_ps(lLtT, RrBb);
  1377. return 0xF != _mm_movemask_ps(mask);
  1378. #elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON)
  1379. float32x4_t lLtT = vzipq_f32(devRect.fVec, devClip.fVec).val[0];
  1380. float32x4_t RrBb = vzipq_f32(devClip.fVec, devRect.fVec).val[1];
  1381. uint32x4_t mask = vcltq_f32(lLtT, RrBb);
  1382. return 0xFFFFFFFFFFFFFFFF != (uint64_t) vmovn_u32(mask);
  1383. #else
  1384. SkRect devRectAsRect;
  1385. SkRect devClipAsRect;
  1386. devRect.store(&devRectAsRect.fLeft);
  1387. devClip.store(&devClipAsRect.fLeft);
  1388. return !devRectAsRect.isFinite() || !devRectAsRect.intersect(devClipAsRect);
  1389. #endif
  1390. }
  1391. // It's important for this function to not be inlined. Otherwise the compiler will share code
  1392. // between the fast path and the slow path, resulting in two slow paths.
  1393. static SK_NEVER_INLINE bool quick_reject_slow_path(const SkRect& src, const SkRect& deviceClip,
  1394. const SkMatrix& matrix) {
  1395. SkRect deviceRect;
  1396. matrix.mapRect(&deviceRect, src);
  1397. return !deviceRect.isFinite() || !deviceRect.intersect(deviceClip);
  1398. }
  1399. bool SkCanvas::quickReject(const SkRect& src) const {
  1400. #ifdef SK_DEBUG
  1401. // Verify that fDeviceClipBounds are set properly.
  1402. SkRect tmp = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
  1403. if (fMCRec->fRasterClip.isEmpty()) {
  1404. SkASSERT(fDeviceClipBounds.isEmpty());
  1405. } else {
  1406. SkASSERT(tmp == fDeviceClipBounds);
  1407. }
  1408. // Verify that fIsScaleTranslate is set properly.
  1409. SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate());
  1410. #endif
  1411. if (!fIsScaleTranslate) {
  1412. return quick_reject_slow_path(src, fDeviceClipBounds, fMCRec->fMatrix);
  1413. }
  1414. // We inline the implementation of mapScaleTranslate() for the fast path.
  1415. float sx = fMCRec->fMatrix.getScaleX();
  1416. float sy = fMCRec->fMatrix.getScaleY();
  1417. float tx = fMCRec->fMatrix.getTranslateX();
  1418. float ty = fMCRec->fMatrix.getTranslateY();
  1419. Sk4f scale(sx, sy, sx, sy);
  1420. Sk4f trans(tx, ty, tx, ty);
  1421. // Apply matrix.
  1422. Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans;
  1423. // Make sure left < right, top < bottom.
  1424. Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]);
  1425. Sk4f min = Sk4f::Min(ltrb, rblt);
  1426. Sk4f max = Sk4f::Max(ltrb, rblt);
  1427. // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on
  1428. // ARM this sequence generates the fastest (a single instruction).
  1429. Sk4f devRect = Sk4f(min[2], min[3], max[0], max[1]);
  1430. // Check if the device rect is NaN or outside the clip.
  1431. return is_nan_or_clipped(devRect, Sk4f::Load(&fDeviceClipBounds.fLeft));
  1432. }
  1433. bool SkCanvas::quickReject(const SkPath& path) const {
  1434. return path.isEmpty() || this->quickReject(path.getBounds());
  1435. }
  1436. SkRect SkCanvas::getLocalClipBounds() const {
  1437. SkIRect ibounds = this->getDeviceClipBounds();
  1438. if (ibounds.isEmpty()) {
  1439. return SkRect::MakeEmpty();
  1440. }
  1441. SkMatrix inverse;
  1442. // if we can't invert the CTM, we can't return local clip bounds
  1443. if (!fMCRec->fMatrix.invert(&inverse)) {
  1444. return SkRect::MakeEmpty();
  1445. }
  1446. SkRect bounds;
  1447. // adjust it outwards in case we are antialiasing
  1448. const int margin = 1;
  1449. SkRect r = SkRect::Make(ibounds.makeOutset(margin, margin));
  1450. inverse.mapRect(&bounds, r);
  1451. return bounds;
  1452. }
  1453. SkIRect SkCanvas::getDeviceClipBounds() const {
  1454. return fMCRec->fRasterClip.getBounds();
  1455. }
  1456. const SkMatrix& SkCanvas::getTotalMatrix() const {
  1457. return fMCRec->fMatrix;
  1458. }
  1459. GrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() {
  1460. SkBaseDevice* dev = this->getTopDevice();
  1461. return dev ? dev->accessRenderTargetContext() : nullptr;
  1462. }
  1463. GrContext* SkCanvas::getGrContext() {
  1464. SkBaseDevice* device = this->getTopDevice();
  1465. return device ? device->context() : nullptr;
  1466. }
  1467. void SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner,
  1468. const SkPaint& paint) {
  1469. TRACE_EVENT0("skia", TRACE_FUNC);
  1470. if (outer.isEmpty()) {
  1471. return;
  1472. }
  1473. if (inner.isEmpty()) {
  1474. this->drawRRect(outer, paint);
  1475. return;
  1476. }
  1477. // We don't have this method (yet), but technically this is what we should
  1478. // be able to return ...
  1479. // if (!outer.contains(inner))) {
  1480. //
  1481. // For now at least check for containment of bounds
  1482. if (!outer.getBounds().contains(inner.getBounds())) {
  1483. return;
  1484. }
  1485. this->onDrawDRRect(outer, inner, paint);
  1486. }
  1487. void SkCanvas::drawPaint(const SkPaint& paint) {
  1488. TRACE_EVENT0("skia", TRACE_FUNC);
  1489. this->onDrawPaint(paint);
  1490. }
  1491. void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
  1492. TRACE_EVENT0("skia", TRACE_FUNC);
  1493. // To avoid redundant logic in our culling code and various backends, we always sort rects
  1494. // before passing them along.
  1495. this->onDrawRect(r.makeSorted(), paint);
  1496. }
  1497. void SkCanvas::drawClippedToSaveBehind(const SkPaint& paint) {
  1498. TRACE_EVENT0("skia", TRACE_FUNC);
  1499. this->onDrawBehind(paint);
  1500. }
  1501. void SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
  1502. TRACE_EVENT0("skia", TRACE_FUNC);
  1503. if (region.isEmpty()) {
  1504. return;
  1505. }
  1506. if (region.isRect()) {
  1507. return this->drawIRect(region.getBounds(), paint);
  1508. }
  1509. this->onDrawRegion(region, paint);
  1510. }
  1511. void SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) {
  1512. TRACE_EVENT0("skia", TRACE_FUNC);
  1513. // To avoid redundant logic in our culling code and various backends, we always sort rects
  1514. // before passing them along.
  1515. this->onDrawOval(r.makeSorted(), paint);
  1516. }
  1517. void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
  1518. TRACE_EVENT0("skia", TRACE_FUNC);
  1519. this->onDrawRRect(rrect, paint);
  1520. }
  1521. void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) {
  1522. TRACE_EVENT0("skia", TRACE_FUNC);
  1523. this->onDrawPoints(mode, count, pts, paint);
  1524. }
  1525. void SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode,
  1526. const SkPaint& paint) {
  1527. TRACE_EVENT0("skia", TRACE_FUNC);
  1528. RETURN_ON_NULL(vertices);
  1529. // We expect fans to be converted to triangles when building or deserializing SkVertices.
  1530. SkASSERT(vertices->mode() != SkVertices::kTriangleFan_VertexMode);
  1531. this->onDrawVerticesObject(vertices.get(), nullptr, 0, mode, paint);
  1532. }
  1533. void SkCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
  1534. TRACE_EVENT0("skia", TRACE_FUNC);
  1535. RETURN_ON_NULL(vertices);
  1536. this->onDrawVerticesObject(vertices, nullptr, 0, mode, paint);
  1537. }
  1538. void SkCanvas::drawVertices(const sk_sp<SkVertices>& vertices, const SkVertices::Bone bones[],
  1539. int boneCount, SkBlendMode mode, const SkPaint& paint) {
  1540. TRACE_EVENT0("skia", TRACE_FUNC);
  1541. RETURN_ON_NULL(vertices);
  1542. SkASSERT(boneCount <= 80);
  1543. this->onDrawVerticesObject(vertices.get(), bones, boneCount, mode, paint);
  1544. }
  1545. void SkCanvas::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
  1546. int boneCount, SkBlendMode mode, const SkPaint& paint) {
  1547. TRACE_EVENT0("skia", TRACE_FUNC);
  1548. RETURN_ON_NULL(vertices);
  1549. SkASSERT(boneCount <= 80);
  1550. this->onDrawVerticesObject(vertices, bones, boneCount, mode, paint);
  1551. }
  1552. void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
  1553. TRACE_EVENT0("skia", TRACE_FUNC);
  1554. this->onDrawPath(path, paint);
  1555. }
  1556. void SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) {
  1557. TRACE_EVENT0("skia", TRACE_FUNC);
  1558. RETURN_ON_NULL(image);
  1559. this->onDrawImage(image, x, y, paint);
  1560. }
  1561. // Returns true if the rect can be "filled" : non-empty and finite
  1562. static bool fillable(const SkRect& r) {
  1563. SkScalar w = r.width();
  1564. SkScalar h = r.height();
  1565. return SkScalarIsFinite(w) && w > 0 && SkScalarIsFinite(h) && h > 0;
  1566. }
  1567. void SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
  1568. const SkPaint* paint, SrcRectConstraint constraint) {
  1569. TRACE_EVENT0("skia", TRACE_FUNC);
  1570. RETURN_ON_NULL(image);
  1571. if (!fillable(dst) || !fillable(src)) {
  1572. return;
  1573. }
  1574. this->onDrawImageRect(image, &src, dst, paint, constraint);
  1575. }
  1576. void SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
  1577. const SkPaint* paint, SrcRectConstraint constraint) {
  1578. RETURN_ON_NULL(image);
  1579. this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint);
  1580. }
  1581. void SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint) {
  1582. RETURN_ON_NULL(image);
  1583. this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint,
  1584. kFast_SrcRectConstraint);
  1585. }
  1586. namespace {
  1587. class LatticePaint : SkNoncopyable {
  1588. public:
  1589. LatticePaint(const SkPaint* origPaint) : fPaint(origPaint) {
  1590. if (!origPaint) {
  1591. return;
  1592. }
  1593. if (origPaint->getFilterQuality() > kLow_SkFilterQuality) {
  1594. fPaint.writable()->setFilterQuality(kLow_SkFilterQuality);
  1595. }
  1596. if (origPaint->getMaskFilter()) {
  1597. fPaint.writable()->setMaskFilter(nullptr);
  1598. }
  1599. if (origPaint->isAntiAlias()) {
  1600. fPaint.writable()->setAntiAlias(false);
  1601. }
  1602. }
  1603. const SkPaint* get() const {
  1604. return fPaint;
  1605. }
  1606. private:
  1607. SkTCopyOnFirstWrite<SkPaint> fPaint;
  1608. };
  1609. } // namespace
  1610. void SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
  1611. const SkPaint* paint) {
  1612. TRACE_EVENT0("skia", TRACE_FUNC);
  1613. RETURN_ON_NULL(image);
  1614. if (dst.isEmpty()) {
  1615. return;
  1616. }
  1617. if (SkLatticeIter::Valid(image->width(), image->height(), center)) {
  1618. LatticePaint latticePaint(paint);
  1619. this->onDrawImageNine(image, center, dst, latticePaint.get());
  1620. } else {
  1621. this->drawImageRect(image, dst, paint);
  1622. }
  1623. }
  1624. void SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
  1625. const SkPaint* paint) {
  1626. TRACE_EVENT0("skia", TRACE_FUNC);
  1627. RETURN_ON_NULL(image);
  1628. if (dst.isEmpty()) {
  1629. return;
  1630. }
  1631. SkIRect bounds;
  1632. Lattice latticePlusBounds = lattice;
  1633. if (!latticePlusBounds.fBounds) {
  1634. bounds = SkIRect::MakeWH(image->width(), image->height());
  1635. latticePlusBounds.fBounds = &bounds;
  1636. }
  1637. if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
  1638. LatticePaint latticePaint(paint);
  1639. this->onDrawImageLattice(image, latticePlusBounds, dst, latticePaint.get());
  1640. } else {
  1641. this->drawImageRect(image, dst, paint);
  1642. }
  1643. }
  1644. void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) {
  1645. TRACE_EVENT0("skia", TRACE_FUNC);
  1646. if (bitmap.drawsNothing()) {
  1647. return;
  1648. }
  1649. this->onDrawBitmap(bitmap, dx, dy, paint);
  1650. }
  1651. void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
  1652. const SkPaint* paint, SrcRectConstraint constraint) {
  1653. TRACE_EVENT0("skia", TRACE_FUNC);
  1654. if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) {
  1655. return;
  1656. }
  1657. this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint);
  1658. }
  1659. void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
  1660. const SkPaint* paint, SrcRectConstraint constraint) {
  1661. this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint);
  1662. }
  1663. void SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
  1664. SrcRectConstraint constraint) {
  1665. this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint,
  1666. constraint);
  1667. }
  1668. void SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
  1669. const SkPaint* paint) {
  1670. TRACE_EVENT0("skia", TRACE_FUNC);
  1671. if (bitmap.drawsNothing() || dst.isEmpty()) {
  1672. return;
  1673. }
  1674. if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) {
  1675. LatticePaint latticePaint(paint);
  1676. this->onDrawBitmapNine(bitmap, center, dst, latticePaint.get());
  1677. } else {
  1678. this->drawBitmapRect(bitmap, dst, paint);
  1679. }
  1680. }
  1681. void SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
  1682. const SkPaint* paint) {
  1683. TRACE_EVENT0("skia", TRACE_FUNC);
  1684. if (bitmap.drawsNothing() || dst.isEmpty()) {
  1685. return;
  1686. }
  1687. SkIRect bounds;
  1688. Lattice latticePlusBounds = lattice;
  1689. if (!latticePlusBounds.fBounds) {
  1690. bounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
  1691. latticePlusBounds.fBounds = &bounds;
  1692. }
  1693. if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) {
  1694. LatticePaint latticePaint(paint);
  1695. this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, latticePaint.get());
  1696. } else {
  1697. this->drawBitmapRect(bitmap, dst, paint);
  1698. }
  1699. }
  1700. void SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
  1701. const SkColor colors[], int count, SkBlendMode mode,
  1702. const SkRect* cull, const SkPaint* paint) {
  1703. TRACE_EVENT0("skia", TRACE_FUNC);
  1704. RETURN_ON_NULL(atlas);
  1705. if (count <= 0) {
  1706. return;
  1707. }
  1708. SkASSERT(atlas);
  1709. SkASSERT(tex);
  1710. this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
  1711. }
  1712. void SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) {
  1713. TRACE_EVENT0("skia", TRACE_FUNC);
  1714. if (key) {
  1715. this->onDrawAnnotation(rect, key, value);
  1716. }
  1717. }
  1718. void SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
  1719. const SkPaint* paint, SrcRectConstraint constraint) {
  1720. if (src) {
  1721. this->drawImageRect(image, *src, dst, paint, constraint);
  1722. } else {
  1723. this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()),
  1724. dst, paint, constraint);
  1725. }
  1726. }
  1727. void SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
  1728. const SkPaint* paint, SrcRectConstraint constraint) {
  1729. if (src) {
  1730. this->drawBitmapRect(bitmap, *src, dst, paint, constraint);
  1731. } else {
  1732. this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()),
  1733. dst, paint, constraint);
  1734. }
  1735. }
  1736. void SkCanvas::private_draw_shadow_rec(const SkPath& path, const SkDrawShadowRec& rec) {
  1737. TRACE_EVENT0("skia", TRACE_FUNC);
  1738. this->onDrawShadowRec(path, rec);
  1739. }
  1740. void SkCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
  1741. SkPaint paint;
  1742. const SkRect& pathBounds = path.getBounds();
  1743. LOOPER_BEGIN(paint, &pathBounds)
  1744. while (iter.next()) {
  1745. iter.fDevice->drawShadow(path, rec);
  1746. }
  1747. LOOPER_END
  1748. }
  1749. void SkCanvas::experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
  1750. QuadAAFlags aaFlags, SkColor color, SkBlendMode mode) {
  1751. TRACE_EVENT0("skia", TRACE_FUNC);
  1752. // Make sure the rect is sorted before passing it along
  1753. this->onDrawEdgeAAQuad(rect.makeSorted(), clip, aaFlags, color, mode);
  1754. }
  1755. void SkCanvas::experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt,
  1756. const SkPoint dstClips[],
  1757. const SkMatrix preViewMatrices[],
  1758. const SkPaint* paint,
  1759. SrcRectConstraint constraint) {
  1760. TRACE_EVENT0("skia", TRACE_FUNC);
  1761. this->onDrawEdgeAAImageSet(imageSet, cnt, dstClips, preViewMatrices, paint, constraint);
  1762. }
  1763. //////////////////////////////////////////////////////////////////////////////
  1764. // These are the virtual drawing methods
  1765. //////////////////////////////////////////////////////////////////////////////
  1766. void SkCanvas::onDiscard() {
  1767. if (fSurfaceBase) {
  1768. fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode);
  1769. }
  1770. }
  1771. void SkCanvas::onDrawPaint(const SkPaint& paint) {
  1772. this->internalDrawPaint(paint);
  1773. }
  1774. void SkCanvas::internalDrawPaint(const SkPaint& paint) {
  1775. LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, nullptr, false)
  1776. while (iter.next()) {
  1777. iter.fDevice->drawPaint(looper.paint());
  1778. }
  1779. LOOPER_END
  1780. }
  1781. void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
  1782. const SkPaint& paint) {
  1783. if ((long)count <= 0) {
  1784. return;
  1785. }
  1786. SkRect r;
  1787. const SkRect* bounds = nullptr;
  1788. if (paint.canComputeFastBounds()) {
  1789. // special-case 2 points (common for drawing a single line)
  1790. if (2 == count) {
  1791. r.set(pts[0], pts[1]);
  1792. } else {
  1793. r.set(pts, SkToInt(count));
  1794. }
  1795. if (!r.isFinite()) {
  1796. return;
  1797. }
  1798. SkRect storage;
  1799. if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) {
  1800. return;
  1801. }
  1802. bounds = &r;
  1803. }
  1804. SkASSERT(pts != nullptr);
  1805. LOOPER_BEGIN(paint, bounds)
  1806. while (iter.next()) {
  1807. iter.fDevice->drawPoints(mode, count, pts, looper.paint());
  1808. }
  1809. LOOPER_END
  1810. }
  1811. static bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) {
  1812. return ((intptr_t)paint.getImageFilter()
  1813. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  1814. | (intptr_t)paint.getLooper()
  1815. #endif
  1816. ) != 0;
  1817. }
  1818. void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
  1819. SkASSERT(r.isSorted());
  1820. if (paint.canComputeFastBounds()) {
  1821. SkRect storage;
  1822. if (this->quickReject(paint.computeFastBounds(r, &storage))) {
  1823. return;
  1824. }
  1825. }
  1826. if (needs_autodrawlooper(this, paint)) {
  1827. LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, &r, false)
  1828. while (iter.next()) {
  1829. iter.fDevice->drawRect(r, looper.paint());
  1830. }
  1831. LOOPER_END
  1832. } else if (!paint.nothingToDraw()) {
  1833. this->predrawNotify(&r, &paint, false);
  1834. SkDrawIter iter(this);
  1835. while (iter.next()) {
  1836. iter.fDevice->drawRect(r, paint);
  1837. }
  1838. }
  1839. }
  1840. void SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
  1841. SkRect regionRect = SkRect::Make(region.getBounds());
  1842. if (paint.canComputeFastBounds()) {
  1843. SkRect storage;
  1844. if (this->quickReject(paint.computeFastBounds(regionRect, &storage))) {
  1845. return;
  1846. }
  1847. }
  1848. LOOPER_BEGIN(paint, &regionRect)
  1849. while (iter.next()) {
  1850. iter.fDevice->drawRegion(region, looper.paint());
  1851. }
  1852. LOOPER_END
  1853. }
  1854. void SkCanvas::onDrawBehind(const SkPaint& paint) {
  1855. SkIRect bounds;
  1856. SkDeque::Iter iter(fMCStack, SkDeque::Iter::kBack_IterStart);
  1857. for (;;) {
  1858. const MCRec* rec = (const MCRec*)iter.prev();
  1859. if (!rec) {
  1860. return; // no backimages, so nothing to draw
  1861. }
  1862. if (rec->fBackImage) {
  1863. bounds = SkIRect::MakeXYWH(rec->fBackImage->fLoc.fX, rec->fBackImage->fLoc.fY,
  1864. rec->fBackImage->fImage->width(),
  1865. rec->fBackImage->fImage->height());
  1866. break;
  1867. }
  1868. }
  1869. LOOPER_BEGIN(paint, nullptr)
  1870. while (iter.next()) {
  1871. SkBaseDevice* dev = iter.fDevice;
  1872. dev->save();
  1873. // We use clipRegion because it is already defined to operate in dev-space
  1874. // (i.e. ignores the ctm). However, it is going to first translate by -origin,
  1875. // but we don't want that, so we undo that before calling in.
  1876. SkRegion rgn(bounds.makeOffset(dev->fOrigin.fX, dev->fOrigin.fY));
  1877. dev->clipRegion(rgn, SkClipOp::kIntersect);
  1878. dev->drawPaint(looper.paint());
  1879. dev->restore(fMCRec->fMatrix);
  1880. }
  1881. LOOPER_END
  1882. }
  1883. void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
  1884. SkASSERT(oval.isSorted());
  1885. if (paint.canComputeFastBounds()) {
  1886. SkRect storage;
  1887. if (this->quickReject(paint.computeFastBounds(oval, &storage))) {
  1888. return;
  1889. }
  1890. }
  1891. LOOPER_BEGIN(paint, &oval)
  1892. while (iter.next()) {
  1893. iter.fDevice->drawOval(oval, looper.paint());
  1894. }
  1895. LOOPER_END
  1896. }
  1897. void SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle,
  1898. SkScalar sweepAngle, bool useCenter,
  1899. const SkPaint& paint) {
  1900. SkASSERT(oval.isSorted());
  1901. if (paint.canComputeFastBounds()) {
  1902. SkRect storage;
  1903. // Note we're using the entire oval as the bounds.
  1904. if (this->quickReject(paint.computeFastBounds(oval, &storage))) {
  1905. return;
  1906. }
  1907. }
  1908. LOOPER_BEGIN(paint, &oval)
  1909. while (iter.next()) {
  1910. iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint());
  1911. }
  1912. LOOPER_END
  1913. }
  1914. void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
  1915. if (paint.canComputeFastBounds()) {
  1916. SkRect storage;
  1917. if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) {
  1918. return;
  1919. }
  1920. }
  1921. if (rrect.isRect()) {
  1922. // call the non-virtual version
  1923. this->SkCanvas::drawRect(rrect.getBounds(), paint);
  1924. return;
  1925. } else if (rrect.isOval()) {
  1926. // call the non-virtual version
  1927. this->SkCanvas::drawOval(rrect.getBounds(), paint);
  1928. return;
  1929. }
  1930. LOOPER_BEGIN(paint, &rrect.getBounds())
  1931. while (iter.next()) {
  1932. iter.fDevice->drawRRect(rrect, looper.paint());
  1933. }
  1934. LOOPER_END
  1935. }
  1936. void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
  1937. if (paint.canComputeFastBounds()) {
  1938. SkRect storage;
  1939. if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) {
  1940. return;
  1941. }
  1942. }
  1943. LOOPER_BEGIN(paint, &outer.getBounds())
  1944. while (iter.next()) {
  1945. iter.fDevice->drawDRRect(outer, inner, looper.paint());
  1946. }
  1947. LOOPER_END
  1948. }
  1949. void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
  1950. if (!path.isFinite()) {
  1951. return;
  1952. }
  1953. const SkRect& pathBounds = path.getBounds();
  1954. if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
  1955. SkRect storage;
  1956. if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) {
  1957. return;
  1958. }
  1959. }
  1960. if (pathBounds.width() <= 0 && pathBounds.height() <= 0) {
  1961. if (path.isInverseFillType()) {
  1962. this->internalDrawPaint(paint);
  1963. return;
  1964. }
  1965. }
  1966. LOOPER_BEGIN(paint, &pathBounds)
  1967. while (iter.next()) {
  1968. iter.fDevice->drawPath(path, looper.paint());
  1969. }
  1970. LOOPER_END
  1971. }
  1972. bool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) {
  1973. if (!paint.getImageFilter()) {
  1974. return false;
  1975. }
  1976. const SkMatrix& ctm = this->getTotalMatrix();
  1977. if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) {
  1978. return false;
  1979. }
  1980. // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds.
  1981. // Once we can filter and the filter will return a result larger than itself, we should be
  1982. // able to remove this constraint.
  1983. // skbug.com/4526
  1984. //
  1985. SkPoint pt;
  1986. ctm.mapXY(x, y, &pt);
  1987. SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h);
  1988. return ir.contains(fMCRec->fRasterClip.getBounds());
  1989. }
  1990. // Given storage for a real paint, and an optional paint parameter, clean-up the param (if non-null)
  1991. // given the drawing semantics for drawImage/bitmap (skbug.com/7804) and return it, or the original
  1992. // null.
  1993. static const SkPaint* init_image_paint(SkPaint* real, const SkPaint* paintParam) {
  1994. if (paintParam) {
  1995. *real = *paintParam;
  1996. real->setStyle(SkPaint::kFill_Style);
  1997. real->setPathEffect(nullptr);
  1998. paintParam = real;
  1999. }
  2000. return paintParam;
  2001. }
  2002. void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) {
  2003. SkPaint realPaint;
  2004. paint = init_image_paint(&realPaint, paint);
  2005. SkRect bounds = SkRect::MakeXYWH(x, y,
  2006. SkIntToScalar(image->width()), SkIntToScalar(image->height()));
  2007. if (nullptr == paint || paint->canComputeFastBounds()) {
  2008. SkRect tmp = bounds;
  2009. if (paint) {
  2010. paint->computeFastBounds(tmp, &tmp);
  2011. }
  2012. if (this->quickReject(tmp)) {
  2013. return;
  2014. }
  2015. }
  2016. // At this point we need a real paint object. If the caller passed null, then we should
  2017. // use realPaint (in its default state). If the caller did pass a paint, then we have copied
  2018. // (and modified) it in realPaint. Thus either way, "realPaint" is what we want to use.
  2019. paint = &realPaint;
  2020. sk_sp<SkSpecialImage> special;
  2021. bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(),
  2022. *paint);
  2023. if (drawAsSprite && paint->getImageFilter()) {
  2024. special = this->getDevice()->makeSpecial(image);
  2025. if (!special) {
  2026. drawAsSprite = false;
  2027. }
  2028. }
  2029. LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds)
  2030. while (iter.next()) {
  2031. const SkPaint& pnt = looper.paint();
  2032. if (special) {
  2033. SkPoint pt;
  2034. iter.fDevice->ctm().mapXY(x, y, &pt);
  2035. iter.fDevice->drawSpecial(special.get(),
  2036. SkScalarRoundToInt(pt.fX),
  2037. SkScalarRoundToInt(pt.fY), pnt,
  2038. nullptr, SkMatrix::I());
  2039. } else {
  2040. iter.fDevice->drawImageRect(
  2041. image, nullptr, SkRect::MakeXYWH(x, y, image->width(), image->height()), pnt,
  2042. kStrict_SrcRectConstraint);
  2043. }
  2044. }
  2045. LOOPER_END
  2046. }
  2047. void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
  2048. const SkPaint* paint, SrcRectConstraint constraint) {
  2049. SkPaint realPaint;
  2050. paint = init_image_paint(&realPaint, paint);
  2051. if (nullptr == paint || paint->canComputeFastBounds()) {
  2052. SkRect storage = dst;
  2053. if (paint) {
  2054. paint->computeFastBounds(dst, &storage);
  2055. }
  2056. if (this->quickReject(storage)) {
  2057. return;
  2058. }
  2059. }
  2060. paint = &realPaint;
  2061. LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, &dst, image->isOpaque())
  2062. while (iter.next()) {
  2063. iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint);
  2064. }
  2065. LOOPER_END
  2066. }
  2067. void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) {
  2068. SkDEBUGCODE(bitmap.validate();)
  2069. if (bitmap.drawsNothing()) {
  2070. return;
  2071. }
  2072. SkPaint realPaint;
  2073. init_image_paint(&realPaint, paint);
  2074. paint = &realPaint;
  2075. SkRect bounds;
  2076. bitmap.getBounds(&bounds);
  2077. bounds.offset(x, y);
  2078. bool canFastBounds = paint->canComputeFastBounds();
  2079. if (canFastBounds) {
  2080. SkRect storage;
  2081. if (this->quickReject(paint->computeFastBounds(bounds, &storage))) {
  2082. return;
  2083. }
  2084. }
  2085. sk_sp<SkSpecialImage> special;
  2086. bool drawAsSprite = canFastBounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(),
  2087. bitmap.height(), *paint);
  2088. if (drawAsSprite && paint->getImageFilter()) {
  2089. special = this->getDevice()->makeSpecial(bitmap);
  2090. if (!special) {
  2091. drawAsSprite = false;
  2092. }
  2093. }
  2094. LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds)
  2095. while (iter.next()) {
  2096. const SkPaint& pnt = looper.paint();
  2097. if (special) {
  2098. SkPoint pt;
  2099. iter.fDevice->ctm().mapXY(x, y, &pt);
  2100. iter.fDevice->drawSpecial(special.get(),
  2101. SkScalarRoundToInt(pt.fX),
  2102. SkScalarRoundToInt(pt.fY), pnt,
  2103. nullptr, SkMatrix::I());
  2104. } else {
  2105. SkRect fullImage = SkRect::MakeWH(bitmap.width(), bitmap.height());
  2106. iter.fDevice->drawBitmapRect(bitmap, &fullImage, fullImage.makeOffset(x, y), pnt,
  2107. kStrict_SrcRectConstraint);
  2108. }
  2109. }
  2110. LOOPER_END
  2111. }
  2112. // this one is non-virtual, so it can be called safely by other canvas apis
  2113. void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
  2114. const SkRect& dst, const SkPaint* paint,
  2115. SrcRectConstraint constraint) {
  2116. if (bitmap.drawsNothing() || dst.isEmpty()) {
  2117. return;
  2118. }
  2119. if (nullptr == paint || paint->canComputeFastBounds()) {
  2120. SkRect storage;
  2121. if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
  2122. return;
  2123. }
  2124. }
  2125. SkLazyPaint lazy;
  2126. if (nullptr == paint) {
  2127. paint = lazy.init();
  2128. }
  2129. LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, &dst, bitmap.isOpaque())
  2130. while (iter.next()) {
  2131. iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint);
  2132. }
  2133. LOOPER_END
  2134. }
  2135. void SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
  2136. const SkPaint* paint, SrcRectConstraint constraint) {
  2137. SkDEBUGCODE(bitmap.validate();)
  2138. this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint);
  2139. }
  2140. void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
  2141. const SkPaint* paint) {
  2142. SkPaint realPaint;
  2143. paint = init_image_paint(&realPaint, paint);
  2144. if (nullptr == paint || paint->canComputeFastBounds()) {
  2145. SkRect storage;
  2146. if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
  2147. return;
  2148. }
  2149. }
  2150. paint = &realPaint;
  2151. LOOPER_BEGIN(*paint, &dst)
  2152. while (iter.next()) {
  2153. iter.fDevice->drawImageNine(image, center, dst, looper.paint());
  2154. }
  2155. LOOPER_END
  2156. }
  2157. void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
  2158. const SkPaint* paint) {
  2159. SkDEBUGCODE(bitmap.validate();)
  2160. SkPaint realPaint;
  2161. paint = init_image_paint(&realPaint, paint);
  2162. if (nullptr == paint || paint->canComputeFastBounds()) {
  2163. SkRect storage;
  2164. if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
  2165. return;
  2166. }
  2167. }
  2168. paint = &realPaint;
  2169. LOOPER_BEGIN(*paint, &dst)
  2170. while (iter.next()) {
  2171. iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint());
  2172. }
  2173. LOOPER_END
  2174. }
  2175. void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
  2176. const SkPaint* paint) {
  2177. SkPaint realPaint;
  2178. paint = init_image_paint(&realPaint, paint);
  2179. if (nullptr == paint || paint->canComputeFastBounds()) {
  2180. SkRect storage;
  2181. if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
  2182. return;
  2183. }
  2184. }
  2185. paint = &realPaint;
  2186. LOOPER_BEGIN(*paint, &dst)
  2187. while (iter.next()) {
  2188. iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint());
  2189. }
  2190. LOOPER_END
  2191. }
  2192. void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
  2193. const SkRect& dst, const SkPaint* paint) {
  2194. SkPaint realPaint;
  2195. paint = init_image_paint(&realPaint, paint);
  2196. if (nullptr == paint || paint->canComputeFastBounds()) {
  2197. SkRect storage;
  2198. if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) {
  2199. return;
  2200. }
  2201. }
  2202. paint = &realPaint;
  2203. LOOPER_BEGIN(*paint, &dst)
  2204. while (iter.next()) {
  2205. iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint());
  2206. }
  2207. LOOPER_END
  2208. }
  2209. void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
  2210. const SkPaint& paint) {
  2211. SkRect storage;
  2212. const SkRect* bounds = nullptr;
  2213. if (paint.canComputeFastBounds()) {
  2214. storage = blob->bounds().makeOffset(x, y);
  2215. SkRect tmp;
  2216. if (this->quickReject(paint.computeFastBounds(storage, &tmp))) {
  2217. return;
  2218. }
  2219. bounds = &storage;
  2220. }
  2221. // We cannot filter in the looper as we normally do, because the paint is
  2222. // incomplete at this point (text-related attributes are embedded within blob run paints).
  2223. LOOPER_BEGIN(paint, bounds)
  2224. while (iter.next()) {
  2225. fScratchGlyphRunBuilder->drawTextBlob(looper.paint(), *blob, {x, y}, iter.fDevice);
  2226. }
  2227. LOOPER_END
  2228. }
  2229. // These call the (virtual) onDraw... method
  2230. void SkCanvas::drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding,
  2231. SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint) {
  2232. TRACE_EVENT0("skia", TRACE_FUNC);
  2233. if (byteLength) {
  2234. sk_msan_assert_initialized(text, SkTAddOffset<const void>(text, byteLength));
  2235. this->drawTextBlob(SkTextBlob::MakeFromText(text, byteLength, font, encoding), x, y, paint);
  2236. }
  2237. }
  2238. void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
  2239. const SkPaint& paint) {
  2240. TRACE_EVENT0("skia", TRACE_FUNC);
  2241. RETURN_ON_NULL(blob);
  2242. RETURN_ON_FALSE(blob->bounds().makeOffset(x, y).isFinite());
  2243. this->onDrawTextBlob(blob, x, y, paint);
  2244. }
  2245. void SkCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
  2246. int boneCount, SkBlendMode bmode, const SkPaint& paint) {
  2247. LOOPER_BEGIN(paint, nullptr)
  2248. while (iter.next()) {
  2249. // In the common case of one iteration we could std::move vertices here.
  2250. iter.fDevice->drawVertices(vertices, bones, boneCount, bmode, looper.paint());
  2251. }
  2252. LOOPER_END
  2253. }
  2254. void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
  2255. const SkPoint texCoords[4], SkBlendMode bmode,
  2256. const SkPaint& paint) {
  2257. TRACE_EVENT0("skia", TRACE_FUNC);
  2258. if (nullptr == cubics) {
  2259. return;
  2260. }
  2261. this->onDrawPatch(cubics, colors, texCoords, bmode, paint);
  2262. }
  2263. void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
  2264. const SkPoint texCoords[4], SkBlendMode bmode,
  2265. const SkPaint& paint) {
  2266. // Since a patch is always within the convex hull of the control points, we discard it when its
  2267. // bounding rectangle is completely outside the current clip.
  2268. SkRect bounds;
  2269. bounds.set(cubics, SkPatchUtils::kNumCtrlPts);
  2270. if (this->quickReject(bounds)) {
  2271. return;
  2272. }
  2273. LOOPER_BEGIN(paint, nullptr)
  2274. while (iter.next()) {
  2275. iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, paint);
  2276. }
  2277. LOOPER_END
  2278. }
  2279. void SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) {
  2280. #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
  2281. TRACE_EVENT0("skia", TRACE_FUNC);
  2282. #endif
  2283. RETURN_ON_NULL(dr);
  2284. if (x || y) {
  2285. SkMatrix matrix = SkMatrix::MakeTrans(x, y);
  2286. this->onDrawDrawable(dr, &matrix);
  2287. } else {
  2288. this->onDrawDrawable(dr, nullptr);
  2289. }
  2290. }
  2291. void SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) {
  2292. #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
  2293. TRACE_EVENT0("skia", TRACE_FUNC);
  2294. #endif
  2295. RETURN_ON_NULL(dr);
  2296. if (matrix && matrix->isIdentity()) {
  2297. matrix = nullptr;
  2298. }
  2299. this->onDrawDrawable(dr, matrix);
  2300. }
  2301. void SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) {
  2302. // drawable bounds are no longer reliable (e.g. android displaylist)
  2303. // so don't use them for quick-reject
  2304. this->getDevice()->drawDrawable(dr, matrix, this);
  2305. }
  2306. void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
  2307. const SkColor colors[], int count, SkBlendMode bmode,
  2308. const SkRect* cull, const SkPaint* paint) {
  2309. if (cull && this->quickReject(*cull)) {
  2310. return;
  2311. }
  2312. SkPaint pnt;
  2313. if (paint) {
  2314. pnt = *paint;
  2315. }
  2316. LOOPER_BEGIN(pnt, nullptr)
  2317. while (iter.next()) {
  2318. iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt);
  2319. }
  2320. LOOPER_END
  2321. }
  2322. void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
  2323. SkASSERT(key);
  2324. SkPaint paint;
  2325. LOOPER_BEGIN(paint, nullptr)
  2326. while (iter.next()) {
  2327. iter.fDevice->drawAnnotation(rect, key, value);
  2328. }
  2329. LOOPER_END
  2330. }
  2331. void SkCanvas::onDrawEdgeAAQuad(const SkRect& r, const SkPoint clip[4], QuadAAFlags edgeAA,
  2332. SkColor color, SkBlendMode mode) {
  2333. SkASSERT(r.isSorted());
  2334. // If this used a paint, it would be a filled color with blend mode, which does not
  2335. // need to use an autodraw loop, so use SkDrawIter directly.
  2336. if (this->quickReject(r)) {
  2337. return;
  2338. }
  2339. this->predrawNotify();
  2340. SkDrawIter iter(this);
  2341. while(iter.next()) {
  2342. iter.fDevice->drawEdgeAAQuad(r, clip, edgeAA, color, mode);
  2343. }
  2344. }
  2345. void SkCanvas::onDrawEdgeAAImageSet(const ImageSetEntry imageSet[], int count,
  2346. const SkPoint dstClips[], const SkMatrix preViewMatrices[],
  2347. const SkPaint* paint, SrcRectConstraint constraint) {
  2348. SkPaint realPaint;
  2349. init_image_paint(&realPaint, paint);
  2350. // Looper is used when there are image filters, which drawEdgeAAImageSet needs to support
  2351. // for Chromium's RenderPassDrawQuads' filters.
  2352. LOOPER_BEGIN(realPaint, nullptr)
  2353. while (iter.next()) {
  2354. iter.fDevice->drawEdgeAAImageSet(
  2355. imageSet, count, dstClips, preViewMatrices, looper.paint(), constraint);
  2356. }
  2357. LOOPER_END
  2358. }
  2359. //////////////////////////////////////////////////////////////////////////////
  2360. // These methods are NOT virtual, and therefore must call back into virtual
  2361. // methods, rather than actually drawing themselves.
  2362. //////////////////////////////////////////////////////////////////////////////
  2363. void SkCanvas::drawColor(SkColor c, SkBlendMode mode) {
  2364. SkPaint paint;
  2365. paint.setColor(c);
  2366. paint.setBlendMode(mode);
  2367. this->drawPaint(paint);
  2368. }
  2369. void SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) {
  2370. const SkPoint pt = { x, y };
  2371. this->drawPoints(kPoints_PointMode, 1, &pt, paint);
  2372. }
  2373. void SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint) {
  2374. SkPoint pts[2];
  2375. pts[0].set(x0, y0);
  2376. pts[1].set(x1, y1);
  2377. this->drawPoints(kLines_PointMode, 2, pts, paint);
  2378. }
  2379. void SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint) {
  2380. if (radius < 0) {
  2381. radius = 0;
  2382. }
  2383. SkRect r;
  2384. r.set(cx - radius, cy - radius, cx + radius, cy + radius);
  2385. this->drawOval(r, paint);
  2386. }
  2387. void SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry,
  2388. const SkPaint& paint) {
  2389. if (rx > 0 && ry > 0) {
  2390. SkRRect rrect;
  2391. rrect.setRectXY(r, rx, ry);
  2392. this->drawRRect(rrect, paint);
  2393. } else {
  2394. this->drawRect(r, paint);
  2395. }
  2396. }
  2397. void SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle,
  2398. SkScalar sweepAngle, bool useCenter,
  2399. const SkPaint& paint) {
  2400. TRACE_EVENT0("skia", TRACE_FUNC);
  2401. if (oval.isEmpty() || !sweepAngle) {
  2402. return;
  2403. }
  2404. this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint);
  2405. }
  2406. ///////////////////////////////////////////////////////////////////////////////
  2407. #ifdef SK_DISABLE_SKPICTURE
  2408. void SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) {}
  2409. void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
  2410. const SkPaint* paint) {}
  2411. #else
  2412. /**
  2413. * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture,
  2414. * against the playback cost of recursing into the subpicture to get at its actual ops.
  2415. *
  2416. * For now we pick a conservatively small value, though measurement (and other heuristics like
  2417. * the type of ops contained) may justify changing this value.
  2418. */
  2419. #define kMaxPictureOpsToUnrollInsteadOfRef 1
  2420. void SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) {
  2421. TRACE_EVENT0("skia", TRACE_FUNC);
  2422. RETURN_ON_NULL(picture);
  2423. if (matrix && matrix->isIdentity()) {
  2424. matrix = nullptr;
  2425. }
  2426. if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) {
  2427. SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
  2428. picture->playback(this);
  2429. } else {
  2430. this->onDrawPicture(picture, matrix, paint);
  2431. }
  2432. }
  2433. void SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
  2434. const SkPaint* paint) {
  2435. if (!paint || paint->canComputeFastBounds()) {
  2436. SkRect bounds = picture->cullRect();
  2437. if (paint) {
  2438. paint->computeFastBounds(bounds, &bounds);
  2439. }
  2440. if (matrix) {
  2441. matrix->mapRect(&bounds);
  2442. }
  2443. if (this->quickReject(bounds)) {
  2444. return;
  2445. }
  2446. }
  2447. SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
  2448. picture->playback(this);
  2449. }
  2450. #endif
  2451. ///////////////////////////////////////////////////////////////////////////////
  2452. ///////////////////////////////////////////////////////////////////////////////
  2453. SkCanvas::LayerIter::LayerIter(SkCanvas* canvas) {
  2454. static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small");
  2455. SkASSERT(canvas);
  2456. fImpl = new (fStorage) SkDrawIter(canvas);
  2457. fDone = !fImpl->next();
  2458. }
  2459. SkCanvas::LayerIter::~LayerIter() {
  2460. fImpl->~SkDrawIter();
  2461. }
  2462. void SkCanvas::LayerIter::next() {
  2463. fDone = !fImpl->next();
  2464. }
  2465. SkBaseDevice* SkCanvas::LayerIter::device() const {
  2466. return fImpl->fDevice;
  2467. }
  2468. const SkMatrix& SkCanvas::LayerIter::matrix() const {
  2469. return fImpl->fDevice->ctm();
  2470. }
  2471. const SkPaint& SkCanvas::LayerIter::paint() const {
  2472. const SkPaint* paint = fImpl->getPaint();
  2473. if (nullptr == paint) {
  2474. paint = &fDefaultPaint;
  2475. }
  2476. return *paint;
  2477. }
  2478. SkIRect SkCanvas::LayerIter::clipBounds() const {
  2479. return fImpl->fDevice->getGlobalBounds();
  2480. }
  2481. int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
  2482. int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
  2483. ///////////////////////////////////////////////////////////////////////////////
  2484. SkCanvas::ImageSetEntry::ImageSetEntry() = default;
  2485. SkCanvas::ImageSetEntry::~ImageSetEntry() = default;
  2486. SkCanvas::ImageSetEntry::ImageSetEntry(const ImageSetEntry&) = default;
  2487. SkCanvas::ImageSetEntry& SkCanvas::ImageSetEntry::operator=(const ImageSetEntry&) = default;
  2488. SkCanvas::ImageSetEntry::ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect,
  2489. const SkRect& dstRect, int matrixIndex, float alpha,
  2490. unsigned aaFlags, bool hasClip)
  2491. : fImage(std::move(image))
  2492. , fSrcRect(srcRect)
  2493. , fDstRect(dstRect)
  2494. , fMatrixIndex(matrixIndex)
  2495. , fAlpha(alpha)
  2496. , fAAFlags(aaFlags)
  2497. , fHasClip(hasClip) {}
  2498. SkCanvas::ImageSetEntry::ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect,
  2499. const SkRect& dstRect, float alpha, unsigned aaFlags)
  2500. : fImage(std::move(image))
  2501. , fSrcRect(srcRect)
  2502. , fDstRect(dstRect)
  2503. , fAlpha(alpha)
  2504. , fAAFlags(aaFlags) {}
  2505. ///////////////////////////////////////////////////////////////////////////////
  2506. std::unique_ptr<SkCanvas> SkCanvas::MakeRasterDirect(const SkImageInfo& info, void* pixels,
  2507. size_t rowBytes, const SkSurfaceProps* props) {
  2508. if (!SkSurfaceValidateRasterInfo(info, rowBytes)) {
  2509. return nullptr;
  2510. }
  2511. SkBitmap bitmap;
  2512. if (!bitmap.installPixels(info, pixels, rowBytes)) {
  2513. return nullptr;
  2514. }
  2515. return props ?
  2516. skstd::make_unique<SkCanvas>(bitmap, *props) :
  2517. skstd::make_unique<SkCanvas>(bitmap);
  2518. }
  2519. ///////////////////////////////////////////////////////////////////////////////
  2520. SkNoDrawCanvas::SkNoDrawCanvas(int width, int height)
  2521. : INHERITED(SkIRect::MakeWH(width, height)) {}
  2522. SkNoDrawCanvas::SkNoDrawCanvas(const SkIRect& bounds)
  2523. : INHERITED(bounds) {}
  2524. SkNoDrawCanvas::SkNoDrawCanvas(sk_sp<SkBaseDevice> device)
  2525. : INHERITED(device) {}
  2526. SkCanvas::SaveLayerStrategy SkNoDrawCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
  2527. (void)this->INHERITED::getSaveLayerStrategy(rec);
  2528. return kNoLayer_SaveLayerStrategy;
  2529. }
  2530. bool SkNoDrawCanvas::onDoSaveBehind(const SkRect*) {
  2531. return false;
  2532. }
  2533. ///////////////////////////////////////////////////////////////////////////////
  2534. static_assert((int)SkRegion::kDifference_Op == (int)kDifference_SkClipOp, "");
  2535. static_assert((int)SkRegion::kIntersect_Op == (int)kIntersect_SkClipOp, "");
  2536. static_assert((int)SkRegion::kUnion_Op == (int)kUnion_SkClipOp, "");
  2537. static_assert((int)SkRegion::kXOR_Op == (int)kXOR_SkClipOp, "");
  2538. static_assert((int)SkRegion::kReverseDifference_Op == (int)kReverseDifference_SkClipOp, "");
  2539. static_assert((int)SkRegion::kReplace_Op == (int)kReplace_SkClipOp, "");
  2540. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2541. SkRasterHandleAllocator::Handle SkCanvas::accessTopRasterHandle() const {
  2542. if (fAllocator && fMCRec->fTopLayer->fDevice) {
  2543. const auto& dev = fMCRec->fTopLayer->fDevice;
  2544. SkRasterHandleAllocator::Handle handle = dev->getRasterHandle();
  2545. SkIPoint origin = dev->getOrigin();
  2546. SkMatrix ctm = this->getTotalMatrix();
  2547. ctm.preTranslate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y()));
  2548. SkIRect clip = fMCRec->fRasterClip.getBounds();
  2549. clip.offset(-origin.x(), -origin.y());
  2550. if (!clip.intersect(0, 0, dev->width(), dev->height())) {
  2551. clip.setEmpty();
  2552. }
  2553. fAllocator->updateHandle(handle, ctm, clip);
  2554. return handle;
  2555. }
  2556. return nullptr;
  2557. }
  2558. static bool install(SkBitmap* bm, const SkImageInfo& info,
  2559. const SkRasterHandleAllocator::Rec& rec) {
  2560. return bm->installPixels(info, rec.fPixels, rec.fRowBytes, rec.fReleaseProc, rec.fReleaseCtx);
  2561. }
  2562. SkRasterHandleAllocator::Handle SkRasterHandleAllocator::allocBitmap(const SkImageInfo& info,
  2563. SkBitmap* bm) {
  2564. SkRasterHandleAllocator::Rec rec;
  2565. if (!this->allocHandle(info, &rec) || !install(bm, info, rec)) {
  2566. return nullptr;
  2567. }
  2568. return rec.fHandle;
  2569. }
  2570. std::unique_ptr<SkCanvas>
  2571. SkRasterHandleAllocator::MakeCanvas(std::unique_ptr<SkRasterHandleAllocator> alloc,
  2572. const SkImageInfo& info, const Rec* rec) {
  2573. if (!alloc || !SkSurfaceValidateRasterInfo(info, rec ? rec->fRowBytes : kIgnoreRowBytesValue)) {
  2574. return nullptr;
  2575. }
  2576. SkBitmap bm;
  2577. Handle hndl;
  2578. if (rec) {
  2579. hndl = install(&bm, info, *rec) ? rec->fHandle : nullptr;
  2580. } else {
  2581. hndl = alloc->allocBitmap(info, &bm);
  2582. }
  2583. return hndl ? std::unique_ptr<SkCanvas>(new SkCanvas(bm, std::move(alloc), hndl)) : nullptr;
  2584. }
  2585. ///////////////////////////////////////////////////////////////////////////////////////////////////