blob: 3d5f4288f441311c36b4e0e7bf5a7e1380c0c1b4 [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))
bsalomon4061b122015-05-29 10:26:19 -070037 , fResourceProvider(resourceProvider)
bsalomon512be532015-09-10 10:42:55 -070038 , fFlushing(false)
39 , fLastFlushToken(0) {
bsalomonb3b9aec2015-09-10 11:16:35 -070040 // TODO: Stop extracting the context (currently needed by GrClipMaskManager)
41 fContext = fGpu->getContext();
Brian Salomone66fec22015-09-10 14:40:20 -040042 fClipMaskManager.reset(new GrClipMaskManager(this));
bsalomon4061b122015-05-29 10:26:19 -070043}
44
45GrDrawTarget::~GrDrawTarget() {
46 fGpu->unref();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000047}
48
49////////////////////////////////////////////////////////////////////////////////
50
bsalomon50785a32015-02-06 07:02:37 -080051bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
egdaniele36914c2015-02-13 09:00:33 -080052 const GrProcOptInfo& colorPOI,
53 const GrProcOptInfo& coveragePOI,
bsalomon6a44c6a2015-05-26 09:49:05 -070054 GrXferProcessor::DstTexture* dstTexture,
bsalomonad792c12015-09-10 11:10:50 -070055 const SkRect& batchBounds) {
56 SkRect bounds = batchBounds;
57 bounds.outset(0.5f, 0.5f);
58
bsalomon6a44c6a2015-05-26 09:49:05 -070059 if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), colorPOI, coveragePOI)) {
bsalomon@google.com26e18b52013-03-29 19:22:36 +000060 return true;
61 }
cdalton9954bc32015-04-29 14:17:00 -070062
bsalomon50785a32015-02-06 07:02:37 -080063 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
cdalton9954bc32015-04-29 14:17:00 -070064
65 if (this->caps()->textureBarrierSupport()) {
66 if (GrTexture* rtTex = rt->asTexture()) {
bsalomondc47ff72015-05-26 12:16:59 -070067 // The render target is a texture, so we can read from it directly in the shader. The XP
cdalton9954bc32015-04-29 14:17:00 -070068 // will be responsible to detect this situation and request a texture barrier.
bsalomon6a44c6a2015-05-26 09:49:05 -070069 dstTexture->setTexture(rtTex);
70 dstTexture->setOffset(0, 0);
cdalton9954bc32015-04-29 14:17:00 -070071 return true;
72 }
73 }
74
75 SkIRect copyRect;
joshualitt44701df2015-02-23 14:44:57 -080076 pipelineBuilder.clip().getConservativeBounds(rt, &copyRect);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +000077
bsalomonad792c12015-09-10 11:10:50 -070078 SkIRect drawIBounds;
79 bounds.roundOut(&drawIBounds);
80 if (!copyRect.intersect(drawIBounds)) {
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000081#ifdef SK_DEBUG
bsalomonb3b9aec2015-09-10 11:16:35 -070082 GrCapsDebugf(this->caps(), "Missed an early reject. "
83 "Bailing on draw from setupDstReadIfNecessary.\n");
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +000084#endif
bsalomonad792c12015-09-10 11:10:50 -070085 return false;
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +000086 }
skia.committer@gmail.com05a2ee02013-04-02 07:01:34 +000087
commit-bot@chromium.org63150af2013-04-11 22:00:22 +000088 // MSAA consideration: When there is support for reading MSAA samples in the shader we could
89 // have per-sample dst values by making the copy multisampled.
bsalomonf2703d82014-10-28 14:33:06 -070090 GrSurfaceDesc desc;
bsalomonb3b9aec2015-09-10 11:16:35 -070091 if (!fGpu->initCopySurfaceDstDesc(rt, &desc)) {
bsalomona73239a2015-04-28 13:35:17 -070092 desc.fOrigin = kDefault_GrSurfaceOrigin;
93 desc.fFlags = kRenderTarget_GrSurfaceFlag;
94 desc.fConfig = rt->config();
95 }
96
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +000097 desc.fWidth = copyRect.width();
98 desc.fHeight = copyRect.height();
bsalomon@google.com26e18b52013-03-29 19:22:36 +000099
bsalomoneae62002015-07-31 13:59:30 -0700100 static const uint32_t kFlags = 0;
101 SkAutoTUnref<GrTexture> copy(fResourceProvider->createApproxTexture(desc, kFlags));
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000102
bsalomone3059732014-10-14 11:47:22 -0700103 if (!copy) {
tfarina38406c82014-10-31 07:11:12 -0700104 SkDebugf("Failed to create temporary copy of destination texture.\n");
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000105 return false;
106 }
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000107 SkIPoint dstPoint = {0, 0};
bsalomon6df86402015-06-01 10:41:49 -0700108 this->copySurface(copy, rt, copyRect, dstPoint);
109 dstTexture->setTexture(copy);
110 dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
111 return true;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000112}
113
bsalomona73239a2015-04-28 13:35:17 -0700114void GrDrawTarget::flush() {
115 if (fFlushing) {
116 return;
117 }
118 fFlushing = true;
119
bsalomon512be532015-09-10 10:42:55 -0700120 GrBatchFlushState flushState(fGpu, fResourceProvider, fLastFlushToken);
121
122 // Loop over all batches and generate geometry
123 for (int i = 0; i < fBatches.count(); ++i) {
124 fBatches[i]->prepare(&flushState);
125 }
126
127 // Upload all data to the GPU
128 flushState.preIssueDraws();
129
130 // Draw all the generated geometry.
131 for (int i = 0; i < fBatches.count(); ++i) {
132 fBatches[i]->draw(&flushState);
133 }
134
135 fLastFlushToken = flushState.lastFlushedToken();
bsalomona73239a2015-04-28 13:35:17 -0700136
bsalomona73239a2015-04-28 13:35:17 -0700137 fFlushing = false;
138 this->reset();
139}
140
bsalomon512be532015-09-10 10:42:55 -0700141void GrDrawTarget::reset() {
142 fBatches.reset();
143}
144
bsalomonabd30f52015-08-13 13:34:48 -0700145void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch) {
joshualitt4d8da812015-01-28 12:53:54 -0800146 // Setup clip
147 GrScissorState scissorState;
joshualitt4421a4c2015-07-13 09:36:41 -0700148 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
joshualitt4d8da812015-01-28 12:53:54 -0800149 GrPipelineBuilder::AutoRestoreStencil ars;
bsalomonb3b9aec2015-09-10 11:16:35 -0700150 if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState,
151 &batch->bounds())) {
joshualitt4d8da812015-01-28 12:53:54 -0800152 return;
153 }
154
bsalomonad792c12015-09-10 11:10:50 -0700155 GrPipeline::CreateArgs args;
156 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &scissorState, batch)) {
egdaniele36914c2015-02-13 09:00:33 -0800157 return;
158 }
bsalomonad792c12015-09-10 11:10:50 -0700159
bsalomon512be532015-09-10 10:42:55 -0700160 this->recordBatch(batch);
joshualitt4d8da812015-01-28 12:53:54 -0800161}
162
joshualitt2c93efe2014-11-06 12:57:13 -0800163static const GrStencilSettings& winding_path_stencil_settings() {
164 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
165 kIncClamp_StencilOp,
166 kIncClamp_StencilOp,
167 kAlwaysIfInClip_StencilFunc,
168 0xFFFF, 0xFFFF, 0xFFFF);
169 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
170}
171
172static const GrStencilSettings& even_odd_path_stencil_settings() {
173 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
174 kInvert_StencilOp,
175 kInvert_StencilOp,
176 kAlwaysIfInClip_StencilFunc,
177 0xFFFF, 0xFFFF, 0xFFFF);
178 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
179}
180
181void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType fill,
egdaniel8dc7c3a2015-04-16 11:22:42 -0700182 const GrStencilAttachment* sb,
joshualitt2c93efe2014-11-06 12:57:13 -0800183 GrStencilSettings* outStencilSettings) {
184
185 switch (fill) {
186 default:
187 SkFAIL("Unexpected path fill.");
188 case GrPathRendering::kWinding_FillType:
189 *outStencilSettings = winding_path_stencil_settings();
190 break;
191 case GrPathRendering::kEvenOdd_FillType:
192 *outStencilSettings = even_odd_path_stencil_settings();
193 break;
194 }
bsalomonb3b9aec2015-09-10 11:16:35 -0700195 fClipMaskManager->adjustPathStencilParams(sb, outStencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800196}
197
joshualitt1c735482015-07-13 08:08:25 -0700198void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualittf2384692015-09-10 11:00:51 -0700199 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800200 const GrPath* path,
201 GrPathRendering::FillType fill) {
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000202 // TODO: extract portions of checkDraw that are relevant to path stenciling.
bsalomon49f085d2014-09-05 13:34:00 -0700203 SkASSERT(path);
jvanverthe9c0fc62015-04-29 11:18:05 -0700204 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
joshualitt2c93efe2014-11-06 12:57:13 -0800205
206 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800207 GrScissorState scissorState;
joshualitt4421a4c2015-07-13 09:36:41 -0700208 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
egdaniel8dd688b2015-01-22 10:16:09 -0800209 GrPipelineBuilder::AutoRestoreStencil ars;
bsalomonb3b9aec2015-09-10 11:16:35 -0700210
211 if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState, nullptr)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800212 return;
213 }
214
215 // set stencil settings for path
216 GrStencilSettings stencilSettings;
joshualitt1c735482015-07-13 08:08:25 -0700217 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
egdanielec00d942015-09-14 12:56:10 -0700218 GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt);
bsalomon6bc1b5f2015-02-23 09:06:38 -0800219 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800220
joshualittf2384692015-09-10 11:00:51 -0700221 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix,
bsalomona44919e2015-08-18 13:28:19 -0700222 pipelineBuilder.isHWAntialias(),
223 stencilSettings, scissorState,
224 pipelineBuilder.getRenderTarget(),
225 path);
bsalomon512be532015-09-10 10:42:55 -0700226 this->recordBatch(batch);
bsalomona44919e2015-08-18 13:28:19 -0700227 batch->unref();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000228}
229
joshualitt1c735482015-07-13 08:08:25 -0700230void GrDrawTarget::drawPath(const GrPipelineBuilder& pipelineBuilder,
joshualittf2384692015-09-10 11:00:51 -0700231 const SkMatrix& viewMatrix,
232 GrColor color,
joshualitt9853cce2014-11-17 14:22:48 -0800233 const GrPath* path,
234 GrPathRendering::FillType fill) {
bsalomon49f085d2014-09-05 13:34:00 -0700235 SkASSERT(path);
jvanverthe9c0fc62015-04-29 11:18:05 -0700236 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000237
joshualittf2384692015-09-10 11:00:51 -0700238 GrDrawPathBatchBase* batch = GrDrawPathBatch::Create(viewMatrix, color, path);
bsalomon1fcc01c2015-09-09 09:48:06 -0700239 this->drawPathBatch(pipelineBuilder, batch, fill);
240 batch->unref();
241}
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000242
bsalomon1fcc01c2015-09-09 09:48:06 -0700243void GrDrawTarget::drawPathsFromRange(const GrPipelineBuilder& pipelineBuilder,
joshualittf2384692015-09-10 11:00:51 -0700244 const SkMatrix& viewMatrix,
245 const SkMatrix& localMatrix,
246 GrColor color,
bsalomon1fcc01c2015-09-09 09:48:06 -0700247 GrPathRangeDraw* draw,
248 GrPathRendering::FillType fill) {
joshualittf2384692015-09-10 11:00:51 -0700249 GrDrawPathBatchBase* batch = GrDrawPathRangeBatch::Create(viewMatrix, localMatrix, color, draw);
bsalomon1fcc01c2015-09-09 09:48:06 -0700250 this->drawPathBatch(pipelineBuilder, batch, fill);
251 batch->unref();
252}
253
254void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder,
255 GrDrawPathBatchBase* batch,
256 GrPathRendering::FillType fill) {
bsalomonadd79ef2015-08-19 13:26:49 -0700257 // This looks like drawBatch() but there is an added wrinkle that stencil settings get inserted
bsalomonb3b9aec2015-09-10 11:16:35 -0700258 // after setting up clipping but before onDrawBatch(). TODO: Figure out a better model for
259 // handling stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and
260 // batches.
bsalomonadd79ef2015-08-19 13:26:49 -0700261
bsalomon3e791242014-12-17 13:43:13 -0800262 GrScissorState scissorState;
joshualitt4421a4c2015-07-13 09:36:41 -0700263 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
egdaniel8dd688b2015-01-22 10:16:09 -0800264 GrPipelineBuilder::AutoRestoreStencil ars;
bsalomonb3b9aec2015-09-10 11:16:35 -0700265 if (!fClipMaskManager->setupClipping(pipelineBuilder, &arfps, &ars, &scissorState,
266 &batch->bounds())) {
bsalomonadd79ef2015-08-19 13:26:49 -0700267 return;
joshualitt2c93efe2014-11-06 12:57:13 -0800268 }
269
bsalomonadd79ef2015-08-19 13:26:49 -0700270 // Ensure the render target has a stencil buffer and get the stencil settings.
joshualitt2c93efe2014-11-06 12:57:13 -0800271 GrStencilSettings stencilSettings;
joshualitt1c735482015-07-13 08:08:25 -0700272 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
egdanielec00d942015-09-14 12:56:10 -0700273 GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt);
bsalomon6bc1b5f2015-02-23 09:06:38 -0800274 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
bsalomonadd79ef2015-08-19 13:26:49 -0700275 batch->setStencilSettings(stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800276
bsalomonad792c12015-09-10 11:10:50 -0700277 GrPipeline::CreateArgs args;
278 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &scissorState, batch)) {
bsalomonadd79ef2015-08-19 13:26:49 -0700279 return;
280 }
egdaniele36914c2015-02-13 09:00:33 -0800281
bsalomon512be532015-09-10 10:42:55 -0700282 this->recordBatch(batch);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000283}
284
joshualittd2b23e02015-08-21 10:53:34 -0700285void GrDrawTarget::drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
joshualitt1c735482015-07-13 08:08:25 -0700286 GrColor color,
287 const SkMatrix& viewMatrix,
joshualittb6b513b2015-08-21 10:25:18 -0700288 const SkRect& rect) {
joshualittd2b23e02015-08-21 10:53:34 -0700289 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
290 nullptr, nullptr));
joshualittad17cfc2015-05-05 10:45:57 -0700291 this->drawBatch(pipelineBuilder, batch);
292}
293
joshualittd2b23e02015-08-21 10:53:34 -0700294void GrDrawTarget::drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
joshualittb6b513b2015-08-21 10:25:18 -0700295 GrColor color,
296 const SkMatrix& viewMatrix,
297 const SkRect& rect,
298 const SkMatrix& localMatrix) {
joshualittd2b23e02015-08-21 10:53:34 -0700299 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
300 nullptr, &localMatrix));
joshualittb6b513b2015-08-21 10:25:18 -0700301 this->drawBatch(pipelineBuilder, batch);
302}
303
joshualittd2b23e02015-08-21 10:53:34 -0700304void GrDrawTarget::drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
joshualittb6b513b2015-08-21 10:25:18 -0700305 GrColor color,
306 const SkMatrix& viewMatrix,
307 const SkRect& rect,
308 const SkRect& localRect) {
joshualittd2b23e02015-08-21 10:53:34 -0700309 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
310 &localRect, nullptr));
joshualittb6b513b2015-08-21 10:25:18 -0700311 this->drawBatch(pipelineBuilder, batch);
312}
313
314
joshualitt1c735482015-07-13 08:08:25 -0700315void GrDrawTarget::drawAARect(const GrPipelineBuilder& pipelineBuilder,
robertphillipsea461502015-05-26 11:38:03 -0700316 GrColor color,
317 const SkMatrix& viewMatrix,
318 const SkRect& rect,
319 const SkRect& devRect) {
joshualittd2b23e02015-08-21 10:53:34 -0700320 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect,
bsalomonabd30f52015-08-13 13:34:48 -0700321 devRect));
joshualitt14205b12015-08-10 11:40:56 -0700322 this->drawBatch(pipelineBuilder, batch);
robertphillipsea461502015-05-26 11:38:03 -0700323}
324
joshualitt9853cce2014-11-17 14:22:48 -0800325void GrDrawTarget::clear(const SkIRect* rect,
326 GrColor color,
327 bool canIgnoreRect,
bsalomon63b21962014-11-05 07:05:34 -0800328 GrRenderTarget* renderTarget) {
egdaniel51c8d402015-08-06 10:54:13 -0700329 SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height());
330 SkIRect clippedRect;
331 if (!rect ||
332 (canIgnoreRect && this->caps()->fullClearIsFree()) ||
333 rect->contains(rtRect)) {
334 rect = &rtRect;
335 } else {
336 clippedRect = *rect;
337 if (!clippedRect.intersect(rtRect)) {
338 return;
339 }
340 rect = &clippedRect;
341 }
342
bsalomonb3b9aec2015-09-10 11:16:35 -0700343 if (this->caps()->useDrawInsteadOfClear()) {
bsalomon63b21962014-11-05 07:05:34 -0800344 // This works around a driver bug with clear by drawing a rect instead.
345 // The driver will ignore a clear if it is the only thing rendered to a
346 // target before the target is read.
egdaniel51c8d402015-08-06 10:54:13 -0700347 if (rect == &rtRect) {
bsalomon63b21962014-11-05 07:05:34 -0800348 this->discard(renderTarget);
349 }
bsalomon63b21962014-11-05 07:05:34 -0800350
egdaniel8dd688b2015-01-22 10:16:09 -0800351 GrPipelineBuilder pipelineBuilder;
352 pipelineBuilder.setRenderTarget(renderTarget);
joshualitt9853cce2014-11-17 14:22:48 -0800353
joshualittd2b23e02015-08-21 10:53:34 -0700354 this->drawNonAARect(pipelineBuilder, color, SkMatrix::I(), *rect);
bsalomon53469832015-08-18 09:20:09 -0700355 } else {
halcanary385fe4d2015-08-26 13:07:48 -0700356 GrBatch* batch = new GrClearBatch(*rect, color, renderTarget);
bsalomon512be532015-09-10 10:42:55 -0700357 this->recordBatch(batch);
bsalomon53469832015-08-18 09:20:09 -0700358 batch->unref();
359 }
360}
361
362void GrDrawTarget::discard(GrRenderTarget* renderTarget) {
363 if (this->caps()->discardRenderTargetSupport()) {
halcanary385fe4d2015-08-26 13:07:48 -0700364 GrBatch* batch = new GrDiscardBatch(renderTarget);
bsalomon512be532015-09-10 10:42:55 -0700365 this->recordBatch(batch);
bsalomon53469832015-08-18 09:20:09 -0700366 batch->unref();
bsalomon63b21962014-11-05 07:05:34 -0800367 }
368}
369
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000370////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000371
bsalomon6df86402015-06-01 10:41:49 -0700372void GrDrawTarget::copySurface(GrSurface* dst,
bsalomon@google.com116ad842013-04-09 15:38:19 +0000373 GrSurface* src,
374 const SkIRect& srcRect,
375 const SkIPoint& dstPoint) {
bsalomon872062c2015-08-18 12:12:35 -0700376 GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint);
377 if (batch) {
bsalomon512be532015-09-10 10:42:55 -0700378 this->recordBatch(batch);
bsalomon872062c2015-08-18 12:12:35 -0700379 batch->unref();
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000380 }
bsalomon@google.comeb851172013-04-15 13:51:00 +0000381}
382
bsalomon512be532015-09-10 10:42:55 -0700383template <class Left, class Right> static bool intersect(const Left& a, const Right& b) {
384 SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom &&
385 b.fLeft <= b.fRight && b.fTop <= b.fBottom);
386 return a.fLeft < b.fRight && b.fLeft < a.fRight && a.fTop < b.fBottom && b.fTop < a.fBottom;
387}
388
389void GrDrawTarget::recordBatch(GrBatch* batch) {
390 // Check if there is a Batch Draw we can batch with by linearly searching back until we either
391 // 1) check every draw
392 // 2) intersect with something
393 // 3) find a 'blocker'
394 // Experimentally we have found that most batching occurs within the first 10 comparisons.
395 static const int kMaxLookback = 10;
396
397 GrBATCH_INFO("Re-Recording (%s, B%u)\n"
398 "\tBounds (%f, %f, %f, %f)\n",
399 batch->name(),
400 batch->uniqueID(),
401 batch->bounds().fLeft, batch->bounds().fRight,
402 batch->bounds().fTop, batch->bounds().fBottom);
403 GrBATCH_INFO(SkTabString(batch->dumpInfo(), 1).c_str());
404 GrBATCH_INFO("\tOutcome:\n");
405 int maxCandidates = SkTMin(kMaxLookback, fBatches.count());
406 if (maxCandidates) {
407 int i = 0;
408 while (true) {
409 GrBatch* candidate = fBatches.fromBack(i);
410 // We cannot continue to search backwards if the render target changes
411 if (candidate->renderTargetUniqueID() != batch->renderTargetUniqueID()) {
412 GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n",
413 candidate->name(), candidate->uniqueID());
414 break;
415 }
416 if (candidate->combineIfPossible(batch, *this->caps())) {
417 GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
418 candidate->uniqueID());
419 return;
420 }
421 // Stop going backwards if we would cause a painter's order violation.
422 if (intersect(candidate->bounds(), batch->bounds())) {
423 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(),
424 candidate->uniqueID());
425 break;
426 }
427 ++i;
428 if (i == maxCandidates) {
429 GrBATCH_INFO("\t\tReached max lookback or beginning of batch array %d\n", i);
430 break;
431 }
432 }
433 } else {
434 GrBATCH_INFO("\t\tFirstBatch\n");
435 }
436 fBatches.push_back().reset(SkRef(batch));
437}
438
egdaniele36914c2015-02-13 09:00:33 -0800439///////////////////////////////////////////////////////////////////////////////
440
bsalomonad792c12015-09-10 11:10:50 -0700441bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
442 const GrScissorState* scissor,
443 GrDrawBatch* batch) {
444 GrPipeline::CreateArgs args;
445 args.fPipelineBuilder = pipelineBuilder;
446 args.fCaps = this->caps();
447 args.fScissor = scissor;
448 args.fColorPOI = pipelineBuilder->colorProcInfo(batch);
449 args.fCoveragePOI = pipelineBuilder->coverageProcInfo(batch);
450 if (!this->setupDstReadIfNecessary(*pipelineBuilder, args.fColorPOI,
451 args.fCoveragePOI, &args.fDstTexture,
452 batch->bounds())) {
453 return false;
egdaniele36914c2015-02-13 09:00:33 -0800454 }
bsalomonad792c12015-09-10 11:10:50 -0700455
456 if (!batch->installPipeline(args)) {
457 return false;
458 }
459
460 return true;
egdaniele36914c2015-02-13 09:00:33 -0800461}
462
bsalomonb3b9aec2015-09-10 11:16:35 -0700463void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
halcanary385fe4d2015-08-26 13:07:48 -0700464 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt);
bsalomon512be532015-09-10 10:42:55 -0700465 this->recordBatch(batch);
bsalomon5ea03632015-08-18 10:33:30 -0700466 batch->unref();
467}