blob: f08f39a1be450456b220c7dacdd7b3ef19c5cf9c [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
robertphillipsea461502015-05-26 11:38:03 -07008#include "GrBatchTest.h"
jvanverth31ff7622015-08-07 10:09:28 -07009#include "GrColor.h"
Brian Osman11052242016-10-27 14:47:55 -040010#include "GrRenderTargetContext.h"
11#include "GrRenderTargetContextPriv.h"
robertphillips77a2e522015-10-17 07:43:27 -070012#include "GrDrawingManager.h"
csmartdalton02fa32c2016-08-19 13:29:27 -070013#include "GrFixedClip.h"
robertphillips714712b2016-08-04 06:20:45 -070014#include "GrGpuResourcePriv.h"
robertphillipsea461502015-05-26 11:38:03 -070015#include "GrOvalRenderer.h"
16#include "GrPathRenderer.h"
robertphillips5fa7f302016-07-21 09:21:04 -070017#include "GrPipelineBuilder.h"
robertphillips2334fb62015-06-17 05:43:33 -070018#include "GrRenderTarget.h"
19#include "GrRenderTargetPriv.h"
bsalomon473addf2015-10-02 07:49:05 -070020#include "GrResourceProvider.h"
robertphillips2d70dcb2015-10-06 07:38:23 -070021#include "SkSurfacePriv.h"
robertphillipsea461502015-05-26 11:38:03 -070022
joshualitt74417822015-08-07 11:42:16 -070023#include "batches/GrBatch.h"
robertphillips9199a9f2016-07-13 07:48:43 -070024#include "batches/GrClearBatch.h"
jvanverth14b88032015-08-07 12:18:54 -070025#include "batches/GrDrawAtlasBatch.h"
joshualitt2771b562015-08-07 12:46:26 -070026#include "batches/GrDrawVerticesBatch.h"
joshualitt7fc2a262015-08-10 10:30:14 -070027#include "batches/GrRectBatchFactory.h"
joshualitt33a5fce2015-11-18 13:28:51 -080028#include "batches/GrNinePatch.h" // TODO Factory
msarettcc319b92016-08-25 18:07:18 -070029#include "batches/GrRegionBatch.h"
Jim Van Verthc5903412016-11-17 15:27:09 -050030#include "batches/GrShadowRRectBatch.h"
joshualitt74417822015-08-07 11:42:16 -070031
robertphillips00095892016-02-29 13:50:40 -080032#include "effects/GrRRectEffect.h"
33
csmartdaltona7f29642016-07-07 08:49:11 -070034#include "instanced/InstancedRendering.h"
35
joshualitte8042922015-12-11 06:11:21 -080036#include "text/GrAtlasTextContext.h"
37#include "text/GrStencilAndCoverTextContext.h"
38
joshualittbc907352016-01-13 06:45:40 -080039#include "../private/GrAuditTrail.h"
40
robertphillips1da3ecd2016-08-31 14:54:15 -070041#include "SkGr.h"
msarett10e3d9b2016-08-18 15:46:03 -070042#include "SkLatticeIter.h"
reeda39667c2016-08-22 06:39:49 -070043#include "SkMatrixPriv.h"
msarett10e3d9b2016-08-18 15:46:03 -070044
robertphillips77a2e522015-10-17 07:43:27 -070045#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fDrawingManager->getContext())
joshualitt1de610a2016-01-06 08:26:09 -080046#define ASSERT_SINGLE_OWNER \
joshualittde8dc7e2016-01-08 10:09:13 -080047 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
robertphillips391395d2016-03-02 09:26:36 -080048#define ASSERT_SINGLE_OWNER_PRIV \
Brian Osman11052242016-10-27 14:47:55 -040049 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->fSingleOwner);)
robertphillips7761d612016-05-16 09:14:53 -070050#define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
Brian Osman11052242016-10-27 14:47:55 -040051#define RETURN_IF_ABANDONED_PRIV if (fRenderTargetContext->fDrawingManager->wasAbandoned()) { return; }
robertphillips7761d612016-05-16 09:14:53 -070052#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
Brian Osman11052242016-10-27 14:47:55 -040053#define RETURN_FALSE_IF_ABANDONED_PRIV if (fRenderTargetContext->fDrawingManager->wasAbandoned()) { return false; }
robertphillips7761d612016-05-16 09:14:53 -070054#define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
robertphillipsea461502015-05-26 11:38:03 -070055
csmartdaltona7f29642016-07-07 08:49:11 -070056using gr_instanced::InstancedRendering;
57
robertphillipsea461502015-05-26 11:38:03 -070058class AutoCheckFlush {
59public:
halcanary9d524f22016-03-29 09:03:52 -070060 AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
robertphillips77a2e522015-10-17 07:43:27 -070061 SkASSERT(fDrawingManager);
62 }
bsalomonb77a9072016-09-07 10:02:04 -070063 ~AutoCheckFlush() { fDrawingManager->flushIfNecessary(); }
robertphillipsea461502015-05-26 11:38:03 -070064
65private:
robertphillips77a2e522015-10-17 07:43:27 -070066 GrDrawingManager* fDrawingManager;
robertphillipsea461502015-05-26 11:38:03 -070067};
68
Brian Osman11052242016-10-27 14:47:55 -040069bool GrRenderTargetContext::wasAbandoned() const {
robertphillips7761d612016-05-16 09:14:53 -070070 return fDrawingManager->wasAbandoned();
71}
72
Robert Phillipsf2361d22016-10-25 14:20:06 -040073// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
Brian Osman11052242016-10-27 14:47:55 -040074// GrOpLists to be picked up and added to by renderTargetContexts lower in the call
Robert Phillipsf2361d22016-10-25 14:20:06 -040075// stack. When this occurs with a closed GrOpList, a new one will be allocated
Brian Osman11052242016-10-27 14:47:55 -040076// when the renderTargetContext attempts to use it (via getOpList).
77GrRenderTargetContext::GrRenderTargetContext(GrContext* context,
78 GrDrawingManager* drawingMgr,
Robert Phillipsc7635fa2016-10-28 13:25:24 -040079 sk_sp<GrRenderTargetProxy> rtp,
Brian Osman11052242016-10-27 14:47:55 -040080 sk_sp<SkColorSpace> colorSpace,
81 const SkSurfaceProps* surfaceProps,
82 GrAuditTrail* auditTrail,
83 GrSingleOwner* singleOwner)
Brian Osman45580d32016-11-23 09:37:01 -050084 : GrSurfaceContext(context, auditTrail, singleOwner)
85 , fDrawingManager(drawingMgr)
Robert Phillipsc7635fa2016-10-28 13:25:24 -040086 , fRenderTargetProxy(std::move(rtp))
87 , fOpList(SkSafeRef(fRenderTargetProxy->getLastRenderTargetOpList()))
Robert Phillipsc7635fa2016-10-28 13:25:24 -040088 , fInstancedPipelineInfo(fRenderTargetProxy.get())
brianosmandfe4f2e2016-07-21 13:28:36 -070089 , fColorSpace(std::move(colorSpace))
brianosman5a7ae7e2016-09-12 12:07:25 -070090 , fColorXformFromSRGB(nullptr)
joshualittde8dc7e2016-01-08 10:09:13 -080091 , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
joshualitt6d0872d2016-01-11 08:27:48 -080092{
brianosman5a7ae7e2016-09-12 12:07:25 -070093 if (fColorSpace) {
94 // sRGB sources are very common (SkColor, etc...), so we cache that gamut transformation
Brian Osman526972e2016-10-24 09:24:02 -040095 auto srgbColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
msarettc71a9b72016-09-16 11:01:27 -070096 fColorXformFromSRGB = GrColorSpaceXform::Make(srgbColorSpace.get(), fColorSpace.get());
brianosman5a7ae7e2016-09-12 12:07:25 -070097 }
robertphillips2e1e51f2015-10-15 08:01:48 -070098 SkDEBUGCODE(this->validate();)
robertphillipsea461502015-05-26 11:38:03 -070099}
100
robertphillips2e1e51f2015-10-15 08:01:48 -0700101#ifdef SK_DEBUG
Brian Osman11052242016-10-27 14:47:55 -0400102void GrRenderTargetContext::validate() const {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400103 SkASSERT(fRenderTargetProxy);
104 fRenderTargetProxy->validate(fContext);
robertphillipsa106c622015-10-16 09:07:06 -0700105
Robert Phillipsf2361d22016-10-25 14:20:06 -0400106 if (fOpList && !fOpList->isClosed()) {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400107 SkASSERT(fRenderTargetProxy->getLastOpList() == fOpList);
robertphillipsa106c622015-10-16 09:07:06 -0700108 }
robertphillips2e1e51f2015-10-15 08:01:48 -0700109}
110#endif
111
Brian Osman11052242016-10-27 14:47:55 -0400112GrRenderTargetContext::~GrRenderTargetContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800113 ASSERT_SINGLE_OWNER
Robert Phillipsf2361d22016-10-25 14:20:06 -0400114 SkSafeUnref(fOpList);
robertphillipsa106c622015-10-16 09:07:06 -0700115}
116
Robert Phillipseaa86252016-11-08 13:49:39 +0000117GrRenderTarget* GrRenderTargetContext::instantiate() {
118 return fRenderTargetProxy->instantiate(fContext->textureProvider());
119}
120
121GrTextureProxy* GrRenderTargetContext::asDeferredTexture() {
122 return fRenderTargetProxy->asTextureProxy();
123}
124
Brian Osman11052242016-10-27 14:47:55 -0400125GrRenderTargetOpList* GrRenderTargetContext::getOpList() {
joshualitt1de610a2016-01-06 08:26:09 -0800126 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -0700127 SkDEBUGCODE(this->validate();)
128
Robert Phillipsf2361d22016-10-25 14:20:06 -0400129 if (!fOpList || fOpList->isClosed()) {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400130 fOpList = fDrawingManager->newOpList(fRenderTargetProxy.get());
robertphillipsa106c622015-10-16 09:07:06 -0700131 }
132
Robert Phillipsf2361d22016-10-25 14:20:06 -0400133 return fOpList;
robertphillipsa106c622015-10-16 09:07:06 -0700134}
135
Brian Osman11052242016-10-27 14:47:55 -0400136bool GrRenderTargetContext::copySurface(GrSurface* src, const SkIRect& srcRect,
137 const SkIPoint& dstPoint) {
joshualitt1de610a2016-01-06 08:26:09 -0800138 ASSERT_SINGLE_OWNER
bsalomonb8fea972016-02-16 07:34:17 -0800139 RETURN_FALSE_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700140 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400141 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copySurface");
robertphillips2d70dcb2015-10-06 07:38:23 -0700142
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400143 // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget
144 sk_sp<GrRenderTarget> rt(
145 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -0500146 if (!rt) {
147 return false;
148 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400149
150 return this->getOpList()->copySurface(rt.get(), src, srcRect, dstPoint);
robertphillipsea461502015-05-26 11:38:03 -0700151}
152
Brian Osman11052242016-10-27 14:47:55 -0400153void GrRenderTargetContext::drawText(const GrClip& clip, const GrPaint& grPaint,
154 const SkPaint& skPaint,
155 const SkMatrix& viewMatrix,
156 const char text[], size_t byteLength,
157 SkScalar x, SkScalar y, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800158 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700159 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700160 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400161 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700162
brianosman86e76262016-08-11 12:17:31 -0700163 GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
164 atlasTextContext->drawText(fContext, this, clip, grPaint, skPaint, viewMatrix, fSurfaceProps,
165 text, byteLength, x, y, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700166}
robertphillipscaef3452015-11-11 13:18:11 -0800167
Brian Osman11052242016-10-27 14:47:55 -0400168void GrRenderTargetContext::drawPosText(const GrClip& clip, const GrPaint& grPaint,
169 const SkPaint& skPaint,
170 const SkMatrix& viewMatrix,
171 const char text[], size_t byteLength,
172 const SkScalar pos[], int scalarsPerPosition,
173 const SkPoint& offset, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800174 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700175 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700176 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400177 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPosText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700178
brianosman86e76262016-08-11 12:17:31 -0700179 GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
180 atlasTextContext->drawPosText(fContext, this, clip, grPaint, skPaint, viewMatrix,
181 fSurfaceProps, text, byteLength, pos, scalarsPerPosition,
182 offset, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700183
184}
robertphillipscaef3452015-11-11 13:18:11 -0800185
Brian Osman11052242016-10-27 14:47:55 -0400186void GrRenderTargetContext::drawTextBlob(const GrClip& clip, const SkPaint& skPaint,
187 const SkMatrix& viewMatrix, const SkTextBlob* blob,
188 SkScalar x, SkScalar y,
189 SkDrawFilter* filter, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800190 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700191 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700192 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400193 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawTextBlob");
robertphillips2d70dcb2015-10-06 07:38:23 -0700194
brianosman86e76262016-08-11 12:17:31 -0700195 GrAtlasTextContext* atlasTextContext = fDrawingManager->getAtlasTextContext();
196 atlasTextContext->drawTextBlob(fContext, this, clip, skPaint, viewMatrix, fSurfaceProps, blob,
197 x, y, filter, clipBounds);
robertphillipsea461502015-05-26 11:38:03 -0700198}
199
Brian Osman11052242016-10-27 14:47:55 -0400200void GrRenderTargetContext::discard() {
joshualitt1de610a2016-01-06 08:26:09 -0800201 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700202 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700203 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400204 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::discard");
robertphillips2e1e51f2015-10-15 08:01:48 -0700205
robertphillips77a2e522015-10-17 07:43:27 -0700206 AutoCheckFlush acf(fDrawingManager);
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400207
208 // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget
209 sk_sp<GrRenderTarget> rt(
210 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -0500211 if (!rt) {
212 return;
213 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400214
215 this->getOpList()->discard(rt.get());
robertphillipsea461502015-05-26 11:38:03 -0700216}
217
Brian Osman11052242016-10-27 14:47:55 -0400218void GrRenderTargetContext::clear(const SkIRect* rect,
219 const GrColor color,
220 bool canIgnoreRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800221 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700222 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700223 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400224 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::clear");
robertphillipsea461502015-05-26 11:38:03 -0700225
robertphillips77a2e522015-10-17 07:43:27 -0700226 AutoCheckFlush acf(fDrawingManager);
csmartdalton29df7602016-08-31 11:55:52 -0700227 this->internalClear(rect ? GrFixedClip(*rect) : GrFixedClip::Disabled(), color, canIgnoreRect);
228}
robertphillips9199a9f2016-07-13 07:48:43 -0700229
Brian Osman11052242016-10-27 14:47:55 -0400230void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
231 const GrColor color,
232 bool canIgnoreClip) {
csmartdalton29df7602016-08-31 11:55:52 -0700233 ASSERT_SINGLE_OWNER_PRIV
234 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400235 SkDEBUGCODE(fRenderTargetContext->validate();)
236 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
237 "GrRenderTargetContextPriv::clear");
csmartdalton29df7602016-08-31 11:55:52 -0700238
Brian Osman11052242016-10-27 14:47:55 -0400239 AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
240 fRenderTargetContext->internalClear(clip, color, canIgnoreClip);
csmartdalton29df7602016-08-31 11:55:52 -0700241}
242
Brian Osman11052242016-10-27 14:47:55 -0400243void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
244 const GrColor color,
245 bool canIgnoreClip) {
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700246 bool isFull = false;
247 if (!clip.hasWindowRectangles()) {
248 isFull = !clip.scissorEnabled() ||
249 (canIgnoreClip && fContext->caps()->fullClearIsFree()) ||
250 clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
251 }
robertphillips9199a9f2016-07-13 07:48:43 -0700252
253 if (fContext->caps()->useDrawInsteadOfClear()) {
254 // This works around a driver bug with clear by drawing a rect instead.
255 // The driver will ignore a clear if it is the only thing rendered to a
256 // target before the target is read.
csmartdalton29df7602016-08-31 11:55:52 -0700257 SkRect clearRect = SkRect::MakeIWH(this->width(), this->height());
258 if (isFull) {
robertphillips9199a9f2016-07-13 07:48:43 -0700259 this->discard();
csmartdalton29df7602016-08-31 11:55:52 -0700260 } else if (!clearRect.intersect(SkRect::Make(clip.scissorRect()))) {
261 return;
robertphillips9199a9f2016-07-13 07:48:43 -0700262 }
263
264 GrPaint paint;
265 paint.setColor4f(GrColor4f::FromGrColor(color));
Mike Reed7d954ad2016-10-28 15:42:34 -0400266 paint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc));
robertphillips9199a9f2016-07-13 07:48:43 -0700267
csmartdalton29df7602016-08-31 11:55:52 -0700268 this->drawRect(clip, paint, SkMatrix::I(), clearRect);
bsalomon9f129de2016-08-10 16:31:05 -0700269 } else if (isFull) {
Robert Phillipse60ad622016-11-17 10:22:48 -0500270 if (this->accessRenderTarget()) {
271 this->getOpList()->fullClear(this->accessRenderTarget(), color);
272 }
robertphillips9199a9f2016-07-13 07:48:43 -0700273 } else {
Robert Phillipse60ad622016-11-17 10:22:48 -0500274 if (!this->accessRenderTarget()) {
275 return;
276 }
csmartdalton29df7602016-08-31 11:55:52 -0700277 sk_sp<GrBatch> batch(GrClearBatch::Make(clip, color, this->accessRenderTarget()));
278 if (!batch) {
279 return;
280 }
Robert Phillipsf2361d22016-10-25 14:20:06 -0400281 this->getOpList()->addBatch(std::move(batch));
robertphillips9199a9f2016-07-13 07:48:43 -0700282 }
robertphillipsea461502015-05-26 11:38:03 -0700283}
284
Brian Osman11052242016-10-27 14:47:55 -0400285void GrRenderTargetContext::drawPaint(const GrClip& clip,
286 const GrPaint& origPaint,
287 const SkMatrix& viewMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800288 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700289 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700290 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400291 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPaint");
robertphillips2e1e51f2015-10-15 08:01:48 -0700292
robertphillipsea461502015-05-26 11:38:03 -0700293 // set rect to be big enough to fill the space, but not super-huge, so we
294 // don't overflow fixed-point implementations
robertphillips13a7eee2016-08-31 15:06:24 -0700295
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400296 SkRect r = fRenderTargetProxy->getBoundsRect();
robertphillipsea461502015-05-26 11:38:03 -0700297 SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
298
bsalomoncb31e512016-08-26 10:48:19 -0700299 SkRRect rrect;
300 bool aaRRect;
301 // Check if we can replace a clipRRect()/drawPaint() with a drawRRect(). We only do the
302 // transformation for non-rect rrects. Rects caused a performance regression on an Android
303 // test that needs investigation. We also skip cases where there are fragment processors
304 // because they may depend on having correct local coords and this path draws in device space
305 // without a local matrix.
306 if (!paint->numTotalFragmentProcessors() &&
307 clip.isRRect(r, &rrect, &aaRRect) && !rrect.isRect()) {
308 paint.writable()->setAntiAlias(aaRRect);
309 this->drawRRect(GrNoClip(), *paint, SkMatrix::I(), rrect, GrStyle::SimpleFill());
310 return;
311 }
312
robertphillipsea461502015-05-26 11:38:03 -0700313 // by definition this fills the entire clip, no need for AA
314 if (paint->isAntiAlias()) {
315 paint.writable()->setAntiAlias(false);
316 }
317
318 bool isPerspective = viewMatrix.hasPerspective();
319
320 // We attempt to map r by the inverse matrix and draw that. mapRect will
321 // map the four corners and bound them with a new rect. This will not
322 // produce a correct result for some perspective matrices.
323 if (!isPerspective) {
reeda39667c2016-08-22 06:39:49 -0700324 if (!SkMatrixPriv::InverseMapRect(viewMatrix, &r, r)) {
robertphillipsea461502015-05-26 11:38:03 -0700325 SkDebugf("Could not invert matrix\n");
326 return;
327 }
robertphillips2e1e51f2015-10-15 08:01:48 -0700328 this->drawRect(clip, *paint, viewMatrix, r);
robertphillipsea461502015-05-26 11:38:03 -0700329 } else {
330 SkMatrix localMatrix;
331 if (!viewMatrix.invert(&localMatrix)) {
332 SkDebugf("Could not invert matrix\n");
333 return;
334 }
335
robertphillips77a2e522015-10-17 07:43:27 -0700336 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700337
csmartdalton34ee0c92016-07-27 13:22:27 -0700338 this->drawNonAAFilledRect(clip, *paint, SkMatrix::I(), r, nullptr, &localMatrix, nullptr,
339 false /* useHWAA */);
robertphillipsea461502015-05-26 11:38:03 -0700340 }
341}
342
robertphillipsea461502015-05-26 11:38:03 -0700343static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
344 return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
345 point.fY >= rect.fTop && point.fY <= rect.fBottom;
346}
347
bsalomonc55271f2015-11-09 11:55:57 -0800348static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
349 return viewMatrix.preservesRightAngles();
350}
351
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400352static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTargetProxy* rtp,
csmartdaltonecbc12b2016-06-08 10:08:43 -0700353 bool* useHWAA = nullptr) {
354 if (!paint.isAntiAlias()) {
355 if (useHWAA) {
356 *useHWAA = false;
357 }
358 return false;
359 } else {
360 if (useHWAA) {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400361 *useHWAA = rtp->isUnifiedMultisampled();
csmartdaltonecbc12b2016-06-08 10:08:43 -0700362 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400363 return !rtp->isUnifiedMultisampled();
csmartdaltonecbc12b2016-06-08 10:08:43 -0700364 }
bsalomonc55271f2015-11-09 11:55:57 -0800365}
366
csmartdalton97f6cd52016-07-13 13:37:08 -0700367// Attempts to crop a rect and optional local rect to the clip boundaries.
368// Returns false if the draw can be skipped entirely.
robertphillips13a7eee2016-08-31 15:06:24 -0700369static bool crop_filled_rect(int width, int height, const GrClip& clip,
csmartdalton97f6cd52016-07-13 13:37:08 -0700370 const SkMatrix& viewMatrix, SkRect* rect,
371 SkRect* localRect = nullptr) {
372 if (!viewMatrix.rectStaysRect()) {
373 return true;
374 }
375
csmartdalton97f6cd52016-07-13 13:37:08 -0700376 SkIRect clipDevBounds;
377 SkRect clipBounds;
csmartdalton97f6cd52016-07-13 13:37:08 -0700378
robertphillips13a7eee2016-08-31 15:06:24 -0700379 clip.getConservativeBounds(width, height, &clipDevBounds);
reeda39667c2016-08-22 06:39:49 -0700380 if (!SkMatrixPriv::InverseMapRect(viewMatrix, &clipBounds, SkRect::Make(clipDevBounds))) {
381 return false;
382 }
csmartdalton97f6cd52016-07-13 13:37:08 -0700383
384 if (localRect) {
385 if (!rect->intersects(clipBounds)) {
386 return false;
387 }
388 const SkScalar dx = localRect->width() / rect->width();
389 const SkScalar dy = localRect->height() / rect->height();
390 if (clipBounds.fLeft > rect->fLeft) {
391 localRect->fLeft += (clipBounds.fLeft - rect->fLeft) * dx;
392 rect->fLeft = clipBounds.fLeft;
393 }
394 if (clipBounds.fTop > rect->fTop) {
395 localRect->fTop += (clipBounds.fTop - rect->fTop) * dy;
396 rect->fTop = clipBounds.fTop;
397 }
398 if (clipBounds.fRight < rect->fRight) {
399 localRect->fRight -= (rect->fRight - clipBounds.fRight) * dx;
400 rect->fRight = clipBounds.fRight;
401 }
402 if (clipBounds.fBottom < rect->fBottom) {
403 localRect->fBottom -= (rect->fBottom - clipBounds.fBottom) * dy;
404 rect->fBottom = clipBounds.fBottom;
405 }
406 return true;
407 }
408
409 return rect->intersect(clipBounds);
410}
411
Brian Osman11052242016-10-27 14:47:55 -0400412bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
413 const GrPaint& paint,
414 const SkMatrix& viewMatrix,
415 const SkRect& rect,
416 const GrUserStencilSettings* ss) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700417 SkRect croppedRect = rect;
robertphillips13a7eee2016-08-31 15:06:24 -0700418 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &croppedRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700419 return true;
420 }
robertphillips44302392016-07-08 14:43:03 -0700421
Hal Canary144caf52016-11-07 17:57:18 -0500422 sk_sp<GrDrawBatch> batch;
robertphillips44302392016-07-08 14:43:03 -0700423 bool useHWAA;
424
csmartdaltone0d36292016-07-29 08:14:20 -0700425 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400426 InstancedRendering* ir = this->getOpList()->instancedRendering();
csmartdalton97f6cd52016-07-13 13:37:08 -0700427 batch.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
robertphillips44302392016-07-08 14:43:03 -0700428 paint.isAntiAlias(), fInstancedPipelineInfo,
429 &useHWAA));
430 if (batch) {
431 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
432 if (ss) {
433 pipelineBuilder.setUserStencil(ss);
434 }
Hal Canary144caf52016-11-07 17:57:18 -0500435 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
robertphillips44302392016-07-08 14:43:03 -0700436 return true;
csmartdaltona7f29642016-07-07 08:49:11 -0700437 }
438 }
robertphillips391395d2016-03-02 09:26:36 -0800439
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400440 if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
robertphillips391395d2016-03-02 09:26:36 -0800441 // The fill path can handle rotation but not skew.
442 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
443 SkRect devBoundRect;
csmartdalton97f6cd52016-07-13 13:37:08 -0700444 viewMatrix.mapRect(&devBoundRect, croppedRect);
robertphillips44302392016-07-08 14:43:03 -0700445
dvonbeck09e12a62016-08-12 12:50:36 -0700446 batch.reset(GrRectBatchFactory::CreateAAFill(paint, viewMatrix, rect, croppedRect,
447 devBoundRect));
robertphillips44302392016-07-08 14:43:03 -0700448 if (batch) {
449 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
450 if (ss) {
451 pipelineBuilder.setUserStencil(ss);
452 }
Hal Canary144caf52016-11-07 17:57:18 -0500453 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
robertphillips44302392016-07-08 14:43:03 -0700454 return true;
455 }
robertphillips391395d2016-03-02 09:26:36 -0800456 }
457 } else {
csmartdalton34ee0c92016-07-27 13:22:27 -0700458 this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr, nullptr, ss,
459 useHWAA);
robertphillips44302392016-07-08 14:43:03 -0700460 return true;
robertphillips391395d2016-03-02 09:26:36 -0800461 }
462
robertphillips44302392016-07-08 14:43:03 -0700463 return false;
robertphillips391395d2016-03-02 09:26:36 -0800464}
465
Brian Osman11052242016-10-27 14:47:55 -0400466void GrRenderTargetContext::drawRect(const GrClip& clip,
467 const GrPaint& paint,
468 const SkMatrix& viewMatrix,
469 const SkRect& rect,
470 const GrStyle* style) {
bsalomon6663acf2016-05-10 09:14:17 -0700471 if (!style) {
472 style = &GrStyle::SimpleFill();
473 }
joshualitt1de610a2016-01-06 08:26:09 -0800474 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700475 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700476 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400477 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawRect");
robertphillips2e1e51f2015-10-15 08:01:48 -0700478
bsalomon6663acf2016-05-10 09:14:17 -0700479 // Path effects should've been devolved to a path in SkGpuDevice
480 SkASSERT(!style->pathEffect());
robertphillipsea461502015-05-26 11:38:03 -0700481
robertphillips77a2e522015-10-17 07:43:27 -0700482 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700483
bsalomon6663acf2016-05-10 09:14:17 -0700484 const SkStrokeRec& stroke = style->strokeRec();
robertphillips3ab14ca2016-07-10 11:49:39 -0700485 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
486
487 if (!fContext->caps()->useDrawInsteadOfClear()) {
488 // Check if this is a full RT draw and can be replaced with a clear. We don't bother
489 // checking cases where the RT is fully inside a stroke.
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400490 SkRect rtRect = fRenderTargetProxy->getBoundsRect();
robertphillips3ab14ca2016-07-10 11:49:39 -0700491 // Does the clip contain the entire RT?
492 if (clip.quickContains(rtRect)) {
493 SkMatrix invM;
494 if (!viewMatrix.invert(&invM)) {
robertphillipsea461502015-05-26 11:38:03 -0700495 return;
496 }
robertphillips3ab14ca2016-07-10 11:49:39 -0700497 // Does the rect bound the RT?
498 SkPoint srcSpaceRTQuad[4];
499 invM.mapRectToQuad(srcSpaceRTQuad, rtRect);
500 if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) &&
501 rect_contains_inclusive(rect, srcSpaceRTQuad[1]) &&
502 rect_contains_inclusive(rect, srcSpaceRTQuad[2]) &&
503 rect_contains_inclusive(rect, srcSpaceRTQuad[3])) {
504 // Will it blend?
505 GrColor clearColor;
506 if (paint.isConstantBlendedColor(&clearColor)) {
robertphillips9199a9f2016-07-13 07:48:43 -0700507 this->clear(nullptr, clearColor, true);
robertphillips3ab14ca2016-07-10 11:49:39 -0700508 return;
509 }
510 }
robertphillipsea461502015-05-26 11:38:03 -0700511 }
512 }
robertphillips44302392016-07-08 14:43:03 -0700513
514 if (this->drawFilledRect(clip, paint, viewMatrix, rect, nullptr)) {
515 return;
516 }
bsalomona7d85ba2016-07-06 11:54:59 -0700517 } else if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
518 stroke.getStyle() == SkStrokeRec::kHairline_Style) {
519 if ((!rect.width() || !rect.height()) &&
520 SkStrokeRec::kHairline_Style != stroke.getStyle()) {
521 SkScalar r = stroke.getWidth() / 2;
522 // TODO: Move these stroke->fill fallbacks to GrShape?
523 switch (stroke.getJoin()) {
524 case SkPaint::kMiter_Join:
525 this->drawRect(clip, paint, viewMatrix,
526 {rect.fLeft - r, rect.fTop - r,
527 rect.fRight + r, rect.fBottom + r},
528 &GrStyle::SimpleFill());
529 return;
530 case SkPaint::kRound_Join:
531 // Raster draws nothing when both dimensions are empty.
532 if (rect.width() || rect.height()){
533 SkRRect rrect = SkRRect::MakeRectXY(rect.makeOutset(r, r), r, r);
534 this->drawRRect(clip, paint, viewMatrix, rrect, GrStyle::SimpleFill());
535 return;
536 }
537 case SkPaint::kBevel_Join:
538 if (!rect.width()) {
539 this->drawRect(clip, paint, viewMatrix,
540 {rect.fLeft - r, rect.fTop, rect.fRight + r, rect.fBottom},
541 &GrStyle::SimpleFill());
542 } else {
543 this->drawRect(clip, paint, viewMatrix,
544 {rect.fLeft, rect.fTop - r, rect.fRight, rect.fBottom + r},
545 &GrStyle::SimpleFill());
546 }
547 return;
548 }
549 }
robertphillips44302392016-07-08 14:43:03 -0700550
551 bool useHWAA;
552 bool snapToPixelCenters = false;
Hal Canary144caf52016-11-07 17:57:18 -0500553 sk_sp<GrDrawBatch> batch;
robertphillips44302392016-07-08 14:43:03 -0700554
robertphillips391395d2016-03-02 09:26:36 -0800555 GrColor color = paint.getColor();
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400556 if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
cdaltonbb539482016-01-04 09:48:25 -0800557 // The stroke path needs the rect to remain axis aligned (no rotation or skew).
558 if (viewMatrix.rectStaysRect()) {
bsalomona7d85ba2016-07-06 11:54:59 -0700559 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, stroke));
cdaltonbb539482016-01-04 09:48:25 -0800560 }
robertphillipsea461502015-05-26 11:38:03 -0700561 } else {
robertphillips391395d2016-03-02 09:26:36 -0800562 // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
halcanary9d524f22016-03-29 09:03:52 -0700563 // hairline rects. We jam all the vertices to pixel centers to avoid this, but not
robertphillips391395d2016-03-02 09:26:36 -0800564 // when MSAA is enabled because it can cause ugly artifacts.
bsalomona7d85ba2016-07-06 11:54:59 -0700565 snapToPixelCenters = stroke.getStyle() == SkStrokeRec::kHairline_Style &&
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400566 !fRenderTargetProxy->isUnifiedMultisampled();
bsalomona7d85ba2016-07-06 11:54:59 -0700567 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect,
568 stroke, snapToPixelCenters));
robertphillips391395d2016-03-02 09:26:36 -0800569 }
robertphillips4bc31812016-03-01 12:22:49 -0800570
robertphillips44302392016-07-08 14:43:03 -0700571 if (batch) {
572 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
robertphillips4bc31812016-03-01 12:22:49 -0800573
robertphillips44302392016-07-08 14:43:03 -0700574 if (snapToPixelCenters) {
575 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
576 snapToPixelCenters);
577 }
578
Hal Canary144caf52016-11-07 17:57:18 -0500579 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
robertphillips44302392016-07-08 14:43:03 -0700580 return;
robertphillips4bc31812016-03-01 12:22:49 -0800581 }
robertphillips4bc31812016-03-01 12:22:49 -0800582 }
halcanary9d524f22016-03-29 09:03:52 -0700583
robertphillips4bc31812016-03-01 12:22:49 -0800584 SkPath path;
585 path.setIsVolatile(true);
586 path.addRect(rect);
bsalomon6663acf2016-05-10 09:14:17 -0700587 this->internalDrawPath(clip, paint, viewMatrix, path, *style);
robertphillipsea461502015-05-26 11:38:03 -0700588}
589
Robert Phillipsec2249f2016-11-09 08:54:35 -0500590int GrRenderTargetContextPriv::maxWindowRectangles() const {
591 return fRenderTargetContext->fRenderTargetProxy->maxWindowRectangles(
592 *fRenderTargetContext->fContext->caps());
593}
594
Brian Osman11052242016-10-27 14:47:55 -0400595void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
robertphillips976f5f02016-06-03 10:59:20 -0700596 ASSERT_SINGLE_OWNER_PRIV
597 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400598 SkDEBUGCODE(fRenderTargetContext->validate();)
599 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
600 "GrRenderTargetContextPriv::clearStencilClip");
robertphillips976f5f02016-06-03 10:59:20 -0700601
Brian Osman11052242016-10-27 14:47:55 -0400602 AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
Robert Phillipse60ad622016-11-17 10:22:48 -0500603 if (!fRenderTargetContext->accessRenderTarget()) {
604 return;
605 }
Brian Osman11052242016-10-27 14:47:55 -0400606 fRenderTargetContext->getOpList()->clearStencilClip(clip, insideStencilMask,
607 fRenderTargetContext->accessRenderTarget());
robertphillips976f5f02016-06-03 10:59:20 -0700608}
609
Brian Osman11052242016-10-27 14:47:55 -0400610void GrRenderTargetContextPriv::stencilPath(const GrClip& clip,
611 bool useHWAA,
612 const SkMatrix& viewMatrix,
613 const GrPath* path) {
614 fRenderTargetContext->getOpList()->stencilPath(fRenderTargetContext, clip, useHWAA, viewMatrix,
615 path);
robertphillips976f5f02016-06-03 10:59:20 -0700616}
617
Brian Osman11052242016-10-27 14:47:55 -0400618void GrRenderTargetContextPriv::stencilRect(const GrClip& clip,
619 const GrUserStencilSettings* ss,
620 bool useHWAA,
621 const SkMatrix& viewMatrix,
622 const SkRect& rect) {
robertphillips976f5f02016-06-03 10:59:20 -0700623 ASSERT_SINGLE_OWNER_PRIV
624 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400625 SkDEBUGCODE(fRenderTargetContext->validate();)
626 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
627 "GrRenderTargetContext::stencilRect");
robertphillips976f5f02016-06-03 10:59:20 -0700628
Brian Osman11052242016-10-27 14:47:55 -0400629 AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
robertphillips976f5f02016-06-03 10:59:20 -0700630
631 GrPaint paint;
csmartdalton656dbe42016-06-10 12:32:57 -0700632 paint.setAntiAlias(useHWAA);
bungeman06ca8ec2016-06-09 08:01:03 -0700633 paint.setXPFactory(GrDisableColorXPFactory::Make());
robertphillips976f5f02016-06-03 10:59:20 -0700634
Brian Osman11052242016-10-27 14:47:55 -0400635 fRenderTargetContext->drawNonAAFilledRect(clip, paint, viewMatrix, rect, nullptr, nullptr, ss,
636 useHWAA);
robertphillips976f5f02016-06-03 10:59:20 -0700637}
638
Brian Osman11052242016-10-27 14:47:55 -0400639bool GrRenderTargetContextPriv::drawAndStencilRect(const GrClip& clip,
640 const GrUserStencilSettings* ss,
641 SkRegion::Op op,
642 bool invert,
643 bool doAA,
644 const SkMatrix& viewMatrix,
645 const SkRect& rect) {
robertphillips391395d2016-03-02 09:26:36 -0800646 ASSERT_SINGLE_OWNER_PRIV
647 RETURN_FALSE_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400648 SkDEBUGCODE(fRenderTargetContext->validate();)
649 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
650 "GrRenderTargetContext::drawAndStencilRect");
robertphillips391395d2016-03-02 09:26:36 -0800651
Brian Osman11052242016-10-27 14:47:55 -0400652 AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
robertphillips391395d2016-03-02 09:26:36 -0800653
654 GrPaint paint;
655 paint.setAntiAlias(doAA);
656 paint.setCoverageSetOpXPFactory(op, invert);
657
Brian Osman11052242016-10-27 14:47:55 -0400658 if (fRenderTargetContext->drawFilledRect(clip, paint, viewMatrix, rect, ss)) {
robertphillips391395d2016-03-02 09:26:36 -0800659 return true;
660 }
661
662 SkPath path;
663 path.setIsVolatile(true);
664 path.addRect(rect);
cdalton862cff32016-05-12 15:09:48 -0700665 return this->drawAndStencilPath(clip, ss, op, invert, doAA, viewMatrix, path);
robertphillips391395d2016-03-02 09:26:36 -0800666}
667
Brian Osman11052242016-10-27 14:47:55 -0400668void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
669 const GrPaint& paint,
670 const SkMatrix& viewMatrix,
671 const SkRect& rectToDraw,
672 const SkRect& localRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800673 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700674 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700675 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400676 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::fillRectToRect");
robertphillipsea461502015-05-26 11:38:03 -0700677
csmartdalton97f6cd52016-07-13 13:37:08 -0700678 SkRect croppedRect = rectToDraw;
679 SkRect croppedLocalRect = localRect;
robertphillips13a7eee2016-08-31 15:06:24 -0700680 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix,
681 &croppedRect, &croppedLocalRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700682 return;
683 }
684
robertphillips77a2e522015-10-17 07:43:27 -0700685 AutoCheckFlush acf(fDrawingManager);
csmartdaltona7f29642016-07-07 08:49:11 -0700686 bool useHWAA;
687
csmartdaltone0d36292016-07-29 08:14:20 -0700688 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400689 InstancedRendering* ir = this->getOpList()->instancedRendering();
Hal Canary144caf52016-11-07 17:57:18 -0500690 sk_sp<GrDrawBatch> batch(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
691 croppedLocalRect, paint.isAntiAlias(),
692 fInstancedPipelineInfo, &useHWAA));
csmartdaltona7f29642016-07-07 08:49:11 -0700693 if (batch) {
bsalomonbb243832016-07-22 07:10:19 -0700694 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -0500695 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
csmartdaltona7f29642016-07-07 08:49:11 -0700696 return;
697 }
698 }
699
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400700 if (!should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700701 this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, &croppedLocalRect,
csmartdalton34ee0c92016-07-27 13:22:27 -0700702 nullptr, nullptr, useHWAA);
csmartdaltonfc49d562016-07-26 17:05:47 -0700703 return;
joshualitt04194f32016-01-13 10:08:27 -0800704 }
bsalomonbb243832016-07-22 07:10:19 -0700705
csmartdaltonfc49d562016-07-26 17:05:47 -0700706 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
Hal Canary144caf52016-11-07 17:57:18 -0500707 sk_sp<GrDrawBatch> batch(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(),
708 viewMatrix,
709 croppedRect,
710 croppedLocalRect));
csmartdaltonfc49d562016-07-26 17:05:47 -0700711 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -0500712 this->drawBatch(pipelineBuilder, clip, batch.get());
csmartdaltonfc49d562016-07-26 17:05:47 -0700713 return;
714 }
715
716 SkMatrix viewAndUnLocalMatrix;
717 if (!viewAndUnLocalMatrix.setRectToRect(localRect, rectToDraw, SkMatrix::kFill_ScaleToFit)) {
718 SkDebugf("fillRectToRect called with empty local matrix.\n");
719 return;
720 }
721 viewAndUnLocalMatrix.postConcat(viewMatrix);
722
723 SkPath path;
724 path.setIsVolatile(true);
725 path.addRect(localRect);
726 this->internalDrawPath(clip, paint, viewAndUnLocalMatrix, path, GrStyle());
joshualittb6b513b2015-08-21 10:25:18 -0700727}
728
Brian Osman11052242016-10-27 14:47:55 -0400729void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
730 const GrPaint& paint,
731 const SkMatrix& viewMatrix,
732 const SkRect& rectToDraw,
733 const SkMatrix& localMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800734 ASSERT_SINGLE_OWNER
joshualittb6b513b2015-08-21 10:25:18 -0700735 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700736 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400737 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::fillRectWithLocalMatrix");
joshualittb6b513b2015-08-21 10:25:18 -0700738
csmartdalton97f6cd52016-07-13 13:37:08 -0700739 SkRect croppedRect = rectToDraw;
robertphillips13a7eee2016-08-31 15:06:24 -0700740 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &croppedRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700741 return;
742 }
743
robertphillips77a2e522015-10-17 07:43:27 -0700744 AutoCheckFlush acf(fDrawingManager);
csmartdaltona7f29642016-07-07 08:49:11 -0700745 bool useHWAA;
746
csmartdaltone0d36292016-07-29 08:14:20 -0700747 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400748 InstancedRendering* ir = this->getOpList()->instancedRendering();
Hal Canary144caf52016-11-07 17:57:18 -0500749 sk_sp<GrDrawBatch> batch(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
csmartdaltonfc49d562016-07-26 17:05:47 -0700750 localMatrix, paint.isAntiAlias(),
751 fInstancedPipelineInfo, &useHWAA));
csmartdaltona7f29642016-07-07 08:49:11 -0700752 if (batch) {
753 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -0500754 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
csmartdaltona7f29642016-07-07 08:49:11 -0700755 return;
756 }
757 }
758
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400759 if (!should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700760 this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr,
csmartdalton34ee0c92016-07-27 13:22:27 -0700761 &localMatrix, nullptr, useHWAA);
csmartdaltonfc49d562016-07-26 17:05:47 -0700762 return;
bsalomonc55271f2015-11-09 11:55:57 -0800763 }
robertphillips4bc31812016-03-01 12:22:49 -0800764
csmartdaltonfc49d562016-07-26 17:05:47 -0700765 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
Hal Canary144caf52016-11-07 17:57:18 -0500766 sk_sp<GrDrawBatch> batch(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix,
767 localMatrix, croppedRect));
csmartdaltonfc49d562016-07-26 17:05:47 -0700768 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -0500769 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
csmartdaltonfc49d562016-07-26 17:05:47 -0700770 return;
771 }
772
773 SkMatrix viewAndUnLocalMatrix;
774 if (!localMatrix.invert(&viewAndUnLocalMatrix)) {
775 SkDebugf("fillRectWithLocalMatrix called with degenerate local matrix.\n");
776 return;
777 }
778 viewAndUnLocalMatrix.postConcat(viewMatrix);
779
780 SkPath path;
781 path.setIsVolatile(true);
782 path.addRect(rectToDraw);
783 path.transform(localMatrix);
784 this->internalDrawPath(clip, paint, viewAndUnLocalMatrix, path, GrStyle());
robertphillipsea461502015-05-26 11:38:03 -0700785}
786
Brian Osman11052242016-10-27 14:47:55 -0400787void GrRenderTargetContext::drawVertices(const GrClip& clip,
788 const GrPaint& paint,
789 const SkMatrix& viewMatrix,
790 GrPrimitiveType primitiveType,
791 int vertexCount,
792 const SkPoint positions[],
793 const SkPoint texCoords[],
794 const GrColor colors[],
795 const uint16_t indices[],
796 int indexCount) {
joshualitt1de610a2016-01-06 08:26:09 -0800797 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700798 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700799 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400800 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawVertices");
robertphillipsea461502015-05-26 11:38:03 -0700801
robertphillips77a2e522015-10-17 07:43:27 -0700802 AutoCheckFlush acf(fDrawingManager);
robertphillips2e1e51f2015-10-15 08:01:48 -0700803
robertphillipsea461502015-05-26 11:38:03 -0700804 // TODO clients should give us bounds
805 SkRect bounds;
806 if (!bounds.setBoundsCheck(positions, vertexCount)) {
807 SkDebugf("drawVertices call empty bounds\n");
808 return;
809 }
810
811 viewMatrix.mapRect(&bounds);
812
Hal Canary144caf52016-11-07 17:57:18 -0500813 sk_sp<GrDrawBatch> batch(new GrDrawVerticesBatch(paint.getColor(),
814 primitiveType, viewMatrix, positions,
815 vertexCount, indices, indexCount,
816 colors, texCoords, bounds));
robertphillipsea461502015-05-26 11:38:03 -0700817
csmartdaltonecbc12b2016-06-08 10:08:43 -0700818 GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
Hal Canary144caf52016-11-07 17:57:18 -0500819 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
robertphillipsea461502015-05-26 11:38:03 -0700820}
821
822///////////////////////////////////////////////////////////////////////////////
823
Brian Osman11052242016-10-27 14:47:55 -0400824void GrRenderTargetContext::drawAtlas(const GrClip& clip,
825 const GrPaint& paint,
826 const SkMatrix& viewMatrix,
827 int spriteCount,
828 const SkRSXform xform[],
829 const SkRect texRect[],
830 const SkColor colors[]) {
joshualitt1de610a2016-01-06 08:26:09 -0800831 ASSERT_SINGLE_OWNER
jvanverth31ff7622015-08-07 10:09:28 -0700832 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700833 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400834 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawAtlas");
robertphillips2e1e51f2015-10-15 08:01:48 -0700835
robertphillips77a2e522015-10-17 07:43:27 -0700836 AutoCheckFlush acf(fDrawingManager);
halcanary9d524f22016-03-29 09:03:52 -0700837
Hal Canary144caf52016-11-07 17:57:18 -0500838 sk_sp<GrDrawBatch> batch(new GrDrawAtlasBatch(paint.getColor(), viewMatrix, spriteCount,
bsalomon0432dd62016-06-30 07:19:27 -0700839 xform, texRect, colors));
halcanary9d524f22016-03-29 09:03:52 -0700840
csmartdaltonecbc12b2016-06-08 10:08:43 -0700841 GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
Hal Canary144caf52016-11-07 17:57:18 -0500842 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
jvanverth31ff7622015-08-07 10:09:28 -0700843}
844
845///////////////////////////////////////////////////////////////////////////////
846
Brian Osman11052242016-10-27 14:47:55 -0400847void GrRenderTargetContext::drawRRect(const GrClip& origClip,
848 const GrPaint& paint,
849 const SkMatrix& viewMatrix,
850 const SkRRect& rrect,
851 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800852 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700853 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700854 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400855 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawRRect");
robertphillipsea461502015-05-26 11:38:03 -0700856 if (rrect.isEmpty()) {
857 return;
858 }
859
bsalomon7f0d9f32016-08-15 14:49:10 -0700860 GrNoClip noclip;
861 const GrClip* clip = &origClip;
862#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
863 // The Android framework frequently clips rrects to themselves where the clip is non-aa and the
864 // draw is aa. Since our lower level clip code works from batch bounds, which are SkRects, it
865 // doesn't detect that the clip can be ignored (modulo antialiasing). The following test
866 // attempts to mitigate the stencil clip cost but will only help when the entire clip stack
867 // can be ignored. We'd prefer to fix this in the framework by removing the clips calls.
868 SkRRect devRRect;
869 if (rrect.transform(viewMatrix, &devRRect) && clip->quickContains(devRRect)) {
870 clip = &noclip;
871 }
872#endif
bsalomon6663acf2016-05-10 09:14:17 -0700873 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
ksakamotoec7f2ac2016-07-05 03:54:53 -0700874
csmartdaltona7f29642016-07-07 08:49:11 -0700875 AutoCheckFlush acf(fDrawingManager);
876 const SkStrokeRec stroke = style.strokeRec();
csmartdaltonecbc12b2016-06-08 10:08:43 -0700877 bool useHWAA;
csmartdaltona7f29642016-07-07 08:49:11 -0700878
csmartdaltone0d36292016-07-29 08:14:20 -0700879 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
880 stroke.isFillStyle()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400881 InstancedRendering* ir = this->getOpList()->instancedRendering();
Hal Canary144caf52016-11-07 17:57:18 -0500882 sk_sp<GrDrawBatch> batch(ir->recordRRect(rrect, viewMatrix, paint.getColor(),
883 paint.isAntiAlias(), fInstancedPipelineInfo,
884 &useHWAA));
csmartdaltona7f29642016-07-07 08:49:11 -0700885 if (batch) {
886 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -0500887 this->getOpList()->drawBatch(pipelineBuilder, this, *clip, batch.get());
csmartdaltona7f29642016-07-07 08:49:11 -0700888 return;
889 }
890 }
891
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400892 if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
robertphillipsb56f9272016-02-25 11:03:52 -0800893 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Hal Canary144caf52016-11-07 17:57:18 -0500894 sk_sp<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.getColor(),
895 paint.usesDistanceVectorField(),
896 viewMatrix,
897 rrect,
898 stroke,
899 shaderCaps));
robertphillipsb56f9272016-02-25 11:03:52 -0800900 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -0700901 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -0500902 this->getOpList()->drawBatch(pipelineBuilder, this, *clip, batch.get());
robertphillipsb56f9272016-02-25 11:03:52 -0800903 return;
904 }
robertphillipsea461502015-05-26 11:38:03 -0700905 }
robertphillipsb56f9272016-02-25 11:03:52 -0800906
907 SkPath path;
908 path.setIsVolatile(true);
909 path.addRRect(rrect);
bsalomon7f0d9f32016-08-15 14:49:10 -0700910 this->internalDrawPath(*clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -0700911}
912
Jim Van Verthc5903412016-11-17 15:27:09 -0500913///////////////////////////////////////////////////////////////////////////////
914
915void GrRenderTargetContext::drawShadowRRect(const GrClip& clip,
916 const GrPaint& paint,
917 const SkMatrix& viewMatrix,
918 const SkRRect& rrect,
919 SkScalar blurRadius,
920 const GrStyle& style) {
921 ASSERT_SINGLE_OWNER
922 RETURN_IF_ABANDONED
923 SkDEBUGCODE(this->validate();)
924 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawShadowRRect");
925 if (rrect.isEmpty()) {
926 return;
927 }
928
929 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
930
931 AutoCheckFlush acf(fDrawingManager);
932 const SkStrokeRec stroke = style.strokeRec();
933 bool useHWAA;
934
935 // TODO: add instancing support
936 //if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
937 // stroke.isFillStyle()) {
938 // InstancedRendering* ir = this->getOpList()->instancedRendering();
939 // SkAutoTUnref<GrDrawBatch> batch(ir->recordRRect(rrect, viewMatrix, paint.getColor(),
940 // paint.isAntiAlias(), fInstancedPipelineInfo,
941 // &useHWAA));
942 // if (batch) {
943 // GrPipelineBuilder pipelineBuilder(paint, useHWAA);
944 // this->getOpList()->drawBatch(pipelineBuilder, this, *clip, batch);
945 // return;
946 // }
947 //}
948
949 if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
950 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
951 sk_sp<GrDrawBatch> batch(CreateShadowRRectBatch(
952 paint.getColor(),
953 viewMatrix,
954 rrect,
955 blurRadius,
956 stroke,
957 shaderCaps));
958 if (batch) {
959 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
960 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
961 return;
962 }
963 }
964
965 SkPath path;
966 path.setIsVolatile(true);
967 path.addRRect(rrect);
968 this->internalDrawPath(clip, paint, viewMatrix, path, style);
969}
970
971///////////////////////////////////////////////////////////////////////////////
972
Brian Osman11052242016-10-27 14:47:55 -0400973bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
974 const GrPaint& paintIn,
975 const SkMatrix& viewMatrix,
976 const SkRRect& origOuter,
977 const SkRRect& origInner) {
robertphillips00095892016-02-29 13:50:40 -0800978 SkASSERT(!origInner.isEmpty());
979 SkASSERT(!origOuter.isEmpty());
980
csmartdaltone0d36292016-07-29 08:14:20 -0700981 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
csmartdaltona7f29642016-07-07 08:49:11 -0700982 bool useHWAA;
Robert Phillipsf2361d22016-10-25 14:20:06 -0400983 InstancedRendering* ir = this->getOpList()->instancedRendering();
Hal Canary144caf52016-11-07 17:57:18 -0500984 sk_sp<GrDrawBatch> batch(ir->recordDRRect(origOuter, origInner, viewMatrix,
985 paintIn.getColor(), paintIn.isAntiAlias(),
986 fInstancedPipelineInfo, &useHWAA));
csmartdaltona7f29642016-07-07 08:49:11 -0700987 if (batch) {
988 GrPipelineBuilder pipelineBuilder(paintIn, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -0500989 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
csmartdaltona7f29642016-07-07 08:49:11 -0700990 return true;
991 }
992 }
993
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400994 bool applyAA = paintIn.isAntiAlias() && !fRenderTargetProxy->isUnifiedMultisampled();
robertphillips00095892016-02-29 13:50:40 -0800995
996 GrPrimitiveEdgeType innerEdgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType :
997 kInverseFillBW_GrProcessorEdgeType;
998 GrPrimitiveEdgeType outerEdgeType = applyAA ? kFillAA_GrProcessorEdgeType :
999 kFillBW_GrProcessorEdgeType;
1000
1001 SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
1002 SkMatrix inverseVM;
1003 if (!viewMatrix.isIdentity()) {
1004 if (!origInner.transform(viewMatrix, inner.writable())) {
1005 return false;
1006 }
1007 if (!origOuter.transform(viewMatrix, outer.writable())) {
1008 return false;
1009 }
1010 if (!viewMatrix.invert(&inverseVM)) {
1011 return false;
1012 }
1013 } else {
1014 inverseVM.reset();
halcanary9d524f22016-03-29 09:03:52 -07001015 }
robertphillips00095892016-02-29 13:50:40 -08001016
1017 GrPaint grPaint(paintIn);
1018 grPaint.setAntiAlias(false);
1019
1020 // TODO these need to be a geometry processors
bungeman06ca8ec2016-06-09 08:01:03 -07001021 sk_sp<GrFragmentProcessor> innerEffect(GrRRectEffect::Make(innerEdgeType, *inner));
robertphillips00095892016-02-29 13:50:40 -08001022 if (!innerEffect) {
1023 return false;
1024 }
1025
bungeman06ca8ec2016-06-09 08:01:03 -07001026 sk_sp<GrFragmentProcessor> outerEffect(GrRRectEffect::Make(outerEdgeType, *outer));
robertphillips00095892016-02-29 13:50:40 -08001027 if (!outerEffect) {
1028 return false;
1029 }
1030
bungeman06ca8ec2016-06-09 08:01:03 -07001031 grPaint.addCoverageFragmentProcessor(std::move(innerEffect));
1032 grPaint.addCoverageFragmentProcessor(std::move(outerEffect));
robertphillips00095892016-02-29 13:50:40 -08001033
1034 SkRect bounds = outer->getBounds();
1035 if (applyAA) {
1036 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1037 }
halcanary9d524f22016-03-29 09:03:52 -07001038
robertphillips00095892016-02-29 13:50:40 -08001039 this->fillRectWithLocalMatrix(clip, grPaint, SkMatrix::I(), bounds, inverseVM);
1040 return true;
1041}
1042
Brian Osman11052242016-10-27 14:47:55 -04001043void GrRenderTargetContext::drawDRRect(const GrClip& clip,
1044 const GrPaint& paint,
1045 const SkMatrix& viewMatrix,
1046 const SkRRect& outer,
1047 const SkRRect& inner) {
robertphillips00095892016-02-29 13:50:40 -08001048 ASSERT_SINGLE_OWNER
1049 RETURN_IF_ABANDONED
1050 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001051 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawDRRect");
robertphillips00095892016-02-29 13:50:40 -08001052
1053 SkASSERT(!outer.isEmpty());
1054 SkASSERT(!inner.isEmpty());
1055
1056 AutoCheckFlush acf(fDrawingManager);
1057
1058 if (this->drawFilledDRRect(clip, paint, viewMatrix, outer, inner)) {
1059 return;
1060 }
1061
1062 SkPath path;
1063 path.setIsVolatile(true);
1064 path.addRRect(inner);
1065 path.addRRect(outer);
1066 path.setFillType(SkPath::kEvenOdd_FillType);
1067
bsalomon6663acf2016-05-10 09:14:17 -07001068 this->internalDrawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
robertphillips00095892016-02-29 13:50:40 -08001069}
1070
robertphillipsea461502015-05-26 11:38:03 -07001071///////////////////////////////////////////////////////////////////////////////
1072
msarettcc319b92016-08-25 18:07:18 -07001073static inline bool is_int(float x) {
1074 return x == (float) sk_float_round2int(x);
1075}
1076
Brian Osman11052242016-10-27 14:47:55 -04001077void GrRenderTargetContext::drawRegion(const GrClip& clip,
1078 const GrPaint& paint,
1079 const SkMatrix& viewMatrix,
1080 const SkRegion& region,
1081 const GrStyle& style) {
msarettcc319b92016-08-25 18:07:18 -07001082 ASSERT_SINGLE_OWNER
1083 RETURN_IF_ABANDONED
1084 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001085 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawRegion");
msarettcc319b92016-08-25 18:07:18 -07001086
1087 bool isNonTranslate = SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask));
1088 bool complexStyle = !style.isSimpleFill();
1089 bool antiAlias = paint.isAntiAlias() && (!is_int(viewMatrix.getTranslateX()) ||
1090 !is_int(viewMatrix.getTranslateY()));
1091 if (isNonTranslate || complexStyle || antiAlias) {
1092 SkPath path;
1093 region.getBoundaryPath(&path);
1094 return this->drawPath(clip, paint, viewMatrix, path, style);
1095 }
1096
Hal Canary144caf52016-11-07 17:57:18 -05001097 sk_sp<GrDrawBatch> batch(GrRegionBatch::Create(paint.getColor(), viewMatrix, region));
msarettcc319b92016-08-25 18:07:18 -07001098 GrPipelineBuilder pipelineBuilder(paint, false);
Hal Canary144caf52016-11-07 17:57:18 -05001099 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
msarettcc319b92016-08-25 18:07:18 -07001100}
1101
Brian Osman11052242016-10-27 14:47:55 -04001102void GrRenderTargetContext::drawOval(const GrClip& clip,
1103 const GrPaint& paint,
1104 const SkMatrix& viewMatrix,
1105 const SkRect& oval,
1106 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001107 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001108 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001109 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001110 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawOval");
robertphillips2e1e51f2015-10-15 08:01:48 -07001111
robertphillipsea461502015-05-26 11:38:03 -07001112 if (oval.isEmpty()) {
1113 return;
1114 }
1115
bsalomon6663acf2016-05-10 09:14:17 -07001116 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
robertphillipsea461502015-05-26 11:38:03 -07001117
robertphillips77a2e522015-10-17 07:43:27 -07001118 AutoCheckFlush acf(fDrawingManager);
bsalomon6663acf2016-05-10 09:14:17 -07001119 const SkStrokeRec& stroke = style.strokeRec();
csmartdaltonecbc12b2016-06-08 10:08:43 -07001120 bool useHWAA;
csmartdaltona7f29642016-07-07 08:49:11 -07001121
csmartdaltone0d36292016-07-29 08:14:20 -07001122 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
1123 stroke.isFillStyle()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -04001124 InstancedRendering* ir = this->getOpList()->instancedRendering();
Hal Canary144caf52016-11-07 17:57:18 -05001125 sk_sp<GrDrawBatch> batch(ir->recordOval(oval, viewMatrix, paint.getColor(),
1126 paint.isAntiAlias(), fInstancedPipelineInfo,
1127 &useHWAA));
csmartdaltona7f29642016-07-07 08:49:11 -07001128 if (batch) {
1129 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -05001130 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
csmartdaltona7f29642016-07-07 08:49:11 -07001131 return;
1132 }
1133 }
1134
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001135 if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
robertphillipsb56f9272016-02-25 11:03:52 -08001136 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Hal Canary144caf52016-11-07 17:57:18 -05001137 sk_sp<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
1138 viewMatrix,
1139 oval,
1140 stroke,
1141 shaderCaps));
robertphillipsb56f9272016-02-25 11:03:52 -08001142 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -07001143 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -05001144 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
robertphillipsb56f9272016-02-25 11:03:52 -08001145 return;
1146 }
robertphillipsea461502015-05-26 11:38:03 -07001147 }
robertphillipsb56f9272016-02-25 11:03:52 -08001148
1149 SkPath path;
1150 path.setIsVolatile(true);
1151 path.addOval(oval);
bsalomon6663acf2016-05-10 09:14:17 -07001152 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -07001153}
1154
Brian Osman11052242016-10-27 14:47:55 -04001155void GrRenderTargetContext::drawArc(const GrClip& clip,
1156 const GrPaint& paint,
1157 const SkMatrix& viewMatrix,
1158 const SkRect& oval,
1159 SkScalar startAngle,
1160 SkScalar sweepAngle,
1161 bool useCenter,
1162 const GrStyle& style) {
bsalomon4f3a0ca2016-08-22 13:14:26 -07001163 bool useHWAA;
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001164 if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
bsalomon4f3a0ca2016-08-22 13:14:26 -07001165 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Hal Canary144caf52016-11-07 17:57:18 -05001166 sk_sp<GrDrawBatch> batch(GrOvalRenderer::CreateArcBatch(paint.getColor(),
1167 viewMatrix,
1168 oval,
1169 startAngle,
1170 sweepAngle,
1171 useCenter,
1172 style,
1173 shaderCaps));
bsalomon4f3a0ca2016-08-22 13:14:26 -07001174 if (batch) {
1175 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -05001176 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
bsalomon4f3a0ca2016-08-22 13:14:26 -07001177 return;
1178 }
1179 }
1180 SkPath path;
bsalomon21af9ca2016-08-25 12:29:23 -07001181 SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
1182 style.isSimpleFill());
bsalomon4f3a0ca2016-08-22 13:14:26 -07001183 this->internalDrawPath(clip, paint, viewMatrix, path, style);
1184 return;
1185}
1186
Brian Osman11052242016-10-27 14:47:55 -04001187void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
1188 const GrPaint& paint,
1189 const SkMatrix& viewMatrix,
1190 int imageWidth,
1191 int imageHeight,
1192 std::unique_ptr<SkLatticeIter> iter,
1193 const SkRect& dst) {
joshualitt1de610a2016-01-06 08:26:09 -08001194 ASSERT_SINGLE_OWNER
joshualitt33a5fce2015-11-18 13:28:51 -08001195 RETURN_IF_ABANDONED
1196 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001197 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawImageLattice");
joshualitt33a5fce2015-11-18 13:28:51 -08001198
1199 AutoCheckFlush acf(fDrawingManager);
1200
Hal Canary144caf52016-11-07 17:57:18 -05001201 sk_sp<GrDrawBatch> batch(GrNinePatch::CreateNonAA(paint.getColor(), viewMatrix,
1202 imageWidth, imageHeight,
1203 std::move(iter), dst));
joshualitt33a5fce2015-11-18 13:28:51 -08001204
csmartdaltonecbc12b2016-06-08 10:08:43 -07001205 GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
Hal Canary144caf52016-11-07 17:57:18 -05001206 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
joshualitt33a5fce2015-11-18 13:28:51 -08001207}
1208
Brian Osman11052242016-10-27 14:47:55 -04001209void GrRenderTargetContext::prepareForExternalIO() {
robertphillips8c523e02016-07-26 07:41:00 -07001210 ASSERT_SINGLE_OWNER
1211 RETURN_IF_ABANDONED
1212 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001213 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::prepareForExternalIO");
robertphillips8c523e02016-07-26 07:41:00 -07001214
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001215 // Deferral of the VRAM resources must end in this instance anyway
1216 sk_sp<GrRenderTarget> rt(
1217 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -05001218 if (!rt) {
1219 return;
1220 }
robertphillips8c523e02016-07-26 07:41:00 -07001221
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001222 ASSERT_OWNED_RESOURCE(rt);
1223
1224 fDrawingManager->prepareSurfaceForExternalIO(rt.get());
robertphillips8c523e02016-07-26 07:41:00 -07001225}
joshualitt33a5fce2015-11-18 13:28:51 -08001226
Brian Osman11052242016-10-27 14:47:55 -04001227void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
1228 const GrPaint& paint,
1229 const SkMatrix& viewMatrix,
1230 const SkRect& rect,
1231 const SkRect* localRect,
1232 const SkMatrix* localMatrix,
1233 const GrUserStencilSettings* ss,
1234 bool useHWAA) {
csmartdalton34ee0c92016-07-27 13:22:27 -07001235 SkASSERT(!useHWAA || this->isStencilBufferMultisampled());
Hal Canary144caf52016-11-07 17:57:18 -05001236 sk_sp<GrDrawBatch> batch(
robertphillips44302392016-07-08 14:43:03 -07001237 GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect, localRect,
1238 localMatrix));
csmartdalton34ee0c92016-07-27 13:22:27 -07001239 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
robertphillips44302392016-07-08 14:43:03 -07001240 if (ss) {
1241 pipelineBuilder.setUserStencil(ss);
1242 }
Hal Canary144caf52016-11-07 17:57:18 -05001243 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
robertphillips44302392016-07-08 14:43:03 -07001244}
1245
Brian Osman11052242016-10-27 14:47:55 -04001246bool GrRenderTargetContext::readPixels(const SkImageInfo& dstInfo, void* dstBuffer,
1247 size_t dstRowBytes, int x, int y) {
robertphillips1da3ecd2016-08-31 14:54:15 -07001248 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
1249 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
1250 if (kUnknown_GrPixelConfig == config) {
1251 return false;
1252 }
1253
1254 uint32_t flags = 0;
1255 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
1256 flags = GrContext::kUnpremul_PixelOpsFlag;
1257 }
1258
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001259 // Deferral of the VRAM resources must end in this instance anyway
1260 sk_sp<GrRenderTarget> rt(
1261 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -05001262 if (!rt) {
1263 return false;
1264 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001265
1266 return rt->readPixels(x, y, dstInfo.width(), dstInfo.height(),
1267 config, dstBuffer, dstRowBytes, flags);
robertphillips1da3ecd2016-08-31 14:54:15 -07001268}
1269
Brian Osman11052242016-10-27 14:47:55 -04001270bool GrRenderTargetContext::writePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
1271 size_t srcRowBytes, int x, int y) {
robertphillips1da3ecd2016-08-31 14:54:15 -07001272 // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
1273 GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
1274 if (kUnknown_GrPixelConfig == config) {
1275 return false;
1276 }
1277 uint32_t flags = 0;
1278 if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
1279 flags = GrContext::kUnpremul_PixelOpsFlag;
1280 }
1281
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001282 // Deferral of the VRAM resources must end in this instance anyway
1283 sk_sp<GrRenderTarget> rt(
1284 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -05001285 if (!rt) {
1286 return false;
1287 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001288
1289 return rt->writePixels(x, y, srcInfo.width(), srcInfo.height(),
1290 config, srcBuffer, srcRowBytes, flags);
robertphillips1da3ecd2016-08-31 14:54:15 -07001291}
1292
robertphillipsea461502015-05-26 11:38:03 -07001293// Can 'path' be drawn as a pair of filled nested rectangles?
bsalomon6663acf2016-05-10 09:14:17 -07001294static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path, SkRect rects[2]) {
robertphillipsea461502015-05-26 11:38:03 -07001295
1296 if (path.isInverseFillType()) {
1297 return false;
1298 }
1299
1300 // TODO: this restriction could be lifted if we were willing to apply
1301 // the matrix to all the points individually rather than just to the rect
robertphillips0e7029e2015-11-30 05:45:06 -08001302 if (!viewMatrix.rectStaysRect()) {
robertphillipsea461502015-05-26 11:38:03 -07001303 return false;
1304 }
1305
1306 SkPath::Direction dirs[2];
1307 if (!path.isNestedFillRects(rects, dirs)) {
1308 return false;
1309 }
1310
1311 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) {
1312 // The two rects need to be wound opposite to each other
1313 return false;
1314 }
1315
1316 // Right now, nested rects where the margin is not the same width
1317 // all around do not render correctly
1318 const SkScalar* outer = rects[0].asScalars();
1319 const SkScalar* inner = rects[1].asScalars();
1320
1321 bool allEq = true;
1322
1323 SkScalar margin = SkScalarAbs(outer[0] - inner[0]);
1324 bool allGoE1 = margin >= SK_Scalar1;
1325
1326 for (int i = 1; i < 4; ++i) {
1327 SkScalar temp = SkScalarAbs(outer[i] - inner[i]);
1328 if (temp < SK_Scalar1) {
1329 allGoE1 = false;
1330 }
1331 if (!SkScalarNearlyEqual(margin, temp)) {
1332 allEq = false;
1333 }
1334 }
1335
1336 return allEq || allGoE1;
1337}
1338
Brian Osman11052242016-10-27 14:47:55 -04001339void GrRenderTargetContext::drawPath(const GrClip& clip,
1340 const GrPaint& paint,
1341 const SkMatrix& viewMatrix,
1342 const SkPath& path,
1343 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001344 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001345 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001346 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001347 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPath");
robertphillips2e1e51f2015-10-15 08:01:48 -07001348
robertphillipsea461502015-05-26 11:38:03 -07001349 if (path.isEmpty()) {
1350 if (path.isInverseFillType()) {
robertphillips2e1e51f2015-10-15 08:01:48 -07001351 this->drawPaint(clip, paint, viewMatrix);
robertphillipsea461502015-05-26 11:38:03 -07001352 }
1353 return;
1354 }
1355
robertphillips77a2e522015-10-17 07:43:27 -07001356 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -07001357
csmartdaltonecbc12b2016-06-08 10:08:43 -07001358 bool useHWAA;
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001359 if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA) &&
1360 !style.pathEffect()) {
bsalomon6663acf2016-05-10 09:14:17 -07001361 if (style.isSimpleFill() && !path.isConvex()) {
robertphillipsea461502015-05-26 11:38:03 -07001362 // Concave AA paths are expensive - try to avoid them for special cases
1363 SkRect rects[2];
1364
bsalomon6663acf2016-05-10 09:14:17 -07001365 if (fills_as_nested_rects(viewMatrix, path, rects)) {
Hal Canary144caf52016-11-07 17:57:18 -05001366 sk_sp<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFillNestedRects(
robertphillips4bc31812016-03-01 12:22:49 -08001367 paint.getColor(), viewMatrix, rects));
bsalomon40ef4852016-05-02 13:22:13 -07001368 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -07001369 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -05001370 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
bsalomon40ef4852016-05-02 13:22:13 -07001371 }
robertphillipsea461502015-05-26 11:38:03 -07001372 return;
1373 }
1374 }
1375 SkRect ovalRect;
1376 bool isOval = path.isOval(&ovalRect);
1377
1378 if (isOval && !path.isInverseFillType()) {
robertphillips0cc2f852016-02-24 13:36:56 -08001379 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Hal Canary144caf52016-11-07 17:57:18 -05001380 sk_sp<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
1381 viewMatrix,
1382 ovalRect,
1383 style.strokeRec(),
1384 shaderCaps));
robertphillips0cc2f852016-02-24 13:36:56 -08001385 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -07001386 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
Hal Canary144caf52016-11-07 17:57:18 -05001387 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch.get());
robertphillipsea461502015-05-26 11:38:03 -07001388 return;
1389 }
1390 }
1391 }
robertphillips4bc31812016-03-01 12:22:49 -08001392
1393 // Note that internalDrawPath may sw-rasterize the path into a scratch texture.
1394 // Scratch textures can be recycled after they are returned to the texture
1395 // cache. This presents a potential hazard for buffered drawing. However,
1396 // the writePixels that uploads to the scratch will perform a flush so we're
1397 // OK.
bsalomon6663acf2016-05-10 09:14:17 -07001398 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -07001399}
1400
Brian Osman11052242016-10-27 14:47:55 -04001401bool GrRenderTargetContextPriv::drawAndStencilPath(const GrClip& clip,
1402 const GrUserStencilSettings* ss,
1403 SkRegion::Op op,
1404 bool invert,
1405 bool doAA,
1406 const SkMatrix& viewMatrix,
1407 const SkPath& path) {
robertphillips391395d2016-03-02 09:26:36 -08001408 ASSERT_SINGLE_OWNER_PRIV
1409 RETURN_FALSE_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -04001410 SkDEBUGCODE(fRenderTargetContext->validate();)
1411 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail, "GrRenderTargetContext::drawPath");
robertphillips391395d2016-03-02 09:26:36 -08001412
1413 if (path.isEmpty() && path.isInverseFillType()) {
cdalton862cff32016-05-12 15:09:48 -07001414 this->drawAndStencilRect(clip, ss, op, invert, false, SkMatrix::I(),
Brian Osman11052242016-10-27 14:47:55 -04001415 SkRect::MakeIWH(fRenderTargetContext->width(),
1416 fRenderTargetContext->height()));
robertphillips391395d2016-03-02 09:26:36 -08001417 return true;
1418 }
1419
Brian Osman11052242016-10-27 14:47:55 -04001420 AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
robertphillips391395d2016-03-02 09:26:36 -08001421
1422 // An Assumption here is that path renderer would use some form of tweaking
1423 // the src color (either the input alpha or in the frag shader) to implement
1424 // aa. If we have some future driver-mojo path AA that can do the right
1425 // thing WRT to the blend then we'll need some query on the PR.
Brian Osman11052242016-10-27 14:47:55 -04001426 bool useCoverageAA = doAA && !fRenderTargetContext->isUnifiedMultisampled();
robertphillips976f5f02016-06-03 10:59:20 -07001427 bool hasUserStencilSettings = !ss->isUnused();
Brian Osman11052242016-10-27 14:47:55 -04001428 bool isStencilBufferMSAA = fRenderTargetContext->isStencilBufferMultisampled();
robertphillips391395d2016-03-02 09:26:36 -08001429
1430 const GrPathRendererChain::DrawType type =
1431 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
1432 : GrPathRendererChain::kColor_DrawType;
1433
bsalomon8acedde2016-06-24 10:42:16 -07001434 GrShape shape(path, GrStyle::SimpleFill());
robertphillips391395d2016-03-02 09:26:36 -08001435 GrPathRenderer::CanDrawPathArgs canDrawArgs;
Brian Osman11052242016-10-27 14:47:55 -04001436 canDrawArgs.fShaderCaps =
1437 fRenderTargetContext->fDrawingManager->getContext()->caps()->shaderCaps();
robertphillips391395d2016-03-02 09:26:36 -08001438 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001439 canDrawArgs.fShape = &shape;
robertphillips391395d2016-03-02 09:26:36 -08001440 canDrawArgs.fAntiAlias = useCoverageAA;
cdalton93a379b2016-05-11 13:58:08 -07001441 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
robertphillips391395d2016-03-02 09:26:36 -08001442 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
1443
1444 // Don't allow the SW renderer
Brian Osman11052242016-10-27 14:47:55 -04001445 GrPathRenderer* pr = fRenderTargetContext->fDrawingManager->getPathRenderer(canDrawArgs, false,
1446 type);
robertphillips391395d2016-03-02 09:26:36 -08001447 if (!pr) {
1448 return false;
1449 }
1450
1451 GrPaint paint;
1452 paint.setCoverageSetOpXPFactory(op, invert);
1453
robertphillips391395d2016-03-02 09:26:36 -08001454 GrPathRenderer::DrawPathArgs args;
Brian Osman11052242016-10-27 14:47:55 -04001455 args.fResourceProvider =
1456 fRenderTargetContext->fDrawingManager->getContext()->resourceProvider();
robertphillips976f5f02016-06-03 10:59:20 -07001457 args.fPaint = &paint;
1458 args.fUserStencilSettings = ss;
Brian Osman11052242016-10-27 14:47:55 -04001459 args.fRenderTargetContext = fRenderTargetContext;
cdalton862cff32016-05-12 15:09:48 -07001460 args.fClip = &clip;
robertphillips391395d2016-03-02 09:26:36 -08001461 args.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001462 args.fShape = &shape;
robertphillips391395d2016-03-02 09:26:36 -08001463 args.fAntiAlias = useCoverageAA;
Brian Osman11052242016-10-27 14:47:55 -04001464 args.fGammaCorrect = fRenderTargetContext->isGammaCorrect();
robertphillips391395d2016-03-02 09:26:36 -08001465 pr->drawPath(args);
1466 return true;
1467}
1468
Brian Osman11052242016-10-27 14:47:55 -04001469SkBudgeted GrRenderTargetContextPriv::isBudgeted() const {
robertphillips714712b2016-08-04 06:20:45 -07001470 ASSERT_SINGLE_OWNER_PRIV
1471
Brian Osman11052242016-10-27 14:47:55 -04001472 if (fRenderTargetContext->wasAbandoned()) {
robertphillips714712b2016-08-04 06:20:45 -07001473 return SkBudgeted::kNo;
1474 }
1475
Brian Osman11052242016-10-27 14:47:55 -04001476 SkDEBUGCODE(fRenderTargetContext->validate();)
robertphillips714712b2016-08-04 06:20:45 -07001477
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001478 return fRenderTargetContext->fRenderTargetProxy->isBudgeted();
robertphillips714712b2016-08-04 06:20:45 -07001479}
1480
Brian Osman11052242016-10-27 14:47:55 -04001481void GrRenderTargetContext::internalDrawPath(const GrClip& clip,
1482 const GrPaint& paint,
1483 const SkMatrix& viewMatrix,
1484 const SkPath& path,
1485 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001486 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001487 RETURN_IF_ABANDONED
bsalomon8acedde2016-06-24 10:42:16 -07001488 SkASSERT(!path.isEmpty());
robertphillipsea461502015-05-26 11:38:03 -07001489
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001490 bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTargetProxy.get());
cdalton93a379b2016-05-11 13:58:08 -07001491 constexpr bool kHasUserStencilSettings = false;
robertphillips13a7eee2016-08-31 15:06:24 -07001492 bool isStencilBufferMSAA = this->isStencilBufferMultisampled();
robertphillipsea461502015-05-26 11:38:03 -07001493
robertphillips68737822015-10-29 12:12:21 -07001494 const GrPathRendererChain::DrawType type =
1495 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
1496 : GrPathRendererChain::kColor_DrawType;
robertphillipsea461502015-05-26 11:38:03 -07001497
bsalomon8acedde2016-06-24 10:42:16 -07001498 GrShape shape(path, style);
bsalomon0a0f67e2016-06-28 11:56:42 -07001499 if (shape.isEmpty()) {
1500 return;
1501 }
robertphillips68737822015-10-29 12:12:21 -07001502 GrPathRenderer::CanDrawPathArgs canDrawArgs;
1503 canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
1504 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001505 canDrawArgs.fShape = &shape;
robertphillips68737822015-10-29 12:12:21 -07001506 canDrawArgs.fAntiAlias = useCoverageAA;
cdalton93a379b2016-05-11 13:58:08 -07001507 canDrawArgs.fHasUserStencilSettings = kHasUserStencilSettings;
robertphillips68737822015-10-29 12:12:21 -07001508 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
1509
bsalomon6663acf2016-05-10 09:14:17 -07001510 // Try a 1st time without applying any of the style to the geometry (and barring sw)
robertphillips68737822015-10-29 12:12:21 -07001511 GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
bsalomon6663acf2016-05-10 09:14:17 -07001512 SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
robertphillipsea461502015-05-26 11:38:03 -07001513
bsalomon8acedde2016-06-24 10:42:16 -07001514 if (!pr && shape.style().pathEffect()) {
bsalomon6663acf2016-05-10 09:14:17 -07001515 // It didn't work above, so try again with the path effect applied.
bsalomon8acedde2016-06-24 10:42:16 -07001516 shape = shape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
1517 if (shape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001518 return;
1519 }
robertphillips68737822015-10-29 12:12:21 -07001520 pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
robertphillipsea461502015-05-26 11:38:03 -07001521 }
bsalomon6663acf2016-05-10 09:14:17 -07001522 if (!pr) {
bsalomon8acedde2016-06-24 10:42:16 -07001523 if (shape.style().applies()) {
1524 shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale);
1525 if (shape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001526 return;
1527 }
bsalomon6663acf2016-05-10 09:14:17 -07001528 }
robertphillipsea461502015-05-26 11:38:03 -07001529 // This time, allow SW renderer
robertphillips68737822015-10-29 12:12:21 -07001530 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type);
robertphillipsea461502015-05-26 11:38:03 -07001531 }
1532
bsalomon8acedde2016-06-24 10:42:16 -07001533 if (!pr) {
robertphillipsea461502015-05-26 11:38:03 -07001534#ifdef SK_DEBUG
1535 SkDebugf("Unable to find path renderer compatible with path.\n");
1536#endif
1537 return;
1538 }
1539
bsalomon0aff2fa2015-07-31 06:48:27 -07001540 GrPathRenderer::DrawPathArgs args;
robertphillips77a2e522015-10-17 07:43:27 -07001541 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider();
robertphillips976f5f02016-06-03 10:59:20 -07001542 args.fPaint = &paint;
1543 args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
Brian Osman11052242016-10-27 14:47:55 -04001544 args.fRenderTargetContext = this;
cdalton862cff32016-05-12 15:09:48 -07001545 args.fClip = &clip;
bsalomon0aff2fa2015-07-31 06:48:27 -07001546 args.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001547 args.fShape = canDrawArgs.fShape;
bsalomon0aff2fa2015-07-31 06:48:27 -07001548 args.fAntiAlias = useCoverageAA;
brianosman0e3c5542016-04-13 13:56:21 -07001549 args.fGammaCorrect = this->isGammaCorrect();
bsalomon0aff2fa2015-07-31 06:48:27 -07001550 pr->drawPath(args);
robertphillipsea461502015-05-26 11:38:03 -07001551}
1552
Brian Osman11052242016-10-27 14:47:55 -04001553void GrRenderTargetContext::drawBatch(const GrPipelineBuilder& pipelineBuilder, const GrClip& clip,
1554 GrDrawBatch* batch) {
joshualitt1de610a2016-01-06 08:26:09 -08001555 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -07001556 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001557 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001558 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawBatch");
robertphillips2d70dcb2015-10-06 07:38:23 -07001559
Robert Phillipsf2361d22016-10-25 14:20:06 -04001560 this->getOpList()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillips2334fb62015-06-17 05:43:33 -07001561}