blob: 805cfafc57752cc9b2201fe9f66bb8a738ab9c54 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
joshualittc2893c52015-01-28 06:54:30 -08009#include "GrDrawTarget.h"
joshualitt4d8da812015-01-28 12:53:54 -080010
bsalomoneb1cb5c2015-05-22 08:01:09 -070011#include "GrCaps.h"
bsalomon4061b122015-05-29 10:26:19 -070012#include "GrGpu.h"
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +000013#include "GrPath.h"
egdaniele36914c2015-02-13 09:00:33 -080014#include "GrPipeline.h"
joshualittb7133be2015-04-08 09:08:31 -070015#include "GrMemoryPool.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000016#include "GrRenderTarget.h"
bsalomon4061b122015-05-29 10:26:19 -070017#include "GrResourceProvider.h"
bsalomon6bc1b5f2015-02-23 09:06:38 -080018#include "GrRenderTargetPriv.h"
bsalomonafbf2d62014-09-30 12:18:44 -070019#include "GrSurfacePriv.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000020#include "GrTexture.h"
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000021#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000022
bsalomon53469832015-08-18 09:20:09 -070023#include "batches/GrClearBatch.h"
bsalomon872062c2015-08-18 12:12:35 -070024#include "batches/GrCopySurfaceBatch.h"
bsalomon53469832015-08-18 09:20:09 -070025#include "batches/GrDiscardBatch.h"
bsalomon16b99132015-08-13 14:55:50 -070026#include "batches/GrDrawBatch.h"
bsalomonadd79ef2015-08-19 13:26:49 -070027#include "batches/GrDrawPathBatch.h"
joshualittecd1a692015-08-10 10:08:26 -070028#include "batches/GrRectBatchFactory.h"
bsalomona44919e2015-08-18 13:28:19 -070029#include "batches/GrStencilPathBatch.h"
joshualitt74417822015-08-07 11:42:16 -070030
sugoi@google.com5f74cf82012-12-17 21:16:45 +000031#include "SkStrokeRec.h"
sugoi@google.com12b4e272012-12-06 20:13:11 +000032
reed@google.comac10a2d2010-12-22 21:39:39 +000033////////////////////////////////////////////////////////////////////////////////
34
bsalomon4061b122015-05-29 10:26:19 -070035GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider)
36 : fGpu(SkRef(gpu))
37 , fCaps(SkRef(gpu->caps()))
38 , fResourceProvider(resourceProvider)
bsalomona73239a2015-04-28 13:35:17 -070039 , fGpuTraceMarkerCount(0)
bsalomona73239a2015-04-28 13:35:17 -070040 , fFlushing(false) {
bsalomon4061b122015-05-29 10:26:19 -070041}
42
43GrDrawTarget::~GrDrawTarget() {
44 fGpu->unref();
45 fCaps->unref();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000046}
47
48////////////////////////////////////////////////////////////////////////////////
49
bsalomon50785a32015-02-06 07:02:37 -080050bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
egdaniele36914c2015-02-13 09:00:33 -080051 const GrProcOptInfo& colorPOI,
52 const GrProcOptInfo& coveragePOI,
bsalomon6a44c6a2015-05-26 09:49:05 -070053 GrXferProcessor::DstTexture* dstTexture,
joshualitt9853cce2014-11-17 14:22:48 -080054 const SkRect* drawBounds) {
bsalomon6a44c6a2015-05-26 09:49:05 -070055 if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), colorPOI, coveragePOI)) {
bsalomon@google.com26e18b52013-03-29 19:22:36 +000056 return true;
57 }
cdalton9954bc32015-04-29 14:17:00 -070058
bsalomon50785a32015-02-06 07:02:37 -080059 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
cdalton9954bc32015-04-29 14:17:00 -070060
61 if (this->caps()->textureBarrierSupport()) {
62 if (GrTexture* rtTex = rt->asTexture()) {
bsalomondc47ff72015-05-26 12:16:59 -070063 // The render target is a texture, so we can read from it directly in the shader. The XP
cdalton9954bc32015-04-29 14:17:00 -070064 // will be responsible to detect this situation and request a texture barrier.
bsalomon6a44c6a2015-05-26 09:49:05 -070065 dstTexture->setTexture(rtTex);
66 dstTexture->setOffset(0, 0);
cdalton9954bc32015-04-29 14:17:00 -070067 return true;
68 }
69 }
70
71 SkIRect copyRect;
joshualitt44701df2015-02-23 14:44:57 -080072 pipelineBuilder.clip().getConservativeBounds(rt, &copyRect);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +000073
bsalomon49f085d2014-09-05 13:34:00 -070074 if (drawBounds) {
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +000075 SkIRect drawIBounds;
76 drawBounds->roundOut(&drawIBounds);
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +000077 if (!copyRect.intersect(drawIBounds)) {
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000078#ifdef SK_DEBUG
bsalomon682c2692015-05-22 14:01:46 -070079 GrCapsDebugf(fCaps, "Missed an early reject. "
80 "Bailing on draw from setupDstReadIfNecessary.\n");
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +000081#endif
82 return false;
83 }
84 } else {
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000085#ifdef SK_DEBUG
tfarina38406c82014-10-31 07:11:12 -070086 //SkDebugf("No dev bounds when dst copy is made.\n");
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +000087#endif
88 }
skia.committer@gmail.com05a2ee02013-04-02 07:01:34 +000089
commit-bot@chromium.org63150af2013-04-11 22:00:22 +000090 // MSAA consideration: When there is support for reading MSAA samples in the shader we could
91 // have per-sample dst values by making the copy multisampled.
bsalomonf2703d82014-10-28 14:33:06 -070092 GrSurfaceDesc desc;
bsalomona73239a2015-04-28 13:35:17 -070093 if (!this->getGpu()->initCopySurfaceDstDesc(rt, &desc)) {
94 desc.fOrigin = kDefault_GrSurfaceOrigin;
95 desc.fFlags = kRenderTarget_GrSurfaceFlag;
96 desc.fConfig = rt->config();
97 }
98
99
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +0000100 desc.fWidth = copyRect.width();
101 desc.fHeight = copyRect.height();
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000102
bsalomoneae62002015-07-31 13:59:30 -0700103 static const uint32_t kFlags = 0;
104 SkAutoTUnref<GrTexture> copy(fResourceProvider->createApproxTexture(desc, kFlags));
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000105
bsalomone3059732014-10-14 11:47:22 -0700106 if (!copy) {
tfarina38406c82014-10-31 07:11:12 -0700107 SkDebugf("Failed to create temporary copy of destination texture.\n");
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000108 return false;
109 }
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000110 SkIPoint dstPoint = {0, 0};
bsalomon6df86402015-06-01 10:41:49 -0700111 this->copySurface(copy, rt, copyRect, dstPoint);
112 dstTexture->setTexture(copy);
113 dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
114 return true;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000115}
116
bsalomona73239a2015-04-28 13:35:17 -0700117void GrDrawTarget::flush() {
118 if (fFlushing) {
119 return;
120 }
121 fFlushing = true;
122
123 this->getGpu()->saveActiveTraceMarkers();
124
125 this->onFlush();
126
127 this->getGpu()->restoreActiveTraceMarkers();
128
129 fFlushing = false;
130 this->reset();
131}
132
bsalomonabd30f52015-08-13 13:34:48 -0700133void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch) {
joshualitt4d8da812015-01-28 12:53:54 -0800134 // Setup clip
135 GrScissorState scissorState;
joshualitt4421a4c2015-07-13 09:36:41 -0700136 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
joshualitt4d8da812015-01-28 12:53:54 -0800137 GrPipelineBuilder::AutoRestoreStencil ars;
joshualitt4421a4c2015-07-13 09:36:41 -0700138 if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->bounds())) {
joshualitt4d8da812015-01-28 12:53:54 -0800139 return;
140 }
141
joshualitt99c7c072015-05-01 13:43:30 -0700142 // Batch bounds are tight, so for dev copies
143 // TODO move this into setupDstReadIfNecessary when paths are in batch
144 SkRect bounds = batch->bounds();
145 bounds.outset(0.5f, 0.5f);
146
bsalomona387a112015-08-11 14:47:42 -0700147 GrDrawTarget::PipelineInfo pipelineInfo(&pipelineBuilder, &scissorState, batch, &bounds,
joshualitt99c7c072015-05-01 13:43:30 -0700148 this);
bsalomonadd79ef2015-08-19 13:26:49 -0700149
bsalomona387a112015-08-11 14:47:42 -0700150 if (!pipelineInfo.valid()) {
egdaniele36914c2015-02-13 09:00:33 -0800151 return;
152 }
bsalomona387a112015-08-11 14:47:42 -0700153 if (!batch->installPipeline(pipelineInfo.pipelineCreateArgs())) {
154 return;
155 }
156 this->onDrawBatch(batch);
joshualitt4d8da812015-01-28 12:53:54 -0800157}
158
joshualitt2c93efe2014-11-06 12:57:13 -0800159static const GrStencilSettings& winding_path_stencil_settings() {
160 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
161 kIncClamp_StencilOp,
162 kIncClamp_StencilOp,
163 kAlwaysIfInClip_StencilFunc,
164 0xFFFF, 0xFFFF, 0xFFFF);
165 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
166}
167
168static const GrStencilSettings& even_odd_path_stencil_settings() {
169 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
170 kInvert_StencilOp,
171 kInvert_StencilOp,
172 kAlwaysIfInClip_StencilFunc,
173 0xFFFF, 0xFFFF, 0xFFFF);
174 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
175}
176
177void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType fill,
egdaniel8dc7c3a2015-04-16 11:22:42 -0700178 const GrStencilAttachment* sb,
joshualitt2c93efe2014-11-06 12:57:13 -0800179 GrStencilSettings* outStencilSettings) {
180
181 switch (fill) {
182 default:
183 SkFAIL("Unexpected path fill.");
184 case GrPathRendering::kWinding_FillType:
185 *outStencilSettings = winding_path_stencil_settings();
186 break;
187 case GrPathRendering::kEvenOdd_FillType:
188 *outStencilSettings = even_odd_path_stencil_settings();
189 break;
190 }
joshualitt9853cce2014-11-17 14:22:48 -0800191 this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800192}
193
joshualitt1c735482015-07-13 08:08:25 -0700194void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800195 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800196 const GrPath* path,
197 GrPathRendering::FillType fill) {
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000198 // TODO: extract portions of checkDraw that are relevant to path stenciling.
bsalomon49f085d2014-09-05 13:34:00 -0700199 SkASSERT(path);
jvanverthe9c0fc62015-04-29 11:18:05 -0700200 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
joshualitt2c93efe2014-11-06 12:57:13 -0800201
202 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800203 GrScissorState scissorState;
joshualitt4421a4c2015-07-13 09:36:41 -0700204 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
egdaniel8dd688b2015-01-22 10:16:09 -0800205 GrPipelineBuilder::AutoRestoreStencil ars;
joshualitt4421a4c2015-07-13 09:36:41 -0700206 if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, NULL)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800207 return;
208 }
209
210 // set stencil settings for path
211 GrStencilSettings stencilSettings;
joshualitt1c735482015-07-13 08:08:25 -0700212 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
egdaniel8dc7c3a2015-04-16 11:22:42 -0700213 GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment();
bsalomon6bc1b5f2015-02-23 09:06:38 -0800214 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800215
bsalomona44919e2015-08-18 13:28:19 -0700216 GrBatch* batch = GrStencilPathBatch::Create(pathProc->viewMatrix(),
217 pipelineBuilder.isHWAntialias(),
218 stencilSettings, scissorState,
219 pipelineBuilder.getRenderTarget(),
220 path);
221 this->onDrawBatch(batch);
222 batch->unref();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000223}
224
joshualitt1c735482015-07-13 08:08:25 -0700225void GrDrawTarget::drawPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800226 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800227 const GrPath* path,
228 GrPathRendering::FillType fill) {
bsalomon49f085d2014-09-05 13:34:00 -0700229 SkASSERT(path);
jvanverthe9c0fc62015-04-29 11:18:05 -0700230 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000231
bsalomonadd79ef2015-08-19 13:26:49 -0700232 GrDrawPathBatch* batch = GrDrawPathBatch::Create(pathProc, path);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000233
bsalomonadd79ef2015-08-19 13:26:49 -0700234 // This looks like drawBatch() but there is an added wrinkle that stencil settings get inserted
235 // after setupClip() but before onDrawBatch(). TODO: Figure out a better model for handling
236 // stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and batches.
237
bsalomon3e791242014-12-17 13:43:13 -0800238 GrScissorState scissorState;
joshualitt4421a4c2015-07-13 09:36:41 -0700239 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
egdaniel8dd688b2015-01-22 10:16:09 -0800240 GrPipelineBuilder::AutoRestoreStencil ars;
bsalomonadd79ef2015-08-19 13:26:49 -0700241 if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, &batch->bounds())) {
242 return;
joshualitt2c93efe2014-11-06 12:57:13 -0800243 }
244
bsalomonadd79ef2015-08-19 13:26:49 -0700245 // Ensure the render target has a stencil buffer and get the stencil settings.
joshualitt2c93efe2014-11-06 12:57:13 -0800246 GrStencilSettings stencilSettings;
joshualitt1c735482015-07-13 08:08:25 -0700247 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
egdaniel8dc7c3a2015-04-16 11:22:42 -0700248 GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment();
bsalomon6bc1b5f2015-02-23 09:06:38 -0800249 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
bsalomonadd79ef2015-08-19 13:26:49 -0700250 batch->setStencilSettings(stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800251
bsalomonadd79ef2015-08-19 13:26:49 -0700252 // Don't compute a bounding box for dst copy texture, we'll opt
253 // instead for it to just copy the entire dst. Realistically this is a moot
254 // point, because any context that supports NV_path_rendering will also
255 // support NV_blend_equation_advanced.
256 GrDrawTarget::PipelineInfo pipelineInfo(&pipelineBuilder, &scissorState, batch, NULL, this);
257
bsalomona387a112015-08-11 14:47:42 -0700258 if (!pipelineInfo.valid()) {
egdaniele36914c2015-02-13 09:00:33 -0800259 return;
260 }
bsalomonadd79ef2015-08-19 13:26:49 -0700261 if (!batch->installPipeline(pipelineInfo.pipelineCreateArgs())) {
262 return;
263 }
egdaniele36914c2015-02-13 09:00:33 -0800264
bsalomonadd79ef2015-08-19 13:26:49 -0700265 this->onDrawBatch(batch);
266 batch->unref();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000267}
268
joshualitt1c735482015-07-13 08:08:25 -0700269void GrDrawTarget::drawPaths(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800270 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800271 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800272 const void* indices,
273 PathIndexType indexType,
274 const float transformValues[],
275 PathTransformType transformType,
joshualitt9853cce2014-11-17 14:22:48 -0800276 int count,
joshualitt92e496f2014-10-31 13:56:50 -0700277 GrPathRendering::FillType fill) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700278 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
bsalomon49f085d2014-09-05 13:34:00 -0700279 SkASSERT(pathRange);
280 SkASSERT(indices);
bsalomonebc1c102015-08-06 17:33:16 -0700281 SkASSERT(0 == reinterpret_cast<intptr_t>(indices) %
282 GrPathRange::PathIndexSizeInBytes(indexType));
cdalton55b24af2014-11-25 11:00:56 -0800283 SkASSERT(transformValues);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000284
joshualitt2c93efe2014-11-06 12:57:13 -0800285 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800286 GrScissorState scissorState;
joshualitt4421a4c2015-07-13 09:36:41 -0700287 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
egdaniel8dd688b2015-01-22 10:16:09 -0800288 GrPipelineBuilder::AutoRestoreStencil ars;
joshualitt4421a4c2015-07-13 09:36:41 -0700289 if (!this->setupClip(pipelineBuilder, &arfps, &ars, &scissorState, NULL)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800290 return;
291 }
292
293 // set stencil settings for path
294 GrStencilSettings stencilSettings;
joshualitt1c735482015-07-13 08:08:25 -0700295 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
egdaniel8dc7c3a2015-04-16 11:22:42 -0700296 GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment();
bsalomon6bc1b5f2015-02-23 09:06:38 -0800297 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800298
bsalomon50785a32015-02-06 07:02:37 -0800299 // Don't compute a bounding box for dst copy texture, we'll opt
cdaltonb85a0aa2014-07-21 15:32:44 -0700300 // instead for it to just copy the entire dst. Realistically this is a moot
301 // point, because any context that supports NV_path_rendering will also
302 // support NV_blend_equation_advanced.
bsalomona387a112015-08-11 14:47:42 -0700303 GrDrawTarget::PipelineInfo pipelineInfo(&pipelineBuilder, &scissorState, pathProc, NULL, this);
304 if (!pipelineInfo.valid()) {
egdaniele36914c2015-02-13 09:00:33 -0800305 return;
306 }
307
308 this->onDrawPaths(pathProc, pathRange, indices, indexType, transformValues,
309 transformType, count, stencilSettings, pipelineInfo);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000310}
311
joshualittd2b23e02015-08-21 10:53:34 -0700312void GrDrawTarget::drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
joshualitt1c735482015-07-13 08:08:25 -0700313 GrColor color,
314 const SkMatrix& viewMatrix,
joshualittb6b513b2015-08-21 10:25:18 -0700315 const SkRect& rect) {
joshualittd2b23e02015-08-21 10:53:34 -0700316 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
317 nullptr, nullptr));
joshualittad17cfc2015-05-05 10:45:57 -0700318 this->drawBatch(pipelineBuilder, batch);
319}
320
joshualittd2b23e02015-08-21 10:53:34 -0700321void GrDrawTarget::drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
joshualittb6b513b2015-08-21 10:25:18 -0700322 GrColor color,
323 const SkMatrix& viewMatrix,
324 const SkRect& rect,
325 const SkMatrix& localMatrix) {
joshualittd2b23e02015-08-21 10:53:34 -0700326 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
327 nullptr, &localMatrix));
joshualittb6b513b2015-08-21 10:25:18 -0700328 this->drawBatch(pipelineBuilder, batch);
329}
330
joshualittd2b23e02015-08-21 10:53:34 -0700331void GrDrawTarget::drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
joshualittb6b513b2015-08-21 10:25:18 -0700332 GrColor color,
333 const SkMatrix& viewMatrix,
334 const SkRect& rect,
335 const SkRect& localRect) {
joshualittd2b23e02015-08-21 10:53:34 -0700336 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
337 &localRect, nullptr));
joshualittb6b513b2015-08-21 10:25:18 -0700338 this->drawBatch(pipelineBuilder, batch);
339}
340
341
joshualitt1c735482015-07-13 08:08:25 -0700342void GrDrawTarget::drawAARect(const GrPipelineBuilder& pipelineBuilder,
robertphillipsea461502015-05-26 11:38:03 -0700343 GrColor color,
344 const SkMatrix& viewMatrix,
345 const SkRect& rect,
346 const SkRect& devRect) {
joshualittd2b23e02015-08-21 10:53:34 -0700347 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect,
bsalomonabd30f52015-08-13 13:34:48 -0700348 devRect));
joshualitt14205b12015-08-10 11:40:56 -0700349 this->drawBatch(pipelineBuilder, batch);
robertphillipsea461502015-05-26 11:38:03 -0700350}
351
joshualitt9853cce2014-11-17 14:22:48 -0800352void GrDrawTarget::clear(const SkIRect* rect,
353 GrColor color,
354 bool canIgnoreRect,
bsalomon63b21962014-11-05 07:05:34 -0800355 GrRenderTarget* renderTarget) {
egdaniel51c8d402015-08-06 10:54:13 -0700356 SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height());
357 SkIRect clippedRect;
358 if (!rect ||
359 (canIgnoreRect && this->caps()->fullClearIsFree()) ||
360 rect->contains(rtRect)) {
361 rect = &rtRect;
362 } else {
363 clippedRect = *rect;
364 if (!clippedRect.intersect(rtRect)) {
365 return;
366 }
367 rect = &clippedRect;
368 }
369
bsalomon63b21962014-11-05 07:05:34 -0800370 if (fCaps->useDrawInsteadOfClear()) {
371 // This works around a driver bug with clear by drawing a rect instead.
372 // The driver will ignore a clear if it is the only thing rendered to a
373 // target before the target is read.
egdaniel51c8d402015-08-06 10:54:13 -0700374 if (rect == &rtRect) {
bsalomon63b21962014-11-05 07:05:34 -0800375 this->discard(renderTarget);
376 }
bsalomon63b21962014-11-05 07:05:34 -0800377
egdaniel8dd688b2015-01-22 10:16:09 -0800378 GrPipelineBuilder pipelineBuilder;
379 pipelineBuilder.setRenderTarget(renderTarget);
joshualitt9853cce2014-11-17 14:22:48 -0800380
joshualittd2b23e02015-08-21 10:53:34 -0700381 this->drawNonAARect(pipelineBuilder, color, SkMatrix::I(), *rect);
bsalomon53469832015-08-18 09:20:09 -0700382 } else {
halcanary385fe4d2015-08-26 13:07:48 -0700383 GrBatch* batch = new GrClearBatch(*rect, color, renderTarget);
bsalomon53469832015-08-18 09:20:09 -0700384 this->onDrawBatch(batch);
385 batch->unref();
386 }
387}
388
389void GrDrawTarget::discard(GrRenderTarget* renderTarget) {
390 if (this->caps()->discardRenderTargetSupport()) {
halcanary385fe4d2015-08-26 13:07:48 -0700391 GrBatch* batch = new GrDiscardBatch(renderTarget);
bsalomon53469832015-08-18 09:20:09 -0700392 this->onDrawBatch(batch);
393 batch->unref();
bsalomon63b21962014-11-05 07:05:34 -0800394 }
395}
396
egdaniel3eee3832014-06-18 13:09:11 -0700397typedef GrTraceMarkerSet::Iter TMIter;
398void GrDrawTarget::saveActiveTraceMarkers() {
399 if (this->caps()->gpuTracingSupport()) {
400 SkASSERT(0 == fStoredTraceMarkers.count());
401 fStoredTraceMarkers.addSet(fActiveTraceMarkers);
402 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
403 this->removeGpuTraceMarker(&(*iter));
404 }
405 }
406}
407
408void GrDrawTarget::restoreActiveTraceMarkers() {
409 if (this->caps()->gpuTracingSupport()) {
410 SkASSERT(0 == fActiveTraceMarkers.count());
411 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
412 this->addGpuTraceMarker(&(*iter));
413 }
414 for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
415 this->fStoredTraceMarkers.remove(*iter);
416 }
417 }
418}
419
420void GrDrawTarget::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000421 if (this->caps()->gpuTracingSupport()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000422 SkASSERT(fGpuTraceMarkerCount >= 0);
423 this->fActiveTraceMarkers.add(*marker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000424 ++fGpuTraceMarkerCount;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000425 }
426}
427
egdaniel3eee3832014-06-18 13:09:11 -0700428void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000429 if (this->caps()->gpuTracingSupport()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000430 SkASSERT(fGpuTraceMarkerCount >= 1);
431 this->fActiveTraceMarkers.remove(*marker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000432 --fGpuTraceMarkerCount;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000433 }
434}
435
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000436////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000437
bsalomon6df86402015-06-01 10:41:49 -0700438void GrDrawTarget::copySurface(GrSurface* dst,
bsalomon@google.com116ad842013-04-09 15:38:19 +0000439 GrSurface* src,
440 const SkIRect& srcRect,
441 const SkIPoint& dstPoint) {
bsalomon872062c2015-08-18 12:12:35 -0700442 GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint);
443 if (batch) {
444 this->onDrawBatch(batch);
445 batch->unref();
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000446 }
bsalomon@google.comeb851172013-04-15 13:51:00 +0000447}
448
egdaniele36914c2015-02-13 09:00:33 -0800449///////////////////////////////////////////////////////////////////////////////
450
bsalomona387a112015-08-11 14:47:42 -0700451GrDrawTarget::PipelineInfo::PipelineInfo(const GrPipelineBuilder* pipelineBuilder,
452 const GrScissorState* scissor,
egdaniele36914c2015-02-13 09:00:33 -0800453 const GrPrimitiveProcessor* primProc,
454 const SkRect* devBounds,
bsalomona387a112015-08-11 14:47:42 -0700455 GrDrawTarget* target) {
456 fArgs.fPipelineBuilder = pipelineBuilder;
457 fArgs.fCaps = target->caps();
458 fArgs.fScissor = scissor;
459 fArgs.fColorPOI = fArgs.fPipelineBuilder->colorProcInfo(primProc);
460 fArgs.fCoveragePOI = fArgs.fPipelineBuilder->coverageProcInfo(primProc);
461 if (!target->setupDstReadIfNecessary(*fArgs.fPipelineBuilder, fArgs.fColorPOI,
462 fArgs.fCoveragePOI, &fArgs.fDstTexture, devBounds)) {
463 fArgs.fPipelineBuilder = NULL;
egdaniele36914c2015-02-13 09:00:33 -0800464 }
465}
466
bsalomona387a112015-08-11 14:47:42 -0700467GrDrawTarget::PipelineInfo::PipelineInfo(const GrPipelineBuilder* pipelineBuilder,
468 const GrScissorState* scissor,
bsalomonabd30f52015-08-13 13:34:48 -0700469 const GrDrawBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800470 const SkRect* devBounds,
bsalomona387a112015-08-11 14:47:42 -0700471 GrDrawTarget* target) {
472 fArgs.fPipelineBuilder = pipelineBuilder;
473 fArgs.fCaps = target->caps();
474 fArgs.fScissor = scissor;
475 fArgs.fColorPOI = fArgs.fPipelineBuilder->colorProcInfo(batch);
476 fArgs.fCoveragePOI = fArgs.fPipelineBuilder->coverageProcInfo(batch);
477 if (!target->setupDstReadIfNecessary(*fArgs.fPipelineBuilder, fArgs.fColorPOI,
478 fArgs.fCoveragePOI, &fArgs.fDstTexture, devBounds)) {
479 fArgs.fPipelineBuilder = NULL;
egdaniele36914c2015-02-13 09:00:33 -0800480 }
481}
482
bsalomon@google.combcce8922013-03-25 15:38:39 +0000483///////////////////////////////////////////////////////////////////////////////
bsalomon4061b122015-05-29 10:26:19 -0700484GrClipTarget::GrClipTarget(GrContext* context)
485 : INHERITED(context->getGpu(), context->resourceProvider())
486 , fContext(context) {
halcanary385fe4d2015-08-26 13:07:48 -0700487 fClipMaskManager.reset(new GrClipMaskManager(this));
bsalomonedd77a12015-05-29 09:45:57 -0700488}
489
bsalomon@google.combcce8922013-03-25 15:38:39 +0000490
joshualitt1c735482015-07-13 08:08:25 -0700491bool GrClipTarget::setupClip(const GrPipelineBuilder& pipelineBuilder,
joshualitt4421a4c2015-07-13 09:36:41 -0700492 GrPipelineBuilder::AutoRestoreFragmentProcessorState* arfps,
egdaniel8dd688b2015-01-22 10:16:09 -0800493 GrPipelineBuilder::AutoRestoreStencil* ars,
joshualitt8059eb92014-12-29 15:10:07 -0800494 GrScissorState* scissorState,
495 const SkRect* devBounds) {
joshualitt1c735482015-07-13 08:08:25 -0700496 return fClipMaskManager->setupClipping(pipelineBuilder,
joshualitt4421a4c2015-07-13 09:36:41 -0700497 arfps,
joshualitt5e6ba212015-07-13 07:35:05 -0700498 ars,
joshualitt5e6ba212015-07-13 07:35:05 -0700499 scissorState,
500 devBounds);
joshualitt2c93efe2014-11-06 12:57:13 -0800501}
bsalomonedd77a12015-05-29 09:45:57 -0700502
503void GrClipTarget::purgeResources() {
504 // The clip mask manager can rebuild all its clip masks so just
505 // get rid of them all.
506 fClipMaskManager->purgeResources();
507};
bsalomon5ea03632015-08-18 10:33:30 -0700508
509void GrClipTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
halcanary385fe4d2015-08-26 13:07:48 -0700510 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt);
bsalomon5ea03632015-08-18 10:33:30 -0700511 this->onDrawBatch(batch);
512 batch->unref();
513}