blob: fc446bfea58893e6de92217dafdb7cafdeba7168 [file] [log] [blame]
robertphillipsea461502015-05-26 11:38:03 -07001/*
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
Brian Osman11052242016-10-27 14:47:55 -04008#include "GrRenderTargetContext.h"
Brian Salomon6d4b65e2017-05-03 17:06:09 -04009#include "../private/GrAuditTrail.h"
Jim Van Verth3af1af92017-05-18 15:06:54 -040010#include "../private/SkShadowFlags.h"
Brian Salomon467921e2017-03-06 16:17:12 -050011#include "GrAppliedClip.h"
Greg Daniela5cb7812017-06-16 09:45:32 -040012#include "GrBackendSemaphore.h"
Brian Salomonf18b1d82017-10-27 11:30:49 -040013#include "GrBlurUtils.h"
Brian Salomon5ec9def2016-12-20 15:34:05 -050014#include "GrColor.h"
Robert Phillipse78b7252017-04-06 07:59:41 -040015#include "GrContextPriv.h"
robertphillips77a2e522015-10-17 07:43:27 -070016#include "GrDrawingManager.h"
csmartdalton02fa32c2016-08-19 13:29:27 -070017#include "GrFixedClip.h"
robertphillips714712b2016-08-04 06:20:45 -070018#include "GrGpuResourcePriv.h"
Robert Phillips9d6c64f2017-09-14 10:56:45 -040019#include "GrOpList.h"
robertphillipsea461502015-05-26 11:38:03 -070020#include "GrPathRenderer.h"
Brian Salomon57caa662017-10-18 12:21:05 +000021#include "GrQuad.h"
robertphillips2334fb62015-06-17 05:43:33 -070022#include "GrRenderTarget.h"
Brian Salomon5ec9def2016-12-20 15:34:05 -050023#include "GrRenderTargetContextPriv.h"
bsalomon473addf2015-10-02 07:49:05 -070024#include "GrResourceProvider.h"
Brian Salomon653f42f2018-07-10 10:07:31 -040025#include "GrShape.h"
Brian Salomon467921e2017-03-06 16:17:12 -050026#include "GrStencilAttachment.h"
Brian Salomon653f42f2018-07-10 10:07:31 -040027#include "GrStyle.h"
Brian Salomondcbb9d92017-07-19 10:53:20 -040028#include "GrTracing.h"
Greg Daniel64cc9aa2018-10-19 13:54:56 -040029#include "SkDrawable.h"
Jim Van Verth1af03d42017-07-31 09:34:58 -040030#include "SkDrawShadowInfo.h"
Herb Derby8378dfb2018-08-30 14:50:04 -040031#include "SkGlyphRunPainter.h"
Brian Salomonf18b1d82017-10-27 11:30:49 -040032#include "SkGr.h"
Brian Salomon467921e2017-03-06 16:17:12 -050033#include "SkLatticeIter.h"
34#include "SkMatrixPriv.h"
Mike Reed242135a2018-02-22 13:41:39 -050035#include "SkRRectPriv.h"
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040036#include "SkShadowUtils.h"
robertphillips2d70dcb2015-10-06 07:38:23 -070037#include "SkSurfacePriv.h"
Brian Salomon467921e2017-03-06 16:17:12 -050038#include "effects/GrRRectEffect.h"
Brian Salomonf18b1d82017-10-27 11:30:49 -040039#include "ops/GrAtlasTextOp.h"
Brian Salomon89527432016-12-16 09:52:16 -050040#include "ops/GrClearOp.h"
Robert Phillipsb9a02a12017-04-06 11:08:40 -040041#include "ops/GrClearStencilClipOp.h"
Robert Phillips65a88fa2017-08-08 08:36:22 -040042#include "ops/GrDebugMarkerOp.h"
Greg Daniel64cc9aa2018-10-19 13:54:56 -040043#include "ops/GrDrawableOp.h"
Brian Salomon0f353322017-05-03 20:58:59 +000044#include "ops/GrDrawAtlasOp.h"
Brian Salomon6d4b65e2017-05-03 17:06:09 -040045#include "ops/GrDrawOp.h"
Brian Salomon89527432016-12-16 09:52:16 -050046#include "ops/GrDrawVerticesOp.h"
47#include "ops/GrLatticeOp.h"
48#include "ops/GrOp.h"
49#include "ops/GrOvalOpFactory.h"
50#include "ops/GrRectOpFactory.h"
51#include "ops/GrRegionOp.h"
Greg Daniela5cb7812017-06-16 09:45:32 -040052#include "ops/GrSemaphoreOp.h"
Brian Salomon89527432016-12-16 09:52:16 -050053#include "ops/GrShadowRRectOp.h"
Brian Salomon467921e2017-03-06 16:17:12 -050054#include "ops/GrStencilPathOp.h"
Brian Salomon34169692017-08-28 15:32:01 -040055#include "ops/GrTextureOp.h"
Herb Derby26cbe512018-05-24 14:39:01 -040056#include "text/GrTextContext.h"
Herb Derbyc1b482c2018-08-09 15:02:27 -040057#include "text/GrTextTarget.h"
Brian Salomonf18b1d82017-10-27 11:30:49 -040058
Herb Derbyc1b482c2018-08-09 15:02:27 -040059class GrRenderTargetContext::TextTarget : public GrTextTarget {
Brian Salomonf18b1d82017-10-27 11:30:49 -040060public:
61 TextTarget(GrRenderTargetContext* renderTargetContext)
Herb Derbyc1b482c2018-08-09 15:02:27 -040062 : GrTextTarget(renderTargetContext->width(), renderTargetContext->height(),
Brian Salomonf18b1d82017-10-27 11:30:49 -040063 renderTargetContext->colorSpaceInfo())
Herb Derby74c6ed32018-07-28 18:07:54 -040064 , fRenderTargetContext(renderTargetContext)
Herb Derby65956872018-08-21 16:55:04 -040065 , fGlyphPainter{*renderTargetContext}{}
Brian Salomonf18b1d82017-10-27 11:30:49 -040066
Robert Phillips7c525e62018-06-12 10:11:12 -040067 void addDrawOp(const GrClip& clip, std::unique_ptr<GrAtlasTextOp> op) override {
Brian Salomonf18b1d82017-10-27 11:30:49 -040068 fRenderTargetContext->addDrawOp(clip, std::move(op));
69 }
70
Robert Phillips46a13382018-08-23 13:53:01 -040071 void drawShape(const GrClip& clip, const SkPaint& paint,
72 const SkMatrix& viewMatrix, const GrShape& shape) override {
Robert Phillips27927a52018-08-20 13:18:12 -040073 GrBlurUtils::drawShapeWithMaskFilter(fRenderTargetContext->fContext, fRenderTargetContext,
74 clip, paint, viewMatrix, shape);
Brian Salomonf18b1d82017-10-27 11:30:49 -040075 }
76
77 void makeGrPaint(GrMaskFormat maskFormat, const SkPaint& skPaint, const SkMatrix& viewMatrix,
Robert Phillips7c525e62018-06-12 10:11:12 -040078 GrPaint* grPaint) override {
Brian Salomonf18b1d82017-10-27 11:30:49 -040079 GrContext* context = fRenderTargetContext->fContext;
80 const GrColorSpaceInfo& colorSpaceInfo = fRenderTargetContext->colorSpaceInfo();
81 if (kARGB_GrMaskFormat == maskFormat) {
82 SkPaintToGrPaintWithPrimitiveColor(context, colorSpaceInfo, skPaint, grPaint);
83 } else {
84 SkPaintToGrPaint(context, colorSpaceInfo, skPaint, viewMatrix, grPaint);
85 }
86 }
87
Robert Phillips7c525e62018-06-12 10:11:12 -040088 GrContext* getContext() override {
89 return fRenderTargetContext->fContext;
90 }
91
Herb Derby65956872018-08-21 16:55:04 -040092 SkGlyphRunListPainter* glyphPainter() override {
93 return &fGlyphPainter;
Herb Derby74c6ed32018-07-28 18:07:54 -040094 }
95
Brian Salomonf18b1d82017-10-27 11:30:49 -040096private:
97 GrRenderTargetContext* fRenderTargetContext;
Herb Derby65956872018-08-21 16:55:04 -040098 SkGlyphRunListPainter fGlyphPainter;
Herb Derby74c6ed32018-07-28 18:07:54 -040099
Brian Salomonf18b1d82017-10-27 11:30:49 -0400100};
joshualittbc907352016-01-13 06:45:40 -0800101
Robert Phillips72152832017-01-25 17:31:35 -0500102#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this->drawingManager()->getContext())
joshualitt1de610a2016-01-06 08:26:09 -0800103#define ASSERT_SINGLE_OWNER \
Robert Phillipsa90aa2b2017-04-10 08:19:26 -0400104 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
robertphillips391395d2016-03-02 09:26:36 -0800105#define ASSERT_SINGLE_OWNER_PRIV \
Robert Phillipsa90aa2b2017-04-10 08:19:26 -0400106 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)
Robert Phillips72152832017-01-25 17:31:35 -0500107#define RETURN_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return; }
108#define RETURN_IF_ABANDONED_PRIV if (fRenderTargetContext->drawingManager()->wasAbandoned()) { return; }
109#define RETURN_FALSE_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return false; }
110#define RETURN_FALSE_IF_ABANDONED_PRIV if (fRenderTargetContext->drawingManager()->wasAbandoned()) { return false; }
111#define RETURN_NULL_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return nullptr; }
robertphillipsea461502015-05-26 11:38:03 -0700112
Brian Salomone225b562017-06-14 13:00:03 -0400113//////////////////////////////////////////////////////////////////////////////
114
115GrAAType GrChooseAAType(GrAA aa, GrFSAAType fsaaType, GrAllowMixedSamples allowMixedSamples,
116 const GrCaps& caps) {
117 if (GrAA::kNo == aa) {
118 // On some devices we cannot disable MSAA if it is enabled so we make the AA type reflect
119 // that.
120 if (fsaaType == GrFSAAType::kUnifiedMSAA && !caps.multisampleDisableSupport()) {
121 return GrAAType::kMSAA;
122 }
123 return GrAAType::kNone;
124 }
125 switch (fsaaType) {
126 case GrFSAAType::kNone:
127 return GrAAType::kCoverage;
128 case GrFSAAType::kUnifiedMSAA:
129 return GrAAType::kMSAA;
130 case GrFSAAType::kMixedSamples:
131 return GrAllowMixedSamples::kYes == allowMixedSamples ? GrAAType::kMixedSamples
132 : GrAAType::kCoverage;
133 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400134 SK_ABORT("Unexpected fsaa type");
Brian Salomone225b562017-06-14 13:00:03 -0400135 return GrAAType::kNone;
136}
137
138//////////////////////////////////////////////////////////////////////////////
139
robertphillipsea461502015-05-26 11:38:03 -0700140class AutoCheckFlush {
141public:
halcanary9d524f22016-03-29 09:03:52 -0700142 AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
robertphillips77a2e522015-10-17 07:43:27 -0700143 SkASSERT(fDrawingManager);
144 }
bsalomonb77a9072016-09-07 10:02:04 -0700145 ~AutoCheckFlush() { fDrawingManager->flushIfNecessary(); }
robertphillipsea461502015-05-26 11:38:03 -0700146
147private:
robertphillips77a2e522015-10-17 07:43:27 -0700148 GrDrawingManager* fDrawingManager;
robertphillipsea461502015-05-26 11:38:03 -0700149};
150
Brian Osman11052242016-10-27 14:47:55 -0400151bool GrRenderTargetContext::wasAbandoned() const {
Robert Phillips72152832017-01-25 17:31:35 -0500152 return this->drawingManager()->wasAbandoned();
robertphillips7761d612016-05-16 09:14:53 -0700153}
154
Robert Phillipsf2361d22016-10-25 14:20:06 -0400155// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
Brian Osman11052242016-10-27 14:47:55 -0400156// GrOpLists to be picked up and added to by renderTargetContexts lower in the call
Robert Phillipsf2361d22016-10-25 14:20:06 -0400157// stack. When this occurs with a closed GrOpList, a new one will be allocated
Brian Osman11052242016-10-27 14:47:55 -0400158// when the renderTargetContext attempts to use it (via getOpList).
159GrRenderTargetContext::GrRenderTargetContext(GrContext* context,
160 GrDrawingManager* drawingMgr,
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400161 sk_sp<GrRenderTargetProxy> rtp,
Brian Osman11052242016-10-27 14:47:55 -0400162 sk_sp<SkColorSpace> colorSpace,
163 const SkSurfaceProps* surfaceProps,
164 GrAuditTrail* auditTrail,
Robert Phillips941d1442017-06-14 16:37:02 -0400165 GrSingleOwner* singleOwner,
166 bool managedOpList)
Brian Salomonf3569f02017-10-24 12:52:33 -0400167 : GrSurfaceContext(context, drawingMgr, rtp->config(), std::move(colorSpace), auditTrail,
168 singleOwner)
169 , fRenderTargetProxy(std::move(rtp))
170 , fOpList(sk_ref_sp(fRenderTargetProxy->getLastRenderTargetOpList()))
Brian Salomonf3569f02017-10-24 12:52:33 -0400171 , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
172 , fManagedOpList(managedOpList) {
Robert Phillips4150eea2018-02-07 17:08:21 -0500173 GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
174 if (resourceProvider && !resourceProvider->explicitlyAllocateGPUResources()) {
175 // MDB TODO: to ensure all resources still get allocated in the correct order in the hybrid
176 // world we need to get the correct opList here so that it, in turn, can grab and hold
177 // its rendertarget.
178 this->getRTOpList();
179 }
180
Brian Salomonf18b1d82017-10-27 11:30:49 -0400181 fTextTarget.reset(new TextTarget(this));
robertphillips2e1e51f2015-10-15 08:01:48 -0700182 SkDEBUGCODE(this->validate();)
robertphillipsea461502015-05-26 11:38:03 -0700183}
184
robertphillips2e1e51f2015-10-15 08:01:48 -0700185#ifdef SK_DEBUG
Brian Osman11052242016-10-27 14:47:55 -0400186void GrRenderTargetContext::validate() const {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400187 SkASSERT(fRenderTargetProxy);
188 fRenderTargetProxy->validate(fContext);
robertphillipsa106c622015-10-16 09:07:06 -0700189
Robert Phillipsf2361d22016-10-25 14:20:06 -0400190 if (fOpList && !fOpList->isClosed()) {
Robert Phillipsdc83b892017-04-13 12:23:54 -0400191 SkASSERT(fRenderTargetProxy->getLastOpList() == fOpList.get());
robertphillipsa106c622015-10-16 09:07:06 -0700192 }
robertphillips2e1e51f2015-10-15 08:01:48 -0700193}
194#endif
195
Brian Osman11052242016-10-27 14:47:55 -0400196GrRenderTargetContext::~GrRenderTargetContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800197 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -0700198}
199
Robert Phillipsf200a902017-01-30 13:27:37 -0500200GrTextureProxy* GrRenderTargetContext::asTextureProxy() {
Robert Phillipseaa86252016-11-08 13:49:39 +0000201 return fRenderTargetProxy->asTextureProxy();
202}
203
Greg Daniele252f082017-10-23 16:05:23 -0400204const GrTextureProxy* GrRenderTargetContext::asTextureProxy() const {
205 return fRenderTargetProxy->asTextureProxy();
206}
207
Robert Phillipsf200a902017-01-30 13:27:37 -0500208sk_sp<GrTextureProxy> GrRenderTargetContext::asTextureProxyRef() {
209 return sk_ref_sp(fRenderTargetProxy->asTextureProxy());
210}
211
Greg Daniele252f082017-10-23 16:05:23 -0400212GrMipMapped GrRenderTargetContext::mipMapped() const {
213 if (const GrTextureProxy* proxy = this->asTextureProxy()) {
214 return proxy->mipMapped();
215 }
216 return GrMipMapped::kNo;
217}
218
Robert Phillips2de8cfa2017-06-28 10:33:41 -0400219GrRenderTargetOpList* GrRenderTargetContext::getRTOpList() {
joshualitt1de610a2016-01-06 08:26:09 -0800220 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -0700221 SkDEBUGCODE(this->validate();)
222
Robert Phillipsf2361d22016-10-25 14:20:06 -0400223 if (!fOpList || fOpList->isClosed()) {
Robert Phillips941d1442017-06-14 16:37:02 -0400224 fOpList = this->drawingManager()->newRTOpList(fRenderTargetProxy.get(), fManagedOpList);
robertphillipsa106c622015-10-16 09:07:06 -0700225 }
226
Robert Phillipsdc83b892017-04-13 12:23:54 -0400227 return fOpList.get();
robertphillipsa106c622015-10-16 09:07:06 -0700228}
229
Robert Phillips2de8cfa2017-06-28 10:33:41 -0400230GrOpList* GrRenderTargetContext::getOpList() {
231 return this->getRTOpList();
robertphillipsea461502015-05-26 11:38:03 -0700232}
233
Herb Derbycddab252018-07-16 11:19:04 -0400234void GrRenderTargetContext::drawGlyphRunList(
235 const GrClip& clip, const SkMatrix& viewMatrix,
Robert Phillipse4643cc2018-08-14 13:01:29 -0400236 const SkGlyphRunList& blob) {
joshualitt1de610a2016-01-06 08:26:09 -0800237 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700238 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700239 SkDEBUGCODE(this->validate();)
Herb Derbycddab252018-07-16 11:19:04 -0400240 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawGlyphRunList", fContext);
robertphillips2d70dcb2015-10-06 07:38:23 -0700241
Herb Derby26cbe512018-05-24 14:39:01 -0400242 GrTextContext* atlasTextContext = this->drawingManager()->getTextContext();
Herb Derbycddab252018-07-16 11:19:04 -0400243 atlasTextContext->drawGlyphRunList(fContext, fTextTarget.get(), clip, viewMatrix,
Robert Phillipse4643cc2018-08-14 13:01:29 -0400244 fSurfaceProps, blob);
robertphillipsea461502015-05-26 11:38:03 -0700245}
246
Brian Osman11052242016-10-27 14:47:55 -0400247void GrRenderTargetContext::discard() {
joshualitt1de610a2016-01-06 08:26:09 -0800248 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700249 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700250 SkDEBUGCODE(this->validate();)
Robert Phillips6b47c7d2017-08-29 07:24:09 -0400251 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "discard", fContext);
robertphillips2e1e51f2015-10-15 08:01:48 -0700252
Robert Phillips72152832017-01-25 17:31:35 -0500253 AutoCheckFlush acf(this->drawingManager());
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400254
Robert Phillips380b90c2017-08-30 07:41:07 -0400255 this->getRTOpList()->discard();
robertphillipsea461502015-05-26 11:38:03 -0700256}
257
Brian Osman11052242016-10-27 14:47:55 -0400258void GrRenderTargetContext::clear(const SkIRect* rect,
Brian Osman9a9baae2018-11-05 15:06:26 -0500259 const SkPMColor4f& color,
Chris Dalton344e9032017-12-11 15:42:09 -0700260 CanClearFullscreen canClearFullscreen) {
joshualitt1de610a2016-01-06 08:26:09 -0800261 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700262 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700263 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400264 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "clear", fContext);
robertphillipsea461502015-05-26 11:38:03 -0700265
Robert Phillips72152832017-01-25 17:31:35 -0500266 AutoCheckFlush acf(this->drawingManager());
Chris Dalton344e9032017-12-11 15:42:09 -0700267 this->internalClear(rect ? GrFixedClip(*rect) : GrFixedClip::Disabled(), color,
268 canClearFullscreen);
csmartdalton29df7602016-08-31 11:55:52 -0700269}
robertphillips9199a9f2016-07-13 07:48:43 -0700270
Brian Osman9a9baae2018-11-05 15:06:26 -0500271void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const SkPMColor4f& color) {
Robert Phillips784b7bf2016-12-09 13:35:02 -0500272 ASSERT_SINGLE_OWNER_PRIV
273 RETURN_IF_ABANDONED_PRIV
274 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400275 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "absClear",
276 fRenderTargetContext->fContext);
Robert Phillips784b7bf2016-12-09 13:35:02 -0500277
Robert Phillips72152832017-01-25 17:31:35 -0500278 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
Robert Phillips784b7bf2016-12-09 13:35:02 -0500279
Brian Salomonbb5711a2017-05-17 13:49:59 -0400280 SkIRect rtRect = SkIRect::MakeWH(fRenderTargetContext->fRenderTargetProxy->worstCaseWidth(),
281 fRenderTargetContext->fRenderTargetProxy->worstCaseHeight());
Robert Phillips784b7bf2016-12-09 13:35:02 -0500282
283 if (clearRect) {
284 if (clearRect->contains(rtRect)) {
285 clearRect = nullptr; // full screen
286 } else {
287 if (!rtRect.intersect(*clearRect)) {
288 return;
289 }
290 }
291 }
292
293 // TODO: in a post-MDB world this should be handled at the OpList level.
294 // An op-list that is initially cleared and has no other ops should receive an
295 // extra draw.
Brian Salomon43f8bf02017-10-18 08:33:29 -0400296 // This path doesn't handle coalescing of full screen clears b.c. it
297 // has to clear the entire render target - not just the content area.
298 // It could be done but will take more finagling.
Ethan Nicholas56d19a52018-10-15 11:26:20 -0400299 if (clearRect && fRenderTargetContext->caps()->performPartialClearsAsDraws()) {
300 GrPaint paint;
Brian Osman9a9baae2018-11-05 15:06:26 -0500301 paint.setColor4f(color);
Ethan Nicholas56d19a52018-10-15 11:26:20 -0400302 SkRect scissor = SkRect::Make(rtRect);
303 std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(fRenderTargetContext->fContext,
304 std::move(paint), SkMatrix::I(),
305 scissor, GrAAType::kNone));
306 if (!op) {
307 return;
308 }
309 fRenderTargetContext->addDrawOp(GrFixedClip(), std::move(op));
Robert Phillips784b7bf2016-12-09 13:35:02 -0500310 }
Ethan Nicholas56d19a52018-10-15 11:26:20 -0400311 else {
312 std::unique_ptr<GrOp> op(GrClearOp::Make(fRenderTargetContext->fContext, rtRect,
313 color, !clearRect));
314 if (!op) {
315 return;
316 }
317 fRenderTargetContext->getRTOpList()->addOp(std::move(op), *fRenderTargetContext->caps());
318 }
Robert Phillips784b7bf2016-12-09 13:35:02 -0500319}
320
Brian Osman11052242016-10-27 14:47:55 -0400321void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
Brian Osman9a9baae2018-11-05 15:06:26 -0500322 const SkPMColor4f& color,
Chris Dalton344e9032017-12-11 15:42:09 -0700323 CanClearFullscreen canClearFullscreen) {
csmartdalton29df7602016-08-31 11:55:52 -0700324 ASSERT_SINGLE_OWNER_PRIV
325 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400326 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400327 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "clear",
328 fRenderTargetContext->fContext);
csmartdalton29df7602016-08-31 11:55:52 -0700329
Robert Phillips72152832017-01-25 17:31:35 -0500330 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
Chris Dalton344e9032017-12-11 15:42:09 -0700331 fRenderTargetContext->internalClear(clip, color, canClearFullscreen);
csmartdalton29df7602016-08-31 11:55:52 -0700332}
333
Brian Osman11052242016-10-27 14:47:55 -0400334void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
Brian Osman9a9baae2018-11-05 15:06:26 -0500335 const SkPMColor4f& color,
Chris Dalton344e9032017-12-11 15:42:09 -0700336 CanClearFullscreen canClearFullscreen) {
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700337 bool isFull = false;
338 if (!clip.hasWindowRectangles()) {
Brian Salomond818ebf2018-07-02 14:08:49 +0000339 isFull = !clip.scissorEnabled() ||
Chris Dalton344e9032017-12-11 15:42:09 -0700340 (CanClearFullscreen::kYes == canClearFullscreen &&
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400341 this->caps()->preferFullscreenClears()) ||
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700342 clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
343 }
robertphillips9199a9f2016-07-13 07:48:43 -0700344
Brian Salomon43f8bf02017-10-18 08:33:29 -0400345 if (isFull) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400346 this->getRTOpList()->fullClear(fContext, color);
robertphillips9199a9f2016-07-13 07:48:43 -0700347 } else {
Ethan Nicholas56d19a52018-10-15 11:26:20 -0400348 if (this->caps()->performPartialClearsAsDraws()) {
349 GrPaint paint;
Brian Osman9a9baae2018-11-05 15:06:26 -0500350 paint.setColor4f(color);
Ethan Nicholas56d19a52018-10-15 11:26:20 -0400351 SkRect scissor = SkRect::Make(clip.scissorRect());
352 std::unique_ptr<GrDrawOp> op(GrRectOpFactory::MakeNonAAFill(fContext, std::move(paint),
353 SkMatrix::I(), scissor,
354 GrAAType::kNone));
355 if (!op) {
356 return;
357 }
358 this->addDrawOp(clip, std::move(op));
csmartdalton29df7602016-08-31 11:55:52 -0700359 }
Ethan Nicholas56d19a52018-10-15 11:26:20 -0400360 else {
361 std::unique_ptr<GrOp> op(GrClearOp::Make(fContext, clip, color,
362 this->asSurfaceProxy()));
363 if (!op) {
364 return;
365 }
366 this->getRTOpList()->addOp(std::move(op), *this->caps());
367 }
robertphillips9199a9f2016-07-13 07:48:43 -0700368 }
robertphillipsea461502015-05-26 11:38:03 -0700369}
370
Brian Osman11052242016-10-27 14:47:55 -0400371void GrRenderTargetContext::drawPaint(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500372 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -0400373 const SkMatrix& viewMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800374 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700375 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700376 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400377 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawPaint", fContext);
robertphillips2e1e51f2015-10-15 08:01:48 -0700378
robertphillipsea461502015-05-26 11:38:03 -0700379 // set rect to be big enough to fill the space, but not super-huge, so we
380 // don't overflow fixed-point implementations
robertphillips13a7eee2016-08-31 15:06:24 -0700381
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400382 SkRect r = fRenderTargetProxy->getBoundsRect();
robertphillipsea461502015-05-26 11:38:03 -0700383
bsalomoncb31e512016-08-26 10:48:19 -0700384 SkRRect rrect;
Michael Ludwig3d6390e2018-10-09 11:45:16 -0400385 GrAA aa = GrAA::kNo;
386
387 // rrect is calculated in one of two places, don't do it twice
388 enum RRectState {
389 kUnknown, kValid, kNotValid
390 };
391 RRectState rrectState = kUnknown;
392
393 // Check if the paint is a constant color, which is the first criterion to being able to turn
394 // the drawPaint() into a clear(). More expensive geometry checks can happen after that.
Brian Osman9a9baae2018-11-05 15:06:26 -0500395 SkPMColor4f clearColor;
Michael Ludwig3d6390e2018-10-09 11:45:16 -0400396 if (paint.isConstantBlendedColor(&clearColor)) {
397 // Regardless of the actual clip geometry, if it completely covers the device bounds it can
398 // be turned into a fullscreen clear.
399 if (clip.quickContains(r)) {
400 // Fill the device with the constant color
401 this->clear(nullptr, clearColor, CanClearFullscreen::kYes);
402 return;
403 }
Michael Ludwig43a54972018-10-09 18:02:19 -0400404 // If the clip intersection with the device is a non-rounded rectangle, it could be a
405 // implemented faster as a clear limited by the scissor test. Not all rectangular clips can
406 // be converted into a simple clear (see GrReducedClip), but for non-AA and "AA rects that
407 // line up with pixel boundaries", we can map it to a clear using the rounded rect.
Michael Ludwig3d6390e2018-10-09 11:45:16 -0400408 rrectState = clip.isRRect(r, &rrect, &aa) ? kValid : kNotValid;
Michael Ludwig43a54972018-10-09 18:02:19 -0400409 if (rrectState == kValid && rrect.isRect() && (aa == GrAA::kNo ||
410 GrClip::IsPixelAligned(rrect.getBounds()))) {
411 SkIRect scissorRect;
412 rrect.getBounds().round(&scissorRect);
Michael Ludwig3d6390e2018-10-09 11:45:16 -0400413 this->clear(&scissorRect, clearColor, CanClearFullscreen::kNo);
414 return;
415 }
416 }
417
bsalomoncb31e512016-08-26 10:48:19 -0700418 // Check if we can replace a clipRRect()/drawPaint() with a drawRRect(). We only do the
419 // transformation for non-rect rrects. Rects caused a performance regression on an Android
420 // test that needs investigation. We also skip cases where there are fragment processors
421 // because they may depend on having correct local coords and this path draws in device space
422 // without a local matrix.
Michael Ludwig3d6390e2018-10-09 11:45:16 -0400423 if (!paint.numTotalFragmentProcessors()) {
424 if (rrectState == kUnknown) {
425 rrectState = clip.isRRect(r, &rrect, &aa) ? kValid : kNotValid;
426 }
427 if (rrectState == kValid && !rrect.isRect()) {
428 this->drawRRect(GrNoClip(), std::move(paint), aa, SkMatrix::I(), rrect,
429 GrStyle::SimpleFill());
430 return;
431 }
bsalomoncb31e512016-08-26 10:48:19 -0700432 }
433
robertphillipsea461502015-05-26 11:38:03 -0700434 bool isPerspective = viewMatrix.hasPerspective();
435
436 // We attempt to map r by the inverse matrix and draw that. mapRect will
437 // map the four corners and bound them with a new rect. This will not
438 // produce a correct result for some perspective matrices.
439 if (!isPerspective) {
reeda39667c2016-08-22 06:39:49 -0700440 if (!SkMatrixPriv::InverseMapRect(viewMatrix, &r, r)) {
robertphillipsea461502015-05-26 11:38:03 -0700441 return;
442 }
Brian Salomon82f44312017-01-11 13:42:54 -0500443 this->drawRect(clip, std::move(paint), GrAA::kNo, viewMatrix, r);
robertphillipsea461502015-05-26 11:38:03 -0700444 } else {
445 SkMatrix localMatrix;
446 if (!viewMatrix.invert(&localMatrix)) {
robertphillipsea461502015-05-26 11:38:03 -0700447 return;
448 }
449
Robert Phillips72152832017-01-25 17:31:35 -0500450 AutoCheckFlush acf(this->drawingManager());
robertphillipsea461502015-05-26 11:38:03 -0700451
Brian Salomonbaaf4392017-06-15 09:59:23 -0400452 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFillWithLocalMatrix(
Robert Phillips7c525e62018-06-12 10:11:12 -0400453 fContext, std::move(paint), SkMatrix::I(), localMatrix, r, GrAAType::kNone);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400454 this->addDrawOp(clip, std::move(op));
robertphillipsea461502015-05-26 11:38:03 -0700455 }
456}
457
robertphillipsea461502015-05-26 11:38:03 -0700458static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
459 return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
460 point.fY >= rect.fTop && point.fY <= rect.fBottom;
461}
462
csmartdalton97f6cd52016-07-13 13:37:08 -0700463// Attempts to crop a rect and optional local rect to the clip boundaries.
464// Returns false if the draw can be skipped entirely.
robertphillips13a7eee2016-08-31 15:06:24 -0700465static bool crop_filled_rect(int width, int height, const GrClip& clip,
csmartdalton97f6cd52016-07-13 13:37:08 -0700466 const SkMatrix& viewMatrix, SkRect* rect,
467 SkRect* localRect = nullptr) {
468 if (!viewMatrix.rectStaysRect()) {
469 return true;
470 }
471
csmartdalton97f6cd52016-07-13 13:37:08 -0700472 SkIRect clipDevBounds;
473 SkRect clipBounds;
csmartdalton97f6cd52016-07-13 13:37:08 -0700474
robertphillips13a7eee2016-08-31 15:06:24 -0700475 clip.getConservativeBounds(width, height, &clipDevBounds);
reeda39667c2016-08-22 06:39:49 -0700476 if (!SkMatrixPriv::InverseMapRect(viewMatrix, &clipBounds, SkRect::Make(clipDevBounds))) {
477 return false;
478 }
csmartdalton97f6cd52016-07-13 13:37:08 -0700479
480 if (localRect) {
481 if (!rect->intersects(clipBounds)) {
482 return false;
483 }
484 const SkScalar dx = localRect->width() / rect->width();
485 const SkScalar dy = localRect->height() / rect->height();
486 if (clipBounds.fLeft > rect->fLeft) {
487 localRect->fLeft += (clipBounds.fLeft - rect->fLeft) * dx;
488 rect->fLeft = clipBounds.fLeft;
489 }
490 if (clipBounds.fTop > rect->fTop) {
491 localRect->fTop += (clipBounds.fTop - rect->fTop) * dy;
492 rect->fTop = clipBounds.fTop;
493 }
494 if (clipBounds.fRight < rect->fRight) {
495 localRect->fRight -= (rect->fRight - clipBounds.fRight) * dx;
496 rect->fRight = clipBounds.fRight;
497 }
498 if (clipBounds.fBottom < rect->fBottom) {
499 localRect->fBottom -= (rect->fBottom - clipBounds.fBottom) * dy;
500 rect->fBottom = clipBounds.fBottom;
501 }
502 return true;
503 }
504
505 return rect->intersect(clipBounds);
506}
507
Brian Osman11052242016-10-27 14:47:55 -0400508bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500509 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500510 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400511 const SkMatrix& viewMatrix,
512 const SkRect& rect,
513 const GrUserStencilSettings* ss) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700514 SkRect croppedRect = rect;
Robert Phillips784b7bf2016-12-09 13:35:02 -0500515 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &croppedRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700516 return true;
517 }
robertphillips44302392016-07-08 14:43:03 -0700518
Brian Salomon7c8460e2017-05-12 11:36:10 -0400519 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400520 std::unique_ptr<GrDrawOp> op;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500521 if (GrAAType::kCoverage == aaType) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400522 op = GrRectOpFactory::MakeAAFill(fContext, std::move(paint), viewMatrix, croppedRect, ss);
robertphillips391395d2016-03-02 09:26:36 -0800523 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400524 op = GrRectOpFactory::MakeNonAAFill(fContext, std::move(paint), viewMatrix, croppedRect,
525 aaType, ss);
robertphillips391395d2016-03-02 09:26:36 -0800526 }
Brian Salomonbaaf4392017-06-15 09:59:23 -0400527 if (!op) {
528 return false;
529 }
530 this->addDrawOp(clip, std::move(op));
531 return true;
robertphillips391395d2016-03-02 09:26:36 -0800532}
533
Brian Osman11052242016-10-27 14:47:55 -0400534void GrRenderTargetContext::drawRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500535 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500536 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400537 const SkMatrix& viewMatrix,
538 const SkRect& rect,
539 const GrStyle* style) {
bsalomon6663acf2016-05-10 09:14:17 -0700540 if (!style) {
541 style = &GrStyle::SimpleFill();
542 }
joshualitt1de610a2016-01-06 08:26:09 -0800543 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700544 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700545 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400546 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawRect", fContext);
robertphillips2e1e51f2015-10-15 08:01:48 -0700547
bsalomon6663acf2016-05-10 09:14:17 -0700548 // Path effects should've been devolved to a path in SkGpuDevice
549 SkASSERT(!style->pathEffect());
robertphillipsea461502015-05-26 11:38:03 -0700550
Robert Phillips72152832017-01-25 17:31:35 -0500551 AutoCheckFlush acf(this->drawingManager());
robertphillipsea461502015-05-26 11:38:03 -0700552
bsalomon6663acf2016-05-10 09:14:17 -0700553 const SkStrokeRec& stroke = style->strokeRec();
Robert Phillips8c8b0462018-08-24 16:18:03 -0400554 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
Brian Salomon43f8bf02017-10-18 08:33:29 -0400555 // Check if this is a full RT draw and can be replaced with a clear. We don't bother
556 // checking cases where the RT is fully inside a stroke.
557 SkRect rtRect = fRenderTargetProxy->getBoundsRect();
558 // Does the clip contain the entire RT?
Robert Phillips8c8b0462018-08-24 16:18:03 -0400559 if (clip.quickContains(rtRect) && !paint.numCoverageFragmentProcessors()) {
Brian Salomon43f8bf02017-10-18 08:33:29 -0400560 SkMatrix invM;
561 if (!viewMatrix.invert(&invM)) {
562 return;
563 }
564 // Does the rect bound the RT?
Brian Salomona33b67c2018-05-17 10:42:14 -0400565 GrQuad quad(rtRect, invM);
Brian Salomon43f8bf02017-10-18 08:33:29 -0400566 if (rect_contains_inclusive(rect, quad.point(0)) &&
567 rect_contains_inclusive(rect, quad.point(1)) &&
568 rect_contains_inclusive(rect, quad.point(2)) &&
569 rect_contains_inclusive(rect, quad.point(3))) {
570 // Will it blend?
Brian Osman9a9baae2018-11-05 15:06:26 -0500571 SkPMColor4f clearColor;
Brian Salomon43f8bf02017-10-18 08:33:29 -0400572 if (paint.isConstantBlendedColor(&clearColor)) {
Chris Dalton344e9032017-12-11 15:42:09 -0700573 this->clear(nullptr, clearColor,
574 GrRenderTargetContext::CanClearFullscreen::kYes);
robertphillipsea461502015-05-26 11:38:03 -0700575 return;
576 }
577 }
578 }
robertphillips44302392016-07-08 14:43:03 -0700579
Brian Salomon82f44312017-01-11 13:42:54 -0500580 if (this->drawFilledRect(clip, std::move(paint), aa, viewMatrix, rect, nullptr)) {
robertphillips44302392016-07-08 14:43:03 -0700581 return;
582 }
bsalomona7d85ba2016-07-06 11:54:59 -0700583 } else if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
584 stroke.getStyle() == SkStrokeRec::kHairline_Style) {
585 if ((!rect.width() || !rect.height()) &&
586 SkStrokeRec::kHairline_Style != stroke.getStyle()) {
587 SkScalar r = stroke.getWidth() / 2;
588 // TODO: Move these stroke->fill fallbacks to GrShape?
589 switch (stroke.getJoin()) {
590 case SkPaint::kMiter_Join:
Brian Salomon82f44312017-01-11 13:42:54 -0500591 this->drawRect(
592 clip, std::move(paint), aa, viewMatrix,
593 {rect.fLeft - r, rect.fTop - r, rect.fRight + r, rect.fBottom + r},
594 &GrStyle::SimpleFill());
bsalomona7d85ba2016-07-06 11:54:59 -0700595 return;
596 case SkPaint::kRound_Join:
597 // Raster draws nothing when both dimensions are empty.
598 if (rect.width() || rect.height()){
599 SkRRect rrect = SkRRect::MakeRectXY(rect.makeOutset(r, r), r, r);
Brian Salomon82f44312017-01-11 13:42:54 -0500600 this->drawRRect(clip, std::move(paint), aa, viewMatrix, rrect,
601 GrStyle::SimpleFill());
bsalomona7d85ba2016-07-06 11:54:59 -0700602 return;
603 }
604 case SkPaint::kBevel_Join:
605 if (!rect.width()) {
Brian Salomon82f44312017-01-11 13:42:54 -0500606 this->drawRect(clip, std::move(paint), aa, viewMatrix,
bsalomona7d85ba2016-07-06 11:54:59 -0700607 {rect.fLeft - r, rect.fTop, rect.fRight + r, rect.fBottom},
608 &GrStyle::SimpleFill());
609 } else {
Brian Salomon82f44312017-01-11 13:42:54 -0500610 this->drawRect(clip, std::move(paint), aa, viewMatrix,
bsalomona7d85ba2016-07-06 11:54:59 -0700611 {rect.fLeft, rect.fTop - r, rect.fRight, rect.fBottom + r},
612 &GrStyle::SimpleFill());
613 }
614 return;
615 }
616 }
robertphillips44302392016-07-08 14:43:03 -0700617
Brian Salomonbaaf4392017-06-15 09:59:23 -0400618 std::unique_ptr<GrDrawOp> op;
robertphillips44302392016-07-08 14:43:03 -0700619
Brian Salomon7c8460e2017-05-12 11:36:10 -0400620 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500621 if (GrAAType::kCoverage == aaType) {
cdaltonbb539482016-01-04 09:48:25 -0800622 // The stroke path needs the rect to remain axis aligned (no rotation or skew).
623 if (viewMatrix.rectStaysRect()) {
Robert Phillips7c525e62018-06-12 10:11:12 -0400624 op = GrRectOpFactory::MakeAAStroke(fContext, std::move(paint), viewMatrix, rect,
625 stroke);
cdaltonbb539482016-01-04 09:48:25 -0800626 }
robertphillipsea461502015-05-26 11:38:03 -0700627 } else {
Robert Phillips7c525e62018-06-12 10:11:12 -0400628 op = GrRectOpFactory::MakeNonAAStroke(fContext, std::move(paint), viewMatrix, rect,
629 stroke, aaType);
robertphillips391395d2016-03-02 09:26:36 -0800630 }
robertphillips4bc31812016-03-01 12:22:49 -0800631
Brian Salomon42521e82016-12-07 16:44:58 -0500632 if (op) {
Brian Salomonbaaf4392017-06-15 09:59:23 -0400633 this->addDrawOp(clip, std::move(op));
robertphillips44302392016-07-08 14:43:03 -0700634 return;
robertphillips4bc31812016-03-01 12:22:49 -0800635 }
robertphillips4bc31812016-03-01 12:22:49 -0800636 }
Brian Salomon2fad74a2017-12-20 13:28:55 -0500637 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, GrShape(rect, *style));
robertphillipsea461502015-05-26 11:38:03 -0700638}
639
Robert Phillipsec2249f2016-11-09 08:54:35 -0500640int GrRenderTargetContextPriv::maxWindowRectangles() const {
641 return fRenderTargetContext->fRenderTargetProxy->maxWindowRectangles(
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400642 *fRenderTargetContext->caps());
Robert Phillipsec2249f2016-11-09 08:54:35 -0500643}
644
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000645void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
robertphillips976f5f02016-06-03 10:59:20 -0700646 ASSERT_SINGLE_OWNER_PRIV
647 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400648 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400649 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "clearStencilClip",
650 fRenderTargetContext->fContext);
robertphillips976f5f02016-06-03 10:59:20 -0700651
Robert Phillips72152832017-01-25 17:31:35 -0500652 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
Robert Phillipsb9a02a12017-04-06 11:08:40 -0400653
Robert Phillips7c525e62018-06-12 10:11:12 -0400654 GrRenderTargetProxy* rtProxy = fRenderTargetContext->fRenderTargetProxy.get();
655 std::unique_ptr<GrOp> op(GrClearStencilClipOp::Make(fRenderTargetContext->fContext,
656 clip, insideStencilMask, rtProxy));
Robert Phillipsb9a02a12017-04-06 11:08:40 -0400657 if (!op) {
Robert Phillipse60ad622016-11-17 10:22:48 -0500658 return;
659 }
Robert Phillips2de8cfa2017-06-28 10:33:41 -0400660 fRenderTargetContext->getRTOpList()->addOp(std::move(op), *fRenderTargetContext->caps());
robertphillips976f5f02016-06-03 10:59:20 -0700661}
662
Chris Daltonbbfd5162017-11-07 13:35:22 -0700663void GrRenderTargetContextPriv::stencilPath(const GrHardClip& clip,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500664 GrAAType aaType,
Brian Osman11052242016-10-27 14:47:55 -0400665 const SkMatrix& viewMatrix,
666 const GrPath* path) {
Brian Salomon467921e2017-03-06 16:17:12 -0500667 ASSERT_SINGLE_OWNER_PRIV
668 RETURN_IF_ABANDONED_PRIV
669 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400670 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "stencilPath",
671 fRenderTargetContext->fContext);
Brian Salomon467921e2017-03-06 16:17:12 -0500672
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500673 SkASSERT(aaType != GrAAType::kCoverage);
Brian Salomon467921e2017-03-06 16:17:12 -0500674
675 bool useHWAA = GrAATypeIsHW(aaType);
676 // TODO: extract portions of checkDraw that are relevant to path stenciling.
677 SkASSERT(path);
678 SkASSERT(fRenderTargetContext->caps()->shaderCaps()->pathRenderingSupport());
679
680 // FIXME: Use path bounds instead of this WAR once
681 // https://bugs.chromium.org/p/skia/issues/detail?id=5640 is resolved.
682 SkRect bounds = SkRect::MakeIWH(fRenderTargetContext->width(), fRenderTargetContext->height());
683
684 // Setup clip
Chris Daltonbbfd5162017-11-07 13:35:22 -0700685 GrAppliedHardClip appliedClip;
686 if (!clip.apply(fRenderTargetContext->width(), fRenderTargetContext->height(), &appliedClip,
687 &bounds)) {
Brian Salomon467921e2017-03-06 16:17:12 -0500688 return;
689 }
690
Robert Phillips65048132017-08-10 08:44:49 -0400691 fRenderTargetContext->setNeedsStencil();
Brian Salomon467921e2017-03-06 16:17:12 -0500692
Robert Phillips7c525e62018-06-12 10:11:12 -0400693 std::unique_ptr<GrOp> op = GrStencilPathOp::Make(fRenderTargetContext->fContext,
694 viewMatrix,
Brian Salomon467921e2017-03-06 16:17:12 -0500695 useHWAA,
696 path->getFillType(),
697 appliedClip.hasStencilClip(),
Brian Salomon467921e2017-03-06 16:17:12 -0500698 appliedClip.scissorState(),
Brian Salomon467921e2017-03-06 16:17:12 -0500699 path);
Robert Phillipsb9a02a12017-04-06 11:08:40 -0400700 if (!op) {
701 return;
702 }
Brian Salomon97180af2017-03-14 13:42:58 -0400703 op->setClippedBounds(bounds);
Robert Phillips2de8cfa2017-06-28 10:33:41 -0400704 fRenderTargetContext->getRTOpList()->addOp(std::move(op), *fRenderTargetContext->caps());
robertphillips976f5f02016-06-03 10:59:20 -0700705}
706
Chris Daltonbbfd5162017-11-07 13:35:22 -0700707void GrRenderTargetContextPriv::stencilRect(const GrHardClip& clip,
Brian Osman11052242016-10-27 14:47:55 -0400708 const GrUserStencilSettings* ss,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500709 GrAAType aaType,
Brian Osman11052242016-10-27 14:47:55 -0400710 const SkMatrix& viewMatrix,
711 const SkRect& rect) {
robertphillips976f5f02016-06-03 10:59:20 -0700712 ASSERT_SINGLE_OWNER_PRIV
713 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400714 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400715 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "stencilRect",
716 fRenderTargetContext->fContext);
717
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500718 SkASSERT(GrAAType::kCoverage != aaType);
Robert Phillips72152832017-01-25 17:31:35 -0500719 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
robertphillips976f5f02016-06-03 10:59:20 -0700720
721 GrPaint paint;
Brian Salomona1633922017-01-09 11:46:10 -0500722 paint.setXPFactory(GrDisableColorXPFactory::Get());
Robert Phillips7c525e62018-06-12 10:11:12 -0400723 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFill(fRenderTargetContext->fContext,
724 std::move(paint), viewMatrix,
725 rect, aaType, ss);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400726 fRenderTargetContext->addDrawOp(clip, std::move(op));
robertphillips976f5f02016-06-03 10:59:20 -0700727}
728
Chris Daltonbbfd5162017-11-07 13:35:22 -0700729bool GrRenderTargetContextPriv::drawAndStencilRect(const GrHardClip& clip,
Brian Osman11052242016-10-27 14:47:55 -0400730 const GrUserStencilSettings* ss,
731 SkRegion::Op op,
732 bool invert,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500733 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400734 const SkMatrix& viewMatrix,
735 const SkRect& rect) {
robertphillips391395d2016-03-02 09:26:36 -0800736 ASSERT_SINGLE_OWNER_PRIV
737 RETURN_FALSE_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400738 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400739 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "drawAndStencilRect",
740 fRenderTargetContext->fContext);
robertphillips391395d2016-03-02 09:26:36 -0800741
Robert Phillips72152832017-01-25 17:31:35 -0500742 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
robertphillips391395d2016-03-02 09:26:36 -0800743
744 GrPaint paint;
robertphillips391395d2016-03-02 09:26:36 -0800745 paint.setCoverageSetOpXPFactory(op, invert);
746
Brian Salomon82f44312017-01-11 13:42:54 -0500747 if (fRenderTargetContext->drawFilledRect(clip, std::move(paint), aa, viewMatrix, rect, ss)) {
robertphillips391395d2016-03-02 09:26:36 -0800748 return true;
749 }
robertphillips391395d2016-03-02 09:26:36 -0800750 SkPath path;
751 path.setIsVolatile(true);
752 path.addRect(rect);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500753 return this->drawAndStencilPath(clip, ss, op, invert, aa, viewMatrix, path);
robertphillips391395d2016-03-02 09:26:36 -0800754}
755
Brian Osman11052242016-10-27 14:47:55 -0400756void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500757 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500758 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400759 const SkMatrix& viewMatrix,
760 const SkRect& rectToDraw,
761 const SkRect& localRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800762 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700763 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700764 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400765 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "fillRectToRect", fContext);
robertphillipsea461502015-05-26 11:38:03 -0700766
csmartdalton97f6cd52016-07-13 13:37:08 -0700767 SkRect croppedRect = rectToDraw;
768 SkRect croppedLocalRect = localRect;
robertphillips13a7eee2016-08-31 15:06:24 -0700769 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix,
770 &croppedRect, &croppedLocalRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700771 return;
772 }
773
Robert Phillips72152832017-01-25 17:31:35 -0500774 AutoCheckFlush acf(this->drawingManager());
csmartdaltona7f29642016-07-07 08:49:11 -0700775
Brian Salomon7c8460e2017-05-12 11:36:10 -0400776 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500777 if (GrAAType::kCoverage != aaType) {
Brian Salomonbaaf4392017-06-15 09:59:23 -0400778 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFillWithLocalRect(
Robert Phillips7c525e62018-06-12 10:11:12 -0400779 fContext, std::move(paint), viewMatrix, croppedRect, croppedLocalRect, aaType);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400780 this->addDrawOp(clip, std::move(op));
csmartdaltonfc49d562016-07-26 17:05:47 -0700781 return;
joshualitt04194f32016-01-13 10:08:27 -0800782 }
bsalomonbb243832016-07-22 07:10:19 -0700783
Brian Salomonbaaf4392017-06-15 09:59:23 -0400784 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeAAFillWithLocalRect(
Robert Phillips7c525e62018-06-12 10:11:12 -0400785 fContext, std::move(paint), viewMatrix, croppedRect, croppedLocalRect);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400786 if (op) {
787 this->addDrawOp(clip, std::move(op));
csmartdaltonfc49d562016-07-26 17:05:47 -0700788 return;
789 }
790
791 SkMatrix viewAndUnLocalMatrix;
792 if (!viewAndUnLocalMatrix.setRectToRect(localRect, rectToDraw, SkMatrix::kFill_ScaleToFit)) {
793 SkDebugf("fillRectToRect called with empty local matrix.\n");
794 return;
795 }
796 viewAndUnLocalMatrix.postConcat(viewMatrix);
797
Brian Salomon2fad74a2017-12-20 13:28:55 -0500798 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewAndUnLocalMatrix,
799 GrShape(localRect));
joshualittb6b513b2015-08-21 10:25:18 -0700800}
801
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400802void GrRenderTargetContext::drawTexture(const GrClip& clip, sk_sp<GrTextureProxy> proxy,
803 GrSamplerState::Filter filter, GrColor color,
Brian Salomon2213ee92018-10-02 10:44:21 -0400804 const SkRect& srcRect, const SkRect& dstRect,
805 GrQuadAAFlags aaFlags,
Brian Salomonb80ffee2018-05-23 16:39:39 -0400806 SkCanvas::SrcRectConstraint constraint,
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400807 const SkMatrix& viewMatrix,
Brian Osman3ebd3542018-07-30 14:36:53 -0400808 sk_sp<GrColorSpaceXform> textureColorSpaceXform,
809 sk_sp<GrColorSpaceXform> paintColorSpaceXform) {
Brian Salomon34169692017-08-28 15:32:01 -0400810 ASSERT_SINGLE_OWNER
811 RETURN_IF_ABANDONED
812 SkDEBUGCODE(this->validate();)
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400813 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawTexture", fContext);
Brian Salomonf1709042018-10-03 11:57:00 -0400814 if (constraint == SkCanvas::kStrict_SrcRectConstraint &&
815 srcRect.contains(proxy->getWorstCaseBoundsRect())) {
816 constraint = SkCanvas::kFast_SrcRectConstraint;
Brian Salomon34169692017-08-28 15:32:01 -0400817 }
Brian Salomon2213ee92018-10-02 10:44:21 -0400818 GrAAType aaType =
819 this->chooseAAType(GrAA(aaFlags != GrQuadAAFlags::kNone), GrAllowMixedSamples::kNo);
Brian Salomonff9d6d32017-08-30 10:27:49 -0400820 SkRect clippedDstRect = dstRect;
821 SkRect clippedSrcRect = srcRect;
822 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &clippedDstRect,
823 &clippedSrcRect)) {
824 return;
825 }
Brian Salomon2213ee92018-10-02 10:44:21 -0400826 auto op = GrTextureOp::Make(fContext, std::move(proxy), filter, color, clippedSrcRect,
827 clippedDstRect, aaType, aaFlags, constraint, viewMatrix,
828 std::move(textureColorSpaceXform), std::move(paintColorSpaceXform));
829 this->addDrawOp(clip, std::move(op));
Brian Salomon34169692017-08-28 15:32:01 -0400830}
831
Brian Salomond7065e72018-10-12 11:42:02 -0400832void GrRenderTargetContext::drawTextureSet(const GrClip& clip, const TextureSetEntry set[], int cnt,
833 GrSamplerState::Filter filter, GrColor color,
834 const SkMatrix& viewMatrix,
835 sk_sp<GrColorSpaceXform> texXform,
836 sk_sp<GrColorSpaceXform> colorXform) {
837 ASSERT_SINGLE_OWNER
838 RETURN_IF_ABANDONED
839 SkDEBUGCODE(this->validate();)
840 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawTextureSet", fContext);
841 GrAAType aaType = this->chooseAAType(GrAA::kYes, GrAllowMixedSamples::kNo);
842 auto op = GrTextureOp::Make(fContext, set, cnt, filter, color, aaType, viewMatrix,
843 std::move(texXform), std::move(colorXform));
844 this->addDrawOp(clip, std::move(op));
845}
846
Brian Osman11052242016-10-27 14:47:55 -0400847void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500848 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500849 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400850 const SkMatrix& viewMatrix,
851 const SkRect& rectToDraw,
852 const SkMatrix& localMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800853 ASSERT_SINGLE_OWNER
joshualittb6b513b2015-08-21 10:25:18 -0700854 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700855 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400856 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "fillRectWithLocalMatrix", fContext);
joshualittb6b513b2015-08-21 10:25:18 -0700857
csmartdalton97f6cd52016-07-13 13:37:08 -0700858 SkRect croppedRect = rectToDraw;
robertphillips13a7eee2016-08-31 15:06:24 -0700859 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &croppedRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700860 return;
861 }
862
Robert Phillips72152832017-01-25 17:31:35 -0500863 AutoCheckFlush acf(this->drawingManager());
csmartdaltona7f29642016-07-07 08:49:11 -0700864
Brian Salomon7c8460e2017-05-12 11:36:10 -0400865 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500866 if (GrAAType::kCoverage != aaType) {
Brian Salomonbaaf4392017-06-15 09:59:23 -0400867 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFillWithLocalMatrix(
Robert Phillips7c525e62018-06-12 10:11:12 -0400868 fContext, std::move(paint), viewMatrix, localMatrix, croppedRect, aaType);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400869 this->addDrawOp(clip, std::move(op));
csmartdaltonfc49d562016-07-26 17:05:47 -0700870 return;
bsalomonc55271f2015-11-09 11:55:57 -0800871 }
robertphillips4bc31812016-03-01 12:22:49 -0800872
Brian Salomonbaaf4392017-06-15 09:59:23 -0400873 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeAAFillWithLocalMatrix(
Robert Phillips7c525e62018-06-12 10:11:12 -0400874 fContext, std::move(paint), viewMatrix, localMatrix, croppedRect);
Brian Salomonbaaf4392017-06-15 09:59:23 -0400875 if (op) {
876 this->addDrawOp(clip, std::move(op));
csmartdaltonfc49d562016-07-26 17:05:47 -0700877 return;
878 }
879
880 SkMatrix viewAndUnLocalMatrix;
881 if (!localMatrix.invert(&viewAndUnLocalMatrix)) {
882 SkDebugf("fillRectWithLocalMatrix called with degenerate local matrix.\n");
883 return;
884 }
885 viewAndUnLocalMatrix.postConcat(viewMatrix);
886
887 SkPath path;
888 path.setIsVolatile(true);
889 path.addRect(rectToDraw);
890 path.transform(localMatrix);
Brian Salomon2fad74a2017-12-20 13:28:55 -0500891 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewAndUnLocalMatrix,
892 GrShape(path));
robertphillipsea461502015-05-26 11:38:03 -0700893}
894
Brian Osman11052242016-10-27 14:47:55 -0400895void GrRenderTargetContext::drawVertices(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500896 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -0400897 const SkMatrix& viewMatrix,
Brian Osmanae0c50c2017-05-25 16:56:34 -0400898 sk_sp<SkVertices> vertices,
Ruiqi Maoc97a3392018-08-15 10:44:19 -0400899 const SkVertices::Bone bones[],
Ruiqi Mao4ec72f72018-07-10 17:21:07 -0400900 int boneCount,
Brian Osmanae0c50c2017-05-25 16:56:34 -0400901 GrPrimitiveType* overridePrimType) {
Brian Salomon199fb872017-02-06 09:41:10 -0500902 ASSERT_SINGLE_OWNER
903 RETURN_IF_ABANDONED
904 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400905 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawVertices", fContext);
Brian Salomon199fb872017-02-06 09:41:10 -0500906
907 AutoCheckFlush acf(this->drawingManager());
908
909 SkASSERT(vertices);
Brian Salomonc2f42542017-07-12 14:11:22 -0400910 GrAAType aaType = this->chooseAAType(GrAA::kNo, GrAllowMixedSamples::kNo);
Brian Salomonf3569f02017-10-24 12:52:33 -0400911 std::unique_ptr<GrDrawOp> op = GrDrawVerticesOp::Make(
Ruiqi Mao4ec72f72018-07-10 17:21:07 -0400912 fContext, std::move(paint), std::move(vertices), bones, boneCount, viewMatrix, aaType,
Brian Salomonf3569f02017-10-24 12:52:33 -0400913 this->colorSpaceInfo().refColorSpaceXformFromSRGB(), overridePrimType);
Brian Salomonc2f42542017-07-12 14:11:22 -0400914 this->addDrawOp(clip, std::move(op));
robertphillipsea461502015-05-26 11:38:03 -0700915}
916
917///////////////////////////////////////////////////////////////////////////////
918
Brian Osman11052242016-10-27 14:47:55 -0400919void GrRenderTargetContext::drawAtlas(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500920 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -0400921 const SkMatrix& viewMatrix,
922 int spriteCount,
923 const SkRSXform xform[],
924 const SkRect texRect[],
925 const SkColor colors[]) {
joshualitt1de610a2016-01-06 08:26:09 -0800926 ASSERT_SINGLE_OWNER
jvanverth31ff7622015-08-07 10:09:28 -0700927 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700928 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400929 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawAtlas", fContext);
robertphillips2e1e51f2015-10-15 08:01:48 -0700930
Robert Phillips72152832017-01-25 17:31:35 -0500931 AutoCheckFlush acf(this->drawingManager());
halcanary9d524f22016-03-29 09:03:52 -0700932
Brian Salomon0088f942017-07-12 11:51:27 -0400933 GrAAType aaType = this->chooseAAType(GrAA::kNo, GrAllowMixedSamples::kNo);
Robert Phillips7c525e62018-06-12 10:11:12 -0400934 std::unique_ptr<GrDrawOp> op = GrDrawAtlasOp::Make(fContext, std::move(paint), viewMatrix,
935 aaType, spriteCount, xform, texRect, colors);
Brian Salomon0088f942017-07-12 11:51:27 -0400936 this->addDrawOp(clip, std::move(op));
jvanverth31ff7622015-08-07 10:09:28 -0700937}
938
939///////////////////////////////////////////////////////////////////////////////
940
Brian Osman11052242016-10-27 14:47:55 -0400941void GrRenderTargetContext::drawRRect(const GrClip& origClip,
Brian Salomon82f44312017-01-11 13:42:54 -0500942 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500943 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400944 const SkMatrix& viewMatrix,
945 const SkRRect& rrect,
946 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800947 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700948 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700949 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -0400950 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawRRect", fContext);
Robert Phillips85290802018-07-02 13:14:28 -0400951
952 const SkStrokeRec& stroke = style.strokeRec();
953 if (stroke.getStyle() == SkStrokeRec::kFill_Style && rrect.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -0700954 return;
955 }
956
bsalomon7f0d9f32016-08-15 14:49:10 -0700957 GrNoClip noclip;
958 const GrClip* clip = &origClip;
959#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
960 // The Android framework frequently clips rrects to themselves where the clip is non-aa and the
Brian Salomon42521e82016-12-07 16:44:58 -0500961 // draw is aa. Since our lower level clip code works from op bounds, which are SkRects, it
bsalomon7f0d9f32016-08-15 14:49:10 -0700962 // doesn't detect that the clip can be ignored (modulo antialiasing). The following test
963 // attempts to mitigate the stencil clip cost but will only help when the entire clip stack
964 // can be ignored. We'd prefer to fix this in the framework by removing the clips calls.
965 SkRRect devRRect;
966 if (rrect.transform(viewMatrix, &devRRect) && clip->quickContains(devRRect)) {
967 clip = &noclip;
968 }
969#endif
bsalomon6663acf2016-05-10 09:14:17 -0700970 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
ksakamotoec7f2ac2016-07-05 03:54:53 -0700971
Robert Phillips72152832017-01-25 17:31:35 -0500972 AutoCheckFlush acf(this->drawingManager());
csmartdaltona7f29642016-07-07 08:49:11 -0700973
Brian Salomonea26d6b2018-01-23 20:33:21 +0000974 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500975 if (GrAAType::kCoverage == aaType) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400976 const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
Robert Phillips7c525e62018-06-12 10:11:12 -0400977 std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeRRectOp(fContext,
978 std::move(paint),
Brian Salomonea26d6b2018-01-23 20:33:21 +0000979 viewMatrix,
980 rrect,
981 stroke,
982 shaderCaps);
Brian Salomon42521e82016-12-07 16:44:58 -0500983 if (op) {
Brian Salomon05441c42017-05-15 16:45:49 -0400984 this->addDrawOp(*clip, std::move(op));
robertphillipsb56f9272016-02-25 11:03:52 -0800985 return;
986 }
robertphillipsea461502015-05-26 11:38:03 -0700987 }
robertphillipsb56f9272016-02-25 11:03:52 -0800988
Brian Salomon2fad74a2017-12-20 13:28:55 -0500989 this->drawShapeUsingPathRenderer(*clip, std::move(paint), aa, viewMatrix,
990 GrShape(rrect, style));
robertphillipsea461502015-05-26 11:38:03 -0700991}
992
Jim Van Verthc5903412016-11-17 15:27:09 -0500993///////////////////////////////////////////////////////////////////////////////
994
Jim Van Verth3af1af92017-05-18 15:06:54 -0400995static SkPoint3 map(const SkMatrix& m, const SkPoint3& pt) {
996 SkPoint3 result;
997 m.mapXY(pt.fX, pt.fY, (SkPoint*)&result.fX);
998 result.fZ = pt.fZ;
999 return result;
1000}
1001
1002bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
Jim Van Verth3af1af92017-05-18 15:06:54 -04001003 const SkMatrix& viewMatrix,
1004 const SkPath& path,
1005 const SkDrawShadowRec& rec) {
Jim Van Verthc5903412016-11-17 15:27:09 -05001006 ASSERT_SINGLE_OWNER
Jim Van Verth3af1af92017-05-18 15:06:54 -04001007 if (this->drawingManager()->wasAbandoned()) {
1008 return true;
1009 }
Jim Van Verthc5903412016-11-17 15:27:09 -05001010 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001011 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawFastShadow", fContext);
Jim Van Verth3af1af92017-05-18 15:06:54 -04001012
1013 // check z plane
1014 bool tiltZPlane = SkToBool(!SkScalarNearlyZero(rec.fZPlaneParams.fX) ||
1015 !SkScalarNearlyZero(rec.fZPlaneParams.fY));
1016 bool skipAnalytic = SkToBool(rec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
1017 if (tiltZPlane || skipAnalytic || !viewMatrix.rectStaysRect() || !viewMatrix.isSimilarity()) {
1018 return false;
1019 }
1020
1021 SkRRect rrect;
1022 SkRect rect;
1023 // we can only handle rects, circles, and rrects with circular corners
Mike Reed242135a2018-02-22 13:41:39 -05001024 bool isRRect = path.isRRect(&rrect) && SkRRectPriv::IsSimpleCircular(rrect) &&
Jim Van Verth3af1af92017-05-18 15:06:54 -04001025 rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero;
1026 if (!isRRect &&
1027 path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
1028 rect.width() > SK_ScalarNearlyZero) {
1029 rrect.setOval(rect);
1030 isRRect = true;
1031 }
1032 if (!isRRect && path.isRect(&rect)) {
1033 rrect.setRect(rect);
1034 isRRect = true;
1035 }
1036
1037 if (!isRRect) {
1038 return false;
1039 }
1040
Jim Van Verthc5903412016-11-17 15:27:09 -05001041 if (rrect.isEmpty()) {
Jim Van Verth3af1af92017-05-18 15:06:54 -04001042 return true;
Jim Van Verthc5903412016-11-17 15:27:09 -05001043 }
1044
Robert Phillips72152832017-01-25 17:31:35 -05001045 AutoCheckFlush acf(this->drawingManager());
Jim Van Verthc5903412016-11-17 15:27:09 -05001046
Jim Van Verth3af1af92017-05-18 15:06:54 -04001047 // transform light
1048 SkPoint3 devLightPos = map(viewMatrix, rec.fLightPos);
1049
1050 // 1/scale
1051 SkScalar devToSrcScale = viewMatrix.isScaleTranslate() ?
1052 SkScalarInvert(viewMatrix[SkMatrix::kMScaleX]) :
1053 sk_float_rsqrt(viewMatrix[SkMatrix::kMScaleX] * viewMatrix[SkMatrix::kMScaleX] +
1054 viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);
1055
1056 SkScalar occluderHeight = rec.fZPlaneParams.fZ;
Jim Van Verth3af1af92017-05-18 15:06:54 -04001057 bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
1058
Jim Van Verthb1b80f72018-01-18 15:19:13 -05001059 if (SkColorGetA(rec.fAmbientColor) > 0) {
Jim Van Verth1af03d42017-07-31 09:34:58 -04001060 SkScalar devSpaceInsetWidth = SkDrawShadowMetrics::AmbientBlurRadius(occluderHeight);
1061 const SkScalar umbraRecipAlpha = SkDrawShadowMetrics::AmbientRecipAlpha(occluderHeight);
1062 const SkScalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraRecipAlpha;
Jim Van Verth3af1af92017-05-18 15:06:54 -04001063
1064 // Outset the shadow rrect to the border of the penumbra
1065 SkScalar ambientPathOutset = devSpaceInsetWidth * devToSrcScale;
1066 SkRRect ambientRRect;
1067 SkRect outsetRect = rrect.rect().makeOutset(ambientPathOutset, ambientPathOutset);
1068 // If the rrect was an oval then its outset will also be one.
1069 // We set it explicitly to avoid errors.
1070 if (rrect.isOval()) {
1071 ambientRRect = SkRRect::MakeOval(outsetRect);
1072 } else {
Mike Reed242135a2018-02-22 13:41:39 -05001073 SkScalar outsetRad = SkRRectPriv::GetSimpleRadii(rrect).fX + ambientPathOutset;
Jim Van Verth3af1af92017-05-18 15:06:54 -04001074 ambientRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
1075 }
1076
Jim Van Verthb1b80f72018-01-18 15:19:13 -05001077 GrColor ambientColor = SkColorToPremulGrColor(rec.fAmbientColor);
Jim Van Verth3af1af92017-05-18 15:06:54 -04001078 if (transparent) {
1079 // set a large inset to force a fill
1080 devSpaceInsetWidth = ambientRRect.width();
1081 }
Jim Van Verth39e71652018-04-23 18:08:45 +00001082
Robert Phillips7c525e62018-06-12 10:11:12 -04001083 std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(fContext,
1084 ambientColor,
1085 viewMatrix,
Brian Salomon05969092017-07-13 11:20:51 -04001086 ambientRRect,
1087 devSpaceAmbientBlur,
Jim Van Verthfb186392018-09-11 11:37:46 -04001088 devSpaceInsetWidth);
Brian Salomon05969092017-07-13 11:20:51 -04001089 SkASSERT(op);
1090 this->addDrawOp(clip, std::move(op));
Jim Van Verthc5903412016-11-17 15:27:09 -05001091 }
Jim Van Verth3af1af92017-05-18 15:06:54 -04001092
Jim Van Verthb1b80f72018-01-18 15:19:13 -05001093 if (SkColorGetA(rec.fSpotColor) > 0) {
Jim Van Verth1af03d42017-07-31 09:34:58 -04001094 SkScalar devSpaceSpotBlur;
1095 SkScalar spotScale;
1096 SkVector spotOffset;
1097 SkDrawShadowMetrics::GetSpotParams(occluderHeight, devLightPos.fX, devLightPos.fY,
1098 devLightPos.fZ, rec.fLightRadius,
1099 &devSpaceSpotBlur, &spotScale, &spotOffset);
1100 // handle scale of radius due to CTM
Jim Van Verth3af1af92017-05-18 15:06:54 -04001101 const SkScalar srcSpaceSpotBlur = devSpaceSpotBlur * devToSrcScale;
1102
Jim Van Verth3af1af92017-05-18 15:06:54 -04001103 // Adjust translate for the effect of the scale.
1104 spotOffset.fX += spotScale*viewMatrix[SkMatrix::kMTransX];
1105 spotOffset.fY += spotScale*viewMatrix[SkMatrix::kMTransY];
1106 // This offset is in dev space, need to transform it into source space.
1107 SkMatrix ctmInverse;
1108 if (viewMatrix.invert(&ctmInverse)) {
1109 ctmInverse.mapPoints(&spotOffset, 1);
1110 } else {
1111 // Since the matrix is a similarity, this should never happen, but just in case...
1112 SkDebugf("Matrix is degenerate. Will not render spot shadow correctly!\n");
1113 SkASSERT(false);
1114 }
1115
1116 // Compute the transformed shadow rrect
1117 SkRRect spotShadowRRect;
1118 SkMatrix shadowTransform;
1119 shadowTransform.setScaleTranslate(spotScale, spotScale, spotOffset.fX, spotOffset.fY);
1120 rrect.transform(shadowTransform, &spotShadowRRect);
Mike Reed242135a2018-02-22 13:41:39 -05001121 SkScalar spotRadius = SkRRectPriv::GetSimpleRadii(spotShadowRRect).fX;
Jim Van Verth3af1af92017-05-18 15:06:54 -04001122
1123 // Compute the insetWidth
Jim Van Verth1af03d42017-07-31 09:34:58 -04001124 SkScalar blurOutset = srcSpaceSpotBlur;
Jim Van Verth3af1af92017-05-18 15:06:54 -04001125 SkScalar insetWidth = blurOutset;
1126 if (transparent) {
1127 // If transparent, just do a fill
1128 insetWidth += spotShadowRRect.width();
1129 } else {
1130 // For shadows, instead of using a stroke we specify an inset from the penumbra
1131 // border. We want to extend this inset area so that it meets up with the caster
1132 // geometry. The inset geometry will by default already be inset by the blur width.
1133 //
1134 // We compare the min and max corners inset by the radius between the original
1135 // rrect and the shadow rrect. The distance between the two plus the difference
1136 // between the scaled radius and the original radius gives the distance from the
1137 // transformed shadow shape to the original shape in that corner. The max
1138 // of these gives the maximum distance we need to cover.
1139 //
1140 // Since we are outsetting by 1/2 the blur distance, we just add the maxOffset to
1141 // that to get the full insetWidth.
1142 SkScalar maxOffset;
1143 if (rrect.isRect()) {
1144 // Manhattan distance works better for rects
1145 maxOffset = SkTMax(SkTMax(SkTAbs(spotShadowRRect.rect().fLeft -
1146 rrect.rect().fLeft),
1147 SkTAbs(spotShadowRRect.rect().fTop -
1148 rrect.rect().fTop)),
1149 SkTMax(SkTAbs(spotShadowRRect.rect().fRight -
1150 rrect.rect().fRight),
1151 SkTAbs(spotShadowRRect.rect().fBottom -
1152 rrect.rect().fBottom)));
1153 } else {
Mike Reed242135a2018-02-22 13:41:39 -05001154 SkScalar dr = spotRadius - SkRRectPriv::GetSimpleRadii(rrect).fX;
Jim Van Verth3af1af92017-05-18 15:06:54 -04001155 SkPoint upperLeftOffset = SkPoint::Make(spotShadowRRect.rect().fLeft -
1156 rrect.rect().fLeft + dr,
1157 spotShadowRRect.rect().fTop -
1158 rrect.rect().fTop + dr);
1159 SkPoint lowerRightOffset = SkPoint::Make(spotShadowRRect.rect().fRight -
1160 rrect.rect().fRight - dr,
1161 spotShadowRRect.rect().fBottom -
1162 rrect.rect().fBottom - dr);
Cary Clarkdf429f32017-11-08 11:44:31 -05001163 maxOffset = SkScalarSqrt(SkTMax(SkPointPriv::LengthSqd(upperLeftOffset),
1164 SkPointPriv::LengthSqd(lowerRightOffset))) + dr;
Jim Van Verth3af1af92017-05-18 15:06:54 -04001165 }
Jim Van Verth4c8c1e82018-04-23 17:14:48 -04001166 insetWidth += SkTMax(blurOutset, maxOffset);
Jim Van Verth3af1af92017-05-18 15:06:54 -04001167 }
1168
1169 // Outset the shadow rrect to the border of the penumbra
1170 SkRect outsetRect = spotShadowRRect.rect().makeOutset(blurOutset, blurOutset);
1171 if (spotShadowRRect.isOval()) {
1172 spotShadowRRect = SkRRect::MakeOval(outsetRect);
1173 } else {
1174 SkScalar outsetRad = spotRadius + blurOutset;
1175 spotShadowRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
1176 }
1177
Jim Van Verthb1b80f72018-01-18 15:19:13 -05001178 GrColor spotColor = SkColorToPremulGrColor(rec.fSpotColor);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -04001179
Robert Phillips7c525e62018-06-12 10:11:12 -04001180 std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(fContext,
1181 spotColor,
1182 viewMatrix,
Brian Salomon05969092017-07-13 11:20:51 -04001183 spotShadowRRect,
Jim Van Verth1af03d42017-07-31 09:34:58 -04001184 2.0f * devSpaceSpotBlur,
Brian Salomon05969092017-07-13 11:20:51 -04001185 insetWidth);
1186 SkASSERT(op);
1187 this->addDrawOp(clip, std::move(op));
Jim Van Verth3af1af92017-05-18 15:06:54 -04001188 }
1189
1190 return true;
Jim Van Verthc5903412016-11-17 15:27:09 -05001191}
1192
1193///////////////////////////////////////////////////////////////////////////////
1194
Brian Osman11052242016-10-27 14:47:55 -04001195bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001196 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001197 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001198 const SkMatrix& viewMatrix,
1199 const SkRRect& origOuter,
1200 const SkRRect& origInner) {
robertphillips00095892016-02-29 13:50:40 -08001201 SkASSERT(!origInner.isEmpty());
1202 SkASSERT(!origOuter.isEmpty());
1203
Brian Salomon65749212017-12-01 16:01:47 -05001204 SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
1205
Brian Salomon45839f92017-12-04 09:02:35 -05001206 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
1207
1208 if (GrAAType::kMSAA == aaType) {
1209 return false;
1210 }
1211
Mike Reed242135a2018-02-22 13:41:39 -05001212 if (GrAAType::kCoverage == aaType && SkRRectPriv::IsCircle(*inner)
1213 && SkRRectPriv::IsCircle(*outer)) {
Brian Salomon65749212017-12-01 16:01:47 -05001214 auto outerR = outer->width() / 2.f;
1215 auto innerR = inner->width() / 2.f;
1216 auto cx = outer->getBounds().fLeft + outerR;
1217 auto cy = outer->getBounds().fTop + outerR;
1218 if (SkScalarNearlyEqual(cx, inner->getBounds().fLeft + innerR) &&
1219 SkScalarNearlyEqual(cy, inner->getBounds().fTop + innerR)) {
1220 auto avgR = (innerR + outerR) / 2.f;
1221 auto circleBounds = SkRect::MakeLTRB(cx - avgR, cy - avgR, cx + avgR, cy + avgR);
1222 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
1223 stroke.setStrokeStyle(outerR - innerR);
Robert Phillips7c525e62018-06-12 10:11:12 -04001224 auto op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix,
1225 circleBounds, GrStyle(stroke, nullptr),
Brian Salomon62e4f3d2018-04-20 13:54:11 -04001226 this->caps()->shaderCaps());
Brian Salomon65749212017-12-01 16:01:47 -05001227 if (op) {
1228 this->addDrawOp(clip, std::move(op));
1229 return true;
1230 }
1231 }
1232 }
1233
Ethan Nicholas0f3c7322017-11-09 14:51:17 -05001234 GrClipEdgeType innerEdgeType, outerEdgeType;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001235 if (GrAAType::kCoverage == aaType) {
Ethan Nicholas1706f842017-11-10 11:58:19 -05001236 innerEdgeType = GrClipEdgeType::kInverseFillAA;
1237 outerEdgeType = GrClipEdgeType::kFillAA;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001238 } else {
Ethan Nicholas1706f842017-11-10 11:58:19 -05001239 innerEdgeType = GrClipEdgeType::kInverseFillBW;
1240 outerEdgeType = GrClipEdgeType::kFillBW;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001241 }
robertphillips00095892016-02-29 13:50:40 -08001242
robertphillips00095892016-02-29 13:50:40 -08001243 SkMatrix inverseVM;
1244 if (!viewMatrix.isIdentity()) {
1245 if (!origInner.transform(viewMatrix, inner.writable())) {
1246 return false;
1247 }
1248 if (!origOuter.transform(viewMatrix, outer.writable())) {
1249 return false;
1250 }
1251 if (!viewMatrix.invert(&inverseVM)) {
1252 return false;
1253 }
1254 } else {
1255 inverseVM.reset();
halcanary9d524f22016-03-29 09:03:52 -07001256 }
robertphillips00095892016-02-29 13:50:40 -08001257
Ethan Nicholaseace9352018-10-15 20:09:54 +00001258 const auto& caps = *this->caps()->shaderCaps();
robertphillips00095892016-02-29 13:50:40 -08001259 // TODO these need to be a geometry processors
Ethan Nicholaseace9352018-10-15 20:09:54 +00001260 auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, caps);
robertphillips00095892016-02-29 13:50:40 -08001261 if (!innerEffect) {
1262 return false;
1263 }
1264
Ethan Nicholaseace9352018-10-15 20:09:54 +00001265 auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, caps);
robertphillips00095892016-02-29 13:50:40 -08001266 if (!outerEffect) {
1267 return false;
1268 }
1269
Brian Salomon82f44312017-01-11 13:42:54 -05001270 paint.addCoverageFragmentProcessor(std::move(innerEffect));
1271 paint.addCoverageFragmentProcessor(std::move(outerEffect));
robertphillips00095892016-02-29 13:50:40 -08001272
1273 SkRect bounds = outer->getBounds();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001274 if (GrAAType::kCoverage == aaType) {
robertphillips00095892016-02-29 13:50:40 -08001275 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1276 }
halcanary9d524f22016-03-29 09:03:52 -07001277
Brian Salomon82f44312017-01-11 13:42:54 -05001278 this->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), bounds,
1279 inverseVM);
robertphillips00095892016-02-29 13:50:40 -08001280 return true;
1281}
1282
Brian Osman11052242016-10-27 14:47:55 -04001283void GrRenderTargetContext::drawDRRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001284 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001285 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001286 const SkMatrix& viewMatrix,
1287 const SkRRect& outer,
1288 const SkRRect& inner) {
robertphillips00095892016-02-29 13:50:40 -08001289 ASSERT_SINGLE_OWNER
1290 RETURN_IF_ABANDONED
1291 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001292 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawDRRect", fContext);
robertphillips00095892016-02-29 13:50:40 -08001293
1294 SkASSERT(!outer.isEmpty());
1295 SkASSERT(!inner.isEmpty());
1296
Robert Phillips72152832017-01-25 17:31:35 -05001297 AutoCheckFlush acf(this->drawingManager());
robertphillips00095892016-02-29 13:50:40 -08001298
Brian Salomon82f44312017-01-11 13:42:54 -05001299 if (this->drawFilledDRRect(clip, std::move(paint), aa, viewMatrix, outer, inner)) {
robertphillips00095892016-02-29 13:50:40 -08001300 return;
1301 }
1302
1303 SkPath path;
1304 path.setIsVolatile(true);
1305 path.addRRect(inner);
1306 path.addRRect(outer);
1307 path.setFillType(SkPath::kEvenOdd_FillType);
Brian Salomon2fad74a2017-12-20 13:28:55 -05001308 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, GrShape(path));
robertphillips00095892016-02-29 13:50:40 -08001309}
1310
robertphillipsea461502015-05-26 11:38:03 -07001311///////////////////////////////////////////////////////////////////////////////
1312
Brian Osman11052242016-10-27 14:47:55 -04001313void GrRenderTargetContext::drawRegion(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001314 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001315 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001316 const SkMatrix& viewMatrix,
1317 const SkRegion& region,
Stan Iliev73d8fd92017-08-02 15:36:24 -04001318 const GrStyle& style,
1319 const GrUserStencilSettings* ss) {
msarettcc319b92016-08-25 18:07:18 -07001320 ASSERT_SINGLE_OWNER
1321 RETURN_IF_ABANDONED
1322 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001323 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawRegion", fContext);
msarettcc319b92016-08-25 18:07:18 -07001324
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001325 if (GrAA::kYes == aa) {
Brian Salomonfc527d22016-12-14 21:07:01 -05001326 // GrRegionOp performs no antialiasing but is much faster, so here we check the matrix
Brian Salomonc57c7c92016-12-06 14:47:34 -05001327 // to see whether aa is really required.
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001328 if (!SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) &&
Brian Salomon34169692017-08-28 15:32:01 -04001329 SkScalarIsInt(viewMatrix.getTranslateX()) &&
1330 SkScalarIsInt(viewMatrix.getTranslateY())) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001331 aa = GrAA::kNo;
1332 }
Brian Salomonc57c7c92016-12-06 14:47:34 -05001333 }
msarettcc319b92016-08-25 18:07:18 -07001334 bool complexStyle = !style.isSimpleFill();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001335 if (complexStyle || GrAA::kYes == aa) {
msarettcc319b92016-08-25 18:07:18 -07001336 SkPath path;
1337 region.getBoundaryPath(&path);
Robert Phillips46a13382018-08-23 13:53:01 -04001338 path.setIsVolatile(true);
1339
Brian Salomon82f44312017-01-11 13:42:54 -05001340 return this->drawPath(clip, std::move(paint), aa, viewMatrix, path, style);
msarettcc319b92016-08-25 18:07:18 -07001341 }
1342
Brian Salomonf0366322017-07-11 15:53:05 -04001343 GrAAType aaType = this->chooseAAType(GrAA::kNo, GrAllowMixedSamples::kNo);
Robert Phillips7c525e62018-06-12 10:11:12 -04001344 std::unique_ptr<GrDrawOp> op = GrRegionOp::Make(fContext, std::move(paint), viewMatrix, region,
1345 aaType, ss);
Brian Salomonf0366322017-07-11 15:53:05 -04001346 this->addDrawOp(clip, std::move(op));
msarettcc319b92016-08-25 18:07:18 -07001347}
1348
Brian Osman11052242016-10-27 14:47:55 -04001349void GrRenderTargetContext::drawOval(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001350 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001351 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001352 const SkMatrix& viewMatrix,
1353 const SkRect& oval,
1354 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001355 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001356 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001357 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001358 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawOval", fContext);
robertphillips2e1e51f2015-10-15 08:01:48 -07001359
Robert Phillips7484d202018-07-03 09:09:08 -04001360 const SkStrokeRec& stroke = style.strokeRec();
1361
Brian Salomon62e4f3d2018-04-20 13:54:11 -04001362 if (oval.isEmpty() && !style.pathEffect()) {
Robert Phillips7484d202018-07-03 09:09:08 -04001363 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
1364 return;
1365 }
1366
1367 this->drawRect(clip, std::move(paint), aa, viewMatrix, oval, &style);
Brian Salomon62e4f3d2018-04-20 13:54:11 -04001368 return;
robertphillipsea461502015-05-26 11:38:03 -07001369 }
1370
Robert Phillips72152832017-01-25 17:31:35 -05001371 AutoCheckFlush acf(this->drawingManager());
csmartdaltona7f29642016-07-07 08:49:11 -07001372
Brian Salomonea26d6b2018-01-23 20:33:21 +00001373 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001374 if (GrAAType::kCoverage == aaType) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -04001375 const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
Robert Phillips7c525e62018-06-12 10:11:12 -04001376 if (auto op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix, oval,
1377 style, shaderCaps)) {
Brian Salomon05441c42017-05-15 16:45:49 -04001378 this->addDrawOp(clip, std::move(op));
robertphillipsb56f9272016-02-25 11:03:52 -08001379 return;
1380 }
robertphillipsea461502015-05-26 11:38:03 -07001381 }
robertphillipsb56f9272016-02-25 11:03:52 -08001382
Brian Salomon5209d7f2018-04-20 16:52:42 -04001383 this->drawShapeUsingPathRenderer(
1384 clip, std::move(paint), aa, viewMatrix,
1385 GrShape(SkRRect::MakeOval(oval), SkPath::kCW_Direction, 2, false, style));
robertphillipsea461502015-05-26 11:38:03 -07001386}
1387
Brian Osman11052242016-10-27 14:47:55 -04001388void GrRenderTargetContext::drawArc(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001389 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001390 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001391 const SkMatrix& viewMatrix,
1392 const SkRect& oval,
1393 SkScalar startAngle,
1394 SkScalar sweepAngle,
1395 bool useCenter,
1396 const GrStyle& style) {
Robert Phillipsf1d0ced2017-02-10 09:31:01 -05001397 ASSERT_SINGLE_OWNER
1398 RETURN_IF_ABANDONED
1399 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001400 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawArc", fContext);
Robert Phillipsf1d0ced2017-02-10 09:31:01 -05001401
1402 AutoCheckFlush acf(this->drawingManager());
1403
Brian Salomonea26d6b2018-01-23 20:33:21 +00001404 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001405 if (GrAAType::kCoverage == aaType) {
Brian Salomonc7fe0f72018-05-11 10:14:21 -04001406 const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
Robert Phillips7c525e62018-06-12 10:11:12 -04001407 std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeArcOp(fContext,
1408 std::move(paint),
Brian Salomonea26d6b2018-01-23 20:33:21 +00001409 viewMatrix,
1410 oval,
1411 startAngle,
1412 sweepAngle,
1413 useCenter,
1414 style,
1415 shaderCaps);
Brian Salomon42521e82016-12-07 16:44:58 -05001416 if (op) {
Brian Salomon05441c42017-05-15 16:45:49 -04001417 this->addDrawOp(clip, std::move(op));
bsalomon4f3a0ca2016-08-22 13:14:26 -07001418 return;
1419 }
1420 }
Brian Salomone4949402018-04-26 15:22:04 -04001421 this->drawShapeUsingPathRenderer(
1422 clip, std::move(paint), aa, viewMatrix,
1423 GrShape::MakeArc(oval, startAngle, sweepAngle, useCenter, style));
bsalomon4f3a0ca2016-08-22 13:14:26 -07001424}
1425
Brian Osman11052242016-10-27 14:47:55 -04001426void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001427 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -04001428 const SkMatrix& viewMatrix,
Brian Salomon2a943df2018-05-04 13:43:19 -04001429 sk_sp<GrTextureProxy> image,
1430 sk_sp<GrColorSpaceXform> csxf,
1431 GrSamplerState::Filter filter,
Brian Osman11052242016-10-27 14:47:55 -04001432 std::unique_ptr<SkLatticeIter> iter,
1433 const SkRect& dst) {
joshualitt1de610a2016-01-06 08:26:09 -08001434 ASSERT_SINGLE_OWNER
joshualitt33a5fce2015-11-18 13:28:51 -08001435 RETURN_IF_ABANDONED
1436 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001437 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawImageLattice", fContext);
joshualitt33a5fce2015-11-18 13:28:51 -08001438
Robert Phillips72152832017-01-25 17:31:35 -05001439 AutoCheckFlush acf(this->drawingManager());
joshualitt33a5fce2015-11-18 13:28:51 -08001440
Brian Salomon2a943df2018-05-04 13:43:19 -04001441 std::unique_ptr<GrDrawOp> op =
Robert Phillips7c525e62018-06-12 10:11:12 -04001442 GrLatticeOp::MakeNonAA(fContext, std::move(paint), viewMatrix, std::move(image),
1443 std::move(csxf), filter, std::move(iter), dst);
Brian Salomon815486c2017-07-11 08:52:13 -04001444 this->addDrawOp(clip, std::move(op));
joshualitt33a5fce2015-11-18 13:28:51 -08001445}
1446
Greg Daniel64cc9aa2018-10-19 13:54:56 -04001447void GrRenderTargetContext::drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable,
1448 const SkRect& bounds) {
1449 std::unique_ptr<GrOp> op(GrDrawableOp::Make(fContext, std::move(drawable), bounds));
1450 SkASSERT(op);
1451 this->getRTOpList()->addOp(std::move(op), *this->caps());
1452}
1453
Greg Daniel51316782017-08-02 15:10:09 +00001454GrSemaphoresSubmitted GrRenderTargetContext::prepareForExternalIO(
1455 int numSemaphores, GrBackendSemaphore backendSemaphores[]) {
robertphillips8c523e02016-07-26 07:41:00 -07001456 ASSERT_SINGLE_OWNER
Greg Daniel51316782017-08-02 15:10:09 +00001457 if (this->drawingManager()->wasAbandoned()) { return GrSemaphoresSubmitted::kNo; }
robertphillips8c523e02016-07-26 07:41:00 -07001458 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001459 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "prepareForExternalIO", fContext);
robertphillips8c523e02016-07-26 07:41:00 -07001460
Greg Daniel51316782017-08-02 15:10:09 +00001461 return this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get(),
1462 numSemaphores,
1463 backendSemaphores);
Greg Daniela5cb7812017-06-16 09:45:32 -04001464}
1465
Greg Danielc64ee462017-06-15 16:59:49 -04001466bool GrRenderTargetContext::waitOnSemaphores(int numSemaphores,
Greg Daniela5cb7812017-06-16 09:45:32 -04001467 const GrBackendSemaphore* waitSemaphores) {
1468 ASSERT_SINGLE_OWNER
Greg Danielc64ee462017-06-15 16:59:49 -04001469 RETURN_FALSE_IF_ABANDONED
Greg Daniela5cb7812017-06-16 09:45:32 -04001470 SkDEBUGCODE(this->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001471 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "waitOnSemaphores", fContext);
Greg Daniela5cb7812017-06-16 09:45:32 -04001472
1473 AutoCheckFlush acf(this->drawingManager());
1474
Greg Danielc64ee462017-06-15 16:59:49 -04001475 if (numSemaphores && !this->caps()->fenceSyncSupport()) {
1476 return false;
1477 }
1478
Robert Phillips6be756b2018-01-16 15:07:54 -05001479 auto resourceProvider = fContext->contextPriv().resourceProvider();
1480
Greg Daniela5cb7812017-06-16 09:45:32 -04001481 SkTArray<sk_sp<GrSemaphore>> semaphores(numSemaphores);
1482 for (int i = 0; i < numSemaphores; ++i) {
Robert Phillips6be756b2018-01-16 15:07:54 -05001483 sk_sp<GrSemaphore> sema = resourceProvider->wrapBackendSemaphore(
Greg Daniel17b7c052018-01-09 13:55:33 -05001484 waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait,
1485 kAdopt_GrWrapOwnership);
Robert Phillips7c525e62018-06-12 10:11:12 -04001486 std::unique_ptr<GrOp> waitOp(GrSemaphoreOp::MakeWait(fContext, sema,
1487 fRenderTargetProxy.get()));
Robert Phillips2de8cfa2017-06-28 10:33:41 -04001488 this->getRTOpList()->addOp(std::move(waitOp), *this->caps());
Greg Daniela5cb7812017-06-16 09:45:32 -04001489 }
Greg Danielc64ee462017-06-15 16:59:49 -04001490 return true;
robertphillips8c523e02016-07-26 07:41:00 -07001491}
joshualitt33a5fce2015-11-18 13:28:51 -08001492
Robert Phillips65a88fa2017-08-08 08:36:22 -04001493void GrRenderTargetContext::insertEventMarker(const SkString& str) {
Robert Phillips88a32ef2018-06-07 11:05:56 -04001494 std::unique_ptr<GrOp> op(GrDebugMarkerOp::Make(fContext, fRenderTargetProxy.get(), str));
Robert Phillips65a88fa2017-08-08 08:36:22 -04001495 this->getRTOpList()->addOp(std::move(op), *this->caps());
1496}
1497
Brian Osman11052242016-10-27 14:47:55 -04001498void GrRenderTargetContext::drawPath(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001499 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001500 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001501 const SkMatrix& viewMatrix,
Brian Salomon40b77a62017-12-22 11:25:52 -05001502 const SkPath& path,
Brian Osman11052242016-10-27 14:47:55 -04001503 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001504 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001505 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001506 SkDEBUGCODE(this->validate();)
Robert Phillips20390c32018-08-17 11:01:03 -04001507 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawPath", fContext);
1508
Brian Salomon40b77a62017-12-22 11:25:52 -05001509 GrShape shape(path, style);
Robert Phillips20390c32018-08-17 11:01:03 -04001510
Robert Phillips27927a52018-08-20 13:18:12 -04001511 this->drawShape(clip, std::move(paint), aa, viewMatrix, shape);
Robert Phillips20390c32018-08-17 11:01:03 -04001512}
1513
1514void GrRenderTargetContext::drawShape(const GrClip& clip,
1515 GrPaint&& paint,
1516 GrAA aa,
1517 const SkMatrix& viewMatrix,
1518 const GrShape& shape) {
1519 ASSERT_SINGLE_OWNER
1520 RETURN_IF_ABANDONED
1521 SkDEBUGCODE(this->validate();)
1522 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawShape", fContext);
1523
Brian Salomon2fad74a2017-12-20 13:28:55 -05001524 if (shape.isEmpty()) {
1525 if (shape.inverseFilled()) {
1526 this->drawPaint(clip, std::move(paint), viewMatrix);
1527 }
1528 return;
robertphillipsea461502015-05-26 11:38:03 -07001529 }
1530
Robert Phillips72152832017-01-25 17:31:35 -05001531 AutoCheckFlush acf(this->drawingManager());
robertphillipsea461502015-05-26 11:38:03 -07001532
Brian Salomon2fad74a2017-12-20 13:28:55 -05001533 if (!shape.style().hasPathEffect()) {
Robert Phillips73653b42018-08-22 12:42:42 -04001534 GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
Brian Salomon2fad74a2017-12-20 13:28:55 -05001535 SkRRect rrect;
1536 // We can ignore the starting point and direction since there is no path effect.
1537 bool inverted;
1538 if (shape.asRRect(&rrect, nullptr, nullptr, &inverted) && !inverted) {
1539 if (rrect.isRect()) {
1540 this->drawRect(clip, std::move(paint), aa, viewMatrix, rrect.rect(),
1541 &shape.style());
1542 return;
1543 } else if (rrect.isOval()) {
1544 this->drawOval(clip, std::move(paint), aa, viewMatrix, rrect.rect(), shape.style());
robertphillipsea461502015-05-26 11:38:03 -07001545 return;
1546 }
Brian Salomon2fad74a2017-12-20 13:28:55 -05001547 this->drawRRect(clip, std::move(paint), aa, viewMatrix, rrect, shape.style());
1548 return;
Robert Phillips73653b42018-08-22 12:42:42 -04001549 } else if (GrAAType::kCoverage == aaType && shape.style().isSimpleFill() &&
1550 viewMatrix.rectStaysRect()) {
1551 // TODO: the rectStaysRect restriction could be lifted if we were willing to apply
1552 // the matrix to all the points individually rather than just to the rect
1553 SkRect rects[2];
1554 if (shape.asNestedRects(rects)) {
1555 // Concave AA paths are expensive - try to avoid them for special cases
1556 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeAAFillNestedRects(
1557 fContext, std::move(paint), viewMatrix, rects);
1558 if (op) {
1559 this->addDrawOp(clip, std::move(op));
1560 }
1561 // Returning here indicates that there is nothing to draw in this case.
1562 return;
1563 }
robertphillipsea461502015-05-26 11:38:03 -07001564 }
1565 }
robertphillips4bc31812016-03-01 12:22:49 -08001566
Brian Salomon2fad74a2017-12-20 13:28:55 -05001567 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, shape);
robertphillipsea461502015-05-26 11:38:03 -07001568}
1569
Chris Daltonbbfd5162017-11-07 13:35:22 -07001570bool GrRenderTargetContextPriv::drawAndStencilPath(const GrHardClip& clip,
Brian Osman11052242016-10-27 14:47:55 -04001571 const GrUserStencilSettings* ss,
1572 SkRegion::Op op,
1573 bool invert,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001574 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001575 const SkMatrix& viewMatrix,
1576 const SkPath& path) {
robertphillips391395d2016-03-02 09:26:36 -08001577 ASSERT_SINGLE_OWNER_PRIV
1578 RETURN_FALSE_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -04001579 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001580 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "drawAndStencilPath",
1581 fRenderTargetContext->fContext);
robertphillips391395d2016-03-02 09:26:36 -08001582
1583 if (path.isEmpty() && path.isInverseFillType()) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001584 this->drawAndStencilRect(clip, ss, op, invert, GrAA::kNo, SkMatrix::I(),
Brian Osman11052242016-10-27 14:47:55 -04001585 SkRect::MakeIWH(fRenderTargetContext->width(),
1586 fRenderTargetContext->height()));
robertphillips391395d2016-03-02 09:26:36 -08001587 return true;
1588 }
1589
Robert Phillips72152832017-01-25 17:31:35 -05001590 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
robertphillips391395d2016-03-02 09:26:36 -08001591
1592 // An Assumption here is that path renderer would use some form of tweaking
1593 // the src color (either the input alpha or in the frag shader) to implement
1594 // aa. If we have some future driver-mojo path AA that can do the right
1595 // thing WRT to the blend then we'll need some query on the PR.
Brian Salomon7c8460e2017-05-12 11:36:10 -04001596 GrAAType aaType = fRenderTargetContext->chooseAAType(aa, GrAllowMixedSamples::kNo);
robertphillips976f5f02016-06-03 10:59:20 -07001597 bool hasUserStencilSettings = !ss->isUnused();
robertphillips391395d2016-03-02 09:26:36 -08001598
Chris Daltondb91c6e2017-09-08 16:25:08 -06001599 SkIRect clipConservativeBounds;
1600 clip.getConservativeBounds(fRenderTargetContext->width(), fRenderTargetContext->height(),
1601 &clipConservativeBounds, nullptr);
1602
bsalomon8acedde2016-06-24 10:42:16 -07001603 GrShape shape(path, GrStyle::SimpleFill());
robertphillips391395d2016-03-02 09:26:36 -08001604 GrPathRenderer::CanDrawPathArgs canDrawArgs;
Brian Salomonc7fe0f72018-05-11 10:14:21 -04001605 canDrawArgs.fCaps = fRenderTargetContext->caps();
robertphillips391395d2016-03-02 09:26:36 -08001606 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001607 canDrawArgs.fShape = &shape;
Chris Daltondb91c6e2017-09-08 16:25:08 -06001608 canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001609 canDrawArgs.fAAType = aaType;
cdalton93a379b2016-05-11 13:58:08 -07001610 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
robertphillips391395d2016-03-02 09:26:36 -08001611
1612 // Don't allow the SW renderer
Robert Phillips72152832017-01-25 17:31:35 -05001613 GrPathRenderer* pr = fRenderTargetContext->drawingManager()->getPathRenderer(
Brian Salomon36aa1762016-12-10 13:24:02 -05001614 canDrawArgs, false, GrPathRendererChain::DrawType::kStencilAndColor);
robertphillips391395d2016-03-02 09:26:36 -08001615 if (!pr) {
1616 return false;
1617 }
1618
1619 GrPaint paint;
1620 paint.setCoverageSetOpXPFactory(op, invert);
1621
Brian Salomonf3569f02017-10-24 12:52:33 -04001622 GrPathRenderer::DrawPathArgs args{fRenderTargetContext->drawingManager()->getContext(),
1623 std::move(paint),
1624 ss,
1625 fRenderTargetContext,
1626 &clip,
1627 &clipConservativeBounds,
1628 &viewMatrix,
1629 &shape,
1630 aaType,
Brian Osman34ec3742018-07-03 10:40:57 -04001631 fRenderTargetContext->colorSpaceInfo().isLinearlyBlended()};
robertphillips391395d2016-03-02 09:26:36 -08001632 pr->drawPath(args);
1633 return true;
1634}
1635
Brian Osman11052242016-10-27 14:47:55 -04001636SkBudgeted GrRenderTargetContextPriv::isBudgeted() const {
robertphillips714712b2016-08-04 06:20:45 -07001637 ASSERT_SINGLE_OWNER_PRIV
1638
Brian Osman11052242016-10-27 14:47:55 -04001639 if (fRenderTargetContext->wasAbandoned()) {
robertphillips714712b2016-08-04 06:20:45 -07001640 return SkBudgeted::kNo;
1641 }
1642
Brian Osman11052242016-10-27 14:47:55 -04001643 SkDEBUGCODE(fRenderTargetContext->validate();)
robertphillips714712b2016-08-04 06:20:45 -07001644
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001645 return fRenderTargetContext->fRenderTargetProxy->isBudgeted();
robertphillips714712b2016-08-04 06:20:45 -07001646}
1647
Brian Salomon2fad74a2017-12-20 13:28:55 -05001648void GrRenderTargetContext::drawShapeUsingPathRenderer(const GrClip& clip,
1649 GrPaint&& paint,
1650 GrAA aa,
1651 const SkMatrix& viewMatrix,
1652 const GrShape& originalShape) {
joshualitt1de610a2016-01-06 08:26:09 -08001653 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001654 RETURN_IF_ABANDONED
Brian Salomondcbb9d92017-07-19 10:53:20 -04001655 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "internalDrawPath", fContext);
1656
Jim Van Verthf86073a2018-10-02 13:05:38 -04001657 if (!viewMatrix.isFinite() || !originalShape.bounds().isFinite()) {
1658 return;
1659 }
1660
Chris Daltondb91c6e2017-09-08 16:25:08 -06001661 SkIRect clipConservativeBounds;
1662 clip.getConservativeBounds(this->width(), this->height(), &clipConservativeBounds, nullptr);
1663
Brian Salomon2fad74a2017-12-20 13:28:55 -05001664 GrShape tempShape;
Brian Salomon7c8460e2017-05-12 11:36:10 -04001665 // NVPR cannot handle hairlines, so this would get picked up by a different stencil and
1666 // cover path renderer (i.e. default path renderer). The hairline renderer produces much
1667 // smoother hairlines than MSAA.
Brian Salomon2fad74a2017-12-20 13:28:55 -05001668 GrAllowMixedSamples allowMixedSamples = originalShape.style().isSimpleHairline()
1669 ? GrAllowMixedSamples::kNo
1670 : GrAllowMixedSamples::kYes;
Brian Salomon7c8460e2017-05-12 11:36:10 -04001671 GrAAType aaType = this->chooseAAType(aa, allowMixedSamples);
robertphillips68737822015-10-29 12:12:21 -07001672 GrPathRenderer::CanDrawPathArgs canDrawArgs;
Brian Salomonc7fe0f72018-05-11 10:14:21 -04001673 canDrawArgs.fCaps = this->caps();
robertphillips68737822015-10-29 12:12:21 -07001674 canDrawArgs.fViewMatrix = &viewMatrix;
Brian Salomon2fad74a2017-12-20 13:28:55 -05001675 canDrawArgs.fShape = &originalShape;
Chris Daltondb91c6e2017-09-08 16:25:08 -06001676 canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001677 canDrawArgs.fHasUserStencilSettings = false;
robertphillips68737822015-10-29 12:12:21 -07001678
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001679 GrPathRenderer* pr;
Brian Salomon82125e92016-12-10 09:35:48 -05001680 static constexpr GrPathRendererChain::DrawType kType = GrPathRendererChain::DrawType::kColor;
Brian Salomon2fad74a2017-12-20 13:28:55 -05001681 if (originalShape.isEmpty() && !originalShape.inverseFilled()) {
Brian Salomon1e5d0ca2017-12-14 10:50:19 -05001682 return;
1683 }
1684
1685 canDrawArgs.fAAType = aaType;
1686
1687 // Try a 1st time without applying any of the style to the geometry (and barring sw)
1688 pr = this->drawingManager()->getPathRenderer(canDrawArgs, false, kType);
1689 SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
1690
Brian Salomon2fad74a2017-12-20 13:28:55 -05001691 if (!pr && originalShape.style().pathEffect()) {
Brian Salomon1e5d0ca2017-12-14 10:50:19 -05001692 // It didn't work above, so try again with the path effect applied.
Brian Salomon2fad74a2017-12-20 13:28:55 -05001693 tempShape = originalShape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
1694 if (tempShape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001695 return;
1696 }
Brian Salomon2fad74a2017-12-20 13:28:55 -05001697 canDrawArgs.fShape = &tempShape;
Robert Phillips72152832017-01-25 17:31:35 -05001698 pr = this->drawingManager()->getPathRenderer(canDrawArgs, false, kType);
Brian Salomon1e5d0ca2017-12-14 10:50:19 -05001699 }
1700 if (!pr) {
Brian Salomon2fad74a2017-12-20 13:28:55 -05001701 if (canDrawArgs.fShape->style().applies()) {
1702 tempShape = canDrawArgs.fShape->applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec,
1703 styleScale);
1704 if (tempShape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001705 return;
1706 }
Brian Salomon2fad74a2017-12-20 13:28:55 -05001707 canDrawArgs.fShape = &tempShape;
Brian Salomone7df0bb2018-05-07 14:44:57 -04001708 // This time, allow SW renderer
1709 pr = this->drawingManager()->getPathRenderer(canDrawArgs, true, kType);
1710 } else {
1711 pr = this->drawingManager()->getSoftwarePathRenderer();
bsalomon6663acf2016-05-10 09:14:17 -07001712 }
Brian Salomon1e5d0ca2017-12-14 10:50:19 -05001713 }
robertphillipsea461502015-05-26 11:38:03 -07001714
bsalomon8acedde2016-06-24 10:42:16 -07001715 if (!pr) {
robertphillipsea461502015-05-26 11:38:03 -07001716#ifdef SK_DEBUG
1717 SkDebugf("Unable to find path renderer compatible with path.\n");
1718#endif
1719 return;
1720 }
1721
Robert Phillips256c37b2017-03-01 14:32:46 -05001722 GrPathRenderer::DrawPathArgs args{this->drawingManager()->getContext(),
Brian Salomon82f44312017-01-11 13:42:54 -05001723 std::move(paint),
1724 &GrUserStencilSettings::kUnused,
1725 this,
1726 &clip,
Chris Daltondb91c6e2017-09-08 16:25:08 -06001727 &clipConservativeBounds,
Brian Salomon82f44312017-01-11 13:42:54 -05001728 &viewMatrix,
Brian Salomon2fad74a2017-12-20 13:28:55 -05001729 canDrawArgs.fShape,
Brian Salomon82f44312017-01-11 13:42:54 -05001730 aaType,
Brian Osman34ec3742018-07-03 10:40:57 -04001731 this->colorSpaceInfo().isLinearlyBlended()};
bsalomon0aff2fa2015-07-31 06:48:27 -07001732 pr->drawPath(args);
robertphillipsea461502015-05-26 11:38:03 -07001733}
1734
Brian Salomon467921e2017-03-06 16:17:12 -05001735static void op_bounds(SkRect* bounds, const GrOp* op) {
1736 *bounds = op->bounds();
1737 if (op->hasZeroArea()) {
1738 if (op->hasAABloat()) {
1739 bounds->outset(0.5f, 0.5f);
1740 } else {
1741 // We don't know which way the particular GPU will snap lines or points at integer
1742 // coords. So we ensure that the bounds is large enough for either snap.
1743 SkRect before = *bounds;
1744 bounds->roundOut(bounds);
1745 if (bounds->fLeft == before.fLeft) {
1746 bounds->fLeft -= 1;
1747 }
1748 if (bounds->fTop == before.fTop) {
1749 bounds->fTop -= 1;
1750 }
1751 if (bounds->fRight == before.fRight) {
1752 bounds->fRight += 1;
1753 }
1754 if (bounds->fBottom == before.fBottom) {
1755 bounds->fBottom += 1;
1756 }
1757 }
1758 }
1759}
1760
Brian Salomon348a0372018-10-31 10:42:18 -04001761void GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<GrDrawOp> op,
1762 const std::function<WillAddOpFn>& willAddFn) {
joshualitt1de610a2016-01-06 08:26:09 -08001763 ASSERT_SINGLE_OWNER
Robert Phillipsc0138922017-03-08 11:50:55 -05001764 if (this->drawingManager()->wasAbandoned()) {
Robert Phillipsc994a932018-06-19 13:09:54 -04001765 fContext->contextPriv().opMemoryPool()->release(std::move(op));
Brian Salomon348a0372018-10-31 10:42:18 -04001766 return;
Robert Phillipsc0138922017-03-08 11:50:55 -05001767 }
robertphillips2e1e51f2015-10-15 08:01:48 -07001768 SkDEBUGCODE(this->validate();)
Ethan Nicholas029b22c2018-10-18 16:49:56 -04001769 SkDEBUGCODE(op->fAddDrawOpCalled = true;)
Brian Salomondcbb9d92017-07-19 10:53:20 -04001770 GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "addDrawOp", fContext);
robertphillips2d70dcb2015-10-06 07:38:23 -07001771
Brian Salomon467921e2017-03-06 16:17:12 -05001772 // Setup clip
1773 SkRect bounds;
1774 op_bounds(&bounds, op.get());
Brian Salomon97180af2017-03-14 13:42:58 -04001775 GrAppliedClip appliedClip;
Brian Salomon54d212e2017-03-21 14:22:38 -04001776 GrDrawOp::FixedFunctionFlags fixedFunctionFlags = op->fixedFunctionFlags();
1777 if (!clip.apply(fContext, this, fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesHWAA,
1778 fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesStencil, &appliedClip,
1779 &bounds)) {
Robert Phillipsc994a932018-06-19 13:09:54 -04001780 fContext->contextPriv().opMemoryPool()->release(std::move(op));
Brian Salomon348a0372018-10-31 10:42:18 -04001781 return;
Brian Salomon54d212e2017-03-21 14:22:38 -04001782 }
1783
Brian Salomon54d212e2017-03-21 14:22:38 -04001784 if (fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesStencil ||
1785 appliedClip.hasStencilClip()) {
Robert Phillips6b47c7d2017-08-29 07:24:09 -04001786 this->getOpList()->setStencilLoadOp(GrLoadOp::kClear);
Robert Phillips95214472017-08-08 18:00:03 -04001787
Robert Phillips65048132017-08-10 08:44:49 -04001788 this->setNeedsStencil();
Brian Salomon54d212e2017-03-21 14:22:38 -04001789 }
1790
Robert Phillipsbb581ce2017-05-29 15:05:15 -04001791 GrXferProcessor::DstProxy dstProxy;
Brian Osman532b3f92018-07-11 10:02:07 -04001792 if (GrDrawOp::RequiresDstTexture::kYes == op->finalize(*this->caps(), &appliedClip)) {
Robert Phillipsbb581ce2017-05-29 15:05:15 -04001793 if (!this->setupDstProxy(this->asRenderTargetProxy(), clip, op->bounds(), &dstProxy)) {
Robert Phillipsc994a932018-06-19 13:09:54 -04001794 fContext->contextPriv().opMemoryPool()->release(std::move(op));
Brian Salomon348a0372018-10-31 10:42:18 -04001795 return;
Brian Salomon54d212e2017-03-21 14:22:38 -04001796 }
1797 }
1798
1799 op->setClippedBounds(bounds);
Brian Salomon348a0372018-10-31 10:42:18 -04001800 auto opList = this->getRTOpList();
1801 if (willAddFn) {
1802 willAddFn(op.get(), opList->uniqueID());
1803 }
1804 opList->addOp(std::move(op), *this->caps(), std::move(appliedClip), dstProxy);
Brian Salomon54d212e2017-03-21 14:22:38 -04001805}
1806
Robert Phillipsbb581ce2017-05-29 15:05:15 -04001807bool GrRenderTargetContext::setupDstProxy(GrRenderTargetProxy* rtProxy, const GrClip& clip,
Robert Phillips16d8ec62017-07-27 16:16:25 -04001808 const SkRect& opBounds,
1809 GrXferProcessor::DstProxy* dstProxy) {
Brian Salomon467921e2017-03-06 16:17:12 -05001810 if (this->caps()->textureBarrierSupport()) {
Robert Phillipsbf25d432017-04-07 10:08:53 -04001811 if (GrTextureProxy* texProxy = rtProxy->asTextureProxy()) {
Brian Salomon467921e2017-03-06 16:17:12 -05001812 // The render target is a texture, so we can read from it directly in the shader. The XP
1813 // will be responsible to detect this situation and request a texture barrier.
Robert Phillipsbb581ce2017-05-29 15:05:15 -04001814 dstProxy->setProxy(sk_ref_sp(texProxy));
1815 dstProxy->setOffset(0, 0);
Robert Phillipsbf25d432017-04-07 10:08:53 -04001816 return true;
Brian Salomon467921e2017-03-06 16:17:12 -05001817 }
1818 }
1819
Robert Phillipsbf25d432017-04-07 10:08:53 -04001820 SkIRect copyRect = SkIRect::MakeWH(rtProxy->width(), rtProxy->height());
Brian Salomon467921e2017-03-06 16:17:12 -05001821
Eric Karl74480882017-04-03 14:49:05 -07001822 SkIRect clippedRect;
Robert Phillipsbf25d432017-04-07 10:08:53 -04001823 clip.getConservativeBounds(rtProxy->width(), rtProxy->height(), &clippedRect);
Eric Karl72e551e2017-04-04 13:42:10 -07001824 SkIRect drawIBounds;
Brian Salomon467921e2017-03-06 16:17:12 -05001825 opBounds.roundOut(&drawIBounds);
Brian Salomon859621f2017-03-16 09:21:54 -04001826 // Cover up for any precision issues by outsetting the op bounds a pixel in each direction.
1827 drawIBounds.outset(1, 1);
Eric Karl72e551e2017-04-04 13:42:10 -07001828 if (!clippedRect.intersect(drawIBounds)) {
Brian Salomon467921e2017-03-06 16:17:12 -05001829#ifdef SK_DEBUG
Robert Phillipsbf25d432017-04-07 10:08:53 -04001830 GrCapsDebugf(this->caps(), "setupDstTexture: Missed an early reject bailing on draw.");
Brian Salomon467921e2017-03-06 16:17:12 -05001831#endif
Robert Phillipsbf25d432017-04-07 10:08:53 -04001832 return false;
Brian Salomon467921e2017-03-06 16:17:12 -05001833 }
1834
1835 // MSAA consideration: When there is support for reading MSAA samples in the shader we could
1836 // have per-sample dst values by making the copy multisampled.
1837 GrSurfaceDesc desc;
Eric Karl74480882017-04-03 14:49:05 -07001838 bool rectsMustMatch = false;
1839 bool disallowSubrect = false;
Brian Salomon2a4f9832018-03-03 22:43:43 -05001840 GrSurfaceOrigin origin;
1841 if (!this->caps()->initDescForDstCopy(rtProxy, &desc, &origin, &rectsMustMatch,
1842 &disallowSubrect)) {
Brian Salomon467921e2017-03-06 16:17:12 -05001843 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillipsbf25d432017-04-07 10:08:53 -04001844 desc.fConfig = rtProxy->config();
Greg Daniel1efe3222018-04-04 14:02:51 -04001845 origin = rtProxy->origin();
Brian Salomon467921e2017-03-06 16:17:12 -05001846 }
1847
Eric Karl74480882017-04-03 14:49:05 -07001848 if (!disallowSubrect) {
1849 copyRect = clippedRect;
1850 }
Brian Salomon467921e2017-03-06 16:17:12 -05001851
Robert Phillipsbf25d432017-04-07 10:08:53 -04001852 SkIPoint dstPoint, dstOffset;
1853 SkBackingFit fit;
Eric Karl74480882017-04-03 14:49:05 -07001854 if (rectsMustMatch) {
Robert Phillipsbf25d432017-04-07 10:08:53 -04001855 desc.fWidth = rtProxy->width();
1856 desc.fHeight = rtProxy->height();
Eric Karl74480882017-04-03 14:49:05 -07001857 dstPoint = {copyRect.fLeft, copyRect.fTop};
1858 dstOffset = {0, 0};
Robert Phillipsbf25d432017-04-07 10:08:53 -04001859 fit = SkBackingFit::kExact;
Eric Karl74480882017-04-03 14:49:05 -07001860 } else {
1861 desc.fWidth = copyRect.width();
1862 desc.fHeight = copyRect.height();
1863 dstPoint = {0, 0};
1864 dstOffset = {copyRect.fLeft, copyRect.fTop};
Robert Phillipsbf25d432017-04-07 10:08:53 -04001865 fit = SkBackingFit::kApprox;
Eric Karl74480882017-04-03 14:49:05 -07001866 }
Brian Salomon467921e2017-03-06 16:17:12 -05001867
Robert Phillipsbf25d432017-04-07 10:08:53 -04001868 sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeDeferredSurfaceContext(
Greg Danield7157b22018-11-14 15:28:10 +00001869 desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes,
Brian Salomonf802e752018-02-13 17:13:31 -05001870 sk_ref_sp(this->colorSpaceInfo().colorSpace()));
Robert Phillipsbf25d432017-04-07 10:08:53 -04001871 if (!sContext) {
1872 SkDebugf("setupDstTexture: surfaceContext creation failed.\n");
1873 return false;
1874 }
1875
1876 if (!sContext->copy(rtProxy, copyRect, dstPoint)) {
1877 SkDebugf("setupDstTexture: copy failed.\n");
1878 return false;
1879 }
1880
Robert Phillipsbb581ce2017-05-29 15:05:15 -04001881 dstProxy->setProxy(sContext->asTextureProxyRef());
1882 dstProxy->setOffset(dstOffset);
Robert Phillipsbf25d432017-04-07 10:08:53 -04001883 return true;
robertphillips2334fb62015-06-17 05:43:33 -07001884}