blob: 24408a2a38edf30029ded4dde664f123c949fc45 [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"
robertphillipsea461502015-05-26 11:38:03 -070010#include "GrDrawContext.h"
robertphillips391395d2016-03-02 09:26:36 -080011#include "GrDrawContextPriv.h"
robertphillips77a2e522015-10-17 07:43:27 -070012#include "GrDrawingManager.h"
robertphillipsea461502015-05-26 11:38:03 -070013#include "GrOvalRenderer.h"
14#include "GrPathRenderer.h"
robertphillips2334fb62015-06-17 05:43:33 -070015#include "GrRenderTarget.h"
16#include "GrRenderTargetPriv.h"
bsalomon473addf2015-10-02 07:49:05 -070017#include "GrResourceProvider.h"
robertphillips2d70dcb2015-10-06 07:38:23 -070018#include "SkSurfacePriv.h"
robertphillipsea461502015-05-26 11:38:03 -070019
joshualitt74417822015-08-07 11:42:16 -070020#include "batches/GrBatch.h"
robertphillips9199a9f2016-07-13 07:48:43 -070021#include "batches/GrClearBatch.h"
jvanverth14b88032015-08-07 12:18:54 -070022#include "batches/GrDrawAtlasBatch.h"
joshualitt2771b562015-08-07 12:46:26 -070023#include "batches/GrDrawVerticesBatch.h"
joshualitt7fc2a262015-08-10 10:30:14 -070024#include "batches/GrRectBatchFactory.h"
joshualitt33a5fce2015-11-18 13:28:51 -080025#include "batches/GrNinePatch.h" // TODO Factory
joshualitt74417822015-08-07 11:42:16 -070026
robertphillips00095892016-02-29 13:50:40 -080027#include "effects/GrRRectEffect.h"
28
csmartdaltona7f29642016-07-07 08:49:11 -070029#include "instanced/InstancedRendering.h"
30
joshualitte8042922015-12-11 06:11:21 -080031#include "text/GrAtlasTextContext.h"
32#include "text/GrStencilAndCoverTextContext.h"
33
joshualittbc907352016-01-13 06:45:40 -080034#include "../private/GrAuditTrail.h"
35
robertphillips77a2e522015-10-17 07:43:27 -070036#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fDrawingManager->getContext())
joshualitt1de610a2016-01-06 08:26:09 -080037#define ASSERT_SINGLE_OWNER \
joshualittde8dc7e2016-01-08 10:09:13 -080038 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
robertphillips391395d2016-03-02 09:26:36 -080039#define ASSERT_SINGLE_OWNER_PRIV \
40 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fDrawContext->fSingleOwner);)
robertphillips7761d612016-05-16 09:14:53 -070041#define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
robertphillips976f5f02016-06-03 10:59:20 -070042#define RETURN_IF_ABANDONED_PRIV if (fDrawContext->fDrawingManager->wasAbandoned()) { return; }
robertphillips7761d612016-05-16 09:14:53 -070043#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
44#define RETURN_FALSE_IF_ABANDONED_PRIV if (fDrawContext->fDrawingManager->wasAbandoned()) { return false; }
45#define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
robertphillipsea461502015-05-26 11:38:03 -070046
csmartdaltona7f29642016-07-07 08:49:11 -070047using gr_instanced::InstancedRendering;
48
robertphillipsea461502015-05-26 11:38:03 -070049class AutoCheckFlush {
50public:
halcanary9d524f22016-03-29 09:03:52 -070051 AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
robertphillips77a2e522015-10-17 07:43:27 -070052 SkASSERT(fDrawingManager);
53 }
54 ~AutoCheckFlush() { fDrawingManager->getContext()->flushIfNecessary(); }
robertphillipsea461502015-05-26 11:38:03 -070055
56private:
robertphillips77a2e522015-10-17 07:43:27 -070057 GrDrawingManager* fDrawingManager;
robertphillipsea461502015-05-26 11:38:03 -070058};
59
robertphillips7761d612016-05-16 09:14:53 -070060bool GrDrawContext::wasAbandoned() const {
61 return fDrawingManager->wasAbandoned();
62}
63
robertphillipsa106c622015-10-16 09:07:06 -070064// In MDB mode the reffing of the 'getLastDrawTarget' call's result allows in-progress
65// drawTargets to be picked up and added to by drawContexts lower in the call
66// stack. When this occurs with a closed drawTarget, a new one will be allocated
67// when the drawContext attempts to use it (via getDrawTarget).
joshualitt1b39f432016-02-11 06:46:52 -080068GrDrawContext::GrDrawContext(GrContext* context,
69 GrDrawingManager* drawingMgr,
robertphillips6c7e3252016-04-27 10:47:51 -070070 sk_sp<GrRenderTarget> rt,
joshualittde8dc7e2016-01-08 10:09:13 -080071 const SkSurfaceProps* surfaceProps,
joshualittbc907352016-01-13 06:45:40 -080072 GrAuditTrail* auditTrail,
joshualittde8dc7e2016-01-08 10:09:13 -080073 GrSingleOwner* singleOwner)
robertphillips77a2e522015-10-17 07:43:27 -070074 : fDrawingManager(drawingMgr)
robertphillips6c7e3252016-04-27 10:47:51 -070075 , fRenderTarget(std::move(rt))
76 , fDrawTarget(SkSafeRef(fRenderTarget->getLastDrawTarget()))
joshualitt1b39f432016-02-11 06:46:52 -080077 , fContext(context)
csmartdaltona7f29642016-07-07 08:49:11 -070078 , fInstancedPipelineInfo(fRenderTarget.get())
joshualittde8dc7e2016-01-08 10:09:13 -080079 , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
joshualittbc907352016-01-13 06:45:40 -080080 , fAuditTrail(auditTrail)
joshualitt6d0872d2016-01-11 08:27:48 -080081#ifdef SK_DEBUG
82 , fSingleOwner(singleOwner)
83#endif
84{
robertphillips2e1e51f2015-10-15 08:01:48 -070085 SkDEBUGCODE(this->validate();)
robertphillipsea461502015-05-26 11:38:03 -070086}
87
robertphillips2e1e51f2015-10-15 08:01:48 -070088#ifdef SK_DEBUG
89void GrDrawContext::validate() const {
90 SkASSERT(fRenderTarget);
91 ASSERT_OWNED_RESOURCE(fRenderTarget);
robertphillipsa106c622015-10-16 09:07:06 -070092
93 if (fDrawTarget && !fDrawTarget->isClosed()) {
94 SkASSERT(fRenderTarget->getLastDrawTarget() == fDrawTarget);
95 }
robertphillips2e1e51f2015-10-15 08:01:48 -070096}
97#endif
98
robertphillipsa106c622015-10-16 09:07:06 -070099GrDrawContext::~GrDrawContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800100 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -0700101 SkSafeUnref(fDrawTarget);
102}
103
104GrDrawTarget* GrDrawContext::getDrawTarget() {
joshualitt1de610a2016-01-06 08:26:09 -0800105 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -0700106 SkDEBUGCODE(this->validate();)
107
108 if (!fDrawTarget || fDrawTarget->isClosed()) {
robertphillips6c7e3252016-04-27 10:47:51 -0700109 fDrawTarget = fDrawingManager->newDrawTarget(fRenderTarget.get());
robertphillipsa106c622015-10-16 09:07:06 -0700110 }
111
112 return fDrawTarget;
113}
114
bsalomonb8fea972016-02-16 07:34:17 -0800115bool GrDrawContext::copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
joshualitt1de610a2016-01-06 08:26:09 -0800116 ASSERT_SINGLE_OWNER
bsalomonb8fea972016-02-16 07:34:17 -0800117 RETURN_FALSE_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700118 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800119 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::copySurface");
robertphillips2d70dcb2015-10-06 07:38:23 -0700120
robertphillips6c7e3252016-04-27 10:47:51 -0700121 return this->getDrawTarget()->copySurface(fRenderTarget.get(), src, srcRect, dstPoint);
robertphillipsea461502015-05-26 11:38:03 -0700122}
123
robertphillips2e1e51f2015-10-15 08:01:48 -0700124void GrDrawContext::drawText(const GrClip& clip, const GrPaint& grPaint,
robertphillips2334fb62015-06-17 05:43:33 -0700125 const SkPaint& skPaint,
126 const SkMatrix& viewMatrix,
127 const char text[], size_t byteLength,
128 SkScalar x, SkScalar y, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800129 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700130 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700131 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800132 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700133
joshualitt96880d92016-02-16 10:36:53 -0800134 if (!fAtlasTextContext) {
joshualitt8db86782016-02-17 05:40:00 -0800135 fAtlasTextContext.reset(GrAtlasTextContext::Create());
robertphillips2334fb62015-06-17 05:43:33 -0700136 }
137
joshualitt96880d92016-02-16 10:36:53 -0800138 fAtlasTextContext->drawText(fContext, this, clip, grPaint, skPaint, viewMatrix, fSurfaceProps,
139 text, byteLength, x, y, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700140}
robertphillipscaef3452015-11-11 13:18:11 -0800141
robertphillips2e1e51f2015-10-15 08:01:48 -0700142void GrDrawContext::drawPosText(const GrClip& clip, const GrPaint& grPaint,
robertphillips2334fb62015-06-17 05:43:33 -0700143 const SkPaint& skPaint,
144 const SkMatrix& viewMatrix,
145 const char text[], size_t byteLength,
146 const SkScalar pos[], int scalarsPerPosition,
147 const SkPoint& offset, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800148 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700149 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700150 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800151 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPosText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700152
joshualitt96880d92016-02-16 10:36:53 -0800153 if (!fAtlasTextContext) {
joshualitt8db86782016-02-17 05:40:00 -0800154 fAtlasTextContext.reset(GrAtlasTextContext::Create());
robertphillips2334fb62015-06-17 05:43:33 -0700155 }
156
joshualitt96880d92016-02-16 10:36:53 -0800157 fAtlasTextContext->drawPosText(fContext, this, clip, grPaint, skPaint, viewMatrix,
158 fSurfaceProps, text, byteLength, pos, scalarsPerPosition,
159 offset, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700160
161}
robertphillipscaef3452015-11-11 13:18:11 -0800162
robertphillips2e1e51f2015-10-15 08:01:48 -0700163void GrDrawContext::drawTextBlob(const GrClip& clip, const SkPaint& skPaint,
robertphillips2334fb62015-06-17 05:43:33 -0700164 const SkMatrix& viewMatrix, const SkTextBlob* blob,
165 SkScalar x, SkScalar y,
166 SkDrawFilter* filter, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800167 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700168 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700169 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800170 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawTextBlob");
robertphillips2d70dcb2015-10-06 07:38:23 -0700171
joshualitt96880d92016-02-16 10:36:53 -0800172 if (!fAtlasTextContext) {
joshualitt8db86782016-02-17 05:40:00 -0800173 fAtlasTextContext.reset(GrAtlasTextContext::Create());
robertphillips2334fb62015-06-17 05:43:33 -0700174 }
175
joshualitt96880d92016-02-16 10:36:53 -0800176 fAtlasTextContext->drawTextBlob(fContext, this, clip, skPaint, viewMatrix, fSurfaceProps, blob,
177 x, y, filter, clipBounds);
robertphillipsea461502015-05-26 11:38:03 -0700178}
179
robertphillips2e1e51f2015-10-15 08:01:48 -0700180void GrDrawContext::discard() {
joshualitt1de610a2016-01-06 08:26:09 -0800181 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700182 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700183 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800184 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::discard");
robertphillips2e1e51f2015-10-15 08:01:48 -0700185
robertphillips77a2e522015-10-17 07:43:27 -0700186 AutoCheckFlush acf(fDrawingManager);
robertphillips6c7e3252016-04-27 10:47:51 -0700187 this->getDrawTarget()->discard(fRenderTarget.get());
robertphillipsea461502015-05-26 11:38:03 -0700188}
189
robertphillips2e1e51f2015-10-15 08:01:48 -0700190void GrDrawContext::clear(const SkIRect* rect,
robertphillipsea461502015-05-26 11:38:03 -0700191 const GrColor color,
192 bool canIgnoreRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800193 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700194 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700195 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800196 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::clear");
robertphillipsea461502015-05-26 11:38:03 -0700197
robertphillips77a2e522015-10-17 07:43:27 -0700198 AutoCheckFlush acf(fDrawingManager);
robertphillips9199a9f2016-07-13 07:48:43 -0700199
200 const SkIRect rtRect = SkIRect::MakeWH(this->width(), this->height());
201 SkIRect clippedRect;
202 if (!rect ||
203 (canIgnoreRect && fContext->caps()->fullClearIsFree()) ||
204 rect->contains(rtRect)) {
205 rect = &rtRect;
206 } else {
207 clippedRect = *rect;
208 if (!clippedRect.intersect(rtRect)) {
209 return;
210 }
211 rect = &clippedRect;
212 }
213
214 if (fContext->caps()->useDrawInsteadOfClear()) {
215 // This works around a driver bug with clear by drawing a rect instead.
216 // The driver will ignore a clear if it is the only thing rendered to a
217 // target before the target is read.
218 if (rect == &rtRect) {
219 this->discard();
220 }
221
222 GrPaint paint;
223 paint.setColor4f(GrColor4f::FromGrColor(color));
224 paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode));
225
226 this->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::Make(*rect));
227 } else {
228 sk_sp<GrBatch> batch = GrClearBatch::Make(*rect, color, this->accessRenderTarget());
229 this->getDrawTarget()->addBatch(std::move(batch));
230 }
robertphillipsea461502015-05-26 11:38:03 -0700231}
232
233
robertphillips2e1e51f2015-10-15 08:01:48 -0700234void GrDrawContext::drawPaint(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700235 const GrPaint& origPaint,
236 const SkMatrix& viewMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800237 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700238 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700239 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800240 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPaint");
robertphillips2e1e51f2015-10-15 08:01:48 -0700241
robertphillipsea461502015-05-26 11:38:03 -0700242 // set rect to be big enough to fill the space, but not super-huge, so we
243 // don't overflow fixed-point implementations
244 SkRect r;
245 r.setLTRB(0, 0,
robertphillips2e1e51f2015-10-15 08:01:48 -0700246 SkIntToScalar(fRenderTarget->width()),
247 SkIntToScalar(fRenderTarget->height()));
robertphillipsea461502015-05-26 11:38:03 -0700248 SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
249
250 // by definition this fills the entire clip, no need for AA
251 if (paint->isAntiAlias()) {
252 paint.writable()->setAntiAlias(false);
253 }
254
255 bool isPerspective = viewMatrix.hasPerspective();
256
257 // We attempt to map r by the inverse matrix and draw that. mapRect will
258 // map the four corners and bound them with a new rect. This will not
259 // produce a correct result for some perspective matrices.
260 if (!isPerspective) {
261 SkMatrix inverse;
262 if (!viewMatrix.invert(&inverse)) {
263 SkDebugf("Could not invert matrix\n");
264 return;
265 }
266 inverse.mapRect(&r);
robertphillips2e1e51f2015-10-15 08:01:48 -0700267 this->drawRect(clip, *paint, viewMatrix, r);
robertphillipsea461502015-05-26 11:38:03 -0700268 } else {
269 SkMatrix localMatrix;
270 if (!viewMatrix.invert(&localMatrix)) {
271 SkDebugf("Could not invert matrix\n");
272 return;
273 }
274
robertphillips77a2e522015-10-17 07:43:27 -0700275 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700276
robertphillips44302392016-07-08 14:43:03 -0700277 this->drawNonAAFilledRect(clip, *paint, SkMatrix::I(), r, nullptr, &localMatrix, nullptr);
robertphillipsea461502015-05-26 11:38:03 -0700278 }
279}
280
robertphillipsea461502015-05-26 11:38:03 -0700281static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
282 return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
283 point.fY >= rect.fTop && point.fY <= rect.fBottom;
284}
285
bsalomonc55271f2015-11-09 11:55:57 -0800286static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
287 return viewMatrix.preservesRightAngles();
288}
289
csmartdaltonecbc12b2016-06-08 10:08:43 -0700290static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt,
291 bool* useHWAA = nullptr) {
292 if (!paint.isAntiAlias()) {
293 if (useHWAA) {
294 *useHWAA = false;
295 }
296 return false;
297 } else {
298 if (useHWAA) {
299 *useHWAA = rt->isUnifiedMultisampled();
300 }
301 return !rt->isUnifiedMultisampled();
302 }
bsalomonc55271f2015-11-09 11:55:57 -0800303}
304
robertphillips44302392016-07-08 14:43:03 -0700305bool GrDrawContext::drawFilledRect(const GrClip& clip,
306 const GrPaint& paint,
307 const SkMatrix& viewMatrix,
308 const SkRect& rect,
309 const GrUserStencilSettings* ss) {
310
311 SkAutoTUnref<GrDrawBatch> batch;
312 bool useHWAA;
313
csmartdaltona7f29642016-07-07 08:49:11 -0700314 if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
msarettba3880f2016-07-12 18:48:21 -0700315 batch.reset(ir->recordRect(rect, viewMatrix, paint.getColor(),
robertphillips44302392016-07-08 14:43:03 -0700316 paint.isAntiAlias(), fInstancedPipelineInfo,
317 &useHWAA));
318 if (batch) {
319 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
320 if (ss) {
321 pipelineBuilder.setUserStencil(ss);
322 }
323 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
324 return true;
csmartdaltona7f29642016-07-07 08:49:11 -0700325 }
326 }
robertphillips391395d2016-03-02 09:26:36 -0800327
robertphillips44302392016-07-08 14:43:03 -0700328 if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
robertphillips391395d2016-03-02 09:26:36 -0800329 // The fill path can handle rotation but not skew.
330 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
331 SkRect devBoundRect;
msarettba3880f2016-07-12 18:48:21 -0700332 viewMatrix.mapRect(&devBoundRect, rect);
robertphillips44302392016-07-08 14:43:03 -0700333
334 batch.reset(GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix,
msarettba3880f2016-07-12 18:48:21 -0700335 rect, devBoundRect));
robertphillips44302392016-07-08 14:43:03 -0700336 if (batch) {
337 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
338 if (ss) {
339 pipelineBuilder.setUserStencil(ss);
340 }
341 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
342 return true;
343 }
robertphillips391395d2016-03-02 09:26:36 -0800344 }
345 } else {
msarettba3880f2016-07-12 18:48:21 -0700346 this->drawNonAAFilledRect(clip, paint, viewMatrix, rect, nullptr, nullptr, ss);
robertphillips44302392016-07-08 14:43:03 -0700347 return true;
robertphillips391395d2016-03-02 09:26:36 -0800348 }
349
robertphillips44302392016-07-08 14:43:03 -0700350 return false;
robertphillips391395d2016-03-02 09:26:36 -0800351}
352
robertphillips2e1e51f2015-10-15 08:01:48 -0700353void GrDrawContext::drawRect(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700354 const GrPaint& paint,
355 const SkMatrix& viewMatrix,
356 const SkRect& rect,
bsalomon6663acf2016-05-10 09:14:17 -0700357 const GrStyle* style) {
358 if (!style) {
359 style = &GrStyle::SimpleFill();
360 }
joshualitt1de610a2016-01-06 08:26:09 -0800361 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700362 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700363 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800364 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect");
robertphillips2e1e51f2015-10-15 08:01:48 -0700365
bsalomon6663acf2016-05-10 09:14:17 -0700366 // Path effects should've been devolved to a path in SkGpuDevice
367 SkASSERT(!style->pathEffect());
robertphillipsea461502015-05-26 11:38:03 -0700368
robertphillips77a2e522015-10-17 07:43:27 -0700369 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700370
bsalomon6663acf2016-05-10 09:14:17 -0700371 const SkStrokeRec& stroke = style->strokeRec();
robertphillips3ab14ca2016-07-10 11:49:39 -0700372 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
373
374 if (!fContext->caps()->useDrawInsteadOfClear()) {
375 // Check if this is a full RT draw and can be replaced with a clear. We don't bother
376 // checking cases where the RT is fully inside a stroke.
377 SkRect rtRect;
378 fRenderTarget->getBoundsRect(&rtRect);
379 // Does the clip contain the entire RT?
380 if (clip.quickContains(rtRect)) {
381 SkMatrix invM;
382 if (!viewMatrix.invert(&invM)) {
robertphillipsea461502015-05-26 11:38:03 -0700383 return;
384 }
robertphillips3ab14ca2016-07-10 11:49:39 -0700385 // Does the rect bound the RT?
386 SkPoint srcSpaceRTQuad[4];
387 invM.mapRectToQuad(srcSpaceRTQuad, rtRect);
388 if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) &&
389 rect_contains_inclusive(rect, srcSpaceRTQuad[1]) &&
390 rect_contains_inclusive(rect, srcSpaceRTQuad[2]) &&
391 rect_contains_inclusive(rect, srcSpaceRTQuad[3])) {
392 // Will it blend?
393 GrColor clearColor;
394 if (paint.isConstantBlendedColor(&clearColor)) {
robertphillips9199a9f2016-07-13 07:48:43 -0700395 this->clear(nullptr, clearColor, true);
robertphillips3ab14ca2016-07-10 11:49:39 -0700396 return;
397 }
398 }
robertphillipsea461502015-05-26 11:38:03 -0700399 }
400 }
robertphillips44302392016-07-08 14:43:03 -0700401
402 if (this->drawFilledRect(clip, paint, viewMatrix, rect, nullptr)) {
403 return;
404 }
bsalomona7d85ba2016-07-06 11:54:59 -0700405 } else if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
406 stroke.getStyle() == SkStrokeRec::kHairline_Style) {
407 if ((!rect.width() || !rect.height()) &&
408 SkStrokeRec::kHairline_Style != stroke.getStyle()) {
409 SkScalar r = stroke.getWidth() / 2;
410 // TODO: Move these stroke->fill fallbacks to GrShape?
411 switch (stroke.getJoin()) {
412 case SkPaint::kMiter_Join:
413 this->drawRect(clip, paint, viewMatrix,
414 {rect.fLeft - r, rect.fTop - r,
415 rect.fRight + r, rect.fBottom + r},
416 &GrStyle::SimpleFill());
417 return;
418 case SkPaint::kRound_Join:
419 // Raster draws nothing when both dimensions are empty.
420 if (rect.width() || rect.height()){
421 SkRRect rrect = SkRRect::MakeRectXY(rect.makeOutset(r, r), r, r);
422 this->drawRRect(clip, paint, viewMatrix, rrect, GrStyle::SimpleFill());
423 return;
424 }
425 case SkPaint::kBevel_Join:
426 if (!rect.width()) {
427 this->drawRect(clip, paint, viewMatrix,
428 {rect.fLeft - r, rect.fTop, rect.fRight + r, rect.fBottom},
429 &GrStyle::SimpleFill());
430 } else {
431 this->drawRect(clip, paint, viewMatrix,
432 {rect.fLeft, rect.fTop - r, rect.fRight, rect.fBottom + r},
433 &GrStyle::SimpleFill());
434 }
435 return;
436 }
437 }
robertphillips44302392016-07-08 14:43:03 -0700438
439 bool useHWAA;
440 bool snapToPixelCenters = false;
441 SkAutoTUnref<GrDrawBatch> batch;
442
robertphillips391395d2016-03-02 09:26:36 -0800443 GrColor color = paint.getColor();
csmartdaltonecbc12b2016-06-08 10:08:43 -0700444 if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
cdaltonbb539482016-01-04 09:48:25 -0800445 // The stroke path needs the rect to remain axis aligned (no rotation or skew).
446 if (viewMatrix.rectStaysRect()) {
bsalomona7d85ba2016-07-06 11:54:59 -0700447 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, stroke));
cdaltonbb539482016-01-04 09:48:25 -0800448 }
robertphillipsea461502015-05-26 11:38:03 -0700449 } else {
robertphillips391395d2016-03-02 09:26:36 -0800450 // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
halcanary9d524f22016-03-29 09:03:52 -0700451 // hairline rects. We jam all the vertices to pixel centers to avoid this, but not
robertphillips391395d2016-03-02 09:26:36 -0800452 // when MSAA is enabled because it can cause ugly artifacts.
bsalomona7d85ba2016-07-06 11:54:59 -0700453 snapToPixelCenters = stroke.getStyle() == SkStrokeRec::kHairline_Style &&
454 !fRenderTarget->isUnifiedMultisampled();
455 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect,
456 stroke, snapToPixelCenters));
robertphillips391395d2016-03-02 09:26:36 -0800457 }
robertphillips4bc31812016-03-01 12:22:49 -0800458
robertphillips44302392016-07-08 14:43:03 -0700459 if (batch) {
460 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
robertphillips4bc31812016-03-01 12:22:49 -0800461
robertphillips44302392016-07-08 14:43:03 -0700462 if (snapToPixelCenters) {
463 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
464 snapToPixelCenters);
465 }
466
467 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
468 return;
robertphillips4bc31812016-03-01 12:22:49 -0800469 }
robertphillips4bc31812016-03-01 12:22:49 -0800470 }
halcanary9d524f22016-03-29 09:03:52 -0700471
robertphillips4bc31812016-03-01 12:22:49 -0800472 SkPath path;
473 path.setIsVolatile(true);
474 path.addRect(rect);
bsalomon6663acf2016-05-10 09:14:17 -0700475 this->internalDrawPath(clip, paint, viewMatrix, path, *style);
robertphillipsea461502015-05-26 11:38:03 -0700476}
477
robertphillips976f5f02016-06-03 10:59:20 -0700478void GrDrawContextPriv::clearStencilClip(const SkIRect& rect, bool insideClip) {
479 ASSERT_SINGLE_OWNER_PRIV
480 RETURN_IF_ABANDONED_PRIV
481 SkDEBUGCODE(fDrawContext->validate();)
482 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContextPriv::clearStencilClip");
483
484 AutoCheckFlush acf(fDrawContext->fDrawingManager);
485 fDrawContext->getDrawTarget()->clearStencilClip(rect, insideClip,
486 fDrawContext->accessRenderTarget());
487}
488
robertphillips59cf61a2016-07-13 09:18:21 -0700489void GrDrawContextPriv::stencilPath(const GrClip& clip,
490 const GrUserStencilSettings* ss,
491 bool useHWAA,
robertphillips976f5f02016-06-03 10:59:20 -0700492 const SkMatrix& viewMatrix,
robertphillips59cf61a2016-07-13 09:18:21 -0700493 const GrPath* path) {
494 fDrawContext->getDrawTarget()->stencilPath(fDrawContext, clip, ss, useHWAA, viewMatrix, path);
robertphillips976f5f02016-06-03 10:59:20 -0700495}
496
497void GrDrawContextPriv::stencilRect(const GrFixedClip& clip,
498 const GrUserStencilSettings* ss,
csmartdalton656dbe42016-06-10 12:32:57 -0700499 bool useHWAA,
robertphillips976f5f02016-06-03 10:59:20 -0700500 const SkMatrix& viewMatrix,
501 const SkRect& rect) {
502 ASSERT_SINGLE_OWNER_PRIV
503 RETURN_IF_ABANDONED_PRIV
504 SkDEBUGCODE(fDrawContext->validate();)
505 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::stencilRect");
506
507 AutoCheckFlush acf(fDrawContext->fDrawingManager);
508
509 GrPaint paint;
csmartdalton656dbe42016-06-10 12:32:57 -0700510 paint.setAntiAlias(useHWAA);
bungeman06ca8ec2016-06-09 08:01:03 -0700511 paint.setXPFactory(GrDisableColorXPFactory::Make());
robertphillips976f5f02016-06-03 10:59:20 -0700512
csmartdalton656dbe42016-06-10 12:32:57 -0700513 SkASSERT(!useHWAA || fDrawContext->isStencilBufferMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700514
robertphillips44302392016-07-08 14:43:03 -0700515 fDrawContext->drawFilledRect(clip, paint, viewMatrix, rect, ss);
robertphillips976f5f02016-06-03 10:59:20 -0700516}
517
cdalton846c0512016-05-13 10:25:00 -0700518bool GrDrawContextPriv::drawAndStencilRect(const GrFixedClip& clip,
cdalton93a379b2016-05-11 13:58:08 -0700519 const GrUserStencilSettings* ss,
robertphillips391395d2016-03-02 09:26:36 -0800520 SkRegion::Op op,
521 bool invert,
522 bool doAA,
523 const SkMatrix& viewMatrix,
524 const SkRect& rect) {
525 ASSERT_SINGLE_OWNER_PRIV
526 RETURN_FALSE_IF_ABANDONED_PRIV
527 SkDEBUGCODE(fDrawContext->validate();)
robertphillips55fdccc2016-06-06 06:16:20 -0700528 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::drawAndStencilRect");
robertphillips391395d2016-03-02 09:26:36 -0800529
530 AutoCheckFlush acf(fDrawContext->fDrawingManager);
531
532 GrPaint paint;
533 paint.setAntiAlias(doAA);
534 paint.setCoverageSetOpXPFactory(op, invert);
535
robertphillips44302392016-07-08 14:43:03 -0700536 if (fDrawContext->drawFilledRect(clip, paint, viewMatrix, rect, ss)) {
robertphillips391395d2016-03-02 09:26:36 -0800537 return true;
538 }
539
540 SkPath path;
541 path.setIsVolatile(true);
542 path.addRect(rect);
cdalton862cff32016-05-12 15:09:48 -0700543 return this->drawAndStencilPath(clip, ss, op, invert, doAA, viewMatrix, path);
robertphillips391395d2016-03-02 09:26:36 -0800544}
545
bsalomona2e69fc2015-11-05 10:41:43 -0800546void GrDrawContext::fillRectToRect(const GrClip& clip,
547 const GrPaint& paint,
548 const SkMatrix& viewMatrix,
549 const SkRect& rectToDraw,
550 const SkRect& localRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800551 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700552 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700553 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800554 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect");
robertphillipsea461502015-05-26 11:38:03 -0700555
robertphillips77a2e522015-10-17 07:43:27 -0700556 AutoCheckFlush acf(fDrawingManager);
ksakamotoec7f2ac2016-07-05 03:54:53 -0700557 SkAutoTUnref<GrDrawBatch> batch;
csmartdaltona7f29642016-07-07 08:49:11 -0700558 bool useHWAA;
559
560 if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
msarettba3880f2016-07-12 18:48:21 -0700561 batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localRect,
csmartdaltona7f29642016-07-07 08:49:11 -0700562 paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA));
563 if (batch) {
564 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
565 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
566 return;
567 }
568 }
569
csmartdaltonecbc12b2016-06-08 10:08:43 -0700570 if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) &&
bsalomonc55271f2015-11-09 11:55:57 -0800571 view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
msarettba3880f2016-07-12 18:48:21 -0700572 batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix, rectToDraw,
573 localRect));
robertphillips44302392016-07-08 14:43:03 -0700574 if (batch) {
575 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
576 this->drawBatch(pipelineBuilder, clip, batch);
577 return;
578 }
bsalomonc55271f2015-11-09 11:55:57 -0800579 } else {
msarettba3880f2016-07-12 18:48:21 -0700580 this->drawNonAAFilledRect(clip, paint, viewMatrix, rectToDraw, &localRect,
robertphillips44302392016-07-08 14:43:03 -0700581 nullptr, nullptr);
joshualitt04194f32016-01-13 10:08:27 -0800582 }
583
joshualittb6b513b2015-08-21 10:25:18 -0700584}
585
bsalomona2e69fc2015-11-05 10:41:43 -0800586void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip,
587 const GrPaint& paint,
588 const SkMatrix& viewMatrix,
589 const SkRect& rectToDraw,
590 const SkMatrix& localMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800591 ASSERT_SINGLE_OWNER
joshualittb6b513b2015-08-21 10:25:18 -0700592 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700593 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800594 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatrix");
joshualittb6b513b2015-08-21 10:25:18 -0700595
robertphillips77a2e522015-10-17 07:43:27 -0700596 AutoCheckFlush acf(fDrawingManager);
ksakamotoec7f2ac2016-07-05 03:54:53 -0700597 SkAutoTUnref<GrDrawBatch> batch;
csmartdaltona7f29642016-07-07 08:49:11 -0700598 bool useHWAA;
599
600 if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
msarettba3880f2016-07-12 18:48:21 -0700601 batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localMatrix,
csmartdaltona7f29642016-07-07 08:49:11 -0700602 paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA));
603 if (batch) {
604 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
605 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
606 return;
607 }
608 }
609
csmartdaltonecbc12b2016-06-08 10:08:43 -0700610 if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) &&
bsalomonc55271f2015-11-09 11:55:57 -0800611 view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
joshualitt04194f32016-01-13 10:08:27 -0800612 batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix,
msarettba3880f2016-07-12 18:48:21 -0700613 rectToDraw));
robertphillips44302392016-07-08 14:43:03 -0700614 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
615 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
bsalomonc55271f2015-11-09 11:55:57 -0800616 } else {
msarettba3880f2016-07-12 18:48:21 -0700617 this->drawNonAAFilledRect(clip, paint, viewMatrix, rectToDraw, nullptr,
robertphillips44302392016-07-08 14:43:03 -0700618 &localMatrix, nullptr);
bsalomonc55271f2015-11-09 11:55:57 -0800619 }
robertphillips4bc31812016-03-01 12:22:49 -0800620
robertphillipsea461502015-05-26 11:38:03 -0700621}
622
robertphillips2e1e51f2015-10-15 08:01:48 -0700623void GrDrawContext::drawVertices(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700624 const GrPaint& paint,
625 const SkMatrix& viewMatrix,
626 GrPrimitiveType primitiveType,
627 int vertexCount,
628 const SkPoint positions[],
629 const SkPoint texCoords[],
630 const GrColor colors[],
631 const uint16_t indices[],
632 int indexCount) {
joshualitt1de610a2016-01-06 08:26:09 -0800633 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700634 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700635 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800636 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawVertices");
robertphillipsea461502015-05-26 11:38:03 -0700637
robertphillips77a2e522015-10-17 07:43:27 -0700638 AutoCheckFlush acf(fDrawingManager);
robertphillips2e1e51f2015-10-15 08:01:48 -0700639
robertphillipsea461502015-05-26 11:38:03 -0700640 // TODO clients should give us bounds
641 SkRect bounds;
642 if (!bounds.setBoundsCheck(positions, vertexCount)) {
643 SkDebugf("drawVertices call empty bounds\n");
644 return;
645 }
646
647 viewMatrix.mapRect(&bounds);
648
649 // If we don't have AA then we outset for a half pixel in each direction to account for
bsalomondb4758c2015-11-23 11:14:20 -0800650 // snapping. We also do this for the "hair" primitive types: lines and points since they have
651 // a 1 pixel thickness in device space.
652 if (!paint.isAntiAlias() || GrIsPrimTypeLines(primitiveType) ||
653 kPoints_GrPrimitiveType == primitiveType) {
robertphillipsea461502015-05-26 11:38:03 -0700654 bounds.outset(0.5f, 0.5f);
655 }
656
bsalomond92b4192016-06-30 07:59:23 -0700657 SkAutoTUnref<GrDrawBatch> batch(new GrDrawVerticesBatch(paint.getColor(),
658 primitiveType, viewMatrix, positions,
659 vertexCount, indices, indexCount,
660 colors, texCoords, bounds));
robertphillipsea461502015-05-26 11:38:03 -0700661
csmartdaltonecbc12b2016-06-08 10:08:43 -0700662 GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
robertphillips976f5f02016-06-03 10:59:20 -0700663 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsea461502015-05-26 11:38:03 -0700664}
665
666///////////////////////////////////////////////////////////////////////////////
667
robertphillips2e1e51f2015-10-15 08:01:48 -0700668void GrDrawContext::drawAtlas(const GrClip& clip,
jvanverth31ff7622015-08-07 10:09:28 -0700669 const GrPaint& paint,
670 const SkMatrix& viewMatrix,
671 int spriteCount,
672 const SkRSXform xform[],
673 const SkRect texRect[],
674 const SkColor colors[]) {
joshualitt1de610a2016-01-06 08:26:09 -0800675 ASSERT_SINGLE_OWNER
jvanverth31ff7622015-08-07 10:09:28 -0700676 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700677 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800678 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawAtlas");
robertphillips2e1e51f2015-10-15 08:01:48 -0700679
robertphillips77a2e522015-10-17 07:43:27 -0700680 AutoCheckFlush acf(fDrawingManager);
halcanary9d524f22016-03-29 09:03:52 -0700681
bsalomon0432dd62016-06-30 07:19:27 -0700682 SkAutoTUnref<GrDrawBatch> batch(new GrDrawAtlasBatch(paint.getColor(), viewMatrix, spriteCount,
683 xform, texRect, colors));
halcanary9d524f22016-03-29 09:03:52 -0700684
csmartdaltonecbc12b2016-06-08 10:08:43 -0700685 GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
robertphillips976f5f02016-06-03 10:59:20 -0700686 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
jvanverth31ff7622015-08-07 10:09:28 -0700687}
688
689///////////////////////////////////////////////////////////////////////////////
690
robertphillips2e1e51f2015-10-15 08:01:48 -0700691void GrDrawContext::drawRRect(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700692 const GrPaint& paint,
693 const SkMatrix& viewMatrix,
694 const SkRRect& rrect,
bsalomon6663acf2016-05-10 09:14:17 -0700695 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800696 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700697 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700698 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800699 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect");
robertphillips2e1e51f2015-10-15 08:01:48 -0700700
robertphillipsea461502015-05-26 11:38:03 -0700701 if (rrect.isEmpty()) {
702 return;
703 }
704
bsalomon6663acf2016-05-10 09:14:17 -0700705 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
ksakamotoec7f2ac2016-07-05 03:54:53 -0700706
csmartdaltona7f29642016-07-07 08:49:11 -0700707 AutoCheckFlush acf(fDrawingManager);
708 const SkStrokeRec stroke = style.strokeRec();
csmartdaltonecbc12b2016-06-08 10:08:43 -0700709 bool useHWAA;
csmartdaltona7f29642016-07-07 08:49:11 -0700710
711 if (this->getDrawTarget()->instancedRendering() && stroke.isFillStyle()) {
712 InstancedRendering* ir = this->getDrawTarget()->instancedRendering();
713 SkAutoTUnref<GrDrawBatch> batch(ir->recordRRect(rrect, viewMatrix, paint.getColor(),
714 paint.isAntiAlias(), fInstancedPipelineInfo,
715 &useHWAA));
716 if (batch) {
717 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
718 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
719 return;
720 }
721 }
722
csmartdaltonecbc12b2016-06-08 10:08:43 -0700723 if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
robertphillipsb56f9272016-02-25 11:03:52 -0800724 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
robertphillips4bc31812016-03-01 12:22:49 -0800725 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.getColor(),
robertphillipsb56f9272016-02-25 11:03:52 -0800726 viewMatrix,
727 rrect,
bsalomon6663acf2016-05-10 09:14:17 -0700728 stroke,
robertphillipsb56f9272016-02-25 11:03:52 -0800729 shaderCaps));
730 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -0700731 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
robertphillips976f5f02016-06-03 10:59:20 -0700732 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsb56f9272016-02-25 11:03:52 -0800733 return;
734 }
robertphillipsea461502015-05-26 11:38:03 -0700735 }
robertphillipsb56f9272016-02-25 11:03:52 -0800736
737 SkPath path;
738 path.setIsVolatile(true);
739 path.addRRect(rrect);
bsalomon6663acf2016-05-10 09:14:17 -0700740 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -0700741}
742
robertphillips00095892016-02-29 13:50:40 -0800743bool GrDrawContext::drawFilledDRRect(const GrClip& clip,
744 const GrPaint& paintIn,
745 const SkMatrix& viewMatrix,
746 const SkRRect& origOuter,
747 const SkRRect& origInner) {
748 SkASSERT(!origInner.isEmpty());
749 SkASSERT(!origOuter.isEmpty());
750
csmartdaltona7f29642016-07-07 08:49:11 -0700751 if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
752 bool useHWAA;
753 SkAutoTUnref<GrDrawBatch> batch(ir->recordDRRect(origOuter, origInner, viewMatrix,
754 paintIn.getColor(), paintIn.isAntiAlias(),
755 fInstancedPipelineInfo, &useHWAA));
756 if (batch) {
757 GrPipelineBuilder pipelineBuilder(paintIn, useHWAA);
758 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
759 return true;
760 }
761 }
762
robertphillips00095892016-02-29 13:50:40 -0800763 bool applyAA = paintIn.isAntiAlias() && !fRenderTarget->isUnifiedMultisampled();
764
765 GrPrimitiveEdgeType innerEdgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType :
766 kInverseFillBW_GrProcessorEdgeType;
767 GrPrimitiveEdgeType outerEdgeType = applyAA ? kFillAA_GrProcessorEdgeType :
768 kFillBW_GrProcessorEdgeType;
769
770 SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
771 SkMatrix inverseVM;
772 if (!viewMatrix.isIdentity()) {
773 if (!origInner.transform(viewMatrix, inner.writable())) {
774 return false;
775 }
776 if (!origOuter.transform(viewMatrix, outer.writable())) {
777 return false;
778 }
779 if (!viewMatrix.invert(&inverseVM)) {
780 return false;
781 }
782 } else {
783 inverseVM.reset();
halcanary9d524f22016-03-29 09:03:52 -0700784 }
robertphillips00095892016-02-29 13:50:40 -0800785
786 GrPaint grPaint(paintIn);
787 grPaint.setAntiAlias(false);
788
789 // TODO these need to be a geometry processors
bungeman06ca8ec2016-06-09 08:01:03 -0700790 sk_sp<GrFragmentProcessor> innerEffect(GrRRectEffect::Make(innerEdgeType, *inner));
robertphillips00095892016-02-29 13:50:40 -0800791 if (!innerEffect) {
792 return false;
793 }
794
bungeman06ca8ec2016-06-09 08:01:03 -0700795 sk_sp<GrFragmentProcessor> outerEffect(GrRRectEffect::Make(outerEdgeType, *outer));
robertphillips00095892016-02-29 13:50:40 -0800796 if (!outerEffect) {
797 return false;
798 }
799
bungeman06ca8ec2016-06-09 08:01:03 -0700800 grPaint.addCoverageFragmentProcessor(std::move(innerEffect));
801 grPaint.addCoverageFragmentProcessor(std::move(outerEffect));
robertphillips00095892016-02-29 13:50:40 -0800802
803 SkRect bounds = outer->getBounds();
804 if (applyAA) {
805 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
806 }
halcanary9d524f22016-03-29 09:03:52 -0700807
robertphillips00095892016-02-29 13:50:40 -0800808 this->fillRectWithLocalMatrix(clip, grPaint, SkMatrix::I(), bounds, inverseVM);
809 return true;
810}
811
812void GrDrawContext::drawDRRect(const GrClip& clip,
813 const GrPaint& paint,
814 const SkMatrix& viewMatrix,
815 const SkRRect& outer,
816 const SkRRect& inner) {
817 ASSERT_SINGLE_OWNER
818 RETURN_IF_ABANDONED
819 SkDEBUGCODE(this->validate();)
820 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawDRRect");
821
822 SkASSERT(!outer.isEmpty());
823 SkASSERT(!inner.isEmpty());
824
825 AutoCheckFlush acf(fDrawingManager);
826
827 if (this->drawFilledDRRect(clip, paint, viewMatrix, outer, inner)) {
828 return;
829 }
830
831 SkPath path;
832 path.setIsVolatile(true);
833 path.addRRect(inner);
834 path.addRRect(outer);
835 path.setFillType(SkPath::kEvenOdd_FillType);
836
bsalomon6663acf2016-05-10 09:14:17 -0700837 this->internalDrawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
robertphillips00095892016-02-29 13:50:40 -0800838}
839
robertphillipsea461502015-05-26 11:38:03 -0700840///////////////////////////////////////////////////////////////////////////////
841
robertphillips2e1e51f2015-10-15 08:01:48 -0700842void GrDrawContext::drawOval(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700843 const GrPaint& paint,
844 const SkMatrix& viewMatrix,
845 const SkRect& oval,
bsalomon6663acf2016-05-10 09:14:17 -0700846 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800847 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700848 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700849 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800850 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval");
robertphillips2e1e51f2015-10-15 08:01:48 -0700851
robertphillipsea461502015-05-26 11:38:03 -0700852 if (oval.isEmpty()) {
853 return;
854 }
855
bsalomon6663acf2016-05-10 09:14:17 -0700856 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
robertphillipsea461502015-05-26 11:38:03 -0700857
robertphillips77a2e522015-10-17 07:43:27 -0700858 AutoCheckFlush acf(fDrawingManager);
bsalomon6663acf2016-05-10 09:14:17 -0700859 const SkStrokeRec& stroke = style.strokeRec();
csmartdaltonecbc12b2016-06-08 10:08:43 -0700860 bool useHWAA;
csmartdaltona7f29642016-07-07 08:49:11 -0700861
862 if (this->getDrawTarget()->instancedRendering() && stroke.isFillStyle()) {
863 InstancedRendering* ir = this->getDrawTarget()->instancedRendering();
864 SkAutoTUnref<GrDrawBatch> batch(ir->recordOval(oval, viewMatrix, paint.getColor(),
865 paint.isAntiAlias(), fInstancedPipelineInfo,
866 &useHWAA));
867 if (batch) {
868 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
869 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
870 return;
871 }
872 }
873
csmartdaltonecbc12b2016-06-08 10:08:43 -0700874 if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
robertphillipsb56f9272016-02-25 11:03:52 -0800875 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
robertphillips4bc31812016-03-01 12:22:49 -0800876 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
robertphillipsb56f9272016-02-25 11:03:52 -0800877 viewMatrix,
878 oval,
bsalomon6663acf2016-05-10 09:14:17 -0700879 stroke,
robertphillipsb56f9272016-02-25 11:03:52 -0800880 shaderCaps));
881 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -0700882 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
robertphillips976f5f02016-06-03 10:59:20 -0700883 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsb56f9272016-02-25 11:03:52 -0800884 return;
885 }
robertphillipsea461502015-05-26 11:38:03 -0700886 }
robertphillipsb56f9272016-02-25 11:03:52 -0800887
888 SkPath path;
889 path.setIsVolatile(true);
890 path.addOval(oval);
bsalomon6663acf2016-05-10 09:14:17 -0700891 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -0700892}
893
joshualitt33a5fce2015-11-18 13:28:51 -0800894void GrDrawContext::drawImageNine(const GrClip& clip,
895 const GrPaint& paint,
896 const SkMatrix& viewMatrix,
897 int imageWidth,
898 int imageHeight,
899 const SkIRect& center,
900 const SkRect& dst) {
joshualitt1de610a2016-01-06 08:26:09 -0800901 ASSERT_SINGLE_OWNER
joshualitt33a5fce2015-11-18 13:28:51 -0800902 RETURN_IF_ABANDONED
903 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800904 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawImageNine");
joshualitt33a5fce2015-11-18 13:28:51 -0800905
906 AutoCheckFlush acf(fDrawingManager);
907
908 SkAutoTUnref<GrDrawBatch> batch(GrNinePatch::CreateNonAA(paint.getColor(), viewMatrix,
909 imageWidth, imageHeight,
910 center, dst));
911
csmartdaltonecbc12b2016-06-08 10:08:43 -0700912 GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
robertphillips976f5f02016-06-03 10:59:20 -0700913 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
joshualitt33a5fce2015-11-18 13:28:51 -0800914}
915
916
robertphillips44302392016-07-08 14:43:03 -0700917void GrDrawContext::drawNonAAFilledRect(const GrClip& clip,
918 const GrPaint& paint,
919 const SkMatrix& viewMatrix,
920 const SkRect& rect,
921 const SkRect* localRect,
922 const SkMatrix* localMatrix,
923 const GrUserStencilSettings* ss) {
924 SkAutoTUnref<GrDrawBatch> batch(
925 GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect, localRect,
926 localMatrix));
927 GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
928 if (ss) {
929 pipelineBuilder.setUserStencil(ss);
930 }
931 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
932}
933
robertphillipsea461502015-05-26 11:38:03 -0700934// Can 'path' be drawn as a pair of filled nested rectangles?
bsalomon6663acf2016-05-10 09:14:17 -0700935static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path, SkRect rects[2]) {
robertphillipsea461502015-05-26 11:38:03 -0700936
937 if (path.isInverseFillType()) {
938 return false;
939 }
940
941 // TODO: this restriction could be lifted if we were willing to apply
942 // the matrix to all the points individually rather than just to the rect
robertphillips0e7029e2015-11-30 05:45:06 -0800943 if (!viewMatrix.rectStaysRect()) {
robertphillipsea461502015-05-26 11:38:03 -0700944 return false;
945 }
946
947 SkPath::Direction dirs[2];
948 if (!path.isNestedFillRects(rects, dirs)) {
949 return false;
950 }
951
952 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) {
953 // The two rects need to be wound opposite to each other
954 return false;
955 }
956
957 // Right now, nested rects where the margin is not the same width
958 // all around do not render correctly
959 const SkScalar* outer = rects[0].asScalars();
960 const SkScalar* inner = rects[1].asScalars();
961
962 bool allEq = true;
963
964 SkScalar margin = SkScalarAbs(outer[0] - inner[0]);
965 bool allGoE1 = margin >= SK_Scalar1;
966
967 for (int i = 1; i < 4; ++i) {
968 SkScalar temp = SkScalarAbs(outer[i] - inner[i]);
969 if (temp < SK_Scalar1) {
970 allGoE1 = false;
971 }
972 if (!SkScalarNearlyEqual(margin, temp)) {
973 allEq = false;
974 }
975 }
976
977 return allEq || allGoE1;
978}
979
robertphillips2e1e51f2015-10-15 08:01:48 -0700980void GrDrawContext::drawPath(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700981 const GrPaint& paint,
982 const SkMatrix& viewMatrix,
983 const SkPath& path,
bsalomon6663acf2016-05-10 09:14:17 -0700984 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800985 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700986 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700987 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800988 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath");
robertphillips2e1e51f2015-10-15 08:01:48 -0700989
robertphillipsea461502015-05-26 11:38:03 -0700990 if (path.isEmpty()) {
991 if (path.isInverseFillType()) {
robertphillips2e1e51f2015-10-15 08:01:48 -0700992 this->drawPaint(clip, paint, viewMatrix);
robertphillipsea461502015-05-26 11:38:03 -0700993 }
994 return;
995 }
996
robertphillips77a2e522015-10-17 07:43:27 -0700997 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700998
csmartdaltonecbc12b2016-06-08 10:08:43 -0700999 bool useHWAA;
1000 if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) && !style.pathEffect()) {
bsalomon6663acf2016-05-10 09:14:17 -07001001 if (style.isSimpleFill() && !path.isConvex()) {
robertphillipsea461502015-05-26 11:38:03 -07001002 // Concave AA paths are expensive - try to avoid them for special cases
1003 SkRect rects[2];
1004
bsalomon6663acf2016-05-10 09:14:17 -07001005 if (fills_as_nested_rects(viewMatrix, path, rects)) {
joshualittd2b23e02015-08-21 10:53:34 -07001006 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFillNestedRects(
robertphillips4bc31812016-03-01 12:22:49 -08001007 paint.getColor(), viewMatrix, rects));
bsalomon40ef4852016-05-02 13:22:13 -07001008 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -07001009 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
robertphillips976f5f02016-06-03 10:59:20 -07001010 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
bsalomon40ef4852016-05-02 13:22:13 -07001011 }
robertphillipsea461502015-05-26 11:38:03 -07001012 return;
1013 }
1014 }
1015 SkRect ovalRect;
1016 bool isOval = path.isOval(&ovalRect);
1017
1018 if (isOval && !path.isInverseFillType()) {
robertphillips0cc2f852016-02-24 13:36:56 -08001019 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
robertphillips4bc31812016-03-01 12:22:49 -08001020 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
robertphillips0cc2f852016-02-24 13:36:56 -08001021 viewMatrix,
robertphillips0cc2f852016-02-24 13:36:56 -08001022 ovalRect,
bsalomon6663acf2016-05-10 09:14:17 -07001023 style.strokeRec(),
robertphillips0cc2f852016-02-24 13:36:56 -08001024 shaderCaps));
1025 if (batch) {
csmartdaltonecbc12b2016-06-08 10:08:43 -07001026 GrPipelineBuilder pipelineBuilder(paint, useHWAA);
robertphillips976f5f02016-06-03 10:59:20 -07001027 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsea461502015-05-26 11:38:03 -07001028 return;
1029 }
1030 }
1031 }
robertphillips4bc31812016-03-01 12:22:49 -08001032
1033 // Note that internalDrawPath may sw-rasterize the path into a scratch texture.
1034 // Scratch textures can be recycled after they are returned to the texture
1035 // cache. This presents a potential hazard for buffered drawing. However,
1036 // the writePixels that uploads to the scratch will perform a flush so we're
1037 // OK.
bsalomon6663acf2016-05-10 09:14:17 -07001038 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -07001039}
1040
cdalton846c0512016-05-13 10:25:00 -07001041bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
cdalton93a379b2016-05-11 13:58:08 -07001042 const GrUserStencilSettings* ss,
robertphillips391395d2016-03-02 09:26:36 -08001043 SkRegion::Op op,
1044 bool invert,
1045 bool doAA,
1046 const SkMatrix& viewMatrix,
1047 const SkPath& path) {
1048 ASSERT_SINGLE_OWNER_PRIV
1049 RETURN_FALSE_IF_ABANDONED_PRIV
1050 SkDEBUGCODE(fDrawContext->validate();)
1051 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::drawPath");
1052
1053 if (path.isEmpty() && path.isInverseFillType()) {
cdalton862cff32016-05-12 15:09:48 -07001054 this->drawAndStencilRect(clip, ss, op, invert, false, SkMatrix::I(),
robertphillips6c7e3252016-04-27 10:47:51 -07001055 SkRect::MakeIWH(fDrawContext->width(),
1056 fDrawContext->height()));
robertphillips391395d2016-03-02 09:26:36 -08001057 return true;
1058 }
1059
1060 AutoCheckFlush acf(fDrawContext->fDrawingManager);
1061
1062 // An Assumption here is that path renderer would use some form of tweaking
1063 // the src color (either the input alpha or in the frag shader) to implement
1064 // aa. If we have some future driver-mojo path AA that can do the right
1065 // thing WRT to the blend then we'll need some query on the PR.
1066 bool useCoverageAA = doAA && !fDrawContext->fRenderTarget->isUnifiedMultisampled();
robertphillips976f5f02016-06-03 10:59:20 -07001067 bool hasUserStencilSettings = !ss->isUnused();
robertphillips391395d2016-03-02 09:26:36 -08001068 bool isStencilBufferMSAA = fDrawContext->fRenderTarget->isStencilBufferMultisampled();
1069
1070 const GrPathRendererChain::DrawType type =
1071 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
1072 : GrPathRendererChain::kColor_DrawType;
1073
bsalomon8acedde2016-06-24 10:42:16 -07001074 GrShape shape(path, GrStyle::SimpleFill());
robertphillips391395d2016-03-02 09:26:36 -08001075 GrPathRenderer::CanDrawPathArgs canDrawArgs;
1076 canDrawArgs.fShaderCaps = fDrawContext->fDrawingManager->getContext()->caps()->shaderCaps();
1077 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001078 canDrawArgs.fShape = &shape;
robertphillips391395d2016-03-02 09:26:36 -08001079 canDrawArgs.fAntiAlias = useCoverageAA;
cdalton93a379b2016-05-11 13:58:08 -07001080 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
robertphillips391395d2016-03-02 09:26:36 -08001081 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
1082
1083 // Don't allow the SW renderer
1084 GrPathRenderer* pr = fDrawContext->fDrawingManager->getPathRenderer(canDrawArgs, false, type);
1085 if (!pr) {
1086 return false;
1087 }
1088
1089 GrPaint paint;
1090 paint.setCoverageSetOpXPFactory(op, invert);
1091
robertphillips391395d2016-03-02 09:26:36 -08001092 GrPathRenderer::DrawPathArgs args;
robertphillips391395d2016-03-02 09:26:36 -08001093 args.fResourceProvider = fDrawContext->fDrawingManager->getContext()->resourceProvider();
robertphillips976f5f02016-06-03 10:59:20 -07001094 args.fPaint = &paint;
1095 args.fUserStencilSettings = ss;
1096 args.fDrawContext = fDrawContext;
cdalton862cff32016-05-12 15:09:48 -07001097 args.fClip = &clip;
robertphillips391395d2016-03-02 09:26:36 -08001098 args.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001099 args.fShape = &shape;
robertphillips391395d2016-03-02 09:26:36 -08001100 args.fAntiAlias = useCoverageAA;
brianosman0e3c5542016-04-13 13:56:21 -07001101 args.fGammaCorrect = fDrawContext->isGammaCorrect();
robertphillips391395d2016-03-02 09:26:36 -08001102 pr->drawPath(args);
1103 return true;
1104}
1105
robertphillips4bc31812016-03-01 12:22:49 -08001106void GrDrawContext::internalDrawPath(const GrClip& clip,
1107 const GrPaint& paint,
robertphillipsea461502015-05-26 11:38:03 -07001108 const SkMatrix& viewMatrix,
bsalomon8acedde2016-06-24 10:42:16 -07001109 const SkPath& path,
1110 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001111 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001112 RETURN_IF_ABANDONED
bsalomon8acedde2016-06-24 10:42:16 -07001113 SkASSERT(!path.isEmpty());
robertphillipsea461502015-05-26 11:38:03 -07001114
robertphillips6c7e3252016-04-27 10:47:51 -07001115 bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget.get());
cdalton93a379b2016-05-11 13:58:08 -07001116 constexpr bool kHasUserStencilSettings = false;
robertphillips4bc31812016-03-01 12:22:49 -08001117 bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled();
robertphillipsea461502015-05-26 11:38:03 -07001118
robertphillips68737822015-10-29 12:12:21 -07001119 const GrPathRendererChain::DrawType type =
1120 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
1121 : GrPathRendererChain::kColor_DrawType;
robertphillipsea461502015-05-26 11:38:03 -07001122
bsalomon8acedde2016-06-24 10:42:16 -07001123 GrShape shape(path, style);
bsalomon0a0f67e2016-06-28 11:56:42 -07001124 if (shape.isEmpty()) {
1125 return;
1126 }
robertphillips68737822015-10-29 12:12:21 -07001127 GrPathRenderer::CanDrawPathArgs canDrawArgs;
1128 canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
1129 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001130 canDrawArgs.fShape = &shape;
robertphillips68737822015-10-29 12:12:21 -07001131 canDrawArgs.fAntiAlias = useCoverageAA;
cdalton93a379b2016-05-11 13:58:08 -07001132 canDrawArgs.fHasUserStencilSettings = kHasUserStencilSettings;
robertphillips68737822015-10-29 12:12:21 -07001133 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
1134
bsalomon6663acf2016-05-10 09:14:17 -07001135 // Try a 1st time without applying any of the style to the geometry (and barring sw)
robertphillips68737822015-10-29 12:12:21 -07001136 GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
bsalomon6663acf2016-05-10 09:14:17 -07001137 SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
robertphillipsea461502015-05-26 11:38:03 -07001138
bsalomon8acedde2016-06-24 10:42:16 -07001139 if (!pr && shape.style().pathEffect()) {
bsalomon6663acf2016-05-10 09:14:17 -07001140 // It didn't work above, so try again with the path effect applied.
bsalomon8acedde2016-06-24 10:42:16 -07001141 shape = shape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
1142 if (shape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001143 return;
1144 }
robertphillips68737822015-10-29 12:12:21 -07001145 pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
robertphillipsea461502015-05-26 11:38:03 -07001146 }
bsalomon6663acf2016-05-10 09:14:17 -07001147 if (!pr) {
bsalomon8acedde2016-06-24 10:42:16 -07001148 if (shape.style().applies()) {
1149 shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale);
1150 if (shape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001151 return;
1152 }
bsalomon6663acf2016-05-10 09:14:17 -07001153 }
robertphillipsea461502015-05-26 11:38:03 -07001154 // This time, allow SW renderer
robertphillips68737822015-10-29 12:12:21 -07001155 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type);
robertphillipsea461502015-05-26 11:38:03 -07001156 }
1157
bsalomon8acedde2016-06-24 10:42:16 -07001158 if (!pr) {
robertphillipsea461502015-05-26 11:38:03 -07001159#ifdef SK_DEBUG
1160 SkDebugf("Unable to find path renderer compatible with path.\n");
1161#endif
1162 return;
1163 }
1164
bsalomon0aff2fa2015-07-31 06:48:27 -07001165 GrPathRenderer::DrawPathArgs args;
robertphillips77a2e522015-10-17 07:43:27 -07001166 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider();
robertphillips976f5f02016-06-03 10:59:20 -07001167 args.fPaint = &paint;
1168 args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
1169 args.fDrawContext = this;
cdalton862cff32016-05-12 15:09:48 -07001170 args.fClip = &clip;
bsalomon0aff2fa2015-07-31 06:48:27 -07001171 args.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001172 args.fShape = canDrawArgs.fShape;
bsalomon0aff2fa2015-07-31 06:48:27 -07001173 args.fAntiAlias = useCoverageAA;
brianosman0e3c5542016-04-13 13:56:21 -07001174 args.fGammaCorrect = this->isGammaCorrect();
bsalomon0aff2fa2015-07-31 06:48:27 -07001175 pr->drawPath(args);
robertphillipsea461502015-05-26 11:38:03 -07001176}
1177
robertphillips976f5f02016-06-03 10:59:20 -07001178void GrDrawContext::drawBatch(const GrPipelineBuilder& pipelineBuilder, const GrClip& clip,
cdalton862cff32016-05-12 15:09:48 -07001179 GrDrawBatch* batch) {
joshualitt1de610a2016-01-06 08:26:09 -08001180 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -07001181 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001182 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -08001183 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch");
robertphillips2d70dcb2015-10-06 07:38:23 -07001184
robertphillips976f5f02016-06-03 10:59:20 -07001185 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillips2334fb62015-06-17 05:43:33 -07001186}