blob: 1ddf8df5115688edb56913270f65905bf66434f6 [file] [log] [blame]
robertphillipsea461502015-05-26 11:38:03 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Brian Osman11052242016-10-27 14:47:55 -04008#include "GrRenderTargetContext.h"
Brian Salomon5ec9def2016-12-20 15:34:05 -05009#include "GrColor.h"
10#include "GrDrawOpTest.h"
robertphillips77a2e522015-10-17 07:43:27 -070011#include "GrDrawingManager.h"
csmartdalton02fa32c2016-08-19 13:29:27 -070012#include "GrFixedClip.h"
robertphillips714712b2016-08-04 06:20:45 -070013#include "GrGpuResourcePriv.h"
robertphillipsea461502015-05-26 11:38:03 -070014#include "GrPathRenderer.h"
robertphillips5fa7f302016-07-21 09:21:04 -070015#include "GrPipelineBuilder.h"
robertphillips2334fb62015-06-17 05:43:33 -070016#include "GrRenderTarget.h"
Brian Salomon5ec9def2016-12-20 15:34:05 -050017#include "GrRenderTargetContextPriv.h"
robertphillips2334fb62015-06-17 05:43:33 -070018#include "GrRenderTargetPriv.h"
bsalomon473addf2015-10-02 07:49:05 -070019#include "GrResourceProvider.h"
robertphillips2d70dcb2015-10-06 07:38:23 -070020#include "SkSurfacePriv.h"
robertphillipsea461502015-05-26 11:38:03 -070021
Brian Salomon89527432016-12-16 09:52:16 -050022#include "ops/GrClearOp.h"
23#include "ops/GrDrawAtlasOp.h"
24#include "ops/GrDrawVerticesOp.h"
25#include "ops/GrLatticeOp.h"
26#include "ops/GrOp.h"
27#include "ops/GrOvalOpFactory.h"
28#include "ops/GrRectOpFactory.h"
29#include "ops/GrRegionOp.h"
30#include "ops/GrShadowRRectOp.h"
joshualitt74417822015-08-07 11:42:16 -070031
robertphillips00095892016-02-29 13:50:40 -080032#include "effects/GrRRectEffect.h"
33
csmartdaltona7f29642016-07-07 08:49:11 -070034#include "instanced/InstancedRendering.h"
35
joshualitte8042922015-12-11 06:11:21 -080036#include "text/GrAtlasTextContext.h"
37#include "text/GrStencilAndCoverTextContext.h"
38
joshualittbc907352016-01-13 06:45:40 -080039#include "../private/GrAuditTrail.h"
40
robertphillips1da3ecd2016-08-31 14:54:15 -070041#include "SkGr.h"
msarett10e3d9b2016-08-18 15:46:03 -070042#include "SkLatticeIter.h"
reeda39667c2016-08-22 06:39:49 -070043#include "SkMatrixPriv.h"
msarett10e3d9b2016-08-18 15:46:03 -070044
Robert Phillips72152832017-01-25 17:31:35 -050045#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this->drawingManager()->getContext())
joshualitt1de610a2016-01-06 08:26:09 -080046#define ASSERT_SINGLE_OWNER \
joshualittde8dc7e2016-01-08 10:09:13 -080047 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
robertphillips391395d2016-03-02 09:26:36 -080048#define ASSERT_SINGLE_OWNER_PRIV \
Brian Osman11052242016-10-27 14:47:55 -040049 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->fSingleOwner);)
Robert Phillips72152832017-01-25 17:31:35 -050050#define RETURN_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return; }
51#define RETURN_IF_ABANDONED_PRIV if (fRenderTargetContext->drawingManager()->wasAbandoned()) { return; }
52#define RETURN_FALSE_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return false; }
53#define RETURN_FALSE_IF_ABANDONED_PRIV if (fRenderTargetContext->drawingManager()->wasAbandoned()) { return false; }
54#define RETURN_NULL_IF_ABANDONED if (this->drawingManager()->wasAbandoned()) { return nullptr; }
robertphillipsea461502015-05-26 11:38:03 -070055
csmartdaltona7f29642016-07-07 08:49:11 -070056using gr_instanced::InstancedRendering;
57
robertphillipsea461502015-05-26 11:38:03 -070058class AutoCheckFlush {
59public:
halcanary9d524f22016-03-29 09:03:52 -070060 AutoCheckFlush(GrDrawingManager* drawingManager) : fDrawingManager(drawingManager) {
robertphillips77a2e522015-10-17 07:43:27 -070061 SkASSERT(fDrawingManager);
62 }
bsalomonb77a9072016-09-07 10:02:04 -070063 ~AutoCheckFlush() { fDrawingManager->flushIfNecessary(); }
robertphillipsea461502015-05-26 11:38:03 -070064
65private:
robertphillips77a2e522015-10-17 07:43:27 -070066 GrDrawingManager* fDrawingManager;
robertphillipsea461502015-05-26 11:38:03 -070067};
68
Brian Osman11052242016-10-27 14:47:55 -040069bool GrRenderTargetContext::wasAbandoned() const {
Robert Phillips72152832017-01-25 17:31:35 -050070 return this->drawingManager()->wasAbandoned();
robertphillips7761d612016-05-16 09:14:53 -070071}
72
Robert Phillipsf2361d22016-10-25 14:20:06 -040073// In MDB mode the reffing of the 'getLastOpList' call's result allows in-progress
Brian Osman11052242016-10-27 14:47:55 -040074// GrOpLists to be picked up and added to by renderTargetContexts lower in the call
Robert Phillipsf2361d22016-10-25 14:20:06 -040075// stack. When this occurs with a closed GrOpList, a new one will be allocated
Brian Osman11052242016-10-27 14:47:55 -040076// when the renderTargetContext attempts to use it (via getOpList).
77GrRenderTargetContext::GrRenderTargetContext(GrContext* context,
78 GrDrawingManager* drawingMgr,
Robert Phillipsc7635fa2016-10-28 13:25:24 -040079 sk_sp<GrRenderTargetProxy> rtp,
Brian Osman11052242016-10-27 14:47:55 -040080 sk_sp<SkColorSpace> colorSpace,
81 const SkSurfaceProps* surfaceProps,
82 GrAuditTrail* auditTrail,
83 GrSingleOwner* singleOwner)
Robert Phillips72152832017-01-25 17:31:35 -050084 : GrSurfaceContext(context, drawingMgr, std::move(colorSpace), auditTrail, singleOwner)
Robert Phillipsc7635fa2016-10-28 13:25:24 -040085 , fRenderTargetProxy(std::move(rtp))
86 , fOpList(SkSafeRef(fRenderTargetProxy->getLastRenderTargetOpList()))
Robert Phillipsc7635fa2016-10-28 13:25:24 -040087 , fInstancedPipelineInfo(fRenderTargetProxy.get())
brianosman5a7ae7e2016-09-12 12:07:25 -070088 , fColorXformFromSRGB(nullptr)
Robert Phillips2c862492017-01-18 10:08:39 -050089 , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps)) {
brianosman5a7ae7e2016-09-12 12:07:25 -070090 if (fColorSpace) {
91 // sRGB sources are very common (SkColor, etc...), so we cache that gamut transformation
Matt Sarett77a7a1b2017-02-07 13:56:11 -050092 auto srgbColorSpace = SkColorSpace::MakeSRGB();
msarettc71a9b72016-09-16 11:01:27 -070093 fColorXformFromSRGB = GrColorSpaceXform::Make(srgbColorSpace.get(), fColorSpace.get());
brianosman5a7ae7e2016-09-12 12:07:25 -070094 }
robertphillips2e1e51f2015-10-15 08:01:48 -070095 SkDEBUGCODE(this->validate();)
robertphillipsea461502015-05-26 11:38:03 -070096}
97
robertphillips2e1e51f2015-10-15 08:01:48 -070098#ifdef SK_DEBUG
Brian Osman11052242016-10-27 14:47:55 -040099void GrRenderTargetContext::validate() const {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400100 SkASSERT(fRenderTargetProxy);
101 fRenderTargetProxy->validate(fContext);
robertphillipsa106c622015-10-16 09:07:06 -0700102
Robert Phillipsf2361d22016-10-25 14:20:06 -0400103 if (fOpList && !fOpList->isClosed()) {
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400104 SkASSERT(fRenderTargetProxy->getLastOpList() == fOpList);
robertphillipsa106c622015-10-16 09:07:06 -0700105 }
robertphillips2e1e51f2015-10-15 08:01:48 -0700106}
107#endif
108
Brian Osman11052242016-10-27 14:47:55 -0400109GrRenderTargetContext::~GrRenderTargetContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800110 ASSERT_SINGLE_OWNER
Robert Phillipsf2361d22016-10-25 14:20:06 -0400111 SkSafeUnref(fOpList);
robertphillipsa106c622015-10-16 09:07:06 -0700112}
113
Robert Phillipseaa86252016-11-08 13:49:39 +0000114GrRenderTarget* GrRenderTargetContext::instantiate() {
Brian Osman32342f02017-03-04 08:12:46 -0500115 return fRenderTargetProxy->instantiate(fContext->resourceProvider());
Robert Phillipseaa86252016-11-08 13:49:39 +0000116}
117
Robert Phillipsf200a902017-01-30 13:27:37 -0500118GrTextureProxy* GrRenderTargetContext::asTextureProxy() {
Robert Phillipseaa86252016-11-08 13:49:39 +0000119 return fRenderTargetProxy->asTextureProxy();
120}
121
Robert Phillipsf200a902017-01-30 13:27:37 -0500122sk_sp<GrTextureProxy> GrRenderTargetContext::asTextureProxyRef() {
123 return sk_ref_sp(fRenderTargetProxy->asTextureProxy());
124}
125
Brian Osman11052242016-10-27 14:47:55 -0400126GrRenderTargetOpList* GrRenderTargetContext::getOpList() {
joshualitt1de610a2016-01-06 08:26:09 -0800127 ASSERT_SINGLE_OWNER
robertphillipsa106c622015-10-16 09:07:06 -0700128 SkDEBUGCODE(this->validate();)
129
Robert Phillipsf2361d22016-10-25 14:20:06 -0400130 if (!fOpList || fOpList->isClosed()) {
Robert Phillips72152832017-01-25 17:31:35 -0500131 fOpList = this->drawingManager()->newOpList(fRenderTargetProxy.get());
robertphillipsa106c622015-10-16 09:07:06 -0700132 }
133
Robert Phillipsf2361d22016-10-25 14:20:06 -0400134 return fOpList;
robertphillipsa106c622015-10-16 09:07:06 -0700135}
136
Robert Phillipse2f7d182016-12-15 09:23:05 -0500137// TODO: move this (and GrTextContext::copy) to GrSurfaceContext?
138bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy,
139 const SkIRect& srcRect,
140 const SkIPoint& dstPoint) {
joshualitt1de610a2016-01-06 08:26:09 -0800141 ASSERT_SINGLE_OWNER
bsalomonb8fea972016-02-16 07:34:17 -0800142 RETURN_FALSE_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700143 SkDEBUGCODE(this->validate();)
Robert Phillipse2f7d182016-12-15 09:23:05 -0500144 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copy");
145
146 // TODO: defer instantiation until flush time
Brian Osman32342f02017-03-04 08:12:46 -0500147 sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->resourceProvider())));
Robert Phillipse2f7d182016-12-15 09:23:05 -0500148 if (!src) {
149 return false;
150 }
robertphillips2d70dcb2015-10-06 07:38:23 -0700151
Brian Salomon69868af2016-12-22 15:42:51 -0500152 // TODO: This needs to be fixed up since it ends the deferral of the GrRenderTarget.
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400153 sk_sp<GrRenderTarget> rt(
Brian Osman32342f02017-03-04 08:12:46 -0500154 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -0500155 if (!rt) {
156 return false;
157 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400158
Robert Phillipse2f7d182016-12-15 09:23:05 -0500159 return this->getOpList()->copySurface(rt.get(), src.get(), srcRect, dstPoint);
robertphillipsea461502015-05-26 11:38:03 -0700160}
161
Robert Phillips2c862492017-01-18 10:08:39 -0500162// TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext?
163bool GrRenderTargetContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
164 size_t dstRowBytes, int x, int y) {
165 // TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels
166 GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
167 if (kUnknown_GrPixelConfig == config) {
168 return false;
169 }
170
171 uint32_t flags = 0;
172 if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
173 flags = GrContext::kUnpremul_PixelOpsFlag;
174 }
175
176 // Deferral of the VRAM resources must end in this instance anyway
177 sk_sp<GrRenderTarget> rt(
Brian Osman32342f02017-03-04 08:12:46 -0500178 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider())));
Robert Phillips2c862492017-01-18 10:08:39 -0500179 if (!rt) {
180 return false;
181 }
182
183 return rt->readPixels(this->getColorSpace(), x, y, dstInfo.width(), dstInfo.height(),
184 config, dstInfo.colorSpace(), dstBuffer, dstRowBytes, flags);
185}
186
187// TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext?
188bool GrRenderTargetContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
Robert Phillips30f9bc62017-02-22 15:28:38 -0500189 size_t srcRowBytes, int x, int y, uint32_t flags) {
Robert Phillips2c862492017-01-18 10:08:39 -0500190 // TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels
191 GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
192 if (kUnknown_GrPixelConfig == config) {
193 return false;
194 }
Robert Phillips2c862492017-01-18 10:08:39 -0500195 if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
Robert Phillips30f9bc62017-02-22 15:28:38 -0500196 flags |= GrContext::kUnpremul_PixelOpsFlag;
Robert Phillips2c862492017-01-18 10:08:39 -0500197 }
198
199 // Deferral of the VRAM resources must end in this instance anyway
200 sk_sp<GrRenderTarget> rt(
Brian Osman32342f02017-03-04 08:12:46 -0500201 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider())));
Robert Phillips2c862492017-01-18 10:08:39 -0500202 if (!rt) {
203 return false;
204 }
205
206 return rt->writePixels(this->getColorSpace(), x, y, srcInfo.width(), srcInfo.height(),
207 config, srcInfo.colorSpace(), srcBuffer, srcRowBytes, flags);
208}
209
210
Brian Salomon6f1d36c2017-01-13 12:02:17 -0500211void GrRenderTargetContext::drawText(const GrClip& clip, const SkPaint& skPaint,
Brian Salomon82f44312017-01-11 13:42:54 -0500212 const SkMatrix& viewMatrix, const char text[],
213 size_t byteLength, SkScalar x, SkScalar y,
214 const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800215 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700216 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700217 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400218 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700219
Robert Phillips72152832017-01-25 17:31:35 -0500220 GrAtlasTextContext* atlasTextContext = this->drawingManager()->getAtlasTextContext();
Brian Salomon6f1d36c2017-01-13 12:02:17 -0500221 atlasTextContext->drawText(fContext, this, clip, skPaint, viewMatrix, fSurfaceProps, text,
222 byteLength, x, y, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700223}
robertphillipscaef3452015-11-11 13:18:11 -0800224
Brian Salomon6f1d36c2017-01-13 12:02:17 -0500225void GrRenderTargetContext::drawPosText(const GrClip& clip, const SkPaint& paint,
226 const SkMatrix& viewMatrix, const char text[],
227 size_t byteLength, const SkScalar pos[],
Brian Salomon82f44312017-01-11 13:42:54 -0500228 int scalarsPerPosition, const SkPoint& offset,
229 const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800230 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700231 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700232 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400233 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPosText");
robertphillips2d70dcb2015-10-06 07:38:23 -0700234
Robert Phillips72152832017-01-25 17:31:35 -0500235 GrAtlasTextContext* atlasTextContext = this->drawingManager()->getAtlasTextContext();
Brian Salomon6f1d36c2017-01-13 12:02:17 -0500236 atlasTextContext->drawPosText(fContext, this, clip, paint, viewMatrix, fSurfaceProps, text,
237 byteLength, pos, scalarsPerPosition, offset, clipBounds);
robertphillips2334fb62015-06-17 05:43:33 -0700238}
robertphillipscaef3452015-11-11 13:18:11 -0800239
Brian Salomon6f1d36c2017-01-13 12:02:17 -0500240void GrRenderTargetContext::drawTextBlob(const GrClip& clip, const SkPaint& paint,
Brian Osman11052242016-10-27 14:47:55 -0400241 const SkMatrix& viewMatrix, const SkTextBlob* blob,
Brian Salomon6f1d36c2017-01-13 12:02:17 -0500242 SkScalar x, SkScalar y, SkDrawFilter* filter,
243 const SkIRect& clipBounds) {
joshualitt1de610a2016-01-06 08:26:09 -0800244 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -0700245 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700246 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400247 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawTextBlob");
robertphillips2d70dcb2015-10-06 07:38:23 -0700248
Robert Phillips72152832017-01-25 17:31:35 -0500249 GrAtlasTextContext* atlasTextContext = this->drawingManager()->getAtlasTextContext();
Brian Salomon6f1d36c2017-01-13 12:02:17 -0500250 atlasTextContext->drawTextBlob(fContext, this, clip, paint, viewMatrix, fSurfaceProps, blob, x,
251 y, filter, clipBounds);
robertphillipsea461502015-05-26 11:38:03 -0700252}
253
Brian Osman11052242016-10-27 14:47:55 -0400254void GrRenderTargetContext::discard() {
joshualitt1de610a2016-01-06 08:26:09 -0800255 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700256 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700257 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400258 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::discard");
robertphillips2e1e51f2015-10-15 08:01:48 -0700259
Robert Phillips72152832017-01-25 17:31:35 -0500260 AutoCheckFlush acf(this->drawingManager());
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400261
Brian Salomon69868af2016-12-22 15:42:51 -0500262 // TODO: This needs to be fixed up since it ends the deferral of the GrRenderTarget.
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400263 sk_sp<GrRenderTarget> rt(
Brian Osman32342f02017-03-04 08:12:46 -0500264 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -0500265 if (!rt) {
266 return;
267 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400268
Brian Salomon69868af2016-12-22 15:42:51 -0500269 this->getOpList()->discard(this);
robertphillipsea461502015-05-26 11:38:03 -0700270}
271
Brian Osman11052242016-10-27 14:47:55 -0400272void GrRenderTargetContext::clear(const SkIRect* rect,
273 const GrColor color,
274 bool canIgnoreRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800275 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700276 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700277 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400278 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::clear");
robertphillipsea461502015-05-26 11:38:03 -0700279
Robert Phillips72152832017-01-25 17:31:35 -0500280 AutoCheckFlush acf(this->drawingManager());
csmartdalton29df7602016-08-31 11:55:52 -0700281 this->internalClear(rect ? GrFixedClip(*rect) : GrFixedClip::Disabled(), color, canIgnoreRect);
282}
robertphillips9199a9f2016-07-13 07:48:43 -0700283
Robert Phillips784b7bf2016-12-09 13:35:02 -0500284void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const GrColor color) {
285 ASSERT_SINGLE_OWNER_PRIV
286 RETURN_IF_ABANDONED_PRIV
287 SkDEBUGCODE(fRenderTargetContext->validate();)
288 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
289 "GrRenderTargetContext::absClear");
290
Robert Phillips72152832017-01-25 17:31:35 -0500291 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
Robert Phillips784b7bf2016-12-09 13:35:02 -0500292
293 SkIRect rtRect = SkIRect::MakeWH(fRenderTargetContext->fRenderTargetProxy->worstCaseWidth(
294 *fRenderTargetContext->caps()),
295 fRenderTargetContext->fRenderTargetProxy->worstCaseHeight(
296 *fRenderTargetContext->caps()));
297
298 if (clearRect) {
299 if (clearRect->contains(rtRect)) {
300 clearRect = nullptr; // full screen
301 } else {
302 if (!rtRect.intersect(*clearRect)) {
303 return;
304 }
305 }
306 }
307
308 // TODO: in a post-MDB world this should be handled at the OpList level.
309 // An op-list that is initially cleared and has no other ops should receive an
310 // extra draw.
311 if (fRenderTargetContext->fContext->caps()->useDrawInsteadOfClear()) {
312 // This works around a driver bug with clear by drawing a rect instead.
313 // The driver will ignore a clear if it is the only thing rendered to a
314 // target before the target is read.
315 GrPaint paint;
316 paint.setColor4f(GrColor4f::FromGrColor(color));
Brian Salomona1633922017-01-09 11:46:10 -0500317 paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
Robert Phillips784b7bf2016-12-09 13:35:02 -0500318
319 // We don't call drawRect() here to avoid the cropping to the, possibly smaller,
320 // RenderTargetProxy bounds
Brian Salomon82f44312017-01-11 13:42:54 -0500321 fRenderTargetContext->drawNonAAFilledRect(GrNoClip(), std::move(paint), SkMatrix::I(),
322 SkRect::Make(rtRect), nullptr, nullptr, nullptr,
323 GrAAType::kNone);
Robert Phillips784b7bf2016-12-09 13:35:02 -0500324
325 } else {
326 if (!fRenderTargetContext->accessRenderTarget()) {
327 return;
328 }
329
330 // This path doesn't handle coalescing of full screen clears b.c. it
331 // has to clear the entire render target - not just the content area.
332 // It could be done but will take more finagling.
Brian Salomonf8334782017-01-03 09:42:58 -0500333 std::unique_ptr<GrOp> op(GrClearOp::Make(
334 rtRect, color, fRenderTargetContext->accessRenderTarget(), !clearRect));
Brian Salomonfc527d22016-12-14 21:07:01 -0500335 if (!op) {
Robert Phillips784b7bf2016-12-09 13:35:02 -0500336 return;
337 }
Brian Salomon69868af2016-12-22 15:42:51 -0500338 fRenderTargetContext->getOpList()->addOp(std::move(op), fRenderTargetContext);
Robert Phillips784b7bf2016-12-09 13:35:02 -0500339 }
340}
341
Brian Osman11052242016-10-27 14:47:55 -0400342void GrRenderTargetContextPriv::clear(const GrFixedClip& clip,
343 const GrColor color,
344 bool canIgnoreClip) {
csmartdalton29df7602016-08-31 11:55:52 -0700345 ASSERT_SINGLE_OWNER_PRIV
346 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400347 SkDEBUGCODE(fRenderTargetContext->validate();)
348 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
349 "GrRenderTargetContextPriv::clear");
csmartdalton29df7602016-08-31 11:55:52 -0700350
Robert Phillips72152832017-01-25 17:31:35 -0500351 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
Brian Osman11052242016-10-27 14:47:55 -0400352 fRenderTargetContext->internalClear(clip, color, canIgnoreClip);
csmartdalton29df7602016-08-31 11:55:52 -0700353}
354
Brian Osman11052242016-10-27 14:47:55 -0400355void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
356 const GrColor color,
357 bool canIgnoreClip) {
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700358 bool isFull = false;
359 if (!clip.hasWindowRectangles()) {
360 isFull = !clip.scissorEnabled() ||
361 (canIgnoreClip && fContext->caps()->fullClearIsFree()) ||
362 clip.scissorRect().contains(SkIRect::MakeWH(this->width(), this->height()));
363 }
robertphillips9199a9f2016-07-13 07:48:43 -0700364
365 if (fContext->caps()->useDrawInsteadOfClear()) {
366 // This works around a driver bug with clear by drawing a rect instead.
367 // The driver will ignore a clear if it is the only thing rendered to a
368 // target before the target is read.
Robert Phillips784b7bf2016-12-09 13:35:02 -0500369 SkIRect clearRect = SkIRect::MakeWH(this->width(), this->height());
csmartdalton29df7602016-08-31 11:55:52 -0700370 if (isFull) {
robertphillips9199a9f2016-07-13 07:48:43 -0700371 this->discard();
Robert Phillips93f16332016-11-23 19:37:13 -0500372 } else if (!clearRect.intersect(clip.scissorRect())) {
csmartdalton29df7602016-08-31 11:55:52 -0700373 return;
robertphillips9199a9f2016-07-13 07:48:43 -0700374 }
375
376 GrPaint paint;
377 paint.setColor4f(GrColor4f::FromGrColor(color));
Brian Salomona1633922017-01-09 11:46:10 -0500378 paint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
robertphillips9199a9f2016-07-13 07:48:43 -0700379
Brian Salomon82f44312017-01-11 13:42:54 -0500380 this->drawRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), SkRect::Make(clearRect));
bsalomon9f129de2016-08-10 16:31:05 -0700381 } else if (isFull) {
Robert Phillipse60ad622016-11-17 10:22:48 -0500382 if (this->accessRenderTarget()) {
Brian Salomon69868af2016-12-22 15:42:51 -0500383 this->getOpList()->fullClear(this, color);
Robert Phillipse60ad622016-11-17 10:22:48 -0500384 }
robertphillips9199a9f2016-07-13 07:48:43 -0700385 } else {
Robert Phillipse60ad622016-11-17 10:22:48 -0500386 if (!this->accessRenderTarget()) {
387 return;
388 }
Brian Salomonf8334782017-01-03 09:42:58 -0500389 std::unique_ptr<GrOp> op(GrClearOp::Make(clip, color, this->accessRenderTarget()));
Brian Salomon42521e82016-12-07 16:44:58 -0500390 if (!op) {
csmartdalton29df7602016-08-31 11:55:52 -0700391 return;
392 }
Brian Salomon69868af2016-12-22 15:42:51 -0500393 this->getOpList()->addOp(std::move(op), this);
robertphillips9199a9f2016-07-13 07:48:43 -0700394 }
robertphillipsea461502015-05-26 11:38:03 -0700395}
396
Brian Osman11052242016-10-27 14:47:55 -0400397void GrRenderTargetContext::drawPaint(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500398 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -0400399 const SkMatrix& viewMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800400 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700401 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700402 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400403 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPaint");
robertphillips2e1e51f2015-10-15 08:01:48 -0700404
robertphillipsea461502015-05-26 11:38:03 -0700405 // set rect to be big enough to fill the space, but not super-huge, so we
406 // don't overflow fixed-point implementations
robertphillips13a7eee2016-08-31 15:06:24 -0700407
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400408 SkRect r = fRenderTargetProxy->getBoundsRect();
robertphillipsea461502015-05-26 11:38:03 -0700409
bsalomoncb31e512016-08-26 10:48:19 -0700410 SkRRect rrect;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500411 GrAA aa;
bsalomoncb31e512016-08-26 10:48:19 -0700412 // Check if we can replace a clipRRect()/drawPaint() with a drawRRect(). We only do the
413 // transformation for non-rect rrects. Rects caused a performance regression on an Android
414 // test that needs investigation. We also skip cases where there are fragment processors
415 // because they may depend on having correct local coords and this path draws in device space
416 // without a local matrix.
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500417 if (!paint.numTotalFragmentProcessors() && clip.isRRect(r, &rrect, &aa) && !rrect.isRect()) {
Brian Salomon82f44312017-01-11 13:42:54 -0500418 this->drawRRect(GrNoClip(), std::move(paint), aa, SkMatrix::I(), rrect,
419 GrStyle::SimpleFill());
bsalomoncb31e512016-08-26 10:48:19 -0700420 return;
421 }
422
robertphillipsea461502015-05-26 11:38:03 -0700423
424 bool isPerspective = viewMatrix.hasPerspective();
425
426 // We attempt to map r by the inverse matrix and draw that. mapRect will
427 // map the four corners and bound them with a new rect. This will not
428 // produce a correct result for some perspective matrices.
429 if (!isPerspective) {
reeda39667c2016-08-22 06:39:49 -0700430 if (!SkMatrixPriv::InverseMapRect(viewMatrix, &r, r)) {
robertphillipsea461502015-05-26 11:38:03 -0700431 SkDebugf("Could not invert matrix\n");
432 return;
433 }
Brian Salomon82f44312017-01-11 13:42:54 -0500434 this->drawRect(clip, std::move(paint), GrAA::kNo, viewMatrix, r);
robertphillipsea461502015-05-26 11:38:03 -0700435 } else {
436 SkMatrix localMatrix;
437 if (!viewMatrix.invert(&localMatrix)) {
438 SkDebugf("Could not invert matrix\n");
439 return;
440 }
441
Robert Phillips72152832017-01-25 17:31:35 -0500442 AutoCheckFlush acf(this->drawingManager());
robertphillipsea461502015-05-26 11:38:03 -0700443
Brian Salomon82f44312017-01-11 13:42:54 -0500444 this->drawNonAAFilledRect(clip, std::move(paint), SkMatrix::I(), r, nullptr, &localMatrix,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500445 nullptr, GrAAType::kNone);
robertphillipsea461502015-05-26 11:38:03 -0700446 }
447}
448
robertphillipsea461502015-05-26 11:38:03 -0700449static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
450 return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
451 point.fY >= rect.fTop && point.fY <= rect.fBottom;
452}
453
bsalomonc55271f2015-11-09 11:55:57 -0800454static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
455 return viewMatrix.preservesRightAngles();
456}
457
csmartdalton97f6cd52016-07-13 13:37:08 -0700458// Attempts to crop a rect and optional local rect to the clip boundaries.
459// Returns false if the draw can be skipped entirely.
robertphillips13a7eee2016-08-31 15:06:24 -0700460static bool crop_filled_rect(int width, int height, const GrClip& clip,
csmartdalton97f6cd52016-07-13 13:37:08 -0700461 const SkMatrix& viewMatrix, SkRect* rect,
462 SkRect* localRect = nullptr) {
463 if (!viewMatrix.rectStaysRect()) {
464 return true;
465 }
466
csmartdalton97f6cd52016-07-13 13:37:08 -0700467 SkIRect clipDevBounds;
468 SkRect clipBounds;
csmartdalton97f6cd52016-07-13 13:37:08 -0700469
robertphillips13a7eee2016-08-31 15:06:24 -0700470 clip.getConservativeBounds(width, height, &clipDevBounds);
reeda39667c2016-08-22 06:39:49 -0700471 if (!SkMatrixPriv::InverseMapRect(viewMatrix, &clipBounds, SkRect::Make(clipDevBounds))) {
472 return false;
473 }
csmartdalton97f6cd52016-07-13 13:37:08 -0700474
475 if (localRect) {
476 if (!rect->intersects(clipBounds)) {
477 return false;
478 }
479 const SkScalar dx = localRect->width() / rect->width();
480 const SkScalar dy = localRect->height() / rect->height();
481 if (clipBounds.fLeft > rect->fLeft) {
482 localRect->fLeft += (clipBounds.fLeft - rect->fLeft) * dx;
483 rect->fLeft = clipBounds.fLeft;
484 }
485 if (clipBounds.fTop > rect->fTop) {
486 localRect->fTop += (clipBounds.fTop - rect->fTop) * dy;
487 rect->fTop = clipBounds.fTop;
488 }
489 if (clipBounds.fRight < rect->fRight) {
490 localRect->fRight -= (rect->fRight - clipBounds.fRight) * dx;
491 rect->fRight = clipBounds.fRight;
492 }
493 if (clipBounds.fBottom < rect->fBottom) {
494 localRect->fBottom -= (rect->fBottom - clipBounds.fBottom) * dy;
495 rect->fBottom = clipBounds.fBottom;
496 }
497 return true;
498 }
499
500 return rect->intersect(clipBounds);
501}
502
Brian Osman11052242016-10-27 14:47:55 -0400503bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500504 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500505 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400506 const SkMatrix& viewMatrix,
507 const SkRect& rect,
508 const GrUserStencilSettings* ss) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700509 SkRect croppedRect = rect;
Robert Phillips784b7bf2016-12-09 13:35:02 -0500510 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &croppedRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700511 return true;
512 }
robertphillips44302392016-07-08 14:43:03 -0700513
Brian Salomonf8334782017-01-03 09:42:58 -0500514 std::unique_ptr<GrDrawOp> op;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500515 GrAAType aaType;
robertphillips44302392016-07-08 14:43:03 -0700516
csmartdaltone0d36292016-07-29 08:14:20 -0700517 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400518 InstancedRendering* ir = this->getOpList()->instancedRendering();
Brian Salomon99ad1642016-12-16 09:50:45 -0500519 op = ir->recordRect(croppedRect, viewMatrix, paint.getColor(), aa, fInstancedPipelineInfo,
520 &aaType);
Brian Salomon42521e82016-12-07 16:44:58 -0500521 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -0500522 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
robertphillips44302392016-07-08 14:43:03 -0700523 if (ss) {
524 pipelineBuilder.setUserStencil(ss);
525 }
Brian Salomon21aa35f2016-12-09 16:01:53 -0500526 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillips44302392016-07-08 14:43:03 -0700527 return true;
csmartdaltona7f29642016-07-07 08:49:11 -0700528 }
529 }
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500530 aaType = this->decideAAType(aa);
531 if (GrAAType::kCoverage == aaType) {
robertphillips391395d2016-03-02 09:26:36 -0800532 // The fill path can handle rotation but not skew.
533 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
534 SkRect devBoundRect;
csmartdalton97f6cd52016-07-13 13:37:08 -0700535 viewMatrix.mapRect(&devBoundRect, croppedRect);
robertphillips44302392016-07-08 14:43:03 -0700536
Brian Salomon6a639042016-12-14 11:08:17 -0500537 op = GrRectOpFactory::MakeAAFill(paint, viewMatrix, rect, croppedRect, devBoundRect);
Brian Salomon42521e82016-12-07 16:44:58 -0500538 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -0500539 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
robertphillips44302392016-07-08 14:43:03 -0700540 if (ss) {
541 pipelineBuilder.setUserStencil(ss);
542 }
Brian Salomon21aa35f2016-12-09 16:01:53 -0500543 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillips44302392016-07-08 14:43:03 -0700544 return true;
545 }
robertphillips391395d2016-03-02 09:26:36 -0800546 }
547 } else {
Brian Salomon82f44312017-01-11 13:42:54 -0500548 this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, nullptr, nullptr,
549 ss, aaType);
robertphillips44302392016-07-08 14:43:03 -0700550 return true;
robertphillips391395d2016-03-02 09:26:36 -0800551 }
552
robertphillips44302392016-07-08 14:43:03 -0700553 return false;
robertphillips391395d2016-03-02 09:26:36 -0800554}
555
Brian Osman11052242016-10-27 14:47:55 -0400556void GrRenderTargetContext::drawRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500557 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500558 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400559 const SkMatrix& viewMatrix,
560 const SkRect& rect,
561 const GrStyle* style) {
bsalomon6663acf2016-05-10 09:14:17 -0700562 if (!style) {
563 style = &GrStyle::SimpleFill();
564 }
joshualitt1de610a2016-01-06 08:26:09 -0800565 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700566 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700567 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400568 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawRect");
robertphillips2e1e51f2015-10-15 08:01:48 -0700569
bsalomon6663acf2016-05-10 09:14:17 -0700570 // Path effects should've been devolved to a path in SkGpuDevice
571 SkASSERT(!style->pathEffect());
robertphillipsea461502015-05-26 11:38:03 -0700572
Robert Phillips72152832017-01-25 17:31:35 -0500573 AutoCheckFlush acf(this->drawingManager());
robertphillipsea461502015-05-26 11:38:03 -0700574
bsalomon6663acf2016-05-10 09:14:17 -0700575 const SkStrokeRec& stroke = style->strokeRec();
robertphillips3ab14ca2016-07-10 11:49:39 -0700576 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
577
578 if (!fContext->caps()->useDrawInsteadOfClear()) {
579 // Check if this is a full RT draw and can be replaced with a clear. We don't bother
580 // checking cases where the RT is fully inside a stroke.
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400581 SkRect rtRect = fRenderTargetProxy->getBoundsRect();
robertphillips3ab14ca2016-07-10 11:49:39 -0700582 // Does the clip contain the entire RT?
583 if (clip.quickContains(rtRect)) {
584 SkMatrix invM;
585 if (!viewMatrix.invert(&invM)) {
robertphillipsea461502015-05-26 11:38:03 -0700586 return;
587 }
robertphillips3ab14ca2016-07-10 11:49:39 -0700588 // Does the rect bound the RT?
589 SkPoint srcSpaceRTQuad[4];
590 invM.mapRectToQuad(srcSpaceRTQuad, rtRect);
591 if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) &&
592 rect_contains_inclusive(rect, srcSpaceRTQuad[1]) &&
593 rect_contains_inclusive(rect, srcSpaceRTQuad[2]) &&
594 rect_contains_inclusive(rect, srcSpaceRTQuad[3])) {
595 // Will it blend?
596 GrColor clearColor;
597 if (paint.isConstantBlendedColor(&clearColor)) {
robertphillips9199a9f2016-07-13 07:48:43 -0700598 this->clear(nullptr, clearColor, true);
robertphillips3ab14ca2016-07-10 11:49:39 -0700599 return;
600 }
601 }
robertphillipsea461502015-05-26 11:38:03 -0700602 }
603 }
robertphillips44302392016-07-08 14:43:03 -0700604
Brian Salomon82f44312017-01-11 13:42:54 -0500605 if (this->drawFilledRect(clip, std::move(paint), aa, viewMatrix, rect, nullptr)) {
robertphillips44302392016-07-08 14:43:03 -0700606 return;
607 }
bsalomona7d85ba2016-07-06 11:54:59 -0700608 } else if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
609 stroke.getStyle() == SkStrokeRec::kHairline_Style) {
610 if ((!rect.width() || !rect.height()) &&
611 SkStrokeRec::kHairline_Style != stroke.getStyle()) {
612 SkScalar r = stroke.getWidth() / 2;
613 // TODO: Move these stroke->fill fallbacks to GrShape?
614 switch (stroke.getJoin()) {
615 case SkPaint::kMiter_Join:
Brian Salomon82f44312017-01-11 13:42:54 -0500616 this->drawRect(
617 clip, std::move(paint), aa, viewMatrix,
618 {rect.fLeft - r, rect.fTop - r, rect.fRight + r, rect.fBottom + r},
619 &GrStyle::SimpleFill());
bsalomona7d85ba2016-07-06 11:54:59 -0700620 return;
621 case SkPaint::kRound_Join:
622 // Raster draws nothing when both dimensions are empty.
623 if (rect.width() || rect.height()){
624 SkRRect rrect = SkRRect::MakeRectXY(rect.makeOutset(r, r), r, r);
Brian Salomon82f44312017-01-11 13:42:54 -0500625 this->drawRRect(clip, std::move(paint), aa, viewMatrix, rrect,
626 GrStyle::SimpleFill());
bsalomona7d85ba2016-07-06 11:54:59 -0700627 return;
628 }
629 case SkPaint::kBevel_Join:
630 if (!rect.width()) {
Brian Salomon82f44312017-01-11 13:42:54 -0500631 this->drawRect(clip, std::move(paint), aa, viewMatrix,
bsalomona7d85ba2016-07-06 11:54:59 -0700632 {rect.fLeft - r, rect.fTop, rect.fRight + r, rect.fBottom},
633 &GrStyle::SimpleFill());
634 } else {
Brian Salomon82f44312017-01-11 13:42:54 -0500635 this->drawRect(clip, std::move(paint), aa, viewMatrix,
bsalomona7d85ba2016-07-06 11:54:59 -0700636 {rect.fLeft, rect.fTop - r, rect.fRight, rect.fBottom + r},
637 &GrStyle::SimpleFill());
638 }
639 return;
640 }
641 }
robertphillips44302392016-07-08 14:43:03 -0700642
robertphillips44302392016-07-08 14:43:03 -0700643 bool snapToPixelCenters = false;
Brian Salomonf8334782017-01-03 09:42:58 -0500644 std::unique_ptr<GrDrawOp> op;
robertphillips44302392016-07-08 14:43:03 -0700645
robertphillips391395d2016-03-02 09:26:36 -0800646 GrColor color = paint.getColor();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500647 GrAAType aaType = this->decideAAType(aa);
648 if (GrAAType::kCoverage == aaType) {
cdaltonbb539482016-01-04 09:48:25 -0800649 // The stroke path needs the rect to remain axis aligned (no rotation or skew).
650 if (viewMatrix.rectStaysRect()) {
Brian Salomon6a639042016-12-14 11:08:17 -0500651 op = GrRectOpFactory::MakeAAStroke(color, viewMatrix, rect, stroke);
cdaltonbb539482016-01-04 09:48:25 -0800652 }
robertphillipsea461502015-05-26 11:38:03 -0700653 } else {
robertphillips391395d2016-03-02 09:26:36 -0800654 // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
halcanary9d524f22016-03-29 09:03:52 -0700655 // hairline rects. We jam all the vertices to pixel centers to avoid this, but not
robertphillips391395d2016-03-02 09:26:36 -0800656 // when MSAA is enabled because it can cause ugly artifacts.
bsalomona7d85ba2016-07-06 11:54:59 -0700657 snapToPixelCenters = stroke.getStyle() == SkStrokeRec::kHairline_Style &&
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400658 !fRenderTargetProxy->isUnifiedMultisampled();
Brian Salomon6a639042016-12-14 11:08:17 -0500659 op = GrRectOpFactory::MakeNonAAStroke(color, viewMatrix, rect, stroke,
660 snapToPixelCenters);
robertphillips391395d2016-03-02 09:26:36 -0800661 }
robertphillips4bc31812016-03-01 12:22:49 -0800662
Brian Salomon42521e82016-12-07 16:44:58 -0500663 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -0500664 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon189098e72017-01-19 09:55:19 -0500665 pipelineBuilder.setSnapVerticesToPixelCenters(snapToPixelCenters);
Brian Salomon21aa35f2016-12-09 16:01:53 -0500666 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillips44302392016-07-08 14:43:03 -0700667 return;
robertphillips4bc31812016-03-01 12:22:49 -0800668 }
robertphillips4bc31812016-03-01 12:22:49 -0800669 }
halcanary9d524f22016-03-29 09:03:52 -0700670
robertphillips4bc31812016-03-01 12:22:49 -0800671 SkPath path;
672 path.setIsVolatile(true);
673 path.addRect(rect);
Brian Salomon82f44312017-01-11 13:42:54 -0500674 this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, *style);
robertphillipsea461502015-05-26 11:38:03 -0700675}
676
Robert Phillipsec2249f2016-11-09 08:54:35 -0500677int GrRenderTargetContextPriv::maxWindowRectangles() const {
678 return fRenderTargetContext->fRenderTargetProxy->maxWindowRectangles(
679 *fRenderTargetContext->fContext->caps());
680}
681
Brian Osman11052242016-10-27 14:47:55 -0400682void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
robertphillips976f5f02016-06-03 10:59:20 -0700683 ASSERT_SINGLE_OWNER_PRIV
684 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400685 SkDEBUGCODE(fRenderTargetContext->validate();)
686 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
687 "GrRenderTargetContextPriv::clearStencilClip");
robertphillips976f5f02016-06-03 10:59:20 -0700688
Robert Phillips72152832017-01-25 17:31:35 -0500689 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
Brian Salomon69868af2016-12-22 15:42:51 -0500690 // TODO: This needs to be fixed up since it ends the deferral of the GrRenderTarget.
Robert Phillipse60ad622016-11-17 10:22:48 -0500691 if (!fRenderTargetContext->accessRenderTarget()) {
692 return;
693 }
Brian Osman11052242016-10-27 14:47:55 -0400694 fRenderTargetContext->getOpList()->clearStencilClip(clip, insideStencilMask,
Brian Salomon69868af2016-12-22 15:42:51 -0500695 fRenderTargetContext);
robertphillips976f5f02016-06-03 10:59:20 -0700696}
697
Brian Osman11052242016-10-27 14:47:55 -0400698void GrRenderTargetContextPriv::stencilPath(const GrClip& clip,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500699 GrAAType aaType,
Brian Osman11052242016-10-27 14:47:55 -0400700 const SkMatrix& viewMatrix,
701 const GrPath* path) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500702 SkASSERT(aaType != GrAAType::kCoverage);
703 fRenderTargetContext->getOpList()->stencilPath(fRenderTargetContext, clip, aaType, viewMatrix,
Brian Osman11052242016-10-27 14:47:55 -0400704 path);
robertphillips976f5f02016-06-03 10:59:20 -0700705}
706
Brian Osman11052242016-10-27 14:47:55 -0400707void GrRenderTargetContextPriv::stencilRect(const GrClip& clip,
708 const GrUserStencilSettings* ss,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500709 GrAAType aaType,
Brian Osman11052242016-10-27 14:47:55 -0400710 const SkMatrix& viewMatrix,
711 const SkRect& rect) {
robertphillips976f5f02016-06-03 10:59:20 -0700712 ASSERT_SINGLE_OWNER_PRIV
713 RETURN_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400714 SkDEBUGCODE(fRenderTargetContext->validate();)
715 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
716 "GrRenderTargetContext::stencilRect");
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500717 SkASSERT(GrAAType::kCoverage != aaType);
Robert Phillips72152832017-01-25 17:31:35 -0500718 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
robertphillips976f5f02016-06-03 10:59:20 -0700719
720 GrPaint paint;
Brian Salomona1633922017-01-09 11:46:10 -0500721 paint.setXPFactory(GrDisableColorXPFactory::Get());
robertphillips976f5f02016-06-03 10:59:20 -0700722
Brian Salomon82f44312017-01-11 13:42:54 -0500723 fRenderTargetContext->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, rect, nullptr,
724 nullptr, ss, aaType);
robertphillips976f5f02016-06-03 10:59:20 -0700725}
726
Brian Osman11052242016-10-27 14:47:55 -0400727bool GrRenderTargetContextPriv::drawAndStencilRect(const GrClip& clip,
728 const GrUserStencilSettings* ss,
729 SkRegion::Op op,
730 bool invert,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500731 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400732 const SkMatrix& viewMatrix,
733 const SkRect& rect) {
robertphillips391395d2016-03-02 09:26:36 -0800734 ASSERT_SINGLE_OWNER_PRIV
735 RETURN_FALSE_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -0400736 SkDEBUGCODE(fRenderTargetContext->validate();)
737 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
738 "GrRenderTargetContext::drawAndStencilRect");
robertphillips391395d2016-03-02 09:26:36 -0800739
Robert Phillips72152832017-01-25 17:31:35 -0500740 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
robertphillips391395d2016-03-02 09:26:36 -0800741
742 GrPaint paint;
robertphillips391395d2016-03-02 09:26:36 -0800743 paint.setCoverageSetOpXPFactory(op, invert);
744
Brian Salomon82f44312017-01-11 13:42:54 -0500745 if (fRenderTargetContext->drawFilledRect(clip, std::move(paint), aa, viewMatrix, rect, ss)) {
robertphillips391395d2016-03-02 09:26:36 -0800746 return true;
747 }
robertphillips391395d2016-03-02 09:26:36 -0800748 SkPath path;
749 path.setIsVolatile(true);
750 path.addRect(rect);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500751 return this->drawAndStencilPath(clip, ss, op, invert, aa, viewMatrix, path);
robertphillips391395d2016-03-02 09:26:36 -0800752}
753
Brian Osman11052242016-10-27 14:47:55 -0400754void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500755 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500756 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400757 const SkMatrix& viewMatrix,
758 const SkRect& rectToDraw,
759 const SkRect& localRect) {
joshualitt1de610a2016-01-06 08:26:09 -0800760 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700761 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700762 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400763 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::fillRectToRect");
robertphillipsea461502015-05-26 11:38:03 -0700764
csmartdalton97f6cd52016-07-13 13:37:08 -0700765 SkRect croppedRect = rectToDraw;
766 SkRect croppedLocalRect = localRect;
robertphillips13a7eee2016-08-31 15:06:24 -0700767 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix,
768 &croppedRect, &croppedLocalRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700769 return;
770 }
771
Robert Phillips72152832017-01-25 17:31:35 -0500772 AutoCheckFlush acf(this->drawingManager());
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500773 GrAAType aaType;
csmartdaltona7f29642016-07-07 08:49:11 -0700774
csmartdaltone0d36292016-07-29 08:14:20 -0700775 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400776 InstancedRendering* ir = this->getOpList()->instancedRendering();
Brian Salomonf8334782017-01-03 09:42:58 -0500777 std::unique_ptr<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
778 croppedLocalRect, aa, fInstancedPipelineInfo,
779 &aaType));
Brian Salomon42521e82016-12-07 16:44:58 -0500780 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -0500781 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -0500782 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
csmartdaltona7f29642016-07-07 08:49:11 -0700783 return;
784 }
785 }
786
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500787 aaType = this->decideAAType(aa);
788 if (GrAAType::kCoverage != aaType) {
Brian Salomon82f44312017-01-11 13:42:54 -0500789 this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect,
790 &croppedLocalRect, nullptr, nullptr, aaType);
csmartdaltonfc49d562016-07-26 17:05:47 -0700791 return;
joshualitt04194f32016-01-13 10:08:27 -0800792 }
bsalomonbb243832016-07-22 07:10:19 -0700793
csmartdaltonfc49d562016-07-26 17:05:47 -0700794 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
Brian Salomonf8334782017-01-03 09:42:58 -0500795 std::unique_ptr<GrDrawOp> op = GrAAFillRectOp::MakeWithLocalRect(
796 paint.getColor(), viewMatrix, croppedRect, croppedLocalRect);
Brian Salomon82f44312017-01-11 13:42:54 -0500797 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon24f19782016-12-13 15:10:11 -0500798 this->addDrawOp(pipelineBuilder, clip, std::move(op));
csmartdaltonfc49d562016-07-26 17:05:47 -0700799 return;
800 }
801
802 SkMatrix viewAndUnLocalMatrix;
803 if (!viewAndUnLocalMatrix.setRectToRect(localRect, rectToDraw, SkMatrix::kFill_ScaleToFit)) {
804 SkDebugf("fillRectToRect called with empty local matrix.\n");
805 return;
806 }
807 viewAndUnLocalMatrix.postConcat(viewMatrix);
808
809 SkPath path;
810 path.setIsVolatile(true);
811 path.addRect(localRect);
Brian Salomon82f44312017-01-11 13:42:54 -0500812 this->internalDrawPath(clip, std::move(paint), aa, viewAndUnLocalMatrix, path, GrStyle());
joshualittb6b513b2015-08-21 10:25:18 -0700813}
814
Brian Osman11052242016-10-27 14:47:55 -0400815void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500816 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500817 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400818 const SkMatrix& viewMatrix,
819 const SkRect& rectToDraw,
820 const SkMatrix& localMatrix) {
joshualitt1de610a2016-01-06 08:26:09 -0800821 ASSERT_SINGLE_OWNER
joshualittb6b513b2015-08-21 10:25:18 -0700822 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700823 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400824 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::fillRectWithLocalMatrix");
joshualittb6b513b2015-08-21 10:25:18 -0700825
csmartdalton97f6cd52016-07-13 13:37:08 -0700826 SkRect croppedRect = rectToDraw;
robertphillips13a7eee2016-08-31 15:06:24 -0700827 if (!crop_filled_rect(this->width(), this->height(), clip, viewMatrix, &croppedRect)) {
csmartdalton97f6cd52016-07-13 13:37:08 -0700828 return;
829 }
830
Robert Phillips72152832017-01-25 17:31:35 -0500831 AutoCheckFlush acf(this->drawingManager());
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500832 GrAAType aaType;
csmartdaltona7f29642016-07-07 08:49:11 -0700833
csmartdaltone0d36292016-07-29 08:14:20 -0700834 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400835 InstancedRendering* ir = this->getOpList()->instancedRendering();
Brian Salomonf8334782017-01-03 09:42:58 -0500836 std::unique_ptr<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
837 localMatrix, aa, fInstancedPipelineInfo,
838 &aaType));
Brian Salomon42521e82016-12-07 16:44:58 -0500839 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -0500840 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -0500841 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
csmartdaltona7f29642016-07-07 08:49:11 -0700842 return;
843 }
844 }
845
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500846 aaType = this->decideAAType(aa);
847 if (GrAAType::kCoverage != aaType) {
Brian Salomon82f44312017-01-11 13:42:54 -0500848 this->drawNonAAFilledRect(clip, std::move(paint), viewMatrix, croppedRect, nullptr,
849 &localMatrix, nullptr, aaType);
csmartdaltonfc49d562016-07-26 17:05:47 -0700850 return;
bsalomonc55271f2015-11-09 11:55:57 -0800851 }
robertphillips4bc31812016-03-01 12:22:49 -0800852
csmartdaltonfc49d562016-07-26 17:05:47 -0700853 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
Brian Salomonf8334782017-01-03 09:42:58 -0500854 std::unique_ptr<GrDrawOp> op =
Brian Salomon6a639042016-12-14 11:08:17 -0500855 GrAAFillRectOp::Make(paint.getColor(), viewMatrix, localMatrix, croppedRect);
Brian Salomon82f44312017-01-11 13:42:54 -0500856 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -0500857 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
csmartdaltonfc49d562016-07-26 17:05:47 -0700858 return;
859 }
860
861 SkMatrix viewAndUnLocalMatrix;
862 if (!localMatrix.invert(&viewAndUnLocalMatrix)) {
863 SkDebugf("fillRectWithLocalMatrix called with degenerate local matrix.\n");
864 return;
865 }
866 viewAndUnLocalMatrix.postConcat(viewMatrix);
867
868 SkPath path;
869 path.setIsVolatile(true);
870 path.addRect(rectToDraw);
871 path.transform(localMatrix);
Brian Salomon82f44312017-01-11 13:42:54 -0500872 this->internalDrawPath(clip, std::move(paint), aa, viewAndUnLocalMatrix, path, GrStyle());
robertphillipsea461502015-05-26 11:38:03 -0700873}
874
Brian Osman11052242016-10-27 14:47:55 -0400875void GrRenderTargetContext::drawVertices(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500876 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -0400877 const SkMatrix& viewMatrix,
878 GrPrimitiveType primitiveType,
879 int vertexCount,
880 const SkPoint positions[],
881 const SkPoint texCoords[],
Brian Salomon3de0aee2017-01-29 09:34:17 -0500882 const uint32_t colors[],
Brian Osman11052242016-10-27 14:47:55 -0400883 const uint16_t indices[],
Brian Salomon3de0aee2017-01-29 09:34:17 -0500884 int indexCount,
885 ColorArrayType colorArrayType) {
joshualitt1de610a2016-01-06 08:26:09 -0800886 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700887 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700888 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400889 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawVertices");
robertphillipsea461502015-05-26 11:38:03 -0700890
Robert Phillips72152832017-01-25 17:31:35 -0500891 AutoCheckFlush acf(this->drawingManager());
robertphillips2e1e51f2015-10-15 08:01:48 -0700892
robertphillipsea461502015-05-26 11:38:03 -0700893 // TODO clients should give us bounds
894 SkRect bounds;
895 if (!bounds.setBoundsCheck(positions, vertexCount)) {
896 SkDebugf("drawVertices call empty bounds\n");
897 return;
898 }
899
Brian Salomon3de0aee2017-01-29 09:34:17 -0500900 std::unique_ptr<GrDrawOp> op = GrDrawVerticesOp::Make(
901 paint.getColor(), primitiveType, viewMatrix, positions, vertexCount, indices,
902 indexCount, colors, texCoords, bounds, colorArrayType);
Brian Salomon199fb872017-02-06 09:41:10 -0500903 if (!op) {
904 return;
905 }
906 GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
907 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
908}
robertphillipsea461502015-05-26 11:38:03 -0700909
Brian Salomon199fb872017-02-06 09:41:10 -0500910void GrRenderTargetContext::drawVertices(const GrClip& clip,
911 GrPaint&& paint,
912 const SkMatrix& viewMatrix,
913 sk_sp<SkVertices> vertices,
914 uint32_t flags) {
915 ASSERT_SINGLE_OWNER
916 RETURN_IF_ABANDONED
917 SkDEBUGCODE(this->validate();)
918 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawVertices");
919
920 AutoCheckFlush acf(this->drawingManager());
921
922 SkASSERT(vertices);
923 std::unique_ptr<GrDrawOp> op =
924 GrDrawVerticesOp::Make(paint.getColor(), std::move(vertices), viewMatrix, flags);
925 if (!op) {
926 return;
927 }
Brian Salomon82f44312017-01-11 13:42:54 -0500928 GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
Brian Salomon21aa35f2016-12-09 16:01:53 -0500929 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillipsea461502015-05-26 11:38:03 -0700930}
931
932///////////////////////////////////////////////////////////////////////////////
933
Brian Osman11052242016-10-27 14:47:55 -0400934void GrRenderTargetContext::drawAtlas(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -0500935 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -0400936 const SkMatrix& viewMatrix,
937 int spriteCount,
938 const SkRSXform xform[],
939 const SkRect texRect[],
940 const SkColor colors[]) {
joshualitt1de610a2016-01-06 08:26:09 -0800941 ASSERT_SINGLE_OWNER
jvanverth31ff7622015-08-07 10:09:28 -0700942 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700943 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400944 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawAtlas");
robertphillips2e1e51f2015-10-15 08:01:48 -0700945
Robert Phillips72152832017-01-25 17:31:35 -0500946 AutoCheckFlush acf(this->drawingManager());
halcanary9d524f22016-03-29 09:03:52 -0700947
Brian Salomonf8334782017-01-03 09:42:58 -0500948 std::unique_ptr<GrDrawOp> op =
Brian Salomonfc527d22016-12-14 21:07:01 -0500949 GrDrawAtlasOp::Make(paint.getColor(), viewMatrix, spriteCount, xform, texRect, colors);
Brian Salomon82f44312017-01-11 13:42:54 -0500950 GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
Brian Salomon21aa35f2016-12-09 16:01:53 -0500951 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
jvanverth31ff7622015-08-07 10:09:28 -0700952}
953
954///////////////////////////////////////////////////////////////////////////////
955
Brian Osman11052242016-10-27 14:47:55 -0400956void GrRenderTargetContext::drawRRect(const GrClip& origClip,
Brian Salomon82f44312017-01-11 13:42:54 -0500957 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500958 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -0400959 const SkMatrix& viewMatrix,
960 const SkRRect& rrect,
961 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -0800962 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700963 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -0700964 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -0400965 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawRRect");
robertphillipsea461502015-05-26 11:38:03 -0700966 if (rrect.isEmpty()) {
967 return;
968 }
969
bsalomon7f0d9f32016-08-15 14:49:10 -0700970 GrNoClip noclip;
971 const GrClip* clip = &origClip;
972#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
973 // The Android framework frequently clips rrects to themselves where the clip is non-aa and the
Brian Salomon42521e82016-12-07 16:44:58 -0500974 // draw is aa. Since our lower level clip code works from op bounds, which are SkRects, it
bsalomon7f0d9f32016-08-15 14:49:10 -0700975 // doesn't detect that the clip can be ignored (modulo antialiasing). The following test
976 // attempts to mitigate the stencil clip cost but will only help when the entire clip stack
977 // can be ignored. We'd prefer to fix this in the framework by removing the clips calls.
978 SkRRect devRRect;
979 if (rrect.transform(viewMatrix, &devRRect) && clip->quickContains(devRRect)) {
980 clip = &noclip;
981 }
982#endif
bsalomon6663acf2016-05-10 09:14:17 -0700983 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
ksakamotoec7f2ac2016-07-05 03:54:53 -0700984
Robert Phillips72152832017-01-25 17:31:35 -0500985 AutoCheckFlush acf(this->drawingManager());
csmartdaltona7f29642016-07-07 08:49:11 -0700986 const SkStrokeRec stroke = style.strokeRec();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -0500987 GrAAType aaType;
csmartdaltona7f29642016-07-07 08:49:11 -0700988
csmartdaltone0d36292016-07-29 08:14:20 -0700989 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
990 stroke.isFillStyle()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400991 InstancedRendering* ir = this->getOpList()->instancedRendering();
Brian Salomonf8334782017-01-03 09:42:58 -0500992 std::unique_ptr<GrDrawOp> op(ir->recordRRect(rrect, viewMatrix, paint.getColor(), aa,
993 fInstancedPipelineInfo, &aaType));
Brian Salomon42521e82016-12-07 16:44:58 -0500994 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -0500995 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -0500996 this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, std::move(op));
csmartdaltona7f29642016-07-07 08:49:11 -0700997 return;
998 }
999 }
1000
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001001 aaType = this->decideAAType(aa);
1002 if (GrAAType::kCoverage == aaType) {
Brian Salomon94efbf52016-11-29 13:43:05 -05001003 const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Brian Salomonf8334782017-01-03 09:42:58 -05001004 std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeRRectOp(paint.getColor(),
1005 paint.usesDistanceVectorField(),
1006 viewMatrix,
1007 rrect,
1008 stroke,
1009 shaderCaps);
Brian Salomon42521e82016-12-07 16:44:58 -05001010 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001011 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001012 this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, std::move(op));
robertphillipsb56f9272016-02-25 11:03:52 -08001013 return;
1014 }
robertphillipsea461502015-05-26 11:38:03 -07001015 }
robertphillipsb56f9272016-02-25 11:03:52 -08001016
1017 SkPath path;
1018 path.setIsVolatile(true);
1019 path.addRRect(rrect);
Brian Salomon82f44312017-01-11 13:42:54 -05001020 this->internalDrawPath(*clip, std::move(paint), aa, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -07001021}
1022
Jim Van Verthc5903412016-11-17 15:27:09 -05001023///////////////////////////////////////////////////////////////////////////////
1024
1025void GrRenderTargetContext::drawShadowRRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001026 GrPaint&& paint,
Jim Van Verthc5903412016-11-17 15:27:09 -05001027 const SkMatrix& viewMatrix,
1028 const SkRRect& rrect,
1029 SkScalar blurRadius,
1030 const GrStyle& style) {
1031 ASSERT_SINGLE_OWNER
1032 RETURN_IF_ABANDONED
1033 SkDEBUGCODE(this->validate();)
1034 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawShadowRRect");
1035 if (rrect.isEmpty()) {
1036 return;
1037 }
1038
1039 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
1040
Robert Phillips72152832017-01-25 17:31:35 -05001041 AutoCheckFlush acf(this->drawingManager());
Jim Van Verthc5903412016-11-17 15:27:09 -05001042 const SkStrokeRec stroke = style.strokeRec();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001043 // TODO: add instancing support?
Jim Van Verthc5903412016-11-17 15:27:09 -05001044
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001045 const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Brian Salomonf8334782017-01-03 09:42:58 -05001046 std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(paint.getColor(), viewMatrix, rrect,
1047 blurRadius, stroke, shaderCaps);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001048 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001049 GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001050 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001051 return;
Jim Van Verthc5903412016-11-17 15:27:09 -05001052 }
Jim Van Verthc5903412016-11-17 15:27:09 -05001053}
1054
1055///////////////////////////////////////////////////////////////////////////////
1056
Brian Osman11052242016-10-27 14:47:55 -04001057bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001058 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001059 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001060 const SkMatrix& viewMatrix,
1061 const SkRRect& origOuter,
1062 const SkRRect& origInner) {
robertphillips00095892016-02-29 13:50:40 -08001063 SkASSERT(!origInner.isEmpty());
1064 SkASSERT(!origOuter.isEmpty());
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001065 GrAAType aaType;
robertphillips00095892016-02-29 13:50:40 -08001066
csmartdaltone0d36292016-07-29 08:14:20 -07001067 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -04001068 InstancedRendering* ir = this->getOpList()->instancedRendering();
Brian Salomonf8334782017-01-03 09:42:58 -05001069 std::unique_ptr<GrDrawOp> op(ir->recordDRRect(origOuter, origInner, viewMatrix,
Brian Salomon82f44312017-01-11 13:42:54 -05001070 paint.getColor(), aa, fInstancedPipelineInfo,
1071 &aaType));
Brian Salomon42521e82016-12-07 16:44:58 -05001072 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001073 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001074 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
csmartdaltona7f29642016-07-07 08:49:11 -07001075 return true;
1076 }
1077 }
1078
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001079 aaType = this->decideAAType(aa);
robertphillips00095892016-02-29 13:50:40 -08001080
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001081 GrPrimitiveEdgeType innerEdgeType, outerEdgeType;
1082 if (GrAAType::kCoverage == aaType) {
1083 innerEdgeType = kInverseFillAA_GrProcessorEdgeType;
1084 outerEdgeType = kFillAA_GrProcessorEdgeType;
1085 } else {
1086 innerEdgeType = kInverseFillBW_GrProcessorEdgeType;
1087 outerEdgeType = kFillBW_GrProcessorEdgeType;
1088 }
robertphillips00095892016-02-29 13:50:40 -08001089
1090 SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
1091 SkMatrix inverseVM;
1092 if (!viewMatrix.isIdentity()) {
1093 if (!origInner.transform(viewMatrix, inner.writable())) {
1094 return false;
1095 }
1096 if (!origOuter.transform(viewMatrix, outer.writable())) {
1097 return false;
1098 }
1099 if (!viewMatrix.invert(&inverseVM)) {
1100 return false;
1101 }
1102 } else {
1103 inverseVM.reset();
halcanary9d524f22016-03-29 09:03:52 -07001104 }
robertphillips00095892016-02-29 13:50:40 -08001105
robertphillips00095892016-02-29 13:50:40 -08001106 // TODO these need to be a geometry processors
bungeman06ca8ec2016-06-09 08:01:03 -07001107 sk_sp<GrFragmentProcessor> innerEffect(GrRRectEffect::Make(innerEdgeType, *inner));
robertphillips00095892016-02-29 13:50:40 -08001108 if (!innerEffect) {
1109 return false;
1110 }
1111
bungeman06ca8ec2016-06-09 08:01:03 -07001112 sk_sp<GrFragmentProcessor> outerEffect(GrRRectEffect::Make(outerEdgeType, *outer));
robertphillips00095892016-02-29 13:50:40 -08001113 if (!outerEffect) {
1114 return false;
1115 }
1116
Brian Salomon82f44312017-01-11 13:42:54 -05001117 paint.addCoverageFragmentProcessor(std::move(innerEffect));
1118 paint.addCoverageFragmentProcessor(std::move(outerEffect));
robertphillips00095892016-02-29 13:50:40 -08001119
1120 SkRect bounds = outer->getBounds();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001121 if (GrAAType::kCoverage == aaType) {
robertphillips00095892016-02-29 13:50:40 -08001122 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1123 }
halcanary9d524f22016-03-29 09:03:52 -07001124
Brian Salomon82f44312017-01-11 13:42:54 -05001125 this->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), bounds,
1126 inverseVM);
robertphillips00095892016-02-29 13:50:40 -08001127 return true;
1128}
1129
Brian Osman11052242016-10-27 14:47:55 -04001130void GrRenderTargetContext::drawDRRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001131 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001132 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001133 const SkMatrix& viewMatrix,
1134 const SkRRect& outer,
1135 const SkRRect& inner) {
robertphillips00095892016-02-29 13:50:40 -08001136 ASSERT_SINGLE_OWNER
1137 RETURN_IF_ABANDONED
1138 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001139 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawDRRect");
robertphillips00095892016-02-29 13:50:40 -08001140
1141 SkASSERT(!outer.isEmpty());
1142 SkASSERT(!inner.isEmpty());
1143
Robert Phillips72152832017-01-25 17:31:35 -05001144 AutoCheckFlush acf(this->drawingManager());
robertphillips00095892016-02-29 13:50:40 -08001145
Brian Salomon82f44312017-01-11 13:42:54 -05001146 if (this->drawFilledDRRect(clip, std::move(paint), aa, viewMatrix, outer, inner)) {
robertphillips00095892016-02-29 13:50:40 -08001147 return;
1148 }
1149
1150 SkPath path;
1151 path.setIsVolatile(true);
1152 path.addRRect(inner);
1153 path.addRRect(outer);
1154 path.setFillType(SkPath::kEvenOdd_FillType);
1155
Brian Salomon82f44312017-01-11 13:42:54 -05001156 this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, GrStyle::SimpleFill());
robertphillips00095892016-02-29 13:50:40 -08001157}
1158
robertphillipsea461502015-05-26 11:38:03 -07001159///////////////////////////////////////////////////////////////////////////////
1160
msarettcc319b92016-08-25 18:07:18 -07001161static inline bool is_int(float x) {
1162 return x == (float) sk_float_round2int(x);
1163}
1164
Brian Osman11052242016-10-27 14:47:55 -04001165void GrRenderTargetContext::drawRegion(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001166 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001167 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001168 const SkMatrix& viewMatrix,
1169 const SkRegion& region,
1170 const GrStyle& style) {
msarettcc319b92016-08-25 18:07:18 -07001171 ASSERT_SINGLE_OWNER
1172 RETURN_IF_ABANDONED
1173 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001174 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawRegion");
msarettcc319b92016-08-25 18:07:18 -07001175
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001176 if (GrAA::kYes == aa) {
Brian Salomonfc527d22016-12-14 21:07:01 -05001177 // GrRegionOp performs no antialiasing but is much faster, so here we check the matrix
Brian Salomonc57c7c92016-12-06 14:47:34 -05001178 // to see whether aa is really required.
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001179 if (!SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) &&
1180 is_int(viewMatrix.getTranslateX()) &&
1181 is_int(viewMatrix.getTranslateY())) {
1182 aa = GrAA::kNo;
1183 }
Brian Salomonc57c7c92016-12-06 14:47:34 -05001184 }
msarettcc319b92016-08-25 18:07:18 -07001185 bool complexStyle = !style.isSimpleFill();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001186 if (complexStyle || GrAA::kYes == aa) {
msarettcc319b92016-08-25 18:07:18 -07001187 SkPath path;
1188 region.getBoundaryPath(&path);
Brian Salomon82f44312017-01-11 13:42:54 -05001189 return this->drawPath(clip, std::move(paint), aa, viewMatrix, path, style);
msarettcc319b92016-08-25 18:07:18 -07001190 }
1191
Brian Salomonf8334782017-01-03 09:42:58 -05001192 std::unique_ptr<GrDrawOp> op = GrRegionOp::Make(paint.getColor(), viewMatrix, region);
Brian Salomon82f44312017-01-11 13:42:54 -05001193 GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001194 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
msarettcc319b92016-08-25 18:07:18 -07001195}
1196
Brian Osman11052242016-10-27 14:47:55 -04001197void GrRenderTargetContext::drawOval(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001198 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001199 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001200 const SkMatrix& viewMatrix,
1201 const SkRect& oval,
1202 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001203 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001204 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001205 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001206 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawOval");
robertphillips2e1e51f2015-10-15 08:01:48 -07001207
robertphillipsea461502015-05-26 11:38:03 -07001208 if (oval.isEmpty()) {
1209 return;
1210 }
1211
bsalomon6663acf2016-05-10 09:14:17 -07001212 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
robertphillipsea461502015-05-26 11:38:03 -07001213
Robert Phillips72152832017-01-25 17:31:35 -05001214 AutoCheckFlush acf(this->drawingManager());
bsalomon6663acf2016-05-10 09:14:17 -07001215 const SkStrokeRec& stroke = style.strokeRec();
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001216 GrAAType aaType;
csmartdaltona7f29642016-07-07 08:49:11 -07001217
csmartdaltone0d36292016-07-29 08:14:20 -07001218 if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
1219 stroke.isFillStyle()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -04001220 InstancedRendering* ir = this->getOpList()->instancedRendering();
Brian Salomonf8334782017-01-03 09:42:58 -05001221 std::unique_ptr<GrDrawOp> op(ir->recordOval(oval, viewMatrix, paint.getColor(), aa,
1222 fInstancedPipelineInfo, &aaType));
Brian Salomon42521e82016-12-07 16:44:58 -05001223 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001224 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001225 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
csmartdaltona7f29642016-07-07 08:49:11 -07001226 return;
1227 }
1228 }
1229
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001230 aaType = this->decideAAType(aa);
1231 if (GrAAType::kCoverage == aaType) {
Brian Salomon94efbf52016-11-29 13:43:05 -05001232 const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Brian Salomonf8334782017-01-03 09:42:58 -05001233 std::unique_ptr<GrDrawOp> op =
Brian Salomon289e3d82016-12-14 15:52:56 -05001234 GrOvalOpFactory::MakeOvalOp(paint.getColor(), viewMatrix, oval, stroke, shaderCaps);
Brian Salomon42521e82016-12-07 16:44:58 -05001235 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001236 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001237 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillipsb56f9272016-02-25 11:03:52 -08001238 return;
1239 }
robertphillipsea461502015-05-26 11:38:03 -07001240 }
robertphillipsb56f9272016-02-25 11:03:52 -08001241
1242 SkPath path;
1243 path.setIsVolatile(true);
1244 path.addOval(oval);
Brian Salomon82f44312017-01-11 13:42:54 -05001245 this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -07001246}
1247
Brian Osman11052242016-10-27 14:47:55 -04001248void GrRenderTargetContext::drawArc(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001249 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001250 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001251 const SkMatrix& viewMatrix,
1252 const SkRect& oval,
1253 SkScalar startAngle,
1254 SkScalar sweepAngle,
1255 bool useCenter,
1256 const GrStyle& style) {
Robert Phillipsf1d0ced2017-02-10 09:31:01 -05001257 ASSERT_SINGLE_OWNER
1258 RETURN_IF_ABANDONED
1259 SkDEBUGCODE(this->validate();)
1260 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawArc");
1261
1262 AutoCheckFlush acf(this->drawingManager());
1263
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001264 GrAAType aaType = this->decideAAType(aa);
1265 if (GrAAType::kCoverage == aaType) {
Brian Salomon94efbf52016-11-29 13:43:05 -05001266 const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Brian Salomonf8334782017-01-03 09:42:58 -05001267 std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeArcOp(paint.getColor(),
1268 viewMatrix,
1269 oval,
1270 startAngle,
1271 sweepAngle,
1272 useCenter,
1273 style,
1274 shaderCaps);
Brian Salomon42521e82016-12-07 16:44:58 -05001275 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001276 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001277 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
bsalomon4f3a0ca2016-08-22 13:14:26 -07001278 return;
1279 }
1280 }
1281 SkPath path;
bsalomon21af9ca2016-08-25 12:29:23 -07001282 SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
1283 style.isSimpleFill());
Brian Salomon82f44312017-01-11 13:42:54 -05001284 this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, style);
bsalomon4f3a0ca2016-08-22 13:14:26 -07001285}
1286
Brian Osman11052242016-10-27 14:47:55 -04001287void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001288 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -04001289 const SkMatrix& viewMatrix,
1290 int imageWidth,
1291 int imageHeight,
1292 std::unique_ptr<SkLatticeIter> iter,
1293 const SkRect& dst) {
joshualitt1de610a2016-01-06 08:26:09 -08001294 ASSERT_SINGLE_OWNER
joshualitt33a5fce2015-11-18 13:28:51 -08001295 RETURN_IF_ABANDONED
1296 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001297 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawImageLattice");
joshualitt33a5fce2015-11-18 13:28:51 -08001298
Robert Phillips72152832017-01-25 17:31:35 -05001299 AutoCheckFlush acf(this->drawingManager());
joshualitt33a5fce2015-11-18 13:28:51 -08001300
Brian Salomonf8334782017-01-03 09:42:58 -05001301 std::unique_ptr<GrDrawOp> op = GrLatticeOp::MakeNonAA(paint.getColor(), viewMatrix, imageWidth,
1302 imageHeight, std::move(iter), dst);
joshualitt33a5fce2015-11-18 13:28:51 -08001303
Brian Salomon82f44312017-01-11 13:42:54 -05001304 GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001305 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
joshualitt33a5fce2015-11-18 13:28:51 -08001306}
1307
Brian Osman11052242016-10-27 14:47:55 -04001308void GrRenderTargetContext::prepareForExternalIO() {
robertphillips8c523e02016-07-26 07:41:00 -07001309 ASSERT_SINGLE_OWNER
1310 RETURN_IF_ABANDONED
1311 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001312 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::prepareForExternalIO");
robertphillips8c523e02016-07-26 07:41:00 -07001313
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001314 // Deferral of the VRAM resources must end in this instance anyway
1315 sk_sp<GrRenderTarget> rt(
Brian Osman32342f02017-03-04 08:12:46 -05001316 sk_ref_sp(fRenderTargetProxy->instantiate(fContext->resourceProvider())));
Robert Phillipse60ad622016-11-17 10:22:48 -05001317 if (!rt) {
1318 return;
1319 }
robertphillips8c523e02016-07-26 07:41:00 -07001320
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001321 ASSERT_OWNED_RESOURCE(rt);
1322
Robert Phillips72152832017-01-25 17:31:35 -05001323 this->drawingManager()->prepareSurfaceForExternalIO(rt.get());
robertphillips8c523e02016-07-26 07:41:00 -07001324}
joshualitt33a5fce2015-11-18 13:28:51 -08001325
Brian Osman11052242016-10-27 14:47:55 -04001326void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001327 GrPaint&& paint,
Brian Osman11052242016-10-27 14:47:55 -04001328 const SkMatrix& viewMatrix,
1329 const SkRect& rect,
1330 const SkRect* localRect,
1331 const SkMatrix* localMatrix,
1332 const GrUserStencilSettings* ss,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001333 GrAAType hwOrNoneAAType) {
1334 SkASSERT(GrAAType::kCoverage != hwOrNoneAAType);
1335 SkASSERT(hwOrNoneAAType == GrAAType::kNone || this->isStencilBufferMultisampled());
Brian Salomonf8334782017-01-03 09:42:58 -05001336 std::unique_ptr<GrDrawOp> op = GrRectOpFactory::MakeNonAAFill(paint.getColor(), viewMatrix,
1337 rect, localRect, localMatrix);
Brian Salomon82f44312017-01-11 13:42:54 -05001338 GrPipelineBuilder pipelineBuilder(std::move(paint), hwOrNoneAAType);
robertphillips44302392016-07-08 14:43:03 -07001339 if (ss) {
1340 pipelineBuilder.setUserStencil(ss);
1341 }
Brian Salomon21aa35f2016-12-09 16:01:53 -05001342 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillips44302392016-07-08 14:43:03 -07001343}
1344
robertphillipsea461502015-05-26 11:38:03 -07001345// Can 'path' be drawn as a pair of filled nested rectangles?
bsalomon6663acf2016-05-10 09:14:17 -07001346static bool fills_as_nested_rects(const SkMatrix& viewMatrix, const SkPath& path, SkRect rects[2]) {
robertphillipsea461502015-05-26 11:38:03 -07001347
1348 if (path.isInverseFillType()) {
1349 return false;
1350 }
1351
1352 // TODO: this restriction could be lifted if we were willing to apply
1353 // the matrix to all the points individually rather than just to the rect
robertphillips0e7029e2015-11-30 05:45:06 -08001354 if (!viewMatrix.rectStaysRect()) {
robertphillipsea461502015-05-26 11:38:03 -07001355 return false;
1356 }
1357
1358 SkPath::Direction dirs[2];
1359 if (!path.isNestedFillRects(rects, dirs)) {
1360 return false;
1361 }
1362
1363 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) {
1364 // The two rects need to be wound opposite to each other
1365 return false;
1366 }
1367
1368 // Right now, nested rects where the margin is not the same width
1369 // all around do not render correctly
1370 const SkScalar* outer = rects[0].asScalars();
1371 const SkScalar* inner = rects[1].asScalars();
1372
1373 bool allEq = true;
1374
1375 SkScalar margin = SkScalarAbs(outer[0] - inner[0]);
1376 bool allGoE1 = margin >= SK_Scalar1;
1377
1378 for (int i = 1; i < 4; ++i) {
1379 SkScalar temp = SkScalarAbs(outer[i] - inner[i]);
1380 if (temp < SK_Scalar1) {
1381 allGoE1 = false;
1382 }
1383 if (!SkScalarNearlyEqual(margin, temp)) {
1384 allEq = false;
1385 }
1386 }
1387
1388 return allEq || allGoE1;
1389}
1390
Brian Osman11052242016-10-27 14:47:55 -04001391void GrRenderTargetContext::drawPath(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001392 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001393 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001394 const SkMatrix& viewMatrix,
1395 const SkPath& path,
1396 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001397 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001398 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001399 SkDEBUGCODE(this->validate();)
Brian Osman11052242016-10-27 14:47:55 -04001400 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawPath");
robertphillips2e1e51f2015-10-15 08:01:48 -07001401
robertphillipsea461502015-05-26 11:38:03 -07001402 if (path.isEmpty()) {
1403 if (path.isInverseFillType()) {
Brian Salomon82f44312017-01-11 13:42:54 -05001404 this->drawPaint(clip, std::move(paint), viewMatrix);
robertphillipsea461502015-05-26 11:38:03 -07001405 }
1406 return;
1407 }
1408
Robert Phillips72152832017-01-25 17:31:35 -05001409 AutoCheckFlush acf(this->drawingManager());
robertphillipsea461502015-05-26 11:38:03 -07001410
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001411 GrAAType aaType = this->decideAAType(aa);
1412 if (GrAAType::kCoverage == aaType && !style.pathEffect()) {
bsalomon6663acf2016-05-10 09:14:17 -07001413 if (style.isSimpleFill() && !path.isConvex()) {
robertphillipsea461502015-05-26 11:38:03 -07001414 // Concave AA paths are expensive - try to avoid them for special cases
1415 SkRect rects[2];
1416
bsalomon6663acf2016-05-10 09:14:17 -07001417 if (fills_as_nested_rects(viewMatrix, path, rects)) {
Brian Salomonf8334782017-01-03 09:42:58 -05001418 std::unique_ptr<GrDrawOp> op =
Brian Salomon6a639042016-12-14 11:08:17 -05001419 GrRectOpFactory::MakeAAFillNestedRects(paint.getColor(), viewMatrix, rects);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001420 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001421 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001422 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
bsalomon40ef4852016-05-02 13:22:13 -07001423 }
robertphillipsea461502015-05-26 11:38:03 -07001424 return;
1425 }
1426 }
1427 SkRect ovalRect;
1428 bool isOval = path.isOval(&ovalRect);
1429
1430 if (isOval && !path.isInverseFillType()) {
Brian Salomon94efbf52016-11-29 13:43:05 -05001431 const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
Brian Salomonf8334782017-01-03 09:42:58 -05001432 std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeOvalOp(
Brian Salomon289e3d82016-12-14 15:52:56 -05001433 paint.getColor(), viewMatrix, ovalRect, style.strokeRec(), shaderCaps);
Brian Salomon42521e82016-12-07 16:44:58 -05001434 if (op) {
Brian Salomon82f44312017-01-11 13:42:54 -05001435 GrPipelineBuilder pipelineBuilder(std::move(paint), aaType);
Brian Salomon21aa35f2016-12-09 16:01:53 -05001436 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillipsea461502015-05-26 11:38:03 -07001437 return;
1438 }
1439 }
1440 }
robertphillips4bc31812016-03-01 12:22:49 -08001441
1442 // Note that internalDrawPath may sw-rasterize the path into a scratch texture.
1443 // Scratch textures can be recycled after they are returned to the texture
1444 // cache. This presents a potential hazard for buffered drawing. However,
1445 // the writePixels that uploads to the scratch will perform a flush so we're
1446 // OK.
Brian Salomon82f44312017-01-11 13:42:54 -05001447 this->internalDrawPath(clip, std::move(paint), aa, viewMatrix, path, style);
robertphillipsea461502015-05-26 11:38:03 -07001448}
1449
Brian Osman11052242016-10-27 14:47:55 -04001450bool GrRenderTargetContextPriv::drawAndStencilPath(const GrClip& clip,
1451 const GrUserStencilSettings* ss,
1452 SkRegion::Op op,
1453 bool invert,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001454 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001455 const SkMatrix& viewMatrix,
1456 const SkPath& path) {
robertphillips391395d2016-03-02 09:26:36 -08001457 ASSERT_SINGLE_OWNER_PRIV
1458 RETURN_FALSE_IF_ABANDONED_PRIV
Brian Osman11052242016-10-27 14:47:55 -04001459 SkDEBUGCODE(fRenderTargetContext->validate();)
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001460 GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
1461 "GrRenderTargetContextPriv::drawAndStencilPath");
robertphillips391395d2016-03-02 09:26:36 -08001462
1463 if (path.isEmpty() && path.isInverseFillType()) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001464 this->drawAndStencilRect(clip, ss, op, invert, GrAA::kNo, SkMatrix::I(),
Brian Osman11052242016-10-27 14:47:55 -04001465 SkRect::MakeIWH(fRenderTargetContext->width(),
1466 fRenderTargetContext->height()));
robertphillips391395d2016-03-02 09:26:36 -08001467 return true;
1468 }
1469
Robert Phillips72152832017-01-25 17:31:35 -05001470 AutoCheckFlush acf(fRenderTargetContext->drawingManager());
robertphillips391395d2016-03-02 09:26:36 -08001471
1472 // An Assumption here is that path renderer would use some form of tweaking
1473 // the src color (either the input alpha or in the frag shader) to implement
1474 // aa. If we have some future driver-mojo path AA that can do the right
1475 // thing WRT to the blend then we'll need some query on the PR.
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001476 GrAAType aaType = fRenderTargetContext->decideAAType(aa);
robertphillips976f5f02016-06-03 10:59:20 -07001477 bool hasUserStencilSettings = !ss->isUnused();
robertphillips391395d2016-03-02 09:26:36 -08001478
bsalomon8acedde2016-06-24 10:42:16 -07001479 GrShape shape(path, GrStyle::SimpleFill());
robertphillips391395d2016-03-02 09:26:36 -08001480 GrPathRenderer::CanDrawPathArgs canDrawArgs;
Brian Osman11052242016-10-27 14:47:55 -04001481 canDrawArgs.fShaderCaps =
Robert Phillips72152832017-01-25 17:31:35 -05001482 fRenderTargetContext->drawingManager()->getContext()->caps()->shaderCaps();
robertphillips391395d2016-03-02 09:26:36 -08001483 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001484 canDrawArgs.fShape = &shape;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001485 canDrawArgs.fAAType = aaType;
cdalton93a379b2016-05-11 13:58:08 -07001486 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
robertphillips391395d2016-03-02 09:26:36 -08001487
1488 // Don't allow the SW renderer
Robert Phillips72152832017-01-25 17:31:35 -05001489 GrPathRenderer* pr = fRenderTargetContext->drawingManager()->getPathRenderer(
Brian Salomon36aa1762016-12-10 13:24:02 -05001490 canDrawArgs, false, GrPathRendererChain::DrawType::kStencilAndColor);
robertphillips391395d2016-03-02 09:26:36 -08001491 if (!pr) {
1492 return false;
1493 }
1494
1495 GrPaint paint;
1496 paint.setCoverageSetOpXPFactory(op, invert);
1497
Brian Salomon82f44312017-01-11 13:42:54 -05001498 GrPathRenderer::DrawPathArgs args{
Robert Phillips256c37b2017-03-01 14:32:46 -05001499 fRenderTargetContext->drawingManager()->getContext(),
Brian Salomon82f44312017-01-11 13:42:54 -05001500 std::move(paint),
1501 ss,
1502 fRenderTargetContext,
1503 &clip,
1504 &viewMatrix,
1505 &shape,
1506 aaType,
1507 fRenderTargetContext->isGammaCorrect()};
robertphillips391395d2016-03-02 09:26:36 -08001508 pr->drawPath(args);
1509 return true;
1510}
1511
Brian Osman11052242016-10-27 14:47:55 -04001512SkBudgeted GrRenderTargetContextPriv::isBudgeted() const {
robertphillips714712b2016-08-04 06:20:45 -07001513 ASSERT_SINGLE_OWNER_PRIV
1514
Brian Osman11052242016-10-27 14:47:55 -04001515 if (fRenderTargetContext->wasAbandoned()) {
robertphillips714712b2016-08-04 06:20:45 -07001516 return SkBudgeted::kNo;
1517 }
1518
Brian Osman11052242016-10-27 14:47:55 -04001519 SkDEBUGCODE(fRenderTargetContext->validate();)
robertphillips714712b2016-08-04 06:20:45 -07001520
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001521 return fRenderTargetContext->fRenderTargetProxy->isBudgeted();
robertphillips714712b2016-08-04 06:20:45 -07001522}
1523
Brian Osman11052242016-10-27 14:47:55 -04001524void GrRenderTargetContext::internalDrawPath(const GrClip& clip,
Brian Salomon82f44312017-01-11 13:42:54 -05001525 GrPaint&& paint,
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001526 GrAA aa,
Brian Osman11052242016-10-27 14:47:55 -04001527 const SkMatrix& viewMatrix,
1528 const SkPath& path,
1529 const GrStyle& style) {
joshualitt1de610a2016-01-06 08:26:09 -08001530 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -07001531 RETURN_IF_ABANDONED
bsalomon8acedde2016-06-24 10:42:16 -07001532 SkASSERT(!path.isEmpty());
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001533 GrShape shape;
robertphillipsea461502015-05-26 11:38:03 -07001534
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001535 GrAAType aaType = this->decideAAType(aa, /*allowMixedSamples*/ true);
1536 if (style.isSimpleHairline() && aaType == GrAAType::kMixedSamples) {
1537 // NVPR cannot handle hairlines, so this will would get picked up by a different stencil and
1538 // cover path renderer (i.e. default path renderer). The hairline renderer produces much
1539 // smoother hairlines than MSAA.
1540 aaType = GrAAType::kCoverage;
bsalomon0a0f67e2016-06-28 11:56:42 -07001541 }
robertphillips68737822015-10-29 12:12:21 -07001542 GrPathRenderer::CanDrawPathArgs canDrawArgs;
Robert Phillips72152832017-01-25 17:31:35 -05001543 canDrawArgs.fShaderCaps = this->drawingManager()->getContext()->caps()->shaderCaps();
robertphillips68737822015-10-29 12:12:21 -07001544 canDrawArgs.fViewMatrix = &viewMatrix;
bsalomon8acedde2016-06-24 10:42:16 -07001545 canDrawArgs.fShape = &shape;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001546 canDrawArgs.fHasUserStencilSettings = false;
robertphillips68737822015-10-29 12:12:21 -07001547
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001548 GrPathRenderer* pr;
Brian Salomon82125e92016-12-10 09:35:48 -05001549 static constexpr GrPathRendererChain::DrawType kType = GrPathRendererChain::DrawType::kColor;
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001550 do {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001551 shape = GrShape(path, style);
bsalomon8acedde2016-06-24 10:42:16 -07001552 if (shape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001553 return;
1554 }
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001555
1556 canDrawArgs.fAAType = aaType;
1557
1558 // Try a 1st time without applying any of the style to the geometry (and barring sw)
Robert Phillips72152832017-01-25 17:31:35 -05001559 pr = this->drawingManager()->getPathRenderer(canDrawArgs, false, kType);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001560 SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
1561
1562 if (!pr && shape.style().pathEffect()) {
1563 // It didn't work above, so try again with the path effect applied.
1564 shape = shape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
bsalomon8acedde2016-06-24 10:42:16 -07001565 if (shape.isEmpty()) {
robertphillipsea461502015-05-26 11:38:03 -07001566 return;
1567 }
Robert Phillips72152832017-01-25 17:31:35 -05001568 pr = this->drawingManager()->getPathRenderer(canDrawArgs, false, kType);
bsalomon6663acf2016-05-10 09:14:17 -07001569 }
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001570 if (!pr) {
1571 if (shape.style().applies()) {
1572 shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale);
1573 if (shape.isEmpty()) {
1574 return;
1575 }
1576 }
1577 // This time, allow SW renderer
Robert Phillips72152832017-01-25 17:31:35 -05001578 pr = this->drawingManager()->getPathRenderer(canDrawArgs, true, kType);
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001579 }
Brian Salomon0abc8b42016-12-13 10:22:54 -05001580 if (!pr && GrAATypeIsHW(aaType)) {
Brian Salomon0e8fc8b2016-12-09 15:10:07 -05001581 // There are exceptional cases where we may wind up falling back to coverage based AA
1582 // when the target is MSAA (e.g. through disabling path renderers via GrContextOptions).
1583 aaType = GrAAType::kCoverage;
1584 } else {
1585 break;
1586 }
1587 } while(true);
robertphillipsea461502015-05-26 11:38:03 -07001588
bsalomon8acedde2016-06-24 10:42:16 -07001589 if (!pr) {
robertphillipsea461502015-05-26 11:38:03 -07001590#ifdef SK_DEBUG
1591 SkDebugf("Unable to find path renderer compatible with path.\n");
1592#endif
1593 return;
1594 }
1595
Robert Phillips256c37b2017-03-01 14:32:46 -05001596 GrPathRenderer::DrawPathArgs args{this->drawingManager()->getContext(),
Brian Salomon82f44312017-01-11 13:42:54 -05001597 std::move(paint),
1598 &GrUserStencilSettings::kUnused,
1599 this,
1600 &clip,
1601 &viewMatrix,
1602 &shape,
1603 aaType,
1604 this->isGammaCorrect()};
bsalomon0aff2fa2015-07-31 06:48:27 -07001605 pr->drawPath(args);
robertphillipsea461502015-05-26 11:38:03 -07001606}
1607
Brian Salomon42521e82016-12-07 16:44:58 -05001608void GrRenderTargetContext::addDrawOp(const GrPipelineBuilder& pipelineBuilder, const GrClip& clip,
Brian Salomonf8334782017-01-03 09:42:58 -05001609 std::unique_ptr<GrDrawOp> op) {
joshualitt1de610a2016-01-06 08:26:09 -08001610 ASSERT_SINGLE_OWNER
robertphillips2d70dcb2015-10-06 07:38:23 -07001611 RETURN_IF_ABANDONED
robertphillips2e1e51f2015-10-15 08:01:48 -07001612 SkDEBUGCODE(this->validate();)
Brian Salomon42521e82016-12-07 16:44:58 -05001613 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::addDrawOp");
robertphillips2d70dcb2015-10-06 07:38:23 -07001614
Brian Salomon24f19782016-12-13 15:10:11 -05001615 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
robertphillips2334fb62015-06-17 05:43:33 -07001616}