blob: 263f0c8dddff3144fc0efa308b6759ec7b89b2f6 [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"
jvanverth14b88032015-08-07 12:18:54 -070021#include "batches/GrDrawAtlasBatch.h"
joshualitt2771b562015-08-07 12:46:26 -070022#include "batches/GrDrawVerticesBatch.h"
joshualitt7fc2a262015-08-10 10:30:14 -070023#include "batches/GrRectBatchFactory.h"
joshualitt33a5fce2015-11-18 13:28:51 -080024#include "batches/GrNinePatch.h" // TODO Factory
joshualitt74417822015-08-07 11:42:16 -070025
robertphillips00095892016-02-29 13:50:40 -080026#include "effects/GrRRectEffect.h"
27
joshualitte8042922015-12-11 06:11:21 -080028#include "text/GrAtlasTextContext.h"
29#include "text/GrStencilAndCoverTextContext.h"
30
joshualittbc907352016-01-13 06:45:40 -080031#include "../private/GrAuditTrail.h"
32
robertphillips77a2e522015-10-17 07:43:27 -070033#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fDrawingManager->getContext())
joshualitt1de610a2016-01-06 08:26:09 -080034#define ASSERT_SINGLE_OWNER \
joshualittde8dc7e2016-01-08 10:09:13 -080035 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
robertphillips391395d2016-03-02 09:26:36 -080036#define ASSERT_SINGLE_OWNER_PRIV \
37 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fDrawContext->fSingleOwner);)
robertphillips7761d612016-05-16 09:14:53 -070038#define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
robertphillips976f5f02016-06-03 10:59:20 -070039#define RETURN_IF_ABANDONED_PRIV if (fDrawContext->fDrawingManager->wasAbandoned()) { return; }
robertphillips7761d612016-05-16 09:14:53 -070040#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
41#define RETURN_FALSE_IF_ABANDONED_PRIV if (fDrawContext->fDrawingManager->wasAbandoned()) { return false; }
42#define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
robertphillipsea461502015-05-26 11:38:03 -070043
44class AutoCheckFlush {
45public:
halcanary9d524f22016-03-29 09:03:52 -070046 AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
robertphillips77a2e522015-10-17 07:43:27 -070047 SkASSERT(fDrawingManager);
48 }
49 ~AutoCheckFlush() { fDrawingManager->getContext()->flushIfNecessary(); }
robertphillipsea461502015-05-26 11:38:03 -070050
51private:
robertphillips77a2e522015-10-17 07:43:27 -070052 GrDrawingManager* fDrawingManager;
robertphillipsea461502015-05-26 11:38:03 -070053};
54
robertphillips7761d612016-05-16 09:14:53 -070055bool GrDrawContext::wasAbandoned() const {
56 return fDrawingManager->wasAbandoned();
57}
58
robertphillipsa106c622015-10-16 09:07:06 -070059// In MDB mode the reffing of the 'getLastDrawTarget' call's result allows in-progress
60// drawTargets to be picked up and added to by drawContexts lower in the call
61// stack. When this occurs with a closed drawTarget, a new one will be allocated
62// when the drawContext attempts to use it (via getDrawTarget).
joshualitt1b39f432016-02-11 06:46:52 -080063GrDrawContext::GrDrawContext(GrContext* context,
64 GrDrawingManager* drawingMgr,
robertphillips6c7e3252016-04-27 10:47:51 -070065 sk_sp<GrRenderTarget> rt,
joshualittde8dc7e2016-01-08 10:09:13 -080066 const SkSurfaceProps* surfaceProps,
joshualittbc907352016-01-13 06:45:40 -080067 GrAuditTrail* auditTrail,
joshualittde8dc7e2016-01-08 10:09:13 -080068 GrSingleOwner* singleOwner)
robertphillips77a2e522015-10-17 07:43:27 -070069 : fDrawingManager(drawingMgr)
robertphillips6c7e3252016-04-27 10:47:51 -070070 , fRenderTarget(std::move(rt))
71 , fDrawTarget(SkSafeRef(fRenderTarget->getLastDrawTarget()))
joshualitt1b39f432016-02-11 06:46:52 -080072 , fContext(context)
joshualittde8dc7e2016-01-08 10:09:13 -080073 , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
joshualittbc907352016-01-13 06:45:40 -080074 , fAuditTrail(auditTrail)
joshualitt6d0872d2016-01-11 08:27:48 -080075#ifdef SK_DEBUG
76 , fSingleOwner(singleOwner)
77#endif
78{
robertphillips2e1e51f2015-10-15 08:01:48 -070079 SkDEBUGCODE(this->validate();)
robertphillipsea461502015-05-26 11:38:03 -070080}
81
robertphillips2e1e51f2015-10-15 08:01:48 -070082#ifdef SK_DEBUG
83void GrDrawContext::validate() const {
84 SkASSERT(fRenderTarget);
85 ASSERT_OWNED_RESOURCE(fRenderTarget);
robertphillipsa106c622015-10-16 09:07:06 -070086
87 if (fDrawTarget && !fDrawTarget->isClosed()) {
88 SkASSERT(fRenderTarget->getLastDrawTarget() == fDrawTarget);
89 }
robertphillips2e1e51f2015-10-15 08:01:48 -070090}
91#endif
92
robertphillipsa106c622015-10-16 09:07:06 -070093GrDrawContext::~GrDrawContext() {
joshualitt1de610a2016-01-06 08:26:09 -080094 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -070095 SkSafeUnref(fDrawTarget);
96}
97
98GrDrawTarget* GrDrawContext::getDrawTarget() {
joshualitt1de610a2016-01-06 08:26:09 -080099 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -0700100 SkDEBUGCODE(this->validate();)
101
102 if (!fDrawTarget || fDrawTarget->isClosed()) {
robertphillips6c7e3252016-04-27 10:47:51 -0700103 fDrawTarget = fDrawingManager->newDrawTarget(fRenderTarget.get());
robertphillipsa106c622015-10-16 09:07:06 -0700104 }
105
106 return fDrawTarget;
107}
108
bsalomonb8fea972016-02-16 07:34:17 -0800109bool GrDrawContext::copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
joshualitt1de610a2016-01-06 08:26:09 -0800110 ASSERT_SINGLE_OWNER
bsalomonb8fea972016-02-16 07:34:17 -0800111 RETURN_FALSE_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700112 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800113 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::copySurface");
robertphillips2d70dcb2015-10-06 07:38:23 -0700114
robertphillips6c7e3252016-04-27 10:47:51 -0700115 return this->getDrawTarget()->copySurface(fRenderTarget.get(), src, srcRect, dstPoint);
robertphillipsea461502015-05-26 11:38:03 -0700116}
117
robertphillips2e1e51f2015-10-15 08:01:48 -0700118void GrDrawContext::drawText(const GrClip& clip, const GrPaint& grPaint,
robertphillips2334fb62015-06-17 05:43:33 -0700119 const SkPaint& skPaint,
120 const SkMatrix& viewMatrix,
121 const char text[], size_t byteLength,
122 SkScalar x, SkScalar y, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800123 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700124 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700125 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800126 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700127
joshualitt96880d92016-02-16 10:36:53 -0800128 if (!fAtlasTextContext) {
joshualitt8db86782016-02-17 05:40:00 -0800129 fAtlasTextContext.reset(GrAtlasTextContext::Create());
robertphillips2334fb62015-06-17 05:43:33 -0700130 }
131
joshualitt96880d92016-02-16 10:36:53 -0800132 fAtlasTextContext->drawText(fContext, this, clip, grPaint, skPaint, viewMatrix, fSurfaceProps,
133 text, byteLength, x, y, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700134}
robertphillipscaef3452015-11-11 13:18:11 -0800135
robertphillips2e1e51f2015-10-15 08:01:48 -0700136void GrDrawContext::drawPosText(const GrClip& clip, const GrPaint& grPaint,
robertphillips2334fb62015-06-17 05:43:33 -0700137 const SkPaint& skPaint,
138 const SkMatrix& viewMatrix,
139 const char text[], size_t byteLength,
140 const SkScalar pos[], int scalarsPerPosition,
141 const SkPoint& offset, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800142 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700143 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700144 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800145 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPosText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700146
joshualitt96880d92016-02-16 10:36:53 -0800147 if (!fAtlasTextContext) {
joshualitt8db86782016-02-17 05:40:00 -0800148 fAtlasTextContext.reset(GrAtlasTextContext::Create());
robertphillips2334fb62015-06-17 05:43:33 -0700149 }
150
joshualitt96880d92016-02-16 10:36:53 -0800151 fAtlasTextContext->drawPosText(fContext, this, clip, grPaint, skPaint, viewMatrix,
152 fSurfaceProps, text, byteLength, pos, scalarsPerPosition,
153 offset, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700154
155}
robertphillipscaef3452015-11-11 13:18:11 -0800156
robertphillips2e1e51f2015-10-15 08:01:48 -0700157void GrDrawContext::drawTextBlob(const GrClip& clip, const SkPaint& skPaint,
robertphillips2334fb62015-06-17 05:43:33 -0700158 const SkMatrix& viewMatrix, const SkTextBlob* blob,
159 SkScalar x, SkScalar y,
160 SkDrawFilter* filter, const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800161 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700162 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700163 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800164 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawTextBlob");
robertphillips2d70dcb2015-10-06 07:38:23 -0700165
joshualitt96880d92016-02-16 10:36:53 -0800166 if (!fAtlasTextContext) {
joshualitt8db86782016-02-17 05:40:00 -0800167 fAtlasTextContext.reset(GrAtlasTextContext::Create());
robertphillips2334fb62015-06-17 05:43:33 -0700168 }
169
joshualitt96880d92016-02-16 10:36:53 -0800170 fAtlasTextContext->drawTextBlob(fContext, this, clip, skPaint, viewMatrix, fSurfaceProps, blob,
171 x, y, filter, clipBounds);
robertphillipsea461502015-05-26 11:38:03 -0700172}
173
robertphillips2e1e51f2015-10-15 08:01:48 -0700174void GrDrawContext::discard() {
joshualitt1de610a2016-01-06 08:26:09 -0800175 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700176 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700177 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800178 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::discard");
robertphillips2e1e51f2015-10-15 08:01:48 -0700179
robertphillips77a2e522015-10-17 07:43:27 -0700180 AutoCheckFlush acf(fDrawingManager);
robertphillips6c7e3252016-04-27 10:47:51 -0700181 this->getDrawTarget()->discard(fRenderTarget.get());
robertphillipsea461502015-05-26 11:38:03 -0700182}
183
robertphillips2e1e51f2015-10-15 08:01:48 -0700184void GrDrawContext::clear(const SkIRect* rect,
robertphillipsea461502015-05-26 11:38:03 -0700185 const GrColor color,
186 bool canIgnoreRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800187 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700188 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700189 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800190 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::clear");
robertphillipsea461502015-05-26 11:38:03 -0700191
robertphillips77a2e522015-10-17 07:43:27 -0700192 AutoCheckFlush acf(fDrawingManager);
robertphillips976f5f02016-06-03 10:59:20 -0700193 this->getDrawTarget()->clear(rect, color, canIgnoreRect, this);
robertphillipsea461502015-05-26 11:38:03 -0700194}
195
196
robertphillips2e1e51f2015-10-15 08:01:48 -0700197void GrDrawContext::drawPaint(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700198 const GrPaint& origPaint,
199 const SkMatrix& viewMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800200 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700201 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700202 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800203 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPaint");
robertphillips2e1e51f2015-10-15 08:01:48 -0700204
robertphillipsea461502015-05-26 11:38:03 -0700205 // set rect to be big enough to fill the space, but not super-huge, so we
206 // don't overflow fixed-point implementations
207 SkRect r;
208 r.setLTRB(0, 0,
robertphillips2e1e51f2015-10-15 08:01:48 -0700209 SkIntToScalar(fRenderTarget->width()),
210 SkIntToScalar(fRenderTarget->height()));
robertphillipsea461502015-05-26 11:38:03 -0700211 SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
212
213 // by definition this fills the entire clip, no need for AA
214 if (paint->isAntiAlias()) {
215 paint.writable()->setAntiAlias(false);
216 }
217
218 bool isPerspective = viewMatrix.hasPerspective();
219
220 // We attempt to map r by the inverse matrix and draw that. mapRect will
221 // map the four corners and bound them with a new rect. This will not
222 // produce a correct result for some perspective matrices.
223 if (!isPerspective) {
224 SkMatrix inverse;
225 if (!viewMatrix.invert(&inverse)) {
226 SkDebugf("Could not invert matrix\n");
227 return;
228 }
229 inverse.mapRect(&r);
robertphillips2e1e51f2015-10-15 08:01:48 -0700230 this->drawRect(clip, *paint, viewMatrix, r);
robertphillipsea461502015-05-26 11:38:03 -0700231 } else {
232 SkMatrix localMatrix;
233 if (!viewMatrix.invert(&localMatrix)) {
234 SkDebugf("Could not invert matrix\n");
235 return;
236 }
237
robertphillips77a2e522015-10-17 07:43:27 -0700238 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700239
joshualitt04194f32016-01-13 10:08:27 -0800240 SkAutoTUnref<GrDrawBatch> batch(
241 GrRectBatchFactory::CreateNonAAFill(paint->getColor(), SkMatrix::I(), r, nullptr,
242 &localMatrix));
robertphillips40ff8ed2016-05-28 08:51:06 -0700243 GrPipelineBuilder pipelineBuilder(*paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700244 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsea461502015-05-26 11:38:03 -0700245 }
246}
247
robertphillipsea461502015-05-26 11:38:03 -0700248static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
249 return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
250 point.fY >= rect.fTop && point.fY <= rect.fBottom;
251}
252
bsalomonc55271f2015-11-09 11:55:57 -0800253static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
254 return viewMatrix.preservesRightAngles();
255}
256
257static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt) {
258 return paint.isAntiAlias() && !rt->isUnifiedMultisampled();
259}
260
robertphillips391395d2016-03-02 09:26:36 -0800261GrDrawBatch* GrDrawContext::getFillRectBatch(const GrPaint& paint,
262 const SkMatrix& viewMatrix,
263 const SkRect& rect) {
264
265 GrDrawBatch* batch = nullptr;
robertphillips6c7e3252016-04-27 10:47:51 -0700266 if (should_apply_coverage_aa(paint, fRenderTarget.get())) {
robertphillips391395d2016-03-02 09:26:36 -0800267 // The fill path can handle rotation but not skew.
268 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
269 SkRect devBoundRect;
270 viewMatrix.mapRect(&devBoundRect, rect);
271 batch = GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix,
272 rect, devBoundRect);
273 }
274 } else {
275 // filled BW rect
276 batch = GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect,
halcanary9d524f22016-03-29 09:03:52 -0700277 nullptr, nullptr);
robertphillips391395d2016-03-02 09:26:36 -0800278 }
279
280 return batch;
281}
282
robertphillips2e1e51f2015-10-15 08:01:48 -0700283void GrDrawContext::drawRect(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700284 const GrPaint& paint,
285 const SkMatrix& viewMatrix,
286 const SkRect& rect,
bsalomon6663acf2016-05-10 09:14:17 -0700287 const GrStyle* style) {
288 if (!style) {
289 style = &GrStyle::SimpleFill();
290 }
joshualitt1de610a2016-01-06 08:26:09 -0800291 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700292 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700293 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800294 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect");
robertphillips2e1e51f2015-10-15 08:01:48 -0700295
bsalomon6663acf2016-05-10 09:14:17 -0700296 // Path effects should've been devolved to a path in SkGpuDevice
297 SkASSERT(!style->pathEffect());
robertphillipsea461502015-05-26 11:38:03 -0700298
robertphillips77a2e522015-10-17 07:43:27 -0700299 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700300
bsalomon6663acf2016-05-10 09:14:17 -0700301 const SkStrokeRec& stroke = style->strokeRec();
302 SkScalar width = stroke.getWidth();
robertphillipsea461502015-05-26 11:38:03 -0700303
304 // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
305 // cases where the RT is fully inside a stroke.
306 if (width < 0) {
307 SkRect rtRect;
robertphillips954cbc12015-12-02 10:33:46 -0800308 fRenderTarget->getBoundsRect(&rtRect);
robertphillipsea461502015-05-26 11:38:03 -0700309 // Does the clip contain the entire RT?
cdalton846c0512016-05-13 10:25:00 -0700310 if (clip.quickContains(rtRect)) {
robertphillipsea461502015-05-26 11:38:03 -0700311 SkMatrix invM;
312 if (!viewMatrix.invert(&invM)) {
313 return;
314 }
315 // Does the rect bound the RT?
316 SkPoint srcSpaceRTQuad[4];
317 invM.mapRectToQuad(srcSpaceRTQuad, rtRect);
318 if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) &&
319 rect_contains_inclusive(rect, srcSpaceRTQuad[1]) &&
320 rect_contains_inclusive(rect, srcSpaceRTQuad[2]) &&
321 rect_contains_inclusive(rect, srcSpaceRTQuad[3])) {
322 // Will it blend?
323 GrColor clearColor;
cdalton1fa45722015-06-02 10:43:39 -0700324 if (paint.isConstantBlendedColor(&clearColor)) {
robertphillips976f5f02016-06-03 10:59:20 -0700325 this->getDrawTarget()->clear(nullptr, clearColor, true, this);
robertphillipsea461502015-05-26 11:38:03 -0700326 return;
327 }
328 }
329 }
330 }
331
robertphillips4bc31812016-03-01 12:22:49 -0800332 bool snapToPixelCenters = false;
joshualitt04194f32016-01-13 10:08:27 -0800333 SkAutoTUnref<GrDrawBatch> batch;
robertphillips391395d2016-03-02 09:26:36 -0800334 if (width < 0) {
335 batch.reset(this->getFillRectBatch(paint, viewMatrix, rect));
336 } else {
337 GrColor color = paint.getColor();
338
robertphillips6c7e3252016-04-27 10:47:51 -0700339 if (should_apply_coverage_aa(paint, fRenderTarget.get())) {
cdaltonbb539482016-01-04 09:48:25 -0800340 // The stroke path needs the rect to remain axis aligned (no rotation or skew).
341 if (viewMatrix.rectStaysRect()) {
robertphillips391395d2016-03-02 09:26:36 -0800342 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect,
bsalomon6663acf2016-05-10 09:14:17 -0700343 stroke));
cdaltonbb539482016-01-04 09:48:25 -0800344 }
robertphillipsea461502015-05-26 11:38:03 -0700345 } else {
robertphillips391395d2016-03-02 09:26:36 -0800346 // Non-AA hairlines are snapped to pixel centers to make which pixels are hit
347 // deterministic
348 snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisampled());
349 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect,
350 width, snapToPixelCenters));
robertphillips8b8f36f2016-03-02 08:53:12 -0800351
robertphillips391395d2016-03-02 09:26:36 -0800352 // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
halcanary9d524f22016-03-29 09:03:52 -0700353 // hairline rects. We jam all the vertices to pixel centers to avoid this, but not
robertphillips391395d2016-03-02 09:26:36 -0800354 // when MSAA is enabled because it can cause ugly artifacts.
355 }
robertphillipsea461502015-05-26 11:38:03 -0700356 }
robertphillips4bc31812016-03-01 12:22:49 -0800357
358 if (batch) {
robertphillips55fdccc2016-06-06 06:16:20 -0700359 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips4bc31812016-03-01 12:22:49 -0800360
361 if (snapToPixelCenters) {
362 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
363 snapToPixelCenters);
364 }
365
robertphillips976f5f02016-06-03 10:59:20 -0700366 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillips4bc31812016-03-01 12:22:49 -0800367 return;
368 }
halcanary9d524f22016-03-29 09:03:52 -0700369
robertphillips4bc31812016-03-01 12:22:49 -0800370 SkPath path;
371 path.setIsVolatile(true);
372 path.addRect(rect);
bsalomon6663acf2016-05-10 09:14:17 -0700373 this->internalDrawPath(clip, paint, viewMatrix, path, *style);
robertphillipsea461502015-05-26 11:38:03 -0700374}
375
robertphillips976f5f02016-06-03 10:59:20 -0700376void GrDrawContextPriv::clearStencilClip(const SkIRect& rect, bool insideClip) {
377 ASSERT_SINGLE_OWNER_PRIV
378 RETURN_IF_ABANDONED_PRIV
379 SkDEBUGCODE(fDrawContext->validate();)
380 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContextPriv::clearStencilClip");
381
382 AutoCheckFlush acf(fDrawContext->fDrawingManager);
383 fDrawContext->getDrawTarget()->clearStencilClip(rect, insideClip,
384 fDrawContext->accessRenderTarget());
385}
386
387void GrDrawContextPriv::stencilPath(const GrPipelineBuilder& pipelineBuilder,
388 const GrClip& clip,
389 const SkMatrix& viewMatrix,
390 const GrPath* path,
391 GrPathRendering::FillType fill) {
392 fDrawContext->getDrawTarget()->stencilPath(pipelineBuilder, fDrawContext,
393 clip, viewMatrix, path, fill);
394}
395
396void GrDrawContextPriv::stencilRect(const GrFixedClip& clip,
397 const GrUserStencilSettings* ss,
398 bool doAA,
399 const SkMatrix& viewMatrix,
400 const SkRect& rect) {
401 ASSERT_SINGLE_OWNER_PRIV
402 RETURN_IF_ABANDONED_PRIV
403 SkDEBUGCODE(fDrawContext->validate();)
404 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::stencilRect");
405
406 AutoCheckFlush acf(fDrawContext->fDrawingManager);
407
408 GrPaint paint;
409 paint.setAntiAlias(doAA);
bungemanab0bf2e2016-06-03 14:25:05 -0700410 SkSafeUnref(paint.setXPFactory(GrDisableColorXPFactory::Create()));
robertphillips976f5f02016-06-03 10:59:20 -0700411
412 SkAutoTUnref<GrDrawBatch> batch(fDrawContext->getFillRectBatch(paint, viewMatrix, rect));
413 SkASSERT(batch);
414
415 GrPipelineBuilder pipelineBuilder(paint, fDrawContext->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700416 pipelineBuilder.setUserStencil(ss);
417
418 fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, fDrawContext, clip, batch);
419}
420
cdalton846c0512016-05-13 10:25:00 -0700421bool GrDrawContextPriv::drawAndStencilRect(const GrFixedClip& clip,
cdalton93a379b2016-05-11 13:58:08 -0700422 const GrUserStencilSettings* ss,
robertphillips391395d2016-03-02 09:26:36 -0800423 SkRegion::Op op,
424 bool invert,
425 bool doAA,
426 const SkMatrix& viewMatrix,
427 const SkRect& rect) {
428 ASSERT_SINGLE_OWNER_PRIV
429 RETURN_FALSE_IF_ABANDONED_PRIV
430 SkDEBUGCODE(fDrawContext->validate();)
robertphillips55fdccc2016-06-06 06:16:20 -0700431 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::drawAndStencilRect");
robertphillips391395d2016-03-02 09:26:36 -0800432
433 AutoCheckFlush acf(fDrawContext->fDrawingManager);
434
435 GrPaint paint;
436 paint.setAntiAlias(doAA);
437 paint.setCoverageSetOpXPFactory(op, invert);
438
439 SkAutoTUnref<GrDrawBatch> batch(fDrawContext->getFillRectBatch(paint, viewMatrix, rect));
440 if (batch) {
robertphillips40ff8ed2016-05-28 08:51:06 -0700441 GrPipelineBuilder pipelineBuilder(paint, fDrawContext->isUnifiedMultisampled());
cdalton93a379b2016-05-11 13:58:08 -0700442 pipelineBuilder.setUserStencil(ss);
robertphillips391395d2016-03-02 09:26:36 -0800443
robertphillips976f5f02016-06-03 10:59:20 -0700444 fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, fDrawContext, clip, batch);
robertphillips391395d2016-03-02 09:26:36 -0800445 return true;
446 }
447
448 SkPath path;
449 path.setIsVolatile(true);
450 path.addRect(rect);
cdalton862cff32016-05-12 15:09:48 -0700451 return this->drawAndStencilPath(clip, ss, op, invert, doAA, viewMatrix, path);
robertphillips391395d2016-03-02 09:26:36 -0800452}
453
bsalomona2e69fc2015-11-05 10:41:43 -0800454void GrDrawContext::fillRectToRect(const GrClip& clip,
455 const GrPaint& paint,
456 const SkMatrix& viewMatrix,
457 const SkRect& rectToDraw,
458 const SkRect& localRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800459 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700460 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700461 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800462 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect");
robertphillipsea461502015-05-26 11:38:03 -0700463
robertphillips77a2e522015-10-17 07:43:27 -0700464 AutoCheckFlush acf(fDrawingManager);
robertphillips2e1e51f2015-10-15 08:01:48 -0700465
joshualitt04194f32016-01-13 10:08:27 -0800466 SkAutoTUnref<GrDrawBatch> batch;
robertphillips6c7e3252016-04-27 10:47:51 -0700467 if (should_apply_coverage_aa(paint, fRenderTarget.get()) &&
bsalomonc55271f2015-11-09 11:55:57 -0800468 view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
joshualitt04194f32016-01-13 10:08:27 -0800469 batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix, rectToDraw,
470 localRect));
bsalomonc55271f2015-11-09 11:55:57 -0800471 } else {
joshualitt04194f32016-01-13 10:08:27 -0800472 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rectToDraw,
473 &localRect, nullptr));
474 }
475
476 if (batch) {
robertphillips40ff8ed2016-05-28 08:51:06 -0700477 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700478 this->drawBatch(pipelineBuilder, clip, batch);
bsalomonc55271f2015-11-09 11:55:57 -0800479 }
joshualittb6b513b2015-08-21 10:25:18 -0700480}
481
bsalomona2e69fc2015-11-05 10:41:43 -0800482void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip,
483 const GrPaint& paint,
484 const SkMatrix& viewMatrix,
485 const SkRect& rectToDraw,
486 const SkMatrix& localMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800487 ASSERT_SINGLE_OWNER
joshualittb6b513b2015-08-21 10:25:18 -0700488 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700489 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800490 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatrix");
joshualittb6b513b2015-08-21 10:25:18 -0700491
robertphillips77a2e522015-10-17 07:43:27 -0700492 AutoCheckFlush acf(fDrawingManager);
robertphillips2e1e51f2015-10-15 08:01:48 -0700493
joshualitt04194f32016-01-13 10:08:27 -0800494 SkAutoTUnref<GrDrawBatch> batch;
robertphillips6c7e3252016-04-27 10:47:51 -0700495 if (should_apply_coverage_aa(paint, fRenderTarget.get()) &&
bsalomonc55271f2015-11-09 11:55:57 -0800496 view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
joshualitt04194f32016-01-13 10:08:27 -0800497 batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix,
498 rectToDraw));
bsalomonc55271f2015-11-09 11:55:57 -0800499 } else {
joshualitt04194f32016-01-13 10:08:27 -0800500 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rectToDraw,
501 nullptr, &localMatrix));
bsalomonc55271f2015-11-09 11:55:57 -0800502 }
robertphillips4bc31812016-03-01 12:22:49 -0800503
robertphillips55fdccc2016-06-06 06:16:20 -0700504 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700505 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsea461502015-05-26 11:38:03 -0700506}
507
robertphillips2e1e51f2015-10-15 08:01:48 -0700508void GrDrawContext::drawVertices(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700509 const GrPaint& paint,
510 const SkMatrix& viewMatrix,
511 GrPrimitiveType primitiveType,
512 int vertexCount,
513 const SkPoint positions[],
514 const SkPoint texCoords[],
515 const GrColor colors[],
516 const uint16_t indices[],
517 int indexCount) {
joshualitt1de610a2016-01-06 08:26:09 -0800518 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700519 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700520 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800521 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawVertices");
robertphillipsea461502015-05-26 11:38:03 -0700522
robertphillips77a2e522015-10-17 07:43:27 -0700523 AutoCheckFlush acf(fDrawingManager);
robertphillips2e1e51f2015-10-15 08:01:48 -0700524
robertphillipsea461502015-05-26 11:38:03 -0700525 // TODO clients should give us bounds
526 SkRect bounds;
527 if (!bounds.setBoundsCheck(positions, vertexCount)) {
528 SkDebugf("drawVertices call empty bounds\n");
529 return;
530 }
531
532 viewMatrix.mapRect(&bounds);
533
534 // 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 -0800535 // snapping. We also do this for the "hair" primitive types: lines and points since they have
536 // a 1 pixel thickness in device space.
537 if (!paint.isAntiAlias() || GrIsPrimTypeLines(primitiveType) ||
538 kPoints_GrPrimitiveType == primitiveType) {
robertphillipsea461502015-05-26 11:38:03 -0700539 bounds.outset(0.5f, 0.5f);
540 }
541
joshualitt2771b562015-08-07 12:46:26 -0700542 GrDrawVerticesBatch::Geometry geometry;
robertphillipsea461502015-05-26 11:38:03 -0700543 geometry.fColor = paint.getColor();
bsalomonabd30f52015-08-13 13:34:48 -0700544 SkAutoTUnref<GrDrawBatch> batch(GrDrawVerticesBatch::Create(geometry, primitiveType, viewMatrix,
545 positions, vertexCount, indices,
546 indexCount, colors, texCoords,
547 bounds));
robertphillipsea461502015-05-26 11:38:03 -0700548
robertphillips55fdccc2016-06-06 06:16:20 -0700549 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700550 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsea461502015-05-26 11:38:03 -0700551}
552
553///////////////////////////////////////////////////////////////////////////////
554
robertphillips2e1e51f2015-10-15 08:01:48 -0700555void GrDrawContext::drawAtlas(const GrClip& clip,
jvanverth31ff7622015-08-07 10:09:28 -0700556 const GrPaint& paint,
557 const SkMatrix& viewMatrix,
558 int spriteCount,
559 const SkRSXform xform[],
560 const SkRect texRect[],
561 const SkColor colors[]) {
joshualitt1de610a2016-01-06 08:26:09 -0800562 ASSERT_SINGLE_OWNER
jvanverth31ff7622015-08-07 10:09:28 -0700563 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700564 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800565 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawAtlas");
robertphillips2e1e51f2015-10-15 08:01:48 -0700566
robertphillips77a2e522015-10-17 07:43:27 -0700567 AutoCheckFlush acf(fDrawingManager);
halcanary9d524f22016-03-29 09:03:52 -0700568
jvanverth14b88032015-08-07 12:18:54 -0700569 GrDrawAtlasBatch::Geometry geometry;
jvanverth31ff7622015-08-07 10:09:28 -0700570 geometry.fColor = paint.getColor();
bsalomonabd30f52015-08-13 13:34:48 -0700571 SkAutoTUnref<GrDrawBatch> batch(GrDrawAtlasBatch::Create(geometry, viewMatrix, spriteCount,
572 xform, texRect, colors));
halcanary9d524f22016-03-29 09:03:52 -0700573
robertphillips55fdccc2016-06-06 06:16:20 -0700574 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700575 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
jvanverth31ff7622015-08-07 10:09:28 -0700576}
577
578///////////////////////////////////////////////////////////////////////////////
579
robertphillips2e1e51f2015-10-15 08:01:48 -0700580void GrDrawContext::drawRRect(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700581 const GrPaint& paint,
582 const SkMatrix& viewMatrix,
583 const SkRRect& rrect,
bsalomon6663acf2016-05-10 09:14:17 -0700584 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800585 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700586 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700587 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800588 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect");
robertphillips2e1e51f2015-10-15 08:01:48 -0700589
robertphillipsea461502015-05-26 11:38:03 -0700590 if (rrect.isEmpty()) {
591 return;
592 }
593
bsalomon6663acf2016-05-10 09:14:17 -0700594 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
595 const SkStrokeRec stroke = style.strokeRec();
robertphillips77a2e522015-10-17 07:43:27 -0700596 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700597
robertphillips6c7e3252016-04-27 10:47:51 -0700598 if (should_apply_coverage_aa(paint, fRenderTarget.get())) {
robertphillipsb56f9272016-02-25 11:03:52 -0800599 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
600
robertphillips4bc31812016-03-01 12:22:49 -0800601 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.getColor(),
robertphillipsb56f9272016-02-25 11:03:52 -0800602 viewMatrix,
603 rrect,
bsalomon6663acf2016-05-10 09:14:17 -0700604 stroke,
robertphillipsb56f9272016-02-25 11:03:52 -0800605 shaderCaps));
606 if (batch) {
robertphillips55fdccc2016-06-06 06:16:20 -0700607 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700608 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsb56f9272016-02-25 11:03:52 -0800609 return;
610 }
robertphillipsea461502015-05-26 11:38:03 -0700611 }
robertphillipsb56f9272016-02-25 11:03:52 -0800612
613 SkPath path;
614 path.setIsVolatile(true);
615 path.addRRect(rrect);
bsalomon6663acf2016-05-10 09:14:17 -0700616 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -0700617}
618
robertphillips00095892016-02-29 13:50:40 -0800619bool GrDrawContext::drawFilledDRRect(const GrClip& clip,
620 const GrPaint& paintIn,
621 const SkMatrix& viewMatrix,
622 const SkRRect& origOuter,
623 const SkRRect& origInner) {
624 SkASSERT(!origInner.isEmpty());
625 SkASSERT(!origOuter.isEmpty());
626
627 bool applyAA = paintIn.isAntiAlias() && !fRenderTarget->isUnifiedMultisampled();
628
629 GrPrimitiveEdgeType innerEdgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType :
630 kInverseFillBW_GrProcessorEdgeType;
631 GrPrimitiveEdgeType outerEdgeType = applyAA ? kFillAA_GrProcessorEdgeType :
632 kFillBW_GrProcessorEdgeType;
633
634 SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
635 SkMatrix inverseVM;
636 if (!viewMatrix.isIdentity()) {
637 if (!origInner.transform(viewMatrix, inner.writable())) {
638 return false;
639 }
640 if (!origOuter.transform(viewMatrix, outer.writable())) {
641 return false;
642 }
643 if (!viewMatrix.invert(&inverseVM)) {
644 return false;
645 }
646 } else {
647 inverseVM.reset();
halcanary9d524f22016-03-29 09:03:52 -0700648 }
robertphillips00095892016-02-29 13:50:40 -0800649
650 GrPaint grPaint(paintIn);
651 grPaint.setAntiAlias(false);
652
653 // TODO these need to be a geometry processors
654 SkAutoTUnref<GrFragmentProcessor> innerEffect(GrRRectEffect::Create(innerEdgeType, *inner));
655 if (!innerEffect) {
656 return false;
657 }
658
659 SkAutoTUnref<GrFragmentProcessor> outerEffect(GrRRectEffect::Create(outerEdgeType, *outer));
660 if (!outerEffect) {
661 return false;
662 }
663
664 grPaint.addCoverageFragmentProcessor(innerEffect);
665 grPaint.addCoverageFragmentProcessor(outerEffect);
666
667 SkRect bounds = outer->getBounds();
668 if (applyAA) {
669 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
670 }
halcanary9d524f22016-03-29 09:03:52 -0700671
robertphillips00095892016-02-29 13:50:40 -0800672 this->fillRectWithLocalMatrix(clip, grPaint, SkMatrix::I(), bounds, inverseVM);
673 return true;
674}
675
676void GrDrawContext::drawDRRect(const GrClip& clip,
677 const GrPaint& paint,
678 const SkMatrix& viewMatrix,
679 const SkRRect& outer,
680 const SkRRect& inner) {
681 ASSERT_SINGLE_OWNER
682 RETURN_IF_ABANDONED
683 SkDEBUGCODE(this->validate();)
684 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawDRRect");
685
686 SkASSERT(!outer.isEmpty());
687 SkASSERT(!inner.isEmpty());
688
689 AutoCheckFlush acf(fDrawingManager);
690
691 if (this->drawFilledDRRect(clip, paint, viewMatrix, outer, inner)) {
692 return;
693 }
694
695 SkPath path;
696 path.setIsVolatile(true);
697 path.addRRect(inner);
698 path.addRRect(outer);
699 path.setFillType(SkPath::kEvenOdd_FillType);
700
bsalomon6663acf2016-05-10 09:14:17 -0700701 this->internalDrawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
robertphillips00095892016-02-29 13:50:40 -0800702}
703
robertphillipsea461502015-05-26 11:38:03 -0700704///////////////////////////////////////////////////////////////////////////////
705
robertphillips2e1e51f2015-10-15 08:01:48 -0700706void GrDrawContext::drawOval(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700707 const GrPaint& paint,
708 const SkMatrix& viewMatrix,
709 const SkRect& oval,
bsalomon6663acf2016-05-10 09:14:17 -0700710 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800711 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700712 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700713 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800714 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval");
robertphillips2e1e51f2015-10-15 08:01:48 -0700715
robertphillipsea461502015-05-26 11:38:03 -0700716 if (oval.isEmpty()) {
717 return;
718 }
719
bsalomon6663acf2016-05-10 09:14:17 -0700720 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
robertphillipsea461502015-05-26 11:38:03 -0700721
robertphillips77a2e522015-10-17 07:43:27 -0700722 AutoCheckFlush acf(fDrawingManager);
bsalomon6663acf2016-05-10 09:14:17 -0700723 const SkStrokeRec& stroke = style.strokeRec();
robertphillips6c7e3252016-04-27 10:47:51 -0700724 if (should_apply_coverage_aa(paint, fRenderTarget.get())) {
robertphillipsb56f9272016-02-25 11:03:52 -0800725 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
robertphillips4bc31812016-03-01 12:22:49 -0800726 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
robertphillipsb56f9272016-02-25 11:03:52 -0800727 viewMatrix,
728 oval,
bsalomon6663acf2016-05-10 09:14:17 -0700729 stroke,
robertphillipsb56f9272016-02-25 11:03:52 -0800730 shaderCaps));
731 if (batch) {
robertphillips55fdccc2016-06-06 06:16:20 -0700732 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700733 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsb56f9272016-02-25 11:03:52 -0800734 return;
735 }
robertphillipsea461502015-05-26 11:38:03 -0700736 }
robertphillipsb56f9272016-02-25 11:03:52 -0800737
738 SkPath path;
739 path.setIsVolatile(true);
740 path.addOval(oval);
bsalomon6663acf2016-05-10 09:14:17 -0700741 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -0700742}
743
joshualitt33a5fce2015-11-18 13:28:51 -0800744void GrDrawContext::drawImageNine(const GrClip& clip,
745 const GrPaint& paint,
746 const SkMatrix& viewMatrix,
747 int imageWidth,
748 int imageHeight,
749 const SkIRect& center,
750 const SkRect& dst) {
joshualitt1de610a2016-01-06 08:26:09 -0800751 ASSERT_SINGLE_OWNER
joshualitt33a5fce2015-11-18 13:28:51 -0800752 RETURN_IF_ABANDONED
753 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800754 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawImageNine");
joshualitt33a5fce2015-11-18 13:28:51 -0800755
756 AutoCheckFlush acf(fDrawingManager);
757
758 SkAutoTUnref<GrDrawBatch> batch(GrNinePatch::CreateNonAA(paint.getColor(), viewMatrix,
759 imageWidth, imageHeight,
760 center, dst));
761
robertphillips55fdccc2016-06-06 06:16:20 -0700762 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700763 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
joshualitt33a5fce2015-11-18 13:28:51 -0800764}
765
766
robertphillipsea461502015-05-26 11:38:03 -0700767// Can 'path' be drawn as a pair of filled nested rectangles?
bsalomon6663acf2016-05-10 09:14:17 -0700768static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path, SkRect rects[2]) {
robertphillipsea461502015-05-26 11:38:03 -0700769
770 if (path.isInverseFillType()) {
771 return false;
772 }
773
774 // TODO: this restriction could be lifted if we were willing to apply
775 // the matrix to all the points individually rather than just to the rect
robertphillips0e7029e2015-11-30 05:45:06 -0800776 if (!viewMatrix.rectStaysRect()) {
robertphillipsea461502015-05-26 11:38:03 -0700777 return false;
778 }
779
780 SkPath::Direction dirs[2];
781 if (!path.isNestedFillRects(rects, dirs)) {
782 return false;
783 }
784
785 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) {
786 // The two rects need to be wound opposite to each other
787 return false;
788 }
789
790 // Right now, nested rects where the margin is not the same width
791 // all around do not render correctly
792 const SkScalar* outer = rects[0].asScalars();
793 const SkScalar* inner = rects[1].asScalars();
794
795 bool allEq = true;
796
797 SkScalar margin = SkScalarAbs(outer[0] - inner[0]);
798 bool allGoE1 = margin >= SK_Scalar1;
799
800 for (int i = 1; i < 4; ++i) {
801 SkScalar temp = SkScalarAbs(outer[i] - inner[i]);
802 if (temp < SK_Scalar1) {
803 allGoE1 = false;
804 }
805 if (!SkScalarNearlyEqual(margin, temp)) {
806 allEq = false;
807 }
808 }
809
810 return allEq || allGoE1;
811}
812
robertphillips2e1e51f2015-10-15 08:01:48 -0700813void GrDrawContext::drawBatch(const GrClip& clip,
bsalomonabd30f52015-08-13 13:34:48 -0700814 const GrPaint& paint, GrDrawBatch* batch) {
joshualitt1de610a2016-01-06 08:26:09 -0800815 ASSERT_SINGLE_OWNER
joshualittb7ee1bf2015-08-10 11:59:02 -0700816 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700817 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800818 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch");
joshualittb7ee1bf2015-08-10 11:59:02 -0700819
robertphillips77a2e522015-10-17 07:43:27 -0700820 AutoCheckFlush acf(fDrawingManager);
joshualittb7ee1bf2015-08-10 11:59:02 -0700821
robertphillips55fdccc2016-06-06 06:16:20 -0700822 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700823 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
joshualittb7ee1bf2015-08-10 11:59:02 -0700824}
825
robertphillips2e1e51f2015-10-15 08:01:48 -0700826void GrDrawContext::drawPath(const GrClip& clip,
robertphillipsea461502015-05-26 11:38:03 -0700827 const GrPaint& paint,
828 const SkMatrix& viewMatrix,
829 const SkPath& path,
bsalomon6663acf2016-05-10 09:14:17 -0700830 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800831 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700832 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700833 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -0800834 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath");
robertphillips2e1e51f2015-10-15 08:01:48 -0700835
robertphillipsea461502015-05-26 11:38:03 -0700836 if (path.isEmpty()) {
837 if (path.isInverseFillType()) {
robertphillips2e1e51f2015-10-15 08:01:48 -0700838 this->drawPaint(clip, paint, viewMatrix);
robertphillipsea461502015-05-26 11:38:03 -0700839 }
840 return;
841 }
842
robertphillips77a2e522015-10-17 07:43:27 -0700843 AutoCheckFlush acf(fDrawingManager);
robertphillipsea461502015-05-26 11:38:03 -0700844
bsalomon6663acf2016-05-10 09:14:17 -0700845 if (should_apply_coverage_aa(paint, fRenderTarget.get()) && !style.pathEffect()) {
846 if (style.isSimpleFill() && !path.isConvex()) {
robertphillipsea461502015-05-26 11:38:03 -0700847 // Concave AA paths are expensive - try to avoid them for special cases
848 SkRect rects[2];
849
bsalomon6663acf2016-05-10 09:14:17 -0700850 if (fills_as_nested_rects(viewMatrix, path, rects)) {
joshualittd2b23e02015-08-21 10:53:34 -0700851 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFillNestedRects(
robertphillips4bc31812016-03-01 12:22:49 -0800852 paint.getColor(), viewMatrix, rects));
bsalomon40ef4852016-05-02 13:22:13 -0700853 if (batch) {
robertphillips55fdccc2016-06-06 06:16:20 -0700854 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700855 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
bsalomon40ef4852016-05-02 13:22:13 -0700856 }
robertphillipsea461502015-05-26 11:38:03 -0700857 return;
858 }
859 }
860 SkRect ovalRect;
861 bool isOval = path.isOval(&ovalRect);
862
863 if (isOval && !path.isInverseFillType()) {
robertphillips0cc2f852016-02-24 13:36:56 -0800864 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
robertphillips4bc31812016-03-01 12:22:49 -0800865 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
robertphillips0cc2f852016-02-24 13:36:56 -0800866 viewMatrix,
robertphillips0cc2f852016-02-24 13:36:56 -0800867 ovalRect,
bsalomon6663acf2016-05-10 09:14:17 -0700868 style.strokeRec(),
robertphillips0cc2f852016-02-24 13:36:56 -0800869 shaderCaps));
870 if (batch) {
robertphillips55fdccc2016-06-06 06:16:20 -0700871 GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
robertphillips976f5f02016-06-03 10:59:20 -0700872 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillipsea461502015-05-26 11:38:03 -0700873 return;
874 }
875 }
876 }
robertphillips4bc31812016-03-01 12:22:49 -0800877
878 // Note that internalDrawPath may sw-rasterize the path into a scratch texture.
879 // Scratch textures can be recycled after they are returned to the texture
880 // cache. This presents a potential hazard for buffered drawing. However,
881 // the writePixels that uploads to the scratch will perform a flush so we're
882 // OK.
bsalomon6663acf2016-05-10 09:14:17 -0700883 this->internalDrawPath(clip, paint, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -0700884}
885
cdalton846c0512016-05-13 10:25:00 -0700886bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
cdalton93a379b2016-05-11 13:58:08 -0700887 const GrUserStencilSettings* ss,
robertphillips391395d2016-03-02 09:26:36 -0800888 SkRegion::Op op,
889 bool invert,
890 bool doAA,
891 const SkMatrix& viewMatrix,
892 const SkPath& path) {
893 ASSERT_SINGLE_OWNER_PRIV
894 RETURN_FALSE_IF_ABANDONED_PRIV
895 SkDEBUGCODE(fDrawContext->validate();)
896 GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::drawPath");
897
898 if (path.isEmpty() && path.isInverseFillType()) {
cdalton862cff32016-05-12 15:09:48 -0700899 this->drawAndStencilRect(clip, ss, op, invert, false, SkMatrix::I(),
robertphillips6c7e3252016-04-27 10:47:51 -0700900 SkRect::MakeIWH(fDrawContext->width(),
901 fDrawContext->height()));
robertphillips391395d2016-03-02 09:26:36 -0800902 return true;
903 }
904
905 AutoCheckFlush acf(fDrawContext->fDrawingManager);
906
907 // An Assumption here is that path renderer would use some form of tweaking
908 // the src color (either the input alpha or in the frag shader) to implement
909 // aa. If we have some future driver-mojo path AA that can do the right
910 // thing WRT to the blend then we'll need some query on the PR.
911 bool useCoverageAA = doAA && !fDrawContext->fRenderTarget->isUnifiedMultisampled();
robertphillips976f5f02016-06-03 10:59:20 -0700912 bool hasUserStencilSettings = !ss->isUnused();
robertphillips391395d2016-03-02 09:26:36 -0800913 bool isStencilBufferMSAA = fDrawContext->fRenderTarget->isStencilBufferMultisampled();
914
915 const GrPathRendererChain::DrawType type =
916 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
917 : GrPathRendererChain::kColor_DrawType;
918
919 GrPathRenderer::CanDrawPathArgs canDrawArgs;
920 canDrawArgs.fShaderCaps = fDrawContext->fDrawingManager->getContext()->caps()->shaderCaps();
921 canDrawArgs.fViewMatrix = &viewMatrix;
922 canDrawArgs.fPath = &path;
bsalomon6663acf2016-05-10 09:14:17 -0700923 canDrawArgs.fStyle = &GrStyle::SimpleFill();
robertphillips391395d2016-03-02 09:26:36 -0800924 canDrawArgs.fAntiAlias = useCoverageAA;
cdalton93a379b2016-05-11 13:58:08 -0700925 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
robertphillips391395d2016-03-02 09:26:36 -0800926 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
927
928 // Don't allow the SW renderer
929 GrPathRenderer* pr = fDrawContext->fDrawingManager->getPathRenderer(canDrawArgs, false, type);
930 if (!pr) {
931 return false;
932 }
933
934 GrPaint paint;
935 paint.setCoverageSetOpXPFactory(op, invert);
936
robertphillips391395d2016-03-02 09:26:36 -0800937 GrPathRenderer::DrawPathArgs args;
robertphillips391395d2016-03-02 09:26:36 -0800938 args.fResourceProvider = fDrawContext->fDrawingManager->getContext()->resourceProvider();
robertphillips976f5f02016-06-03 10:59:20 -0700939 args.fPaint = &paint;
940 args.fUserStencilSettings = ss;
941 args.fDrawContext = fDrawContext;
cdalton862cff32016-05-12 15:09:48 -0700942 args.fClip = &clip;
robertphillips391395d2016-03-02 09:26:36 -0800943 args.fColor = GrColor_WHITE;
944 args.fViewMatrix = &viewMatrix;
945 args.fPath = &path;
bsalomon6663acf2016-05-10 09:14:17 -0700946 args.fStyle = &GrStyle::SimpleFill();
robertphillips391395d2016-03-02 09:26:36 -0800947 args.fAntiAlias = useCoverageAA;
brianosman0e3c5542016-04-13 13:56:21 -0700948 args.fGammaCorrect = fDrawContext->isGammaCorrect();
robertphillips391395d2016-03-02 09:26:36 -0800949 pr->drawPath(args);
950 return true;
951}
952
robertphillips4bc31812016-03-01 12:22:49 -0800953void GrDrawContext::internalDrawPath(const GrClip& clip,
954 const GrPaint& paint,
robertphillipsea461502015-05-26 11:38:03 -0700955 const SkMatrix& viewMatrix,
bsalomon6663acf2016-05-10 09:14:17 -0700956 const SkPath& origPath,
957 const GrStyle& origStyle) {
joshualitt1de610a2016-01-06 08:26:09 -0800958 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700959 RETURN_IF_ABANDONED
bsalomon6663acf2016-05-10 09:14:17 -0700960 SkASSERT(!origPath.isEmpty());
robertphillipsea461502015-05-26 11:38:03 -0700961
robertphillips6c7e3252016-04-27 10:47:51 -0700962 bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget.get());
cdalton93a379b2016-05-11 13:58:08 -0700963 constexpr bool kHasUserStencilSettings = false;
robertphillips4bc31812016-03-01 12:22:49 -0800964 bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled();
robertphillipsea461502015-05-26 11:38:03 -0700965
robertphillips68737822015-10-29 12:12:21 -0700966 const GrPathRendererChain::DrawType type =
967 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
968 : GrPathRendererChain::kColor_DrawType;
robertphillipsea461502015-05-26 11:38:03 -0700969
robertphillipsea461502015-05-26 11:38:03 -0700970 SkTLazy<SkPath> tmpPath;
bsalomon6663acf2016-05-10 09:14:17 -0700971 SkTLazy<GrStyle> tmpStyle;
robertphillipsea461502015-05-26 11:38:03 -0700972
robertphillips68737822015-10-29 12:12:21 -0700973 GrPathRenderer::CanDrawPathArgs canDrawArgs;
974 canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
975 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon6663acf2016-05-10 09:14:17 -0700976 canDrawArgs.fPath = &origPath;
977 canDrawArgs.fStyle = &origStyle;
robertphillips68737822015-10-29 12:12:21 -0700978 canDrawArgs.fAntiAlias = useCoverageAA;
cdalton93a379b2016-05-11 13:58:08 -0700979 canDrawArgs.fHasUserStencilSettings = kHasUserStencilSettings;
robertphillips68737822015-10-29 12:12:21 -0700980 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
981
bsalomon6663acf2016-05-10 09:14:17 -0700982 // Try a 1st time without applying any of the style to the geometry (and barring sw)
robertphillips68737822015-10-29 12:12:21 -0700983 GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
bsalomon6663acf2016-05-10 09:14:17 -0700984 SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
robertphillipsea461502015-05-26 11:38:03 -0700985
bsalomon6663acf2016-05-10 09:14:17 -0700986 if (!pr && canDrawArgs.fStyle->pathEffect()) {
987 // It didn't work above, so try again with the path effect applied.
988 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
989 if (!canDrawArgs.fStyle->applyPathEffectToPath(tmpPath.init(), &rec, *canDrawArgs.fPath,
990 styleScale)) {
991 GrStyle noPathEffect(canDrawArgs.fStyle->strokeRec(), nullptr);
992 this->internalDrawPath(clip, paint, viewMatrix, *canDrawArgs.fPath, noPathEffect);
robertphillipsea461502015-05-26 11:38:03 -0700993 return;
994 }
bsalomon6663acf2016-05-10 09:14:17 -0700995 tmpStyle.init(rec, nullptr);
996 canDrawArgs.fPath = tmpPath.get();
997 canDrawArgs.fStyle = tmpStyle.get();
998 if (canDrawArgs.fPath->isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -0700999 return;
1000 }
robertphillips68737822015-10-29 12:12:21 -07001001
1002 pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
robertphillipsea461502015-05-26 11:38:03 -07001003 }
bsalomon6663acf2016-05-10 09:14:17 -07001004 if (!pr) {
1005 SkASSERT(!canDrawArgs.fStyle->pathEffect());
1006 if (canDrawArgs.fStyle->strokeRec().needToApply()) {
robertphillipsea461502015-05-26 11:38:03 -07001007 if (!tmpPath.isValid()) {
1008 tmpPath.init();
1009 }
bsalomon6663acf2016-05-10 09:14:17 -07001010 // It didn't work above, so try again by applying the stroke to the geometry.
1011 SkStrokeRec::InitStyle fillOrHairline;
1012 if (!canDrawArgs.fStyle->applyToPath(tmpPath.get(), &fillOrHairline,
1013 *canDrawArgs.fPath, styleScale)) {
robertphillipsea461502015-05-26 11:38:03 -07001014 return;
1015 }
bsalomon6663acf2016-05-10 09:14:17 -07001016 if (!tmpStyle.isValid()) {
1017 tmpStyle.init(fillOrHairline);
1018 } else {
1019 tmpStyle.get()->resetToInitStyle(fillOrHairline);
1020 }
1021 canDrawArgs.fPath = tmpPath.get();
1022 canDrawArgs.fStyle = tmpStyle.get();
1023 if (canDrawArgs.fPath->isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001024 return;
1025 }
robertphillips68737822015-10-29 12:12:21 -07001026
bsalomon6663acf2016-05-10 09:14:17 -07001027 pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
1028 }
bsalomon85d96672016-05-10 06:19:21 -07001029
robertphillipsea461502015-05-26 11:38:03 -07001030 // This time, allow SW renderer
robertphillips68737822015-10-29 12:12:21 -07001031 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type);
robertphillipsea461502015-05-26 11:38:03 -07001032 }
1033
halcanary96fcdcc2015-08-27 07:41:13 -07001034 if (nullptr == pr) {
robertphillipsea461502015-05-26 11:38:03 -07001035#ifdef SK_DEBUG
1036 SkDebugf("Unable to find path renderer compatible with path.\n");
1037#endif
1038 return;
1039 }
1040
bsalomon0aff2fa2015-07-31 06:48:27 -07001041 GrPathRenderer::DrawPathArgs args;
robertphillips77a2e522015-10-17 07:43:27 -07001042 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider();
robertphillips976f5f02016-06-03 10:59:20 -07001043 args.fPaint = &paint;
1044 args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
1045 args.fDrawContext = this;
cdalton862cff32016-05-12 15:09:48 -07001046 args.fClip = &clip;
robertphillips4bc31812016-03-01 12:22:49 -08001047 args.fColor = paint.getColor();
bsalomon0aff2fa2015-07-31 06:48:27 -07001048 args.fViewMatrix = &viewMatrix;
bsalomon6663acf2016-05-10 09:14:17 -07001049 args.fPath = canDrawArgs.fPath;
1050 args.fStyle = canDrawArgs.fStyle;
bsalomon0aff2fa2015-07-31 06:48:27 -07001051 args.fAntiAlias = useCoverageAA;
brianosman0e3c5542016-04-13 13:56:21 -07001052 args.fGammaCorrect = this->isGammaCorrect();
bsalomon0aff2fa2015-07-31 06:48:27 -07001053 pr->drawPath(args);
robertphillipsea461502015-05-26 11:38:03 -07001054}
1055
robertphillips976f5f02016-06-03 10:59:20 -07001056void GrDrawContext::drawBatch(const GrPipelineBuilder& pipelineBuilder, const GrClip& clip,
cdalton862cff32016-05-12 15:09:48 -07001057 GrDrawBatch* batch) {
joshualitt1de610a2016-01-06 08:26:09 -08001058 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -07001059 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001060 SkDEBUGCODE(this->validate();)
joshualittbc907352016-01-13 06:45:40 -08001061 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch");
robertphillips2d70dcb2015-10-06 07:38:23 -07001062
robertphillips976f5f02016-06-03 10:59:20 -07001063 this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
robertphillips2334fb62015-06-17 05:43:33 -07001064}