GrRenderTargetContext.cpp 111 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507
  1. /*
  2. * Copyright 2015 Google Inc.
  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 "src/gpu/GrRenderTargetContext.h"
  8. #include "include/core/SkDrawable.h"
  9. #include "include/gpu/GrBackendSemaphore.h"
  10. #include "include/gpu/GrRenderTarget.h"
  11. #include "include/private/GrRecordingContext.h"
  12. #include "include/private/SkShadowFlags.h"
  13. #include "include/utils/SkShadowUtils.h"
  14. #include "src/core/SkAutoPixmapStorage.h"
  15. #include "src/core/SkConvertPixels.h"
  16. #include "src/core/SkDrawShadowInfo.h"
  17. #include "src/core/SkGlyphRunPainter.h"
  18. #include "src/core/SkLatticeIter.h"
  19. #include "src/core/SkMatrixPriv.h"
  20. #include "src/core/SkRRectPriv.h"
  21. #include "src/core/SkSurfacePriv.h"
  22. #include "src/gpu/GrAppliedClip.h"
  23. #include "src/gpu/GrAuditTrail.h"
  24. #include "src/gpu/GrBlurUtils.h"
  25. #include "src/gpu/GrCaps.h"
  26. #include "src/gpu/GrColor.h"
  27. #include "src/gpu/GrContextPriv.h"
  28. #include "src/gpu/GrDataUtils.h"
  29. #include "src/gpu/GrDrawingManager.h"
  30. #include "src/gpu/GrFixedClip.h"
  31. #include "src/gpu/GrGpuResourcePriv.h"
  32. #include "src/gpu/GrMemoryPool.h"
  33. #include "src/gpu/GrOpList.h"
  34. #include "src/gpu/GrPathRenderer.h"
  35. #include "src/gpu/GrRecordingContextPriv.h"
  36. #include "src/gpu/GrRenderTargetContextPriv.h"
  37. #include "src/gpu/GrResourceProvider.h"
  38. #include "src/gpu/GrStencilAttachment.h"
  39. #include "src/gpu/GrStyle.h"
  40. #include "src/gpu/GrTracing.h"
  41. #include "src/gpu/SkGr.h"
  42. #include "src/gpu/effects/GrBicubicEffect.h"
  43. #include "src/gpu/effects/GrRRectEffect.h"
  44. #include "src/gpu/effects/GrTextureDomain.h"
  45. #include "src/gpu/effects/generated/GrColorMatrixFragmentProcessor.h"
  46. #include "src/gpu/geometry/GrQuad.h"
  47. #include "src/gpu/geometry/GrQuadUtils.h"
  48. #include "src/gpu/geometry/GrShape.h"
  49. #include "src/gpu/ops/GrAtlasTextOp.h"
  50. #include "src/gpu/ops/GrClearOp.h"
  51. #include "src/gpu/ops/GrClearStencilClipOp.h"
  52. #include "src/gpu/ops/GrDebugMarkerOp.h"
  53. #include "src/gpu/ops/GrDrawAtlasOp.h"
  54. #include "src/gpu/ops/GrDrawOp.h"
  55. #include "src/gpu/ops/GrDrawVerticesOp.h"
  56. #include "src/gpu/ops/GrDrawableOp.h"
  57. #include "src/gpu/ops/GrFillRRectOp.h"
  58. #include "src/gpu/ops/GrFillRectOp.h"
  59. #include "src/gpu/ops/GrLatticeOp.h"
  60. #include "src/gpu/ops/GrOp.h"
  61. #include "src/gpu/ops/GrOvalOpFactory.h"
  62. #include "src/gpu/ops/GrRegionOp.h"
  63. #include "src/gpu/ops/GrSemaphoreOp.h"
  64. #include "src/gpu/ops/GrShadowRRectOp.h"
  65. #include "src/gpu/ops/GrStencilPathOp.h"
  66. #include "src/gpu/ops/GrStrokeRectOp.h"
  67. #include "src/gpu/ops/GrTextureOp.h"
  68. #include "src/gpu/ops/GrTransferFromOp.h"
  69. #include "src/gpu/text/GrTextContext.h"
  70. #include "src/gpu/text/GrTextTarget.h"
  71. class GrRenderTargetContext::TextTarget : public GrTextTarget {
  72. public:
  73. TextTarget(GrRenderTargetContext* renderTargetContext)
  74. : GrTextTarget(renderTargetContext->width(), renderTargetContext->height(),
  75. renderTargetContext->colorSpaceInfo())
  76. , fRenderTargetContext(renderTargetContext)
  77. , fGlyphPainter{*renderTargetContext}{}
  78. void addDrawOp(const GrClip& clip, std::unique_ptr<GrAtlasTextOp> op) override {
  79. fRenderTargetContext->addDrawOp(clip, std::move(op));
  80. }
  81. void drawShape(const GrClip& clip, const SkPaint& paint,
  82. const SkMatrix& viewMatrix, const GrShape& shape) override {
  83. GrBlurUtils::drawShapeWithMaskFilter(fRenderTargetContext->fContext, fRenderTargetContext,
  84. clip, paint, viewMatrix, shape);
  85. }
  86. void makeGrPaint(GrMaskFormat maskFormat, const SkPaint& skPaint, const SkMatrix& viewMatrix,
  87. GrPaint* grPaint) override {
  88. auto context = fRenderTargetContext->fContext;
  89. const GrColorSpaceInfo& colorSpaceInfo = fRenderTargetContext->colorSpaceInfo();
  90. if (kARGB_GrMaskFormat == maskFormat) {
  91. SkPaintToGrPaintWithPrimitiveColor(context, colorSpaceInfo, skPaint, grPaint);
  92. } else {
  93. SkPaintToGrPaint(context, colorSpaceInfo, skPaint, viewMatrix, grPaint);
  94. }
  95. }
  96. GrRecordingContext* getContext() override {
  97. return fRenderTargetContext->fContext;
  98. }
  99. SkGlyphRunListPainter* glyphPainter() override {
  100. return &fGlyphPainter;
  101. }
  102. private:
  103. GrRenderTargetContext* fRenderTargetContext;
  104. SkGlyphRunListPainter fGlyphPainter;
  105. };
  106. #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this->drawingManager()->getContext())
  107. #define ASSERT_SINGLE_OWNER \
  108. SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
  109. #define ASSERT_SINGLE_OWNER_PRIV \
  110. SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)
  111. #define RETURN_IF_ABANDONED if (fContext->priv().abandoned()) { return; }
  112. #define RETURN_IF_ABANDONED_PRIV if (fRenderTargetContext->fContext->priv().abandoned()) { return; }
  113. #define RETURN_FALSE_IF_ABANDONED if (fContext->priv().abandoned()) { return false; }
  114. #define RETURN_FALSE_IF_ABANDONED_PRIV if (fRenderTargetContext->fContext->priv().abandoned()) { return false; }
  115. #define RETURN_NULL_IF_ABANDONED if (fContext->priv().abandoned()) { return nullptr; }
  116. //////////////////////////////////////////////////////////////////////////////
  117. class AutoCheckFlush {
  118. public:
  119. AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
  120. SkASSERT(fDrawingManager);
  121. }
  122. ~AutoCheckFlush() { fDrawingManager->flushIfNecessary(); }
  123. private:
  124. GrDrawingManager* fDrawingManager;
  125. };
  126. // In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
  127. // GrOpLists to be picked up and added to by renderTargetContexts lower in the call
  128. // stack. When this occurs with a closed GrOpList, a new one will be allocated
  129. // when the renderTargetContext attempts to use it (via getOpList).
  130. GrRenderTargetContext::GrRenderTargetContext(GrRecordingContext* context,
  131. sk_sp<GrRenderTargetProxy> rtp,
  132. GrColorType colorType,
  133. sk_sp<SkColorSpace> colorSpace,
  134. const SkSurfaceProps* surfaceProps,
  135. bool managedOpList)
  136. : GrSurfaceContext(context, colorType, kPremul_SkAlphaType, std::move(colorSpace))
  137. , fRenderTargetProxy(std::move(rtp))
  138. , fOpList(sk_ref_sp(fRenderTargetProxy->getLastRenderTargetOpList()))
  139. , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
  140. , fManagedOpList(managedOpList) {
  141. fTextTarget.reset(new TextTarget(this));
  142. SkDEBUGCODE(this->validate();)
  143. }
  144. #ifdef SK_DEBUG
  145. void GrRenderTargetContext::validate() const {
  146. SkASSERT(fRenderTargetProxy);
  147. fRenderTargetProxy->validate(fContext);
  148. if (fOpList && !fOpList->isClosed()) {
  149. SkASSERT(fRenderTargetProxy->getLastOpList() == fOpList.get());
  150. }
  151. }
  152. #endif
  153. GrRenderTargetContext::~GrRenderTargetContext() {
  154. ASSERT_SINGLE_OWNER
  155. }
  156. inline GrAAType GrRenderTargetContext::chooseAAType(GrAA aa) {
  157. if (GrAA::kNo == aa) {
  158. // On some devices we cannot disable MSAA if it is enabled so we make the AA type reflect
  159. // that.
  160. if (this->numSamples() > 1 && !this->caps()->multisampleDisableSupport()) {
  161. return GrAAType::kMSAA;
  162. }
  163. return GrAAType::kNone;
  164. }
  165. return (this->numSamples() > 1) ? GrAAType::kMSAA : GrAAType::kCoverage;
  166. }
  167. GrTextureProxy* GrRenderTargetContext::asTextureProxy() {
  168. return fRenderTargetProxy->asTextureProxy();
  169. }
  170. const GrTextureProxy* GrRenderTargetContext::asTextureProxy() const {
  171. return fRenderTargetProxy->asTextureProxy();
  172. }
  173. sk_sp<GrTextureProxy> GrRenderTargetContext::asTextureProxyRef() {
  174. return sk_ref_sp(fRenderTargetProxy->asTextureProxy());
  175. }
  176. GrMipMapped GrRenderTargetContext::mipMapped() const {
  177. if (const GrTextureProxy* proxy = this->asTextureProxy()) {
  178. return proxy->mipMapped();
  179. }
  180. return GrMipMapped::kNo;
  181. }
  182. GrRenderTargetOpList* GrRenderTargetContext::getRTOpList() {
  183. ASSERT_SINGLE_OWNER
  184. SkDEBUGCODE(this->validate();)
  185. if (!fOpList || fOpList->isClosed()) {
  186. fOpList = this->drawingManager()->newRTOpList(fRenderTargetProxy, fManagedOpList);
  187. }
  188. return fOpList.get();
  189. }
  190. GrOpList* GrRenderTargetContext::getOpList() {
  191. return this->getRTOpList();
  192. }
  193. void GrRenderTargetContext::drawGlyphRunList(
  194. const GrClip& clip, const SkMatrix& viewMatrix,
  195. const SkGlyphRunList& blob) {
  196. ASSERT_SINGLE_OWNER
  197. RETURN_IF_ABANDONED
  198. SkDEBUGCODE(this->validate();)
  199. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawGlyphRunList", fContext);
  200. // Drawing text can cause us to do inline uploads. This is not supported for wrapped vulkan
  201. // secondary command buffers because it would require stopping and starting a render pass which
  202. // we don't have access to.
  203. if (this->wrapsVkSecondaryCB()) {
  204. return;
  205. }
  206. GrTextContext* atlasTextContext = this->drawingManager()->getTextContext();
  207. atlasTextContext->drawGlyphRunList(fContext, fTextTarget.get(), clip, viewMatrix,
  208. fSurfaceProps, blob);
  209. }
  210. void GrRenderTargetContext::discard() {
  211. ASSERT_SINGLE_OWNER
  212. RETURN_IF_ABANDONED
  213. SkDEBUGCODE(this->validate();)
  214. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "discard", fContext);
  215. AutoCheckFlush acf(this->drawingManager());
  216. this->getRTOpList()->discard();
  217. }
  218. void GrRenderTargetContext::clear(const SkIRect* rect,
  219. const SkPMColor4f& color,
  220. CanClearFullscreen canClearFullscreen) {
  221. ASSERT_SINGLE_OWNER
  222. RETURN_IF_ABANDONED
  223. SkDEBUGCODE(this->validate();)
  224. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "clear", fContext);
  225. AutoCheckFlush acf(this->drawingManager());
  226. this->internalClear(rect ? GrFixedClip(*rect) : GrFixedClip::Disabled(), color,
  227. canClearFullscreen);
  228. }
  229. void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
  230. const SkPMColor4f& color,
  231. CanClearFullscreen canClearFullscreen) {
  232. ASSERT_SINGLE_OWNER_PRIV
  233. RETURN_IF_ABANDONED_PRIV
  234. SkDEBUGCODE(fRenderTargetContext->validate();)
  235. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "clear",
  236. fRenderTargetContext->fContext);
  237. AutoCheckFlush acf(fRenderTargetContext->drawingManager());
  238. fRenderTargetContext->internalClear(clip, color, canClearFullscreen);
  239. }
  240. static void clear_to_grpaint(const SkPMColor4f& color, GrPaint* paint) {
  241. paint->setColor4f(color);
  242. if (color.isOpaque()) {
  243. // Can just rely on the src-over blend mode to do the right thing
  244. paint->setPorterDuffXPFactory(SkBlendMode::kSrcOver);
  245. } else {
  246. // A clear overwrites the prior color, so even if it's transparent, it behaves as if it
  247. // were src blended
  248. paint->setPorterDuffXPFactory(SkBlendMode::kSrc);
  249. }
  250. }
  251. void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
  252. const SkPMColor4f& color,
  253. CanClearFullscreen canClearFullscreen) {
  254. bool isFull = false;
  255. if (!clip.hasWindowRectangles()) {
  256. // TODO: wrt the shouldInitializeTextures path, it would be more performant to
  257. // only clear the entire target if we knew it had not been cleared before. As
  258. // is this could end up doing a lot of redundant clears.
  259. isFull = !clip.scissorEnabled() ||
  260. (CanClearFullscreen::kYes == canClearFullscreen &&
  261. (this->caps()->preferFullscreenClears() || this->caps()->shouldInitializeTextures())) ||
  262. clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
  263. }
  264. if (isFull) {
  265. GrRenderTargetOpList* opList = this->getRTOpList();
  266. if (opList->resetForFullscreenClear(this->canDiscardPreviousOpsOnFullClear()) &&
  267. !this->caps()->performColorClearsAsDraws()) {
  268. // The op list was emptied and native clears are allowed, so just use the load op
  269. opList->setColorLoadOp(GrLoadOp::kClear, color);
  270. return;
  271. } else {
  272. // Will use an op for the clear, reset the load op to discard since the op will
  273. // blow away the color buffer contents
  274. opList->setColorLoadOp(GrLoadOp::kDiscard);
  275. }
  276. // Must add an op to the list (either because we couldn't use a load op, or because the
  277. // clear load op isn't supported)
  278. if (this->caps()->performColorClearsAsDraws()) {
  279. SkRect rtRect = SkRect::MakeWH(this->width(), this->height());
  280. GrPaint paint;
  281. clear_to_grpaint(color, &paint);
  282. this->addDrawOp(GrFixedClip::Disabled(),
  283. GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
  284. rtRect));
  285. } else {
  286. opList->addOp(GrClearOp::Make(fContext, SkIRect::MakeEmpty(), color,
  287. /* fullscreen */ true), *this->caps());
  288. }
  289. } else {
  290. if (this->caps()->performPartialClearsAsDraws()) {
  291. // performPartialClearsAsDraws() also returns true if any clear has to be a draw.
  292. GrPaint paint;
  293. clear_to_grpaint(color, &paint);
  294. this->addDrawOp(clip,
  295. GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
  296. SkRect::Make(clip.scissorRect())));
  297. } else {
  298. std::unique_ptr<GrOp> op(GrClearOp::Make(fContext, clip, color,
  299. this->asSurfaceProxy()));
  300. // This version of the clear op factory can return null if the clip doesn't intersect
  301. // with the surface proxy's boundary
  302. if (!op) {
  303. return;
  304. }
  305. this->getRTOpList()->addOp(std::move(op), *this->caps());
  306. }
  307. }
  308. }
  309. void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const SkPMColor4f& color) {
  310. ASSERT_SINGLE_OWNER_PRIV
  311. RETURN_IF_ABANDONED_PRIV
  312. SkDEBUGCODE(fRenderTargetContext->validate();)
  313. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "absClear",
  314. fRenderTargetContext->fContext);
  315. AutoCheckFlush acf(fRenderTargetContext->drawingManager());
  316. SkIRect rtRect = SkIRect::MakeWH(fRenderTargetContext->fRenderTargetProxy->worstCaseWidth(),
  317. fRenderTargetContext->fRenderTargetProxy->worstCaseHeight());
  318. if (clearRect) {
  319. if (clearRect->contains(rtRect)) {
  320. clearRect = nullptr; // full screen
  321. } else {
  322. if (!rtRect.intersect(*clearRect)) {
  323. return;
  324. }
  325. }
  326. }
  327. // TODO: in a post-MDB world this should be handled at the OpList level.
  328. // This makes sure to always add an op to the list, instead of marking the clear as a load op.
  329. // This code follows very similar logic to internalClear() below, but critical differences are
  330. // highlighted in line related to absClear()'s unique behavior.
  331. if (clearRect) {
  332. if (fRenderTargetContext->caps()->performPartialClearsAsDraws()) {
  333. GrPaint paint;
  334. clear_to_grpaint(color, &paint);
  335. // Use the disabled clip; the rect geometry already matches the clear rectangle and
  336. // if it were added to a scissor, that would be intersected with the logical surface
  337. // bounds and not the worst case dimensions required here.
  338. fRenderTargetContext->addDrawOp(
  339. GrFixedClip::Disabled(),
  340. GrFillRectOp::MakeNonAARect(fRenderTargetContext->fContext, std::move(paint),
  341. SkMatrix::I(), SkRect::Make(rtRect)));
  342. } else {
  343. // Must use the ClearOp factory that takes a boolean (false) instead of a surface
  344. // proxy. The surface proxy variant would intersect the clip rect with its logical
  345. // bounds, which is not desired in this special case.
  346. fRenderTargetContext->getRTOpList()->addOp(
  347. GrClearOp::Make(fRenderTargetContext->fContext, rtRect, color,
  348. /* fullscreen */ false),
  349. *fRenderTargetContext->caps());
  350. }
  351. } else {
  352. // Reset the oplist like in internalClear(), but do not rely on a load op for the clear
  353. fRenderTargetContext->getRTOpList()->resetForFullscreenClear(
  354. fRenderTargetContext->canDiscardPreviousOpsOnFullClear());
  355. fRenderTargetContext->getRTOpList()->setColorLoadOp(GrLoadOp::kDiscard);
  356. if (fRenderTargetContext->caps()->performColorClearsAsDraws()) {
  357. // This draws a quad covering the worst case dimensions instead of just the logical
  358. // width and height like in internalClear().
  359. GrPaint paint;
  360. clear_to_grpaint(color, &paint);
  361. fRenderTargetContext->addDrawOp(
  362. GrFixedClip::Disabled(),
  363. GrFillRectOp::MakeNonAARect(fRenderTargetContext->fContext, std::move(paint),
  364. SkMatrix::I(), SkRect::Make(rtRect)));
  365. } else {
  366. // Nothing special about this path in absClear compared to internalClear()
  367. fRenderTargetContext->getRTOpList()->addOp(
  368. GrClearOp::Make(fRenderTargetContext->fContext, SkIRect::MakeEmpty(), color,
  369. /* fullscreen */ true),
  370. *fRenderTargetContext->caps());
  371. }
  372. }
  373. }
  374. void GrRenderTargetContext::drawPaint(const GrClip& clip,
  375. GrPaint&& paint,
  376. const SkMatrix& viewMatrix) {
  377. // Start with the render target, since that is the maximum content we could possibly fill.
  378. // drawFilledQuad() will automatically restrict it to clip bounds for us if possible.
  379. SkRect r = fRenderTargetProxy->getBoundsRect();
  380. if (!paint.numTotalFragmentProcessors()) {
  381. // The paint is trivial so we won't need to use local coordinates, so skip calculating the
  382. // inverse view matrix.
  383. this->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), r, r);
  384. } else {
  385. // Use the inverse view matrix to arrive at appropriate local coordinates for the paint.
  386. SkMatrix localMatrix;
  387. if (!viewMatrix.invert(&localMatrix)) {
  388. return;
  389. }
  390. this->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), r,
  391. localMatrix);
  392. }
  393. }
  394. enum class GrRenderTargetContext::QuadOptimization {
  395. // The rect to draw doesn't intersect clip or render target, so no draw op should be added
  396. kDiscarded,
  397. // The rect to draw was converted to some other op and appended to the oplist, so no additional
  398. // op is necessary. Currently this can convert it to a clear op or a rrect op. Only valid if
  399. // a constColor is provided.
  400. kSubmitted,
  401. // The clip was folded into the device quad, with updated edge flags and local coords, and
  402. // caller is responsible for adding an appropriate op.
  403. kClipApplied,
  404. // No change to clip, but quad updated to better fit clip/render target, and caller is
  405. // responsible for adding an appropriate op.
  406. kCropped
  407. };
  408. static bool make_vertex_finite(float* value) {
  409. if (SkScalarIsNaN(*value)) {
  410. return false;
  411. }
  412. if (!SkScalarIsFinite(*value)) {
  413. // +/- infinity at this point. Don't use exactly SK_ScalarMax so that we have some precision
  414. // left when calculating crops.
  415. static constexpr float kNearInfinity = SK_ScalarMax / 4.f;
  416. *value = *value < 0.f ? -kNearInfinity : kNearInfinity;
  417. }
  418. return true;
  419. }
  420. GrRenderTargetContext::QuadOptimization GrRenderTargetContext::attemptQuadOptimization(
  421. const GrClip& clip, const SkPMColor4f* constColor,
  422. const GrUserStencilSettings* stencilSettings, GrAA* aa, GrQuadAAFlags* edgeFlags,
  423. GrQuad* deviceQuad, GrQuad* localQuad) {
  424. // Optimization requirements:
  425. // 1. kDiscard applies when clip bounds and quad bounds do not intersect
  426. // 2. kClear applies when constColor and final geom is pixel aligned rect;
  427. // pixel aligned rect requires rect clip and (rect quad or quad covers clip)
  428. // 3. kRRect applies when constColor and rrect clip and quad covers clip
  429. // 4. kExplicitClip applies when rect clip and (rect quad or quad covers clip)
  430. // 5. kCropped applies when rect quad (currently)
  431. // 6. kNone always applies
  432. GrQuadAAFlags newFlags = *edgeFlags;
  433. SkRect rtRect;
  434. if (stencilSettings) {
  435. // Must use worst case bounds so that stencil buffer updates on approximately sized render
  436. // targets don't get corrupted.
  437. rtRect = SkRect::MakeWH(fRenderTargetProxy->worstCaseWidth(),
  438. fRenderTargetProxy->worstCaseHeight());
  439. } else {
  440. // Use the logical size of the render target, which allows for "fullscreen" clears even if
  441. // the render target has an approximate backing fit
  442. rtRect = SkRect::MakeWH(this->width(), this->height());
  443. }
  444. SkRect drawBounds = deviceQuad->bounds();
  445. if (constColor) {
  446. // Don't bother updating local coordinates when the paint will ignore them anyways
  447. localQuad = nullptr;
  448. // If the device quad is not finite, coerce into a finite quad. This is acceptable since it
  449. // will be cropped to the finite 'clip' or render target and there is no local space mapping
  450. if (!deviceQuad->isFinite()) {
  451. for (int i = 0; i < 4; ++i) {
  452. if (!make_vertex_finite(deviceQuad->xs() + i) ||
  453. !make_vertex_finite(deviceQuad->ys() + i) ||
  454. !make_vertex_finite(deviceQuad->ws() + i)) {
  455. // Discard if we see a nan
  456. return QuadOptimization::kDiscarded;
  457. }
  458. }
  459. SkASSERT(deviceQuad->isFinite());
  460. }
  461. } else {
  462. // CropToRect requires the quads to be finite. If they are not finite and we have local
  463. // coordinates, the mapping from local space to device space is poorly defined so drop it
  464. if (!deviceQuad->isFinite()) {
  465. return QuadOptimization::kDiscarded;
  466. }
  467. }
  468. // If the quad is entirely off screen, it doesn't matter what the clip does
  469. if (!rtRect.intersects(drawBounds)) {
  470. return QuadOptimization::kDiscarded;
  471. }
  472. // Check if clip can be represented as a rounded rect (initialize as if clip fully contained
  473. // the render target).
  474. SkRRect clipRRect = SkRRect::MakeRect(rtRect);
  475. // We initialize clipAA to *aa when there are stencil settings so that we don't artificially
  476. // encounter mixed-aa edges (not allowed for stencil), but we want to start as non-AA for
  477. // regular draws so that if we fully cover the render target, that can stop being anti-aliased.
  478. GrAA clipAA = stencilSettings ? *aa : GrAA::kNo;
  479. bool axisAlignedClip = true;
  480. if (!clip.quickContains(rtRect)) {
  481. if (!clip.isRRect(rtRect, &clipRRect, &clipAA)) {
  482. axisAlignedClip = false;
  483. }
  484. }
  485. // If the clip rrect is valid (i.e. axis-aligned), we can potentially combine it with the
  486. // draw geometry so that no clip is needed when drawing.
  487. if (axisAlignedClip && (!stencilSettings || clipAA == *aa)) {
  488. // Tighten clip bounds (if clipRRect.isRect() is true, clipBounds now holds the intersection
  489. // of the render target and the clip rect)
  490. SkRect clipBounds = rtRect;
  491. if (!clipBounds.intersect(clipRRect.rect()) || !clipBounds.intersects(drawBounds)) {
  492. return QuadOptimization::kDiscarded;
  493. }
  494. if (clipRRect.isRect()) {
  495. // No rounded corners, so the kClear and kExplicitClip optimizations are possible
  496. if (GrQuadUtils::CropToRect(clipBounds, clipAA, &newFlags, deviceQuad, localQuad)) {
  497. if (constColor && deviceQuad->quadType() == GrQuad::Type::kAxisAligned) {
  498. // Clear optimization is possible
  499. drawBounds = deviceQuad->bounds();
  500. if (drawBounds.contains(rtRect)) {
  501. // Fullscreen clear
  502. this->clear(nullptr, *constColor, CanClearFullscreen::kYes);
  503. return QuadOptimization::kSubmitted;
  504. } else if (GrClip::IsPixelAligned(drawBounds) &&
  505. drawBounds.width() > 256 && drawBounds.height() > 256) {
  506. // Scissor + clear (round shouldn't do anything since we are pixel aligned)
  507. SkIRect scissorRect;
  508. drawBounds.round(&scissorRect);
  509. this->clear(&scissorRect, *constColor, CanClearFullscreen::kNo);
  510. return QuadOptimization::kSubmitted;
  511. }
  512. }
  513. // Update overall AA setting.
  514. *edgeFlags = newFlags;
  515. if (*aa == GrAA::kNo && clipAA == GrAA::kYes &&
  516. newFlags != GrQuadAAFlags::kNone) {
  517. // The clip was anti-aliased and now the draw needs to be upgraded to AA to
  518. // properly reflect the smooth edge of the clip.
  519. *aa = GrAA::kYes;
  520. }
  521. // We intentionally do not downgrade AA here because we don't know if we need to
  522. // preserve MSAA (see GrQuadAAFlags docs). But later in the pipeline, the ops can
  523. // use GrResolveAATypeForQuad() to turn off coverage AA when all flags are off.
  524. // deviceQuad is exactly the intersection of original quad and clip, so it can be
  525. // drawn with no clip (submitted by caller)
  526. return QuadOptimization::kClipApplied;
  527. } else {
  528. // The quads have been updated to better fit the clip bounds, but can't get rid of
  529. // the clip entirely
  530. return QuadOptimization::kCropped;
  531. }
  532. } else if (constColor) {
  533. // Rounded corners and constant filled color (limit ourselves to solid colors because
  534. // there is no way to use custom local coordinates with drawRRect).
  535. if (GrQuadUtils::CropToRect(clipBounds, clipAA, &newFlags, deviceQuad, localQuad) &&
  536. deviceQuad->quadType() == GrQuad::Type::kAxisAligned &&
  537. deviceQuad->bounds().contains(clipBounds)) {
  538. // Since the cropped quad became a rectangle which covered the bounds of the rrect,
  539. // we can draw the rrect directly and ignore the edge flags
  540. GrPaint paint;
  541. clear_to_grpaint(*constColor, &paint);
  542. this->drawRRect(GrFixedClip::Disabled(), std::move(paint), clipAA, SkMatrix::I(),
  543. clipRRect, GrStyle::SimpleFill());
  544. return QuadOptimization::kSubmitted;
  545. } else {
  546. // The quad has been updated to better fit clip bounds, but can't remove the clip
  547. return QuadOptimization::kCropped;
  548. }
  549. }
  550. }
  551. // Crop the quad to the conservative bounds of the clip.
  552. SkIRect clipDevBounds;
  553. clip.getConservativeBounds(rtRect.width(), rtRect.height(), &clipDevBounds);
  554. SkRect clipBounds = SkRect::Make(clipDevBounds);
  555. // One final check for discarding, since we may have gone here directly due to a complex clip
  556. if (!clipBounds.intersects(drawBounds)) {
  557. return QuadOptimization::kDiscarded;
  558. }
  559. // Even if this were to return true, the crop rect does not exactly match the clip, so can not
  560. // report explicit-clip. Since these edges aren't visible, don't update the final edge flags.
  561. GrQuadUtils::CropToRect(clipBounds, clipAA, &newFlags, deviceQuad, localQuad);
  562. return QuadOptimization::kCropped;
  563. }
  564. void GrRenderTargetContext::drawFilledQuad(const GrClip& clip,
  565. GrPaint&& paint,
  566. GrAA aa,
  567. GrQuadAAFlags edgeFlags,
  568. const GrQuad& deviceQuad,
  569. const GrQuad& localQuad,
  570. const GrUserStencilSettings* ss) {
  571. ASSERT_SINGLE_OWNER
  572. RETURN_IF_ABANDONED
  573. SkDEBUGCODE(this->validate();)
  574. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawFilledQuad", fContext);
  575. AutoCheckFlush acf(this->drawingManager());
  576. SkPMColor4f* constColor = nullptr;
  577. SkPMColor4f paintColor;
  578. if (!ss && !paint.numCoverageFragmentProcessors() &&
  579. paint.isConstantBlendedColor(&paintColor)) {
  580. // Only consider clears/rrects when it's easy to guarantee 100% fill with single color
  581. constColor = &paintColor;
  582. }
  583. GrQuad croppedDeviceQuad = deviceQuad;
  584. GrQuad croppedLocalQuad = localQuad;
  585. QuadOptimization opt = this->attemptQuadOptimization(clip, constColor, ss, &aa, &edgeFlags,
  586. &croppedDeviceQuad, &croppedLocalQuad);
  587. if (opt >= QuadOptimization::kClipApplied) {
  588. // These optimizations require caller to add an op themselves
  589. const GrClip& finalClip = opt == QuadOptimization::kClipApplied ? GrFixedClip::Disabled()
  590. : clip;
  591. GrAAType aaType = ss ? (aa == GrAA::kYes ? GrAAType::kMSAA : GrAAType::kNone)
  592. : this->chooseAAType(aa);
  593. this->addDrawOp(finalClip, GrFillRectOp::Make(fContext, std::move(paint), aaType, edgeFlags,
  594. croppedDeviceQuad, croppedLocalQuad, ss));
  595. }
  596. // All other optimization levels were completely handled inside attempt(), so no extra op needed
  597. }
  598. void GrRenderTargetContext::drawTexturedQuad(const GrClip& clip,
  599. sk_sp<GrTextureProxy> proxy,
  600. sk_sp<GrColorSpaceXform> textureXform,
  601. GrSamplerState::Filter filter,
  602. const SkPMColor4f& color,
  603. SkBlendMode blendMode,
  604. GrAA aa,
  605. GrQuadAAFlags edgeFlags,
  606. const GrQuad& deviceQuad,
  607. const GrQuad& localQuad,
  608. const SkRect* domain) {
  609. ASSERT_SINGLE_OWNER
  610. RETURN_IF_ABANDONED
  611. SkDEBUGCODE(this->validate();)
  612. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawTexturedQuad", fContext);
  613. AutoCheckFlush acf(this->drawingManager());
  614. // Functionally this is very similar to drawFilledQuad except that there's no constColor to
  615. // enable the kSubmitted optimizations, no stencil settings support, and its a GrTextureOp.
  616. GrQuad croppedDeviceQuad = deviceQuad;
  617. GrQuad croppedLocalQuad = localQuad;
  618. QuadOptimization opt = this->attemptQuadOptimization(clip, nullptr, nullptr, &aa, &edgeFlags,
  619. &croppedDeviceQuad, &croppedLocalQuad);
  620. SkASSERT(opt != QuadOptimization::kSubmitted);
  621. if (opt != QuadOptimization::kDiscarded) {
  622. // And the texture op if not discarded
  623. const GrClip& finalClip = opt == QuadOptimization::kClipApplied ? GrFixedClip::Disabled()
  624. : clip;
  625. GrAAType aaType = this->chooseAAType(aa);
  626. // Use the provided domain, although hypothetically we could detect that the cropped local
  627. // quad is sufficiently inside the domain and the constraint could be dropped.
  628. this->addDrawOp(finalClip, GrTextureOp::Make(fContext, std::move(proxy),
  629. std::move(textureXform), filter, color,
  630. blendMode, aaType, edgeFlags,
  631. croppedDeviceQuad, croppedLocalQuad, domain));
  632. }
  633. }
  634. void GrRenderTargetContext::drawRect(const GrClip& clip,
  635. GrPaint&& paint,
  636. GrAA aa,
  637. const SkMatrix& viewMatrix,
  638. const SkRect& rect,
  639. const GrStyle* style) {
  640. if (!style) {
  641. style = &GrStyle::SimpleFill();
  642. }
  643. ASSERT_SINGLE_OWNER
  644. RETURN_IF_ABANDONED
  645. SkDEBUGCODE(this->validate();)
  646. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawRect", fContext);
  647. // Path effects should've been devolved to a path in SkGpuDevice
  648. SkASSERT(!style->pathEffect());
  649. AutoCheckFlush acf(this->drawingManager());
  650. const SkStrokeRec& stroke = style->strokeRec();
  651. if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
  652. // Fills the rect, using rect as its own local coordinates
  653. this->fillRectToRect(clip, std::move(paint), aa, viewMatrix, rect, rect);
  654. return;
  655. } else if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
  656. stroke.getStyle() == SkStrokeRec::kHairline_Style) {
  657. if ((!rect.width() || !rect.height()) &&
  658. SkStrokeRec::kHairline_Style != stroke.getStyle()) {
  659. SkScalar r = stroke.getWidth() / 2;
  660. // TODO: Move these stroke->fill fallbacks to GrShape?
  661. switch (stroke.getJoin()) {
  662. case SkPaint::kMiter_Join:
  663. this->drawRect(
  664. clip, std::move(paint), aa, viewMatrix,
  665. {rect.fLeft - r, rect.fTop - r, rect.fRight + r, rect.fBottom + r},
  666. &GrStyle::SimpleFill());
  667. return;
  668. case SkPaint::kRound_Join:
  669. // Raster draws nothing when both dimensions are empty.
  670. if (rect.width() || rect.height()){
  671. SkRRect rrect = SkRRect::MakeRectXY(rect.makeOutset(r, r), r, r);
  672. this->drawRRect(clip, std::move(paint), aa, viewMatrix, rrect,
  673. GrStyle::SimpleFill());
  674. return;
  675. }
  676. case SkPaint::kBevel_Join:
  677. if (!rect.width()) {
  678. this->drawRect(clip, std::move(paint), aa, viewMatrix,
  679. {rect.fLeft - r, rect.fTop, rect.fRight + r, rect.fBottom},
  680. &GrStyle::SimpleFill());
  681. } else {
  682. this->drawRect(clip, std::move(paint), aa, viewMatrix,
  683. {rect.fLeft, rect.fTop - r, rect.fRight, rect.fBottom + r},
  684. &GrStyle::SimpleFill());
  685. }
  686. return;
  687. }
  688. }
  689. std::unique_ptr<GrDrawOp> op;
  690. GrAAType aaType = this->chooseAAType(aa);
  691. op = GrStrokeRectOp::Make(fContext, std::move(paint), aaType, viewMatrix, rect, stroke);
  692. // op may be null if the stroke is not supported or if using coverage aa and the view matrix
  693. // does not preserve rectangles.
  694. if (op) {
  695. this->addDrawOp(clip, std::move(op));
  696. return;
  697. }
  698. }
  699. assert_alive(paint);
  700. this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, GrShape(rect, *style));
  701. }
  702. void GrRenderTargetContext::drawQuadSet(const GrClip& clip, GrPaint&& paint, GrAA aa,
  703. const SkMatrix& viewMatrix, const QuadSetEntry quads[],
  704. int cnt) {
  705. GrAAType aaType = this->chooseAAType(aa);
  706. this->addDrawOp(clip, GrFillRectOp::MakeSet(fContext, std::move(paint), aaType, viewMatrix,
  707. quads, cnt));
  708. }
  709. int GrRenderTargetContextPriv::maxWindowRectangles() const {
  710. return fRenderTargetContext->fRenderTargetProxy->maxWindowRectangles(
  711. *fRenderTargetContext->caps());
  712. }
  713. GrRenderTargetOpList::CanDiscardPreviousOps GrRenderTargetContext::canDiscardPreviousOpsOnFullClear(
  714. ) const {
  715. #if GR_TEST_UTILS
  716. if (fPreserveOpsOnFullClear_TestingOnly) {
  717. return GrRenderTargetOpList::CanDiscardPreviousOps::kNo;
  718. }
  719. #endif
  720. // Regardless of how the clear is implemented (native clear or a fullscreen quad), all prior ops
  721. // would normally be overwritten. The one exception is if the render target context is marked as
  722. // needing a stencil buffer then there may be a prior op that writes to the stencil buffer.
  723. // Although the clear will ignore the stencil buffer, following draw ops may not so we can't get
  724. // rid of all the preceding ops. Beware! If we ever add any ops that have a side effect beyond
  725. // modifying the stencil buffer we will need a more elaborate tracking system (skbug.com/7002).
  726. return GrRenderTargetOpList::CanDiscardPreviousOps(!fNumStencilSamples);
  727. }
  728. void GrRenderTargetContext::setNeedsStencil(bool multisampled) {
  729. // Don't clear stencil until after we've changed fNumStencilSamples. This ensures we don't loop
  730. // forever in the event that there are driver bugs and we need to clear as a draw.
  731. bool needsStencilClear = !fNumStencilSamples;
  732. int numRequiredSamples = this->numSamples();
  733. if (multisampled && 1 == numRequiredSamples) {
  734. // The caller has requested a multisampled stencil buffer on a non-MSAA render target. Use
  735. // mixed samples.
  736. SkASSERT(fRenderTargetProxy->canUseMixedSamples(*this->caps()));
  737. numRequiredSamples = this->caps()->internalMultisampleCount(
  738. this->asSurfaceProxy()->config());
  739. }
  740. SkASSERT(numRequiredSamples > 0);
  741. if (numRequiredSamples > fNumStencilSamples) {
  742. fNumStencilSamples = numRequiredSamples;
  743. fRenderTargetProxy->setNeedsStencil(fNumStencilSamples);
  744. }
  745. if (needsStencilClear) {
  746. if (this->caps()->performStencilClearsAsDraws()) {
  747. // There is a driver bug with clearing stencil. We must use an op to manually clear the
  748. // stencil buffer before the op that required 'setNeedsStencil'.
  749. this->internalStencilClear(GrFixedClip::Disabled(), /* inside mask */ false);
  750. } else {
  751. // Setting the clear stencil load op is preferable. On non-tilers, this lets the flush
  752. // code note when the instantiated stencil buffer is already clear and skip the clear
  753. // altogether. And on tilers, loading the stencil buffer cleared is even faster than
  754. // preserving the previous contents.
  755. this->getRTOpList()->setStencilLoadOp(GrLoadOp::kClear);
  756. }
  757. }
  758. }
  759. void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
  760. ASSERT_SINGLE_OWNER_PRIV
  761. RETURN_IF_ABANDONED_PRIV
  762. SkDEBUGCODE(fRenderTargetContext->validate();)
  763. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "clearStencilClip",
  764. fRenderTargetContext->fContext);
  765. AutoCheckFlush acf(fRenderTargetContext->drawingManager());
  766. fRenderTargetContext->internalStencilClear(clip, insideStencilMask);
  767. }
  768. void GrRenderTargetContext::internalStencilClear(const GrFixedClip& clip, bool insideStencilMask) {
  769. if (this->caps()->performStencilClearsAsDraws()) {
  770. const GrUserStencilSettings* ss = GrStencilSettings::SetClipBitSettings(insideStencilMask);
  771. SkRect rtRect = SkRect::MakeWH(this->width(), this->height());
  772. // Configure the paint to have no impact on the color buffer
  773. GrPaint paint;
  774. paint.setXPFactory(GrDisableColorXPFactory::Get());
  775. this->addDrawOp(clip, GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
  776. rtRect, ss));
  777. } else {
  778. std::unique_ptr<GrOp> op(GrClearStencilClipOp::Make(fContext, clip, insideStencilMask,
  779. fRenderTargetProxy.get()));
  780. if (!op) {
  781. return;
  782. }
  783. this->getRTOpList()->addOp(std::move(op), *this->caps());
  784. }
  785. }
  786. void GrRenderTargetContextPriv::stencilPath(const GrHardClip& clip,
  787. GrAA doStencilMSAA,
  788. const SkMatrix& viewMatrix,
  789. const GrPath* path) {
  790. ASSERT_SINGLE_OWNER_PRIV
  791. RETURN_IF_ABANDONED_PRIV
  792. SkDEBUGCODE(fRenderTargetContext->validate();)
  793. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "stencilPath",
  794. fRenderTargetContext->fContext);
  795. // TODO: extract portions of checkDraw that are relevant to path stenciling.
  796. SkASSERT(path);
  797. SkASSERT(fRenderTargetContext->caps()->shaderCaps()->pathRenderingSupport());
  798. // FIXME: Use path bounds instead of this WAR once
  799. // https://bugs.chromium.org/p/skia/issues/detail?id=5640 is resolved.
  800. SkRect bounds = SkRect::MakeIWH(fRenderTargetContext->width(), fRenderTargetContext->height());
  801. // Setup clip
  802. GrAppliedHardClip appliedClip;
  803. if (!clip.apply(fRenderTargetContext->width(), fRenderTargetContext->height(), &appliedClip,
  804. &bounds)) {
  805. return;
  806. }
  807. std::unique_ptr<GrOp> op = GrStencilPathOp::Make(fRenderTargetContext->fContext,
  808. viewMatrix,
  809. GrAA::kYes == doStencilMSAA,
  810. path->getFillType(),
  811. appliedClip.hasStencilClip(),
  812. appliedClip.scissorState(),
  813. path);
  814. if (!op) {
  815. return;
  816. }
  817. op->setClippedBounds(bounds);
  818. fRenderTargetContext->setNeedsStencil(GrAA::kYes == doStencilMSAA);
  819. fRenderTargetContext->getRTOpList()->addOp(std::move(op), *fRenderTargetContext->caps());
  820. }
  821. void GrRenderTargetContext::drawTextureSet(const GrClip& clip, const TextureSetEntry set[], int cnt,
  822. GrSamplerState::Filter filter, SkBlendMode mode,
  823. GrAA aa, SkCanvas::SrcRectConstraint constraint,
  824. const SkMatrix& viewMatrix,
  825. sk_sp<GrColorSpaceXform> texXform) {
  826. ASSERT_SINGLE_OWNER
  827. RETURN_IF_ABANDONED
  828. SkDEBUGCODE(this->validate();)
  829. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawTextureSet", fContext);
  830. if (mode != SkBlendMode::kSrcOver ||
  831. !fContext->priv().caps()->dynamicStateArrayGeometryProcessorTextureSupport()) {
  832. // Draw one at a time since the bulk API doesn't support non src-over blending, or the
  833. // backend can't support the bulk geometry processor yet.
  834. SkMatrix ctm;
  835. for (int i = 0; i < cnt; ++i) {
  836. float alpha = set[i].fAlpha;
  837. ctm = viewMatrix;
  838. if (set[i].fPreViewMatrix) {
  839. ctm.preConcat(*set[i].fPreViewMatrix);
  840. }
  841. GrQuad quad, srcQuad;
  842. if (set[i].fDstClipQuad) {
  843. quad = GrQuad::MakeFromSkQuad(set[i].fDstClipQuad, ctm);
  844. SkPoint srcPts[4];
  845. GrMapRectPoints(set[i].fDstRect, set[i].fSrcRect, set[i].fDstClipQuad, srcPts, 4);
  846. srcQuad = GrQuad::MakeFromSkQuad(srcPts, SkMatrix::I());
  847. } else {
  848. quad = GrQuad::MakeFromRect(set[i].fDstRect, ctm);
  849. srcQuad = GrQuad(set[i].fSrcRect);
  850. }
  851. const SkRect* domain = constraint == SkCanvas::kStrict_SrcRectConstraint
  852. ? &set[i].fSrcRect : nullptr;
  853. this->drawTexturedQuad(clip, set[i].fProxy, texXform, filter,
  854. {alpha, alpha, alpha, alpha}, mode, aa, set[i].fAAFlags,
  855. quad, srcQuad, domain);
  856. }
  857. } else {
  858. // Can use a single op, avoiding GrPaint creation, and can batch across proxies
  859. AutoCheckFlush acf(this->drawingManager());
  860. GrAAType aaType = this->chooseAAType(aa);
  861. auto op = GrTextureOp::MakeSet(fContext, set, cnt, filter, aaType, constraint, viewMatrix,
  862. std::move(texXform));
  863. this->addDrawOp(clip, std::move(op));
  864. }
  865. }
  866. void GrRenderTargetContext::drawVertices(const GrClip& clip,
  867. GrPaint&& paint,
  868. const SkMatrix& viewMatrix,
  869. sk_sp<SkVertices> vertices,
  870. const SkVertices::Bone bones[],
  871. int boneCount,
  872. GrPrimitiveType* overridePrimType) {
  873. ASSERT_SINGLE_OWNER
  874. RETURN_IF_ABANDONED
  875. SkDEBUGCODE(this->validate();)
  876. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawVertices", fContext);
  877. AutoCheckFlush acf(this->drawingManager());
  878. SkASSERT(vertices);
  879. GrAAType aaType = this->chooseAAType(GrAA::kNo);
  880. std::unique_ptr<GrDrawOp> op = GrDrawVerticesOp::Make(
  881. fContext, std::move(paint), std::move(vertices), bones, boneCount, viewMatrix, aaType,
  882. this->colorSpaceInfo().refColorSpaceXformFromSRGB(), overridePrimType);
  883. this->addDrawOp(clip, std::move(op));
  884. }
  885. ///////////////////////////////////////////////////////////////////////////////
  886. void GrRenderTargetContext::drawAtlas(const GrClip& clip,
  887. GrPaint&& paint,
  888. const SkMatrix& viewMatrix,
  889. int spriteCount,
  890. const SkRSXform xform[],
  891. const SkRect texRect[],
  892. const SkColor colors[]) {
  893. ASSERT_SINGLE_OWNER
  894. RETURN_IF_ABANDONED
  895. SkDEBUGCODE(this->validate();)
  896. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawAtlas", fContext);
  897. AutoCheckFlush acf(this->drawingManager());
  898. GrAAType aaType = this->chooseAAType(GrAA::kNo);
  899. std::unique_ptr<GrDrawOp> op = GrDrawAtlasOp::Make(fContext, std::move(paint), viewMatrix,
  900. aaType, spriteCount, xform, texRect, colors);
  901. this->addDrawOp(clip, std::move(op));
  902. }
  903. ///////////////////////////////////////////////////////////////////////////////
  904. void GrRenderTargetContext::drawRRect(const GrClip& origClip,
  905. GrPaint&& paint,
  906. GrAA aa,
  907. const SkMatrix& viewMatrix,
  908. const SkRRect& rrect,
  909. const GrStyle& style) {
  910. ASSERT_SINGLE_OWNER
  911. RETURN_IF_ABANDONED
  912. SkDEBUGCODE(this->validate();)
  913. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawRRect", fContext);
  914. const SkStrokeRec& stroke = style.strokeRec();
  915. if (stroke.getStyle() == SkStrokeRec::kFill_Style && rrect.isEmpty()) {
  916. return;
  917. }
  918. GrNoClip noclip;
  919. const GrClip* clip = &origClip;
  920. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  921. // The Android framework frequently clips rrects to themselves where the clip is non-aa and the
  922. // draw is aa. Since our lower level clip code works from op bounds, which are SkRects, it
  923. // doesn't detect that the clip can be ignored (modulo antialiasing). The following test
  924. // attempts to mitigate the stencil clip cost but will only help when the entire clip stack
  925. // can be ignored. We'd prefer to fix this in the framework by removing the clips calls. This
  926. // only works for filled rrects since the stroke width outsets beyond the rrect itself.
  927. SkRRect devRRect;
  928. if (stroke.getStyle() == SkStrokeRec::kFill_Style && rrect.transform(viewMatrix, &devRRect) &&
  929. clip->quickContains(devRRect)) {
  930. clip = &noclip;
  931. }
  932. #endif
  933. SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
  934. AutoCheckFlush acf(this->drawingManager());
  935. GrAAType aaType = this->chooseAAType(aa);
  936. std::unique_ptr<GrDrawOp> op;
  937. if (GrAAType::kCoverage == aaType && rrect.isSimple() &&
  938. rrect.getSimpleRadii().fX == rrect.getSimpleRadii().fY &&
  939. viewMatrix.rectStaysRect() && viewMatrix.isSimilarity()) {
  940. // In coverage mode, we draw axis-aligned circular roundrects with the GrOvalOpFactory
  941. // to avoid perf regressions on some platforms.
  942. assert_alive(paint);
  943. op = GrOvalOpFactory::MakeCircularRRectOp(
  944. fContext, std::move(paint), viewMatrix, rrect, stroke, this->caps()->shaderCaps());
  945. }
  946. if (!op && style.isSimpleFill()) {
  947. assert_alive(paint);
  948. op = GrFillRRectOp::Make(
  949. fContext, aaType, viewMatrix, rrect, *this->caps(), std::move(paint));
  950. }
  951. if (!op && GrAAType::kCoverage == aaType) {
  952. assert_alive(paint);
  953. op = GrOvalOpFactory::MakeRRectOp(
  954. fContext, std::move(paint), viewMatrix, rrect, stroke, this->caps()->shaderCaps());
  955. }
  956. if (op) {
  957. this->addDrawOp(*clip, std::move(op));
  958. return;
  959. }
  960. assert_alive(paint);
  961. this->drawShapeUsingPathRenderer(*clip, std::move(paint), aa, viewMatrix,
  962. GrShape(rrect, style));
  963. }
  964. ///////////////////////////////////////////////////////////////////////////////
  965. static SkPoint3 map(const SkMatrix& m, const SkPoint3& pt) {
  966. SkPoint3 result;
  967. m.mapXY(pt.fX, pt.fY, (SkPoint*)&result.fX);
  968. result.fZ = pt.fZ;
  969. return result;
  970. }
  971. bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
  972. const SkMatrix& viewMatrix,
  973. const SkPath& path,
  974. const SkDrawShadowRec& rec) {
  975. ASSERT_SINGLE_OWNER
  976. if (fContext->priv().abandoned()) {
  977. return true;
  978. }
  979. SkDEBUGCODE(this->validate();)
  980. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawFastShadow", fContext);
  981. // check z plane
  982. bool tiltZPlane = SkToBool(!SkScalarNearlyZero(rec.fZPlaneParams.fX) ||
  983. !SkScalarNearlyZero(rec.fZPlaneParams.fY));
  984. bool skipAnalytic = SkToBool(rec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
  985. if (tiltZPlane || skipAnalytic || !viewMatrix.rectStaysRect() || !viewMatrix.isSimilarity()) {
  986. return false;
  987. }
  988. SkRRect rrect;
  989. SkRect rect;
  990. // we can only handle rects, circles, and rrects with circular corners
  991. bool isRRect = path.isRRect(&rrect) && SkRRectPriv::IsSimpleCircular(rrect) &&
  992. rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero;
  993. if (!isRRect &&
  994. path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
  995. rect.width() > SK_ScalarNearlyZero) {
  996. rrect.setOval(rect);
  997. isRRect = true;
  998. }
  999. if (!isRRect && path.isRect(&rect)) {
  1000. rrect.setRect(rect);
  1001. isRRect = true;
  1002. }
  1003. if (!isRRect) {
  1004. return false;
  1005. }
  1006. if (rrect.isEmpty()) {
  1007. return true;
  1008. }
  1009. AutoCheckFlush acf(this->drawingManager());
  1010. // transform light
  1011. SkPoint3 devLightPos = map(viewMatrix, rec.fLightPos);
  1012. // 1/scale
  1013. SkScalar devToSrcScale = viewMatrix.isScaleTranslate() ?
  1014. SkScalarInvert(SkScalarAbs(viewMatrix[SkMatrix::kMScaleX])) :
  1015. sk_float_rsqrt(viewMatrix[SkMatrix::kMScaleX] * viewMatrix[SkMatrix::kMScaleX] +
  1016. viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);
  1017. SkScalar occluderHeight = rec.fZPlaneParams.fZ;
  1018. bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
  1019. if (SkColorGetA(rec.fAmbientColor) > 0) {
  1020. SkScalar devSpaceInsetWidth = SkDrawShadowMetrics::AmbientBlurRadius(occluderHeight);
  1021. const SkScalar umbraRecipAlpha = SkDrawShadowMetrics::AmbientRecipAlpha(occluderHeight);
  1022. const SkScalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraRecipAlpha;
  1023. // Outset the shadow rrect to the border of the penumbra
  1024. SkScalar ambientPathOutset = devSpaceInsetWidth * devToSrcScale;
  1025. SkRRect ambientRRect;
  1026. SkRect outsetRect = rrect.rect().makeOutset(ambientPathOutset, ambientPathOutset);
  1027. // If the rrect was an oval then its outset will also be one.
  1028. // We set it explicitly to avoid errors.
  1029. if (rrect.isOval()) {
  1030. ambientRRect = SkRRect::MakeOval(outsetRect);
  1031. } else {
  1032. SkScalar outsetRad = SkRRectPriv::GetSimpleRadii(rrect).fX + ambientPathOutset;
  1033. ambientRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
  1034. }
  1035. GrColor ambientColor = SkColorToPremulGrColor(rec.fAmbientColor);
  1036. if (transparent) {
  1037. // set a large inset to force a fill
  1038. devSpaceInsetWidth = ambientRRect.width();
  1039. }
  1040. std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(fContext,
  1041. ambientColor,
  1042. viewMatrix,
  1043. ambientRRect,
  1044. devSpaceAmbientBlur,
  1045. devSpaceInsetWidth);
  1046. if (op) {
  1047. this->addDrawOp(clip, std::move(op));
  1048. }
  1049. }
  1050. if (SkColorGetA(rec.fSpotColor) > 0) {
  1051. SkScalar devSpaceSpotBlur;
  1052. SkScalar spotScale;
  1053. SkVector spotOffset;
  1054. SkDrawShadowMetrics::GetSpotParams(occluderHeight, devLightPos.fX, devLightPos.fY,
  1055. devLightPos.fZ, rec.fLightRadius,
  1056. &devSpaceSpotBlur, &spotScale, &spotOffset);
  1057. // handle scale of radius due to CTM
  1058. const SkScalar srcSpaceSpotBlur = devSpaceSpotBlur * devToSrcScale;
  1059. // Adjust translate for the effect of the scale.
  1060. spotOffset.fX += spotScale*viewMatrix[SkMatrix::kMTransX];
  1061. spotOffset.fY += spotScale*viewMatrix[SkMatrix::kMTransY];
  1062. // This offset is in dev space, need to transform it into source space.
  1063. SkMatrix ctmInverse;
  1064. if (viewMatrix.invert(&ctmInverse)) {
  1065. ctmInverse.mapPoints(&spotOffset, 1);
  1066. } else {
  1067. // Since the matrix is a similarity, this should never happen, but just in case...
  1068. SkDebugf("Matrix is degenerate. Will not render spot shadow correctly!\n");
  1069. SkASSERT(false);
  1070. }
  1071. // Compute the transformed shadow rrect
  1072. SkRRect spotShadowRRect;
  1073. SkMatrix shadowTransform;
  1074. shadowTransform.setScaleTranslate(spotScale, spotScale, spotOffset.fX, spotOffset.fY);
  1075. rrect.transform(shadowTransform, &spotShadowRRect);
  1076. SkScalar spotRadius = SkRRectPriv::GetSimpleRadii(spotShadowRRect).fX;
  1077. // Compute the insetWidth
  1078. SkScalar blurOutset = srcSpaceSpotBlur;
  1079. SkScalar insetWidth = blurOutset;
  1080. if (transparent) {
  1081. // If transparent, just do a fill
  1082. insetWidth += spotShadowRRect.width();
  1083. } else {
  1084. // For shadows, instead of using a stroke we specify an inset from the penumbra
  1085. // border. We want to extend this inset area so that it meets up with the caster
  1086. // geometry. The inset geometry will by default already be inset by the blur width.
  1087. //
  1088. // We compare the min and max corners inset by the radius between the original
  1089. // rrect and the shadow rrect. The distance between the two plus the difference
  1090. // between the scaled radius and the original radius gives the distance from the
  1091. // transformed shadow shape to the original shape in that corner. The max
  1092. // of these gives the maximum distance we need to cover.
  1093. //
  1094. // Since we are outsetting by 1/2 the blur distance, we just add the maxOffset to
  1095. // that to get the full insetWidth.
  1096. SkScalar maxOffset;
  1097. if (rrect.isRect()) {
  1098. // Manhattan distance works better for rects
  1099. maxOffset = SkTMax(SkTMax(SkTAbs(spotShadowRRect.rect().fLeft -
  1100. rrect.rect().fLeft),
  1101. SkTAbs(spotShadowRRect.rect().fTop -
  1102. rrect.rect().fTop)),
  1103. SkTMax(SkTAbs(spotShadowRRect.rect().fRight -
  1104. rrect.rect().fRight),
  1105. SkTAbs(spotShadowRRect.rect().fBottom -
  1106. rrect.rect().fBottom)));
  1107. } else {
  1108. SkScalar dr = spotRadius - SkRRectPriv::GetSimpleRadii(rrect).fX;
  1109. SkPoint upperLeftOffset = SkPoint::Make(spotShadowRRect.rect().fLeft -
  1110. rrect.rect().fLeft + dr,
  1111. spotShadowRRect.rect().fTop -
  1112. rrect.rect().fTop + dr);
  1113. SkPoint lowerRightOffset = SkPoint::Make(spotShadowRRect.rect().fRight -
  1114. rrect.rect().fRight - dr,
  1115. spotShadowRRect.rect().fBottom -
  1116. rrect.rect().fBottom - dr);
  1117. maxOffset = SkScalarSqrt(SkTMax(SkPointPriv::LengthSqd(upperLeftOffset),
  1118. SkPointPriv::LengthSqd(lowerRightOffset))) + dr;
  1119. }
  1120. insetWidth += SkTMax(blurOutset, maxOffset);
  1121. }
  1122. // Outset the shadow rrect to the border of the penumbra
  1123. SkRect outsetRect = spotShadowRRect.rect().makeOutset(blurOutset, blurOutset);
  1124. if (spotShadowRRect.isOval()) {
  1125. spotShadowRRect = SkRRect::MakeOval(outsetRect);
  1126. } else {
  1127. SkScalar outsetRad = spotRadius + blurOutset;
  1128. spotShadowRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
  1129. }
  1130. GrColor spotColor = SkColorToPremulGrColor(rec.fSpotColor);
  1131. std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(fContext,
  1132. spotColor,
  1133. viewMatrix,
  1134. spotShadowRRect,
  1135. 2.0f * devSpaceSpotBlur,
  1136. insetWidth);
  1137. if (op) {
  1138. this->addDrawOp(clip, std::move(op));
  1139. }
  1140. }
  1141. return true;
  1142. }
  1143. ///////////////////////////////////////////////////////////////////////////////
  1144. bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
  1145. GrPaint&& paint,
  1146. GrAA aa,
  1147. const SkMatrix& viewMatrix,
  1148. const SkRRect& origOuter,
  1149. const SkRRect& origInner) {
  1150. SkASSERT(!origInner.isEmpty());
  1151. SkASSERT(!origOuter.isEmpty());
  1152. SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
  1153. GrAAType aaType = this->chooseAAType(aa);
  1154. if (GrAAType::kMSAA == aaType) {
  1155. return false;
  1156. }
  1157. if (GrAAType::kCoverage == aaType && SkRRectPriv::IsCircle(*inner)
  1158. && SkRRectPriv::IsCircle(*outer)) {
  1159. auto outerR = outer->width() / 2.f;
  1160. auto innerR = inner->width() / 2.f;
  1161. auto cx = outer->getBounds().fLeft + outerR;
  1162. auto cy = outer->getBounds().fTop + outerR;
  1163. if (SkScalarNearlyEqual(cx, inner->getBounds().fLeft + innerR) &&
  1164. SkScalarNearlyEqual(cy, inner->getBounds().fTop + innerR)) {
  1165. auto avgR = (innerR + outerR) / 2.f;
  1166. auto circleBounds = SkRect::MakeLTRB(cx - avgR, cy - avgR, cx + avgR, cy + avgR);
  1167. SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
  1168. stroke.setStrokeStyle(outerR - innerR);
  1169. auto op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix,
  1170. circleBounds, GrStyle(stroke, nullptr),
  1171. this->caps()->shaderCaps());
  1172. if (op) {
  1173. this->addDrawOp(clip, std::move(op));
  1174. return true;
  1175. }
  1176. assert_alive(paint);
  1177. }
  1178. }
  1179. GrClipEdgeType innerEdgeType, outerEdgeType;
  1180. if (GrAAType::kCoverage == aaType) {
  1181. innerEdgeType = GrClipEdgeType::kInverseFillAA;
  1182. outerEdgeType = GrClipEdgeType::kFillAA;
  1183. } else {
  1184. innerEdgeType = GrClipEdgeType::kInverseFillBW;
  1185. outerEdgeType = GrClipEdgeType::kFillBW;
  1186. }
  1187. SkMatrix inverseVM;
  1188. if (!viewMatrix.isIdentity()) {
  1189. if (!origInner.transform(viewMatrix, inner.writable())) {
  1190. return false;
  1191. }
  1192. if (!origOuter.transform(viewMatrix, outer.writable())) {
  1193. return false;
  1194. }
  1195. if (!viewMatrix.invert(&inverseVM)) {
  1196. return false;
  1197. }
  1198. } else {
  1199. inverseVM.reset();
  1200. }
  1201. const auto& caps = *this->caps()->shaderCaps();
  1202. // TODO these need to be a geometry processors
  1203. auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, caps);
  1204. if (!innerEffect) {
  1205. return false;
  1206. }
  1207. auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, caps);
  1208. if (!outerEffect) {
  1209. return false;
  1210. }
  1211. paint.addCoverageFragmentProcessor(std::move(innerEffect));
  1212. paint.addCoverageFragmentProcessor(std::move(outerEffect));
  1213. SkRect bounds = outer->getBounds();
  1214. if (GrAAType::kCoverage == aaType) {
  1215. bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
  1216. }
  1217. this->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), bounds,
  1218. inverseVM);
  1219. return true;
  1220. }
  1221. void GrRenderTargetContext::drawDRRect(const GrClip& clip,
  1222. GrPaint&& paint,
  1223. GrAA aa,
  1224. const SkMatrix& viewMatrix,
  1225. const SkRRect& outer,
  1226. const SkRRect& inner) {
  1227. ASSERT_SINGLE_OWNER
  1228. RETURN_IF_ABANDONED
  1229. SkDEBUGCODE(this->validate();)
  1230. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawDRRect", fContext);
  1231. SkASSERT(!outer.isEmpty());
  1232. SkASSERT(!inner.isEmpty());
  1233. AutoCheckFlush acf(this->drawingManager());
  1234. if (this->drawFilledDRRect(clip, std::move(paint), aa, viewMatrix, outer, inner)) {
  1235. return;
  1236. }
  1237. assert_alive(paint);
  1238. SkPath path;
  1239. path.setIsVolatile(true);
  1240. path.addRRect(inner);
  1241. path.addRRect(outer);
  1242. path.setFillType(SkPath::kEvenOdd_FillType);
  1243. this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, GrShape(path));
  1244. }
  1245. ///////////////////////////////////////////////////////////////////////////////
  1246. void GrRenderTargetContext::drawRegion(const GrClip& clip,
  1247. GrPaint&& paint,
  1248. GrAA aa,
  1249. const SkMatrix& viewMatrix,
  1250. const SkRegion& region,
  1251. const GrStyle& style,
  1252. const GrUserStencilSettings* ss) {
  1253. ASSERT_SINGLE_OWNER
  1254. RETURN_IF_ABANDONED
  1255. SkDEBUGCODE(this->validate();)
  1256. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawRegion", fContext);
  1257. if (GrAA::kYes == aa) {
  1258. // GrRegionOp performs no antialiasing but is much faster, so here we check the matrix
  1259. // to see whether aa is really required.
  1260. if (!SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) &&
  1261. SkScalarIsInt(viewMatrix.getTranslateX()) &&
  1262. SkScalarIsInt(viewMatrix.getTranslateY())) {
  1263. aa = GrAA::kNo;
  1264. }
  1265. }
  1266. bool complexStyle = !style.isSimpleFill();
  1267. if (complexStyle || GrAA::kYes == aa) {
  1268. SkPath path;
  1269. region.getBoundaryPath(&path);
  1270. path.setIsVolatile(true);
  1271. return this->drawPath(clip, std::move(paint), aa, viewMatrix, path, style);
  1272. }
  1273. GrAAType aaType = this->chooseAAType(GrAA::kNo);
  1274. std::unique_ptr<GrDrawOp> op = GrRegionOp::Make(fContext, std::move(paint), viewMatrix, region,
  1275. aaType, ss);
  1276. this->addDrawOp(clip, std::move(op));
  1277. }
  1278. void GrRenderTargetContext::drawOval(const GrClip& clip,
  1279. GrPaint&& paint,
  1280. GrAA aa,
  1281. const SkMatrix& viewMatrix,
  1282. const SkRect& oval,
  1283. const GrStyle& style) {
  1284. ASSERT_SINGLE_OWNER
  1285. RETURN_IF_ABANDONED
  1286. SkDEBUGCODE(this->validate();)
  1287. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawOval", fContext);
  1288. const SkStrokeRec& stroke = style.strokeRec();
  1289. if (oval.isEmpty() && !style.pathEffect()) {
  1290. if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
  1291. return;
  1292. }
  1293. this->drawRect(clip, std::move(paint), aa, viewMatrix, oval, &style);
  1294. return;
  1295. }
  1296. AutoCheckFlush acf(this->drawingManager());
  1297. GrAAType aaType = this->chooseAAType(aa);
  1298. std::unique_ptr<GrDrawOp> op;
  1299. if (GrAAType::kCoverage == aaType && oval.width() > SK_ScalarNearlyZero &&
  1300. oval.width() == oval.height() && viewMatrix.isSimilarity()) {
  1301. // We don't draw true circles as round rects in coverage mode, because it can
  1302. // cause perf regressions on some platforms as compared to the dedicated circle Op.
  1303. assert_alive(paint);
  1304. op = GrOvalOpFactory::MakeCircleOp(fContext, std::move(paint), viewMatrix, oval, style,
  1305. this->caps()->shaderCaps());
  1306. }
  1307. if (!op && style.isSimpleFill()) {
  1308. // GrFillRRectOp has special geometry and a fragment-shader branch to conditionally evaluate
  1309. // the arc equation. This same special geometry and fragment branch also turn out to be a
  1310. // substantial optimization for drawing ovals (namely, by not evaluating the arc equation
  1311. // inside the oval's inner diamond). Given these optimizations, it's a clear win to draw
  1312. // ovals the exact same way we do round rects.
  1313. assert_alive(paint);
  1314. op = GrFillRRectOp::Make(fContext, aaType, viewMatrix, SkRRect::MakeOval(oval),
  1315. *this->caps(), std::move(paint));
  1316. }
  1317. if (!op && GrAAType::kCoverage == aaType) {
  1318. assert_alive(paint);
  1319. op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix, oval, style,
  1320. this->caps()->shaderCaps());
  1321. }
  1322. if (op) {
  1323. this->addDrawOp(clip, std::move(op));
  1324. return;
  1325. }
  1326. assert_alive(paint);
  1327. this->drawShapeUsingPathRenderer(
  1328. clip, std::move(paint), aa, viewMatrix,
  1329. GrShape(SkRRect::MakeOval(oval), SkPath::kCW_Direction, 2, false, style));
  1330. }
  1331. void GrRenderTargetContext::drawArc(const GrClip& clip,
  1332. GrPaint&& paint,
  1333. GrAA aa,
  1334. const SkMatrix& viewMatrix,
  1335. const SkRect& oval,
  1336. SkScalar startAngle,
  1337. SkScalar sweepAngle,
  1338. bool useCenter,
  1339. const GrStyle& style) {
  1340. ASSERT_SINGLE_OWNER
  1341. RETURN_IF_ABANDONED
  1342. SkDEBUGCODE(this->validate();)
  1343. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawArc", fContext);
  1344. AutoCheckFlush acf(this->drawingManager());
  1345. GrAAType aaType = this->chooseAAType(aa);
  1346. if (GrAAType::kCoverage == aaType) {
  1347. const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
  1348. std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeArcOp(fContext,
  1349. std::move(paint),
  1350. viewMatrix,
  1351. oval,
  1352. startAngle,
  1353. sweepAngle,
  1354. useCenter,
  1355. style,
  1356. shaderCaps);
  1357. if (op) {
  1358. this->addDrawOp(clip, std::move(op));
  1359. return;
  1360. }
  1361. assert_alive(paint);
  1362. }
  1363. this->drawShapeUsingPathRenderer(
  1364. clip, std::move(paint), aa, viewMatrix,
  1365. GrShape::MakeArc(oval, startAngle, sweepAngle, useCenter, style));
  1366. }
  1367. void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
  1368. GrPaint&& paint,
  1369. const SkMatrix& viewMatrix,
  1370. sk_sp<GrTextureProxy> image,
  1371. sk_sp<GrColorSpaceXform> csxf,
  1372. GrSamplerState::Filter filter,
  1373. std::unique_ptr<SkLatticeIter> iter,
  1374. const SkRect& dst) {
  1375. ASSERT_SINGLE_OWNER
  1376. RETURN_IF_ABANDONED
  1377. SkDEBUGCODE(this->validate();)
  1378. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawImageLattice", fContext);
  1379. AutoCheckFlush acf(this->drawingManager());
  1380. std::unique_ptr<GrDrawOp> op =
  1381. GrLatticeOp::MakeNonAA(fContext, std::move(paint), viewMatrix, std::move(image),
  1382. std::move(csxf), filter, std::move(iter), dst);
  1383. this->addDrawOp(clip, std::move(op));
  1384. }
  1385. void GrRenderTargetContext::drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable,
  1386. const SkRect& bounds) {
  1387. std::unique_ptr<GrOp> op(GrDrawableOp::Make(fContext, std::move(drawable), bounds));
  1388. SkASSERT(op);
  1389. this->getRTOpList()->addOp(std::move(op), *this->caps());
  1390. }
  1391. void GrRenderTargetContext::asyncRescaleAndReadPixels(
  1392. const SkImageInfo& info, const SkIRect& srcRect, SkSurface::RescaleGamma rescaleGamma,
  1393. SkFilterQuality rescaleQuality, ReadPixelsCallback callback, ReadPixelsContext context) {
  1394. auto direct = fContext->priv().asDirectContext();
  1395. if (!direct) {
  1396. callback(context, nullptr, 0);
  1397. return;
  1398. }
  1399. if (fRenderTargetProxy->wrapsVkSecondaryCB()) {
  1400. callback(context, nullptr, 0);
  1401. return;
  1402. }
  1403. auto dstCT = SkColorTypeToGrColorType(info.colorType());
  1404. bool needsRescale = srcRect.width() != info.width() || srcRect.height() != info.height();
  1405. auto colorTypeOfFinalContext = this->colorSpaceInfo().colorType();
  1406. auto backendFormatOfFinalContext = fRenderTargetProxy->backendFormat();
  1407. if (needsRescale) {
  1408. colorTypeOfFinalContext = dstCT;
  1409. backendFormatOfFinalContext = this->caps()->getBackendFormatFromColorType(dstCT);
  1410. }
  1411. auto readInfo = this->caps()->supportedReadPixelsColorType(colorTypeOfFinalContext,
  1412. backendFormatOfFinalContext, dstCT);
  1413. // Fail if we can't read from the source surface's color type.
  1414. if (readInfo.fColorType == GrColorType::kUnknown) {
  1415. callback(context, nullptr, 0);
  1416. return;
  1417. }
  1418. // Fail if read color type does not have all of dstCT's color channels and those missing color
  1419. // channels are in the src.
  1420. uint32_t dstComponents = GrColorTypeComponentFlags(dstCT);
  1421. uint32_t legalReadComponents = GrColorTypeComponentFlags(readInfo.fColorType);
  1422. uint32_t srcComponents = GrColorTypeComponentFlags(this->colorSpaceInfo().colorType());
  1423. if ((~legalReadComponents & dstComponents) & srcComponents) {
  1424. callback(context, nullptr, 0);
  1425. return;
  1426. }
  1427. sk_sp<GrRenderTargetContext> rtc;
  1428. int x = srcRect.fLeft;
  1429. int y = srcRect.fTop;
  1430. if (needsRescale) {
  1431. rtc = this->rescale(info, srcRect, rescaleGamma, rescaleQuality);
  1432. if (!rtc) {
  1433. callback(context, nullptr, 0);
  1434. return;
  1435. }
  1436. SkASSERT(SkColorSpace::Equals(rtc->colorSpaceInfo().colorSpace(), info.colorSpace()));
  1437. SkASSERT(rtc->origin() == kTopLeft_GrSurfaceOrigin);
  1438. x = y = 0;
  1439. } else {
  1440. sk_sp<GrColorSpaceXform> xform =
  1441. GrColorSpaceXform::Make(this->colorSpaceInfo().colorSpace(),
  1442. this->colorSpaceInfo().alphaType(),
  1443. info.colorSpace(), info.alphaType());
  1444. // Insert a draw to a temporary surface if we need to do a y-flip or color space conversion.
  1445. if (this->origin() == kBottomLeft_GrSurfaceOrigin || xform) {
  1446. // We flip or color convert by drawing and we don't currently support drawing to
  1447. // kPremul.
  1448. if (info.alphaType() == kUnpremul_SkAlphaType) {
  1449. callback(context, nullptr, 0);
  1450. return;
  1451. }
  1452. sk_sp<GrTextureProxy> texProxy = sk_ref_sp(fRenderTargetProxy->asTextureProxy());
  1453. SkRect srcRectToDraw = SkRect::Make(srcRect);
  1454. // If the src is not texturable first try to make a copy to a texture.
  1455. if (!texProxy) {
  1456. texProxy = GrSurfaceProxy::Copy(fContext, fRenderTargetProxy.get(),
  1457. GrMipMapped::kNo, srcRect, SkBackingFit::kApprox,
  1458. SkBudgeted::kNo);
  1459. if (!texProxy) {
  1460. callback(context, nullptr, 0);
  1461. return;
  1462. }
  1463. srcRectToDraw = SkRect::MakeWH(srcRect.width(), srcRect.height());
  1464. }
  1465. rtc = direct->priv().makeDeferredRenderTargetContext(
  1466. SkBackingFit::kApprox, srcRect.width(), srcRect.height(),
  1467. this->colorSpaceInfo().colorType(), info.refColorSpace(), 1, GrMipMapped::kNo,
  1468. kTopLeft_GrSurfaceOrigin);
  1469. if (!rtc) {
  1470. callback(context, nullptr, 0);
  1471. return;
  1472. }
  1473. rtc->drawTexture(GrNoClip(), std::move(texProxy), GrSamplerState::Filter::kNearest,
  1474. SkBlendMode::kSrc, SK_PMColor4fWHITE, srcRectToDraw,
  1475. SkRect::MakeWH(srcRect.width(), srcRect.height()), GrAA::kNo,
  1476. GrQuadAAFlags::kNone, SkCanvas::kFast_SrcRectConstraint, SkMatrix::I(),
  1477. std::move(xform));
  1478. x = y = 0;
  1479. } else {
  1480. rtc = sk_ref_sp(this);
  1481. }
  1482. }
  1483. return rtc->asyncReadPixels(SkIRect::MakeXYWH(x, y, info.width(), info.height()),
  1484. info.colorType(), callback, context);
  1485. }
  1486. GrRenderTargetContext::PixelTransferResult GrRenderTargetContext::transferPixels(
  1487. GrColorType dstCT, const SkIRect& rect) {
  1488. SkASSERT(rect.fLeft >= 0 && rect.fRight <= this->width());
  1489. SkASSERT(rect.fTop >= 0 && rect.fBottom <= this->height());
  1490. auto direct = fContext->priv().asDirectContext();
  1491. if (!direct) {
  1492. return {};
  1493. }
  1494. if (fRenderTargetProxy->wrapsVkSecondaryCB()) {
  1495. return {};
  1496. }
  1497. auto supportedRead = this->caps()->supportedReadPixelsColorType(
  1498. this->colorSpaceInfo().colorType(), fRenderTargetProxy->backendFormat(), dstCT);
  1499. // Fail if read color type does not have all of dstCT's color channels and those missing color
  1500. // channels are in the src.
  1501. uint32_t dstComponents = GrColorTypeComponentFlags(dstCT);
  1502. uint32_t legalReadComponents = GrColorTypeComponentFlags(supportedRead.fColorType);
  1503. uint32_t srcComponents = GrColorTypeComponentFlags(this->colorSpaceInfo().colorType());
  1504. if ((~legalReadComponents & dstComponents) & srcComponents) {
  1505. return {};
  1506. }
  1507. if (!this->caps()->transferBufferSupport() ||
  1508. !this->caps()->transferFromOffsetAlignment(supportedRead.fColorType)) {
  1509. return {};
  1510. }
  1511. size_t rowBytes = GrColorTypeBytesPerPixel(supportedRead.fColorType) * rect.width();
  1512. size_t size = rowBytes * rect.height();
  1513. auto buffer = direct->priv().resourceProvider()->createBuffer(
  1514. size, GrGpuBufferType::kXferGpuToCpu, GrAccessPattern::kStream_GrAccessPattern);
  1515. if (!buffer) {
  1516. return {};
  1517. }
  1518. auto srcRect = rect;
  1519. bool flip = this->origin() == kBottomLeft_GrSurfaceOrigin;
  1520. if (flip) {
  1521. srcRect = SkIRect::MakeLTRB(rect.fLeft, this->height() - rect.fBottom, rect.fRight,
  1522. this->height() - rect.fTop);
  1523. }
  1524. auto op = GrTransferFromOp::Make(fContext, srcRect, supportedRead.fColorType, buffer, 0);
  1525. this->getRTOpList()->addOp(std::move(op), *this->caps());
  1526. PixelTransferResult result;
  1527. result.fTransferBuffer = std::move(buffer);
  1528. if (supportedRead.fColorType != dstCT || supportedRead.fSwizzle != GrSwizzle("rgba") || flip) {
  1529. result.fPixelConverter = [w = rect.width(), h = rect.height(), dstCT, supportedRead](
  1530. void* dst, const void* src) {
  1531. // We're using kPremul here for src and dst simply because we don't want any alpha type
  1532. // conversions.
  1533. GrPixelInfo srcInfo(supportedRead.fColorType, kPremul_SkAlphaType, nullptr, w, h);
  1534. GrPixelInfo dstInfo(dstCT, kPremul_SkAlphaType, nullptr, w, h);
  1535. GrConvertPixels(dstInfo, dst, dstInfo.minRowBytes(),
  1536. srcInfo, src, srcInfo.minRowBytes(),
  1537. /* flipY = */ false, supportedRead.fSwizzle);
  1538. };
  1539. }
  1540. return result;
  1541. }
  1542. void GrRenderTargetContext::asyncReadPixels(const SkIRect& rect, SkColorType colorType,
  1543. ReadPixelsCallback callback,
  1544. ReadPixelsContext context) {
  1545. SkASSERT(rect.fLeft >= 0 && rect.fRight <= this->width());
  1546. SkASSERT(rect.fTop >= 0 && rect.fBottom <= this->height());
  1547. auto transferResult = this->transferPixels(SkColorTypeToGrColorType(colorType), rect);
  1548. if (!transferResult.fTransferBuffer) {
  1549. SkAutoPixmapStorage pm;
  1550. auto ii = SkImageInfo::Make(rect.width(), rect.height(), colorType,
  1551. this->colorSpaceInfo().alphaType(),
  1552. this->colorSpaceInfo().refColorSpace());
  1553. pm.alloc(ii);
  1554. if (!this->readPixels(ii, pm.writable_addr(), pm.rowBytes(), {rect.fLeft, rect.fTop})) {
  1555. callback(context, nullptr, 0);
  1556. }
  1557. callback(context, pm.addr(), pm.rowBytes());
  1558. return;
  1559. }
  1560. struct FinishContext {
  1561. ReadPixelsCallback* fClientCallback;
  1562. ReadPixelsContext fClientContext;
  1563. int fW, fH;
  1564. SkColorType fColorType;
  1565. PixelTransferResult fTransferResult;
  1566. };
  1567. // Assumption is that the caller would like to flush. We could take a parameter or require an
  1568. // explicit flush from the caller. We'd have to have a way to defer attaching the finish
  1569. // callback to GrGpu until after the next flush that flushes our op list, though.
  1570. auto* finishContext = new FinishContext{callback, context, rect.width(),
  1571. rect.height(), colorType, std::move(transferResult)};
  1572. auto finishCallback = [](GrGpuFinishedContext c) {
  1573. const auto* context = reinterpret_cast<const FinishContext*>(c);
  1574. const void* data = context->fTransferResult.fTransferBuffer->map();
  1575. if (!data) {
  1576. (*context->fClientCallback)(context->fClientContext, nullptr, 0);
  1577. delete context;
  1578. return;
  1579. }
  1580. std::unique_ptr<char[]> tmp;
  1581. size_t rowBytes = context->fW * SkColorTypeBytesPerPixel(context->fColorType);
  1582. if (context->fTransferResult.fPixelConverter) {
  1583. tmp.reset(new char[rowBytes * context->fH]);
  1584. context->fTransferResult.fPixelConverter(tmp.get(), data);
  1585. data = tmp.get();
  1586. }
  1587. (*context->fClientCallback)(context->fClientContext, data, rowBytes);
  1588. delete context;
  1589. };
  1590. GrFlushInfo flushInfo;
  1591. flushInfo.fFinishedContext = finishContext;
  1592. flushInfo.fFinishedProc = finishCallback;
  1593. this->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  1594. }
  1595. void GrRenderTargetContext::asyncRescaleAndReadPixelsYUV420(
  1596. SkYUVColorSpace yuvColorSpace, sk_sp<SkColorSpace> dstColorSpace, const SkIRect& srcRect,
  1597. int dstW, int dstH, RescaleGamma rescaleGamma, SkFilterQuality rescaleQuality,
  1598. ReadPixelsCallbackYUV420 callback, ReadPixelsContext context) {
  1599. SkASSERT(srcRect.fLeft >= 0 && srcRect.fRight <= this->width());
  1600. SkASSERT(srcRect.fTop >= 0 && srcRect.fBottom <= this->height());
  1601. SkASSERT((dstW % 2 == 0) && (dstH % 2 == 0));
  1602. auto direct = fContext->priv().asDirectContext();
  1603. if (!direct) {
  1604. callback(context, nullptr, nullptr);
  1605. return;
  1606. }
  1607. if (fRenderTargetProxy->wrapsVkSecondaryCB()) {
  1608. callback(context, nullptr, nullptr);
  1609. return;
  1610. }
  1611. if (dstW & 0x1) {
  1612. return;
  1613. }
  1614. int x = srcRect.fLeft;
  1615. int y = srcRect.fTop;
  1616. auto rtc = sk_ref_sp(this);
  1617. bool needsRescale = srcRect.width() != dstW || srcRect.height() != dstH;
  1618. if (needsRescale) {
  1619. // We assume the caller wants kPremul. There is no way to indicate a preference.
  1620. auto info = SkImageInfo::Make(dstW, dstH, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
  1621. dstColorSpace);
  1622. // TODO: Incorporate the YUV conversion into last pass of rescaling.
  1623. rtc = this->rescale(info, srcRect, rescaleGamma, rescaleQuality);
  1624. if (!rtc) {
  1625. callback(context, nullptr, nullptr);
  1626. return;
  1627. }
  1628. SkASSERT(SkColorSpace::Equals(rtc->colorSpaceInfo().colorSpace(), info.colorSpace()));
  1629. SkASSERT(rtc->origin() == kTopLeft_GrSurfaceOrigin);
  1630. x = y = 0;
  1631. } else {
  1632. // We assume the caller wants kPremul. There is no way to indicate a preference.
  1633. sk_sp<GrColorSpaceXform> xform = GrColorSpaceXform::Make(
  1634. this->colorSpaceInfo().colorSpace(), this->colorSpaceInfo().alphaType(),
  1635. dstColorSpace.get(), kPremul_SkAlphaType);
  1636. if (xform) {
  1637. sk_sp<GrTextureProxy> texProxy = this->asTextureProxyRef();
  1638. // TODO: Do something if the input is not a texture already.
  1639. if (!texProxy) {
  1640. callback(context, nullptr, nullptr);
  1641. return;
  1642. }
  1643. SkRect srcRectToDraw = SkRect::Make(srcRect);
  1644. rtc = direct->priv().makeDeferredRenderTargetContext(
  1645. SkBackingFit::kApprox, dstW, dstH, this->colorSpaceInfo().colorType(),
  1646. dstColorSpace, 1, GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
  1647. if (!rtc) {
  1648. callback(context, nullptr, nullptr);
  1649. return;
  1650. }
  1651. rtc->drawTexture(GrNoClip(), std::move(texProxy), GrSamplerState::Filter::kNearest,
  1652. SkBlendMode::kSrc, SK_PMColor4fWHITE, srcRectToDraw,
  1653. SkRect::MakeWH(srcRect.width(), srcRect.height()), GrAA::kNo,
  1654. GrQuadAAFlags::kNone, SkCanvas::kFast_SrcRectConstraint, SkMatrix::I(),
  1655. std::move(xform));
  1656. x = y = 0;
  1657. }
  1658. }
  1659. auto srcProxy = rtc->asTextureProxyRef();
  1660. // TODO: Do something if the input is not a texture already.
  1661. if (!srcProxy) {
  1662. callback(context, nullptr, nullptr);
  1663. return;
  1664. }
  1665. auto yRTC = direct->priv().makeDeferredRenderTargetContextWithFallback(
  1666. SkBackingFit::kApprox, dstW, dstH, GrColorType::kAlpha_8, dstColorSpace, 1,
  1667. GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
  1668. auto uRTC = direct->priv().makeDeferredRenderTargetContextWithFallback(
  1669. SkBackingFit::kApprox, dstW / 2, dstH / 2, GrColorType::kAlpha_8, dstColorSpace, 1,
  1670. GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
  1671. auto vRTC = direct->priv().makeDeferredRenderTargetContextWithFallback(
  1672. SkBackingFit::kApprox, dstW / 2, dstH / 2, GrColorType::kAlpha_8, dstColorSpace, 1,
  1673. GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
  1674. if (!yRTC || !uRTC || !vRTC) {
  1675. callback(context, nullptr, nullptr);
  1676. return;
  1677. }
  1678. static constexpr float kRec601M[] {
  1679. 65.481f / 255, 128.553f / 255, 24.966f / 255, 16.f / 255, // y
  1680. -37.797f / 255, -74.203f / 255, 112.0f / 255, 128.f / 255, // u
  1681. 112.f / 255, -93.786f / 255, -18.214f / 255, 128.f / 255, // v
  1682. };
  1683. static constexpr float kRec709M[] {
  1684. 45.5594f / 255, 156.6288f / 255, 15.8118f / 255, 16.f / 255, // y
  1685. -25.6642f / 255, -86.3358f / 255, 112.f / 255, 128.f / 255, // u
  1686. 112.f / 255, -101.7303f / 255, -10.2697f / 255, 128.f / 255, // v
  1687. };
  1688. static constexpr float kJpegM[] {
  1689. 0.299f , 0.587f , 0.114f , 0.f / 255, // y
  1690. -0.168736f, -0.331264f, 0.5f , 128.f / 255, // u
  1691. 0.5f , -0.418688f, -0.081312f, 128.f / 255, // v
  1692. };
  1693. static constexpr float kIM[] {
  1694. 1.f, 0.f, 0.f, 0.f,
  1695. 0.f, 1.f, 0.f, 0.f,
  1696. 0.f, 0.f, 1.f, 0.f,
  1697. };
  1698. const float* baseM = kIM;
  1699. switch (yuvColorSpace) {
  1700. case kRec601_SkYUVColorSpace:
  1701. baseM = kRec601M;
  1702. break;
  1703. case kRec709_SkYUVColorSpace:
  1704. baseM = kRec709M;
  1705. break;
  1706. case kJPEG_SkYUVColorSpace:
  1707. baseM = kJpegM;
  1708. break;
  1709. case kIdentity_SkYUVColorSpace:
  1710. baseM = kIM;
  1711. break;
  1712. }
  1713. // TODO: Use one transfer buffer for all three planes to reduce map/unmap cost?
  1714. auto texMatrix = SkMatrix::MakeTrans(x, y);
  1715. SkRect dstRectY = SkRect::MakeWH(dstW, dstH);
  1716. SkRect dstRectUV = SkRect::MakeWH(dstW / 2, dstH / 2);
  1717. // This matrix generates (r,g,b,a) = (0, 0, 0, y)
  1718. float yM[20];
  1719. std::fill_n(yM, 15, 0.f);
  1720. yM[15] = baseM[0]; yM[16] = baseM[1]; yM[17] = baseM[2]; yM[18] = 0; yM[19] = baseM[3];
  1721. GrPaint yPaint;
  1722. yPaint.addColorTextureProcessor(srcProxy, texMatrix);
  1723. auto yFP = GrColorMatrixFragmentProcessor::Make(yM, false, true, false);
  1724. yPaint.addColorFragmentProcessor(std::move(yFP));
  1725. yPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
  1726. yRTC->fillRectToRect(GrNoClip(), std::move(yPaint), GrAA::kNo, SkMatrix::I(),
  1727. dstRectY, dstRectY);
  1728. auto yTransfer = yRTC->transferPixels(GrColorType::kAlpha_8,
  1729. SkIRect::MakeWH(yRTC->width(), yRTC->height()));
  1730. if (!yTransfer.fTransferBuffer) {
  1731. callback(context, nullptr, nullptr);
  1732. return;
  1733. }
  1734. texMatrix.preScale(2.f, 2.f);
  1735. // This matrix generates (r,g,b,a) = (0, 0, 0, u)
  1736. float uM[20];
  1737. std::fill_n(uM, 15, 0.f);
  1738. uM[15] = baseM[4]; uM[16] = baseM[5]; uM[17] = baseM[6]; uM[18] = 0; uM[19] = baseM[7];
  1739. GrPaint uPaint;
  1740. uPaint.addColorTextureProcessor(srcProxy, texMatrix, GrSamplerState::ClampBilerp());
  1741. auto uFP = GrColorMatrixFragmentProcessor::Make(uM, false, true, false);
  1742. uPaint.addColorFragmentProcessor(std::move(uFP));
  1743. uPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
  1744. uRTC->fillRectToRect(GrNoClip(), std::move(uPaint), GrAA::kNo, SkMatrix::I(),
  1745. dstRectUV, dstRectUV);
  1746. auto uTransfer = uRTC->transferPixels(GrColorType::kAlpha_8,
  1747. SkIRect::MakeWH(uRTC->width(), uRTC->height()));
  1748. if (!uTransfer.fTransferBuffer) {
  1749. callback(context, nullptr, nullptr);
  1750. return;
  1751. }
  1752. // This matrix generates (r,g,b,a) = (0, 0, 0, v)
  1753. float vM[20];
  1754. std::fill_n(vM, 15, 0.f);
  1755. vM[15] = baseM[8]; vM[16] = baseM[9]; vM[17] = baseM[10]; vM[18] = 0; vM[19] = baseM[11];
  1756. GrPaint vPaint;
  1757. vPaint.addColorTextureProcessor(srcProxy, texMatrix, GrSamplerState::ClampBilerp());
  1758. auto vFP = GrColorMatrixFragmentProcessor::Make(vM, false, true, false);
  1759. vPaint.addColorFragmentProcessor(std::move(vFP));
  1760. vPaint.setPorterDuffXPFactory(SkBlendMode::kSrc);
  1761. vRTC->fillRectToRect(GrNoClip(), std::move(vPaint), GrAA::kNo, SkMatrix::I(),
  1762. dstRectUV, dstRectUV);
  1763. auto vTransfer = vRTC->transferPixels(GrColorType::kAlpha_8,
  1764. SkIRect::MakeWH(vRTC->width(), vRTC->height()));
  1765. if (!vTransfer.fTransferBuffer) {
  1766. callback(context, nullptr, nullptr);
  1767. return;
  1768. }
  1769. struct FinishContext {
  1770. ReadPixelsCallbackYUV420* fClientCallback;
  1771. ReadPixelsContext fClientContext;
  1772. int fW, fH;
  1773. PixelTransferResult fYTransfer;
  1774. PixelTransferResult fUTransfer;
  1775. PixelTransferResult fVTransfer;
  1776. };
  1777. // Assumption is that the caller would like to flush. We could take a parameter or require an
  1778. // explicit flush from the caller. We'd have to have a way to defer attaching the finish
  1779. // callback to GrGpu until after the next flush that flushes our op list, though.
  1780. auto* finishContext = new FinishContext{callback,
  1781. context,
  1782. dstW,
  1783. dstH,
  1784. std::move(yTransfer),
  1785. std::move(uTransfer),
  1786. std::move(vTransfer)};
  1787. auto finishCallback = [](GrGpuFinishedContext c) {
  1788. const auto* context = reinterpret_cast<const FinishContext*>(c);
  1789. const void* y = context->fYTransfer.fTransferBuffer->map();
  1790. const void* u = context->fUTransfer.fTransferBuffer->map();
  1791. const void* v = context->fVTransfer.fTransferBuffer->map();
  1792. if (!y || !u || !v) {
  1793. if (y) {
  1794. context->fYTransfer.fTransferBuffer->unmap();
  1795. }
  1796. if (u) {
  1797. context->fUTransfer.fTransferBuffer->unmap();
  1798. }
  1799. if (v) {
  1800. context->fVTransfer.fTransferBuffer->unmap();
  1801. }
  1802. (*context->fClientCallback)(context->fClientContext, nullptr, 0);
  1803. delete context;
  1804. return;
  1805. }
  1806. size_t w = SkToSizeT(context->fW);
  1807. size_t h = SkToSizeT(context->fH);
  1808. std::unique_ptr<uint8_t[]> yTemp;
  1809. if (context->fYTransfer.fPixelConverter) {
  1810. yTemp.reset(new uint8_t[w * h]);
  1811. context->fYTransfer.fPixelConverter(yTemp.get(), y);
  1812. y = yTemp.get();
  1813. }
  1814. std::unique_ptr<uint8_t[]> uTemp;
  1815. if (context->fUTransfer.fPixelConverter) {
  1816. uTemp.reset(new uint8_t[w / 2 * h / 2]);
  1817. context->fUTransfer.fPixelConverter(uTemp.get(), u);
  1818. u = uTemp.get();
  1819. }
  1820. std::unique_ptr<uint8_t[]> vTemp;
  1821. if (context->fVTransfer.fPixelConverter) {
  1822. vTemp.reset(new uint8_t[w / 2 * h / 2]);
  1823. context->fVTransfer.fPixelConverter(vTemp.get(), v);
  1824. v = vTemp.get();
  1825. }
  1826. const void* data[] = {y, u, v};
  1827. size_t rowBytes[] = {w, w / 2, w / 2};
  1828. (*context->fClientCallback)(context->fClientContext, data, rowBytes);
  1829. context->fYTransfer.fTransferBuffer->unmap();
  1830. context->fUTransfer.fTransferBuffer->unmap();
  1831. context->fVTransfer.fTransferBuffer->unmap();
  1832. delete context;
  1833. };
  1834. GrFlushInfo flushInfo;
  1835. flushInfo.fFinishedContext = finishContext;
  1836. flushInfo.fFinishedProc = finishCallback;
  1837. this->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  1838. }
  1839. GrSemaphoresSubmitted GrRenderTargetContext::flush(SkSurface::BackendSurfaceAccess access,
  1840. const GrFlushInfo& info) {
  1841. ASSERT_SINGLE_OWNER
  1842. if (fContext->priv().abandoned()) {
  1843. return GrSemaphoresSubmitted::kNo;
  1844. }
  1845. SkDEBUGCODE(this->validate();)
  1846. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "flush", fContext);
  1847. return this->drawingManager()->flushSurface(fRenderTargetProxy.get(), access, info);
  1848. }
  1849. bool GrRenderTargetContext::waitOnSemaphores(int numSemaphores,
  1850. const GrBackendSemaphore waitSemaphores[]) {
  1851. ASSERT_SINGLE_OWNER
  1852. RETURN_FALSE_IF_ABANDONED
  1853. SkDEBUGCODE(this->validate();)
  1854. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "waitOnSemaphores", fContext);
  1855. AutoCheckFlush acf(this->drawingManager());
  1856. if (numSemaphores && !this->caps()->semaphoreSupport()) {
  1857. return false;
  1858. }
  1859. auto direct = fContext->priv().asDirectContext();
  1860. if (!direct) {
  1861. return false;
  1862. }
  1863. auto resourceProvider = direct->priv().resourceProvider();
  1864. for (int i = 0; i < numSemaphores; ++i) {
  1865. sk_sp<GrSemaphore> sema = resourceProvider->wrapBackendSemaphore(
  1866. waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait,
  1867. kAdopt_GrWrapOwnership);
  1868. std::unique_ptr<GrOp> waitOp(GrSemaphoreOp::MakeWait(fContext, std::move(sema),
  1869. fRenderTargetProxy.get()));
  1870. this->getRTOpList()->addWaitOp(std::move(waitOp), *this->caps());
  1871. }
  1872. return true;
  1873. }
  1874. void GrRenderTargetContext::insertEventMarker(const SkString& str) {
  1875. std::unique_ptr<GrOp> op(GrDebugMarkerOp::Make(fContext, fRenderTargetProxy.get(), str));
  1876. this->getRTOpList()->addOp(std::move(op), *this->caps());
  1877. }
  1878. const GrCaps* GrRenderTargetContext::caps() const {
  1879. return fContext->priv().caps();
  1880. }
  1881. void GrRenderTargetContext::drawPath(const GrClip& clip,
  1882. GrPaint&& paint,
  1883. GrAA aa,
  1884. const SkMatrix& viewMatrix,
  1885. const SkPath& path,
  1886. const GrStyle& style) {
  1887. ASSERT_SINGLE_OWNER
  1888. RETURN_IF_ABANDONED
  1889. SkDEBUGCODE(this->validate();)
  1890. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawPath", fContext);
  1891. GrShape shape(path, style);
  1892. this->drawShape(clip, std::move(paint), aa, viewMatrix, shape);
  1893. }
  1894. void GrRenderTargetContext::drawShape(const GrClip& clip,
  1895. GrPaint&& paint,
  1896. GrAA aa,
  1897. const SkMatrix& viewMatrix,
  1898. const GrShape& shape) {
  1899. ASSERT_SINGLE_OWNER
  1900. RETURN_IF_ABANDONED
  1901. SkDEBUGCODE(this->validate();)
  1902. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawShape", fContext);
  1903. if (shape.isEmpty()) {
  1904. if (shape.inverseFilled()) {
  1905. this->drawPaint(clip, std::move(paint), viewMatrix);
  1906. }
  1907. return;
  1908. }
  1909. AutoCheckFlush acf(this->drawingManager());
  1910. if (!shape.style().hasPathEffect()) {
  1911. GrAAType aaType = this->chooseAAType(aa);
  1912. SkRRect rrect;
  1913. // We can ignore the starting point and direction since there is no path effect.
  1914. bool inverted;
  1915. if (shape.asRRect(&rrect, nullptr, nullptr, &inverted) && !inverted) {
  1916. if (rrect.isRect()) {
  1917. this->drawRect(clip, std::move(paint), aa, viewMatrix, rrect.rect(),
  1918. &shape.style());
  1919. return;
  1920. } else if (rrect.isOval()) {
  1921. this->drawOval(clip, std::move(paint), aa, viewMatrix, rrect.rect(), shape.style());
  1922. return;
  1923. }
  1924. this->drawRRect(clip, std::move(paint), aa, viewMatrix, rrect, shape.style());
  1925. return;
  1926. } else if (GrAAType::kCoverage == aaType && shape.style().isSimpleFill() &&
  1927. viewMatrix.rectStaysRect()) {
  1928. // TODO: the rectStaysRect restriction could be lifted if we were willing to apply
  1929. // the matrix to all the points individually rather than just to the rect
  1930. SkRect rects[2];
  1931. if (shape.asNestedRects(rects)) {
  1932. // Concave AA paths are expensive - try to avoid them for special cases
  1933. std::unique_ptr<GrDrawOp> op = GrStrokeRectOp::MakeNested(
  1934. fContext, std::move(paint), viewMatrix, rects);
  1935. if (op) {
  1936. this->addDrawOp(clip, std::move(op));
  1937. }
  1938. // Returning here indicates that there is nothing to draw in this case.
  1939. return;
  1940. }
  1941. }
  1942. }
  1943. this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, shape);
  1944. }
  1945. bool GrRenderTargetContextPriv::drawAndStencilPath(const GrHardClip& clip,
  1946. const GrUserStencilSettings* ss,
  1947. SkRegion::Op op,
  1948. bool invert,
  1949. GrAA aa,
  1950. const SkMatrix& viewMatrix,
  1951. const SkPath& path) {
  1952. ASSERT_SINGLE_OWNER_PRIV
  1953. RETURN_FALSE_IF_ABANDONED_PRIV
  1954. SkDEBUGCODE(fRenderTargetContext->validate();)
  1955. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "drawAndStencilPath",
  1956. fRenderTargetContext->fContext);
  1957. if (path.isEmpty() && path.isInverseFillType()) {
  1958. GrPaint paint;
  1959. paint.setCoverageSetOpXPFactory(op, invert);
  1960. this->stencilRect(clip, ss, std::move(paint), GrAA::kNo, SkMatrix::I(),
  1961. SkRect::MakeIWH(fRenderTargetContext->width(),
  1962. fRenderTargetContext->height()));
  1963. return true;
  1964. }
  1965. AutoCheckFlush acf(fRenderTargetContext->drawingManager());
  1966. // An Assumption here is that path renderer would use some form of tweaking
  1967. // the src color (either the input alpha or in the frag shader) to implement
  1968. // aa. If we have some future driver-mojo path AA that can do the right
  1969. // thing WRT to the blend then we'll need some query on the PR.
  1970. GrAAType aaType = fRenderTargetContext->chooseAAType(aa);
  1971. bool hasUserStencilSettings = !ss->isUnused();
  1972. SkIRect clipConservativeBounds;
  1973. clip.getConservativeBounds(fRenderTargetContext->width(), fRenderTargetContext->height(),
  1974. &clipConservativeBounds, nullptr);
  1975. GrShape shape(path, GrStyle::SimpleFill());
  1976. GrPathRenderer::CanDrawPathArgs canDrawArgs;
  1977. canDrawArgs.fCaps = fRenderTargetContext->caps();
  1978. canDrawArgs.fProxy = fRenderTargetContext->proxy();
  1979. canDrawArgs.fViewMatrix = &viewMatrix;
  1980. canDrawArgs.fShape = &shape;
  1981. canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
  1982. canDrawArgs.fAAType = aaType;
  1983. SkASSERT(!fRenderTargetContext->wrapsVkSecondaryCB());
  1984. canDrawArgs.fTargetIsWrappedVkSecondaryCB = false;
  1985. canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
  1986. // Don't allow the SW renderer
  1987. GrPathRenderer* pr = fRenderTargetContext->drawingManager()->getPathRenderer(
  1988. canDrawArgs, false, GrPathRendererChain::DrawType::kStencilAndColor);
  1989. if (!pr) {
  1990. return false;
  1991. }
  1992. GrPaint paint;
  1993. paint.setCoverageSetOpXPFactory(op, invert);
  1994. GrPathRenderer::DrawPathArgs args{fRenderTargetContext->drawingManager()->getContext(),
  1995. std::move(paint),
  1996. ss,
  1997. fRenderTargetContext,
  1998. &clip,
  1999. &clipConservativeBounds,
  2000. &viewMatrix,
  2001. &shape,
  2002. aaType,
  2003. fRenderTargetContext->colorSpaceInfo().isLinearlyBlended()};
  2004. pr->drawPath(args);
  2005. return true;
  2006. }
  2007. SkBudgeted GrRenderTargetContextPriv::isBudgeted() const {
  2008. ASSERT_SINGLE_OWNER_PRIV
  2009. if (fRenderTargetContext->fContext->priv().abandoned()) {
  2010. return SkBudgeted::kNo;
  2011. }
  2012. SkDEBUGCODE(fRenderTargetContext->validate();)
  2013. return fRenderTargetContext->fRenderTargetProxy->isBudgeted();
  2014. }
  2015. void GrRenderTargetContext::drawShapeUsingPathRenderer(const GrClip& clip,
  2016. GrPaint&& paint,
  2017. GrAA aa,
  2018. const SkMatrix& viewMatrix,
  2019. const GrShape& originalShape) {
  2020. ASSERT_SINGLE_OWNER
  2021. RETURN_IF_ABANDONED
  2022. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "internalDrawPath", fContext);
  2023. if (!viewMatrix.isFinite() || !originalShape.bounds().isFinite()) {
  2024. return;
  2025. }
  2026. SkIRect clipConservativeBounds;
  2027. clip.getConservativeBounds(this->width(), this->height(), &clipConservativeBounds, nullptr);
  2028. GrShape tempShape;
  2029. GrAAType aaType = this->chooseAAType(aa);
  2030. GrPathRenderer::CanDrawPathArgs canDrawArgs;
  2031. canDrawArgs.fCaps = this->caps();
  2032. canDrawArgs.fProxy = this->proxy();
  2033. canDrawArgs.fViewMatrix = &viewMatrix;
  2034. canDrawArgs.fShape = &originalShape;
  2035. canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
  2036. canDrawArgs.fTargetIsWrappedVkSecondaryCB = this->wrapsVkSecondaryCB();
  2037. canDrawArgs.fHasUserStencilSettings = false;
  2038. GrPathRenderer* pr;
  2039. static constexpr GrPathRendererChain::DrawType kType = GrPathRendererChain::DrawType::kColor;
  2040. if (originalShape.isEmpty() && !originalShape.inverseFilled()) {
  2041. return;
  2042. }
  2043. canDrawArgs.fAAType = aaType;
  2044. // Try a 1st time without applying any of the style to the geometry (and barring sw)
  2045. pr = this->drawingManager()->getPathRenderer(canDrawArgs, false, kType);
  2046. SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
  2047. if (!pr && originalShape.style().pathEffect()) {
  2048. // It didn't work above, so try again with the path effect applied.
  2049. tempShape = originalShape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
  2050. if (tempShape.isEmpty()) {
  2051. return;
  2052. }
  2053. canDrawArgs.fShape = &tempShape;
  2054. pr = this->drawingManager()->getPathRenderer(canDrawArgs, false, kType);
  2055. }
  2056. if (!pr) {
  2057. if (canDrawArgs.fShape->style().applies()) {
  2058. tempShape = canDrawArgs.fShape->applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec,
  2059. styleScale);
  2060. if (tempShape.isEmpty()) {
  2061. return;
  2062. }
  2063. canDrawArgs.fShape = &tempShape;
  2064. // This time, allow SW renderer
  2065. pr = this->drawingManager()->getPathRenderer(canDrawArgs, true, kType);
  2066. } else {
  2067. pr = this->drawingManager()->getSoftwarePathRenderer();
  2068. }
  2069. }
  2070. if (!pr) {
  2071. #ifdef SK_DEBUG
  2072. SkDebugf("Unable to find path renderer compatible with path.\n");
  2073. #endif
  2074. return;
  2075. }
  2076. GrPathRenderer::DrawPathArgs args{this->drawingManager()->getContext(),
  2077. std::move(paint),
  2078. &GrUserStencilSettings::kUnused,
  2079. this,
  2080. &clip,
  2081. &clipConservativeBounds,
  2082. &viewMatrix,
  2083. canDrawArgs.fShape,
  2084. aaType,
  2085. this->colorSpaceInfo().isLinearlyBlended()};
  2086. pr->drawPath(args);
  2087. }
  2088. static void op_bounds(SkRect* bounds, const GrOp* op) {
  2089. *bounds = op->bounds();
  2090. if (op->hasZeroArea()) {
  2091. if (op->hasAABloat()) {
  2092. bounds->outset(0.5f, 0.5f);
  2093. } else {
  2094. // We don't know which way the particular GPU will snap lines or points at integer
  2095. // coords. So we ensure that the bounds is large enough for either snap.
  2096. SkRect before = *bounds;
  2097. bounds->roundOut(bounds);
  2098. if (bounds->fLeft == before.fLeft) {
  2099. bounds->fLeft -= 1;
  2100. }
  2101. if (bounds->fTop == before.fTop) {
  2102. bounds->fTop -= 1;
  2103. }
  2104. if (bounds->fRight == before.fRight) {
  2105. bounds->fRight += 1;
  2106. }
  2107. if (bounds->fBottom == before.fBottom) {
  2108. bounds->fBottom += 1;
  2109. }
  2110. }
  2111. }
  2112. }
  2113. void GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<GrDrawOp> op,
  2114. const std::function<WillAddOpFn>& willAddFn) {
  2115. ASSERT_SINGLE_OWNER
  2116. if (fContext->priv().abandoned()) {
  2117. fContext->priv().opMemoryPool()->release(std::move(op));
  2118. return;
  2119. }
  2120. SkDEBUGCODE(this->validate();)
  2121. SkDEBUGCODE(op->fAddDrawOpCalled = true;)
  2122. GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "addDrawOp", fContext);
  2123. // Setup clip
  2124. SkRect bounds;
  2125. op_bounds(&bounds, op.get());
  2126. GrAppliedClip appliedClip;
  2127. GrDrawOp::FixedFunctionFlags fixedFunctionFlags = op->fixedFunctionFlags();
  2128. bool usesHWAA = fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesHWAA;
  2129. bool usesStencil = fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesStencil;
  2130. if (usesStencil) {
  2131. this->setNeedsStencil(usesHWAA);
  2132. }
  2133. if (!clip.apply(fContext, this, usesHWAA, usesStencil, &appliedClip, &bounds)) {
  2134. fContext->priv().opMemoryPool()->release(std::move(op));
  2135. return;
  2136. }
  2137. SkASSERT((!usesStencil && !appliedClip.hasStencilClip()) || (fNumStencilSamples > 0));
  2138. GrClampType clampType = GrColorTypeClampType(this->colorSpaceInfo().colorType());
  2139. // MIXED SAMPLES TODO: If we start using mixed samples for clips we will need to check the clip
  2140. // here as well.
  2141. bool hasMixedSampledCoverage = (usesHWAA && this->numSamples() <= 1);
  2142. #ifdef SK_DEBUG
  2143. if (hasMixedSampledCoverage) {
  2144. SkASSERT(usesStencil);
  2145. SkASSERT(fRenderTargetProxy->canUseMixedSamples(*this->caps()));
  2146. }
  2147. #endif
  2148. GrProcessorSet::Analysis analysis = op->finalize(
  2149. *this->caps(), &appliedClip, hasMixedSampledCoverage, clampType);
  2150. GrXferProcessor::DstProxy dstProxy;
  2151. if (analysis.requiresDstTexture()) {
  2152. if (!this->setupDstProxy(this->asRenderTargetProxy(), clip, *op, &dstProxy)) {
  2153. fContext->priv().opMemoryPool()->release(std::move(op));
  2154. return;
  2155. }
  2156. }
  2157. op->setClippedBounds(bounds);
  2158. auto opList = this->getRTOpList();
  2159. if (willAddFn) {
  2160. willAddFn(op.get(), opList->uniqueID());
  2161. }
  2162. opList->addDrawOp(std::move(op), analysis, std::move(appliedClip), dstProxy, *this->caps());
  2163. }
  2164. bool GrRenderTargetContext::setupDstProxy(GrRenderTargetProxy* rtProxy, const GrClip& clip,
  2165. const GrOp& op, GrXferProcessor::DstProxy* dstProxy) {
  2166. // If we are wrapping a vulkan secondary command buffer, we can't make a dst copy because we
  2167. // don't actually have a VkImage to make a copy of. Additionally we don't have the power to
  2168. // start and stop the render pass in order to make the copy.
  2169. if (rtProxy->wrapsVkSecondaryCB()) {
  2170. return false;
  2171. }
  2172. if (this->caps()->textureBarrierSupport()) {
  2173. if (GrTextureProxy* texProxy = rtProxy->asTextureProxy()) {
  2174. // The render target is a texture, so we can read from it directly in the shader. The XP
  2175. // will be responsible to detect this situation and request a texture barrier.
  2176. dstProxy->setProxy(sk_ref_sp(texProxy));
  2177. dstProxy->setOffset(0, 0);
  2178. return true;
  2179. }
  2180. }
  2181. SkIRect copyRect = SkIRect::MakeWH(rtProxy->width(), rtProxy->height());
  2182. SkIRect clippedRect;
  2183. clip.getConservativeBounds(rtProxy->width(), rtProxy->height(), &clippedRect);
  2184. SkRect opBounds = op.bounds();
  2185. // If the op has aa bloating or is a infinitely thin geometry (hairline) outset the bounds by
  2186. // 0.5 pixels.
  2187. if (op.hasAABloat() || op.hasZeroArea()) {
  2188. opBounds.outset(0.5f, 0.5f);
  2189. // An antialiased/hairline draw can sometimes bleed outside of the clips bounds. For
  2190. // performance we may ignore the clip when the draw is entirely inside the clip is float
  2191. // space but will hit pixels just outside the clip when actually rasterizing.
  2192. clippedRect.outset(1, 1);
  2193. clippedRect.intersect(SkIRect::MakeWH(rtProxy->width(), rtProxy->height()));
  2194. }
  2195. SkIRect opIBounds;
  2196. opBounds.roundOut(&opIBounds);
  2197. if (!clippedRect.intersect(opIBounds)) {
  2198. #ifdef SK_DEBUG
  2199. GrCapsDebugf(this->caps(), "setupDstTexture: Missed an early reject bailing on draw.");
  2200. #endif
  2201. return false;
  2202. }
  2203. // MSAA consideration: When there is support for reading MSAA samples in the shader we could
  2204. // have per-sample dst values by making the copy multisampled.
  2205. GrCaps::DstCopyRestrictions restrictions = this->caps()->getDstCopyRestrictions(rtProxy);
  2206. if (!restrictions.fMustCopyWholeSrc) {
  2207. copyRect = clippedRect;
  2208. }
  2209. SkIPoint dstOffset;
  2210. SkBackingFit fit;
  2211. if (restrictions.fRectsMustMatch == GrSurfaceProxy::RectsMustMatch::kYes) {
  2212. dstOffset = {0, 0};
  2213. fit = SkBackingFit::kExact;
  2214. } else {
  2215. dstOffset = {copyRect.fLeft, copyRect.fTop};
  2216. fit = SkBackingFit::kApprox;
  2217. }
  2218. sk_sp<GrTextureProxy> newProxy =
  2219. GrSurfaceProxy::Copy(fContext, rtProxy, GrMipMapped::kNo, copyRect, fit,
  2220. SkBudgeted::kYes, restrictions.fRectsMustMatch);
  2221. SkASSERT(newProxy);
  2222. dstProxy->setProxy(std::move(newProxy));
  2223. dstProxy->setOffset(dstOffset);
  2224. return true;
  2225. }
  2226. bool GrRenderTargetContext::blitTexture(GrTextureProxy* src, const SkIRect& srcRect,
  2227. const SkIPoint& dstPoint) {
  2228. SkIRect clippedSrcRect;
  2229. SkIPoint clippedDstPoint;
  2230. if (!GrClipSrcRectAndDstPoint(this->asSurfaceProxy()->isize(), src->isize(), srcRect, dstPoint,
  2231. &clippedSrcRect, &clippedDstPoint)) {
  2232. return false;
  2233. }
  2234. GrPaint paint;
  2235. paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
  2236. auto fp = GrSimpleTextureEffect::Make(sk_ref_sp(src->asTextureProxy()),
  2237. SkMatrix::I());
  2238. if (!fp) {
  2239. return false;
  2240. }
  2241. paint.addColorFragmentProcessor(std::move(fp));
  2242. this->fillRectToRect(
  2243. GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
  2244. SkRect::MakeXYWH(clippedDstPoint.fX, clippedDstPoint.fY, clippedSrcRect.width(),
  2245. clippedSrcRect.height()),
  2246. SkRect::Make(clippedSrcRect));
  2247. return true;
  2248. }