blob: 7ccdce5309dffb3004a6d02b530004c019dfd489 [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
11#include "GrBatch.h"
bsalomon@google.com26e18b52013-03-29 19:22:36 +000012#include "GrContext.h"
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000013#include "GrDrawTargetCaps.h"
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +000014#include "GrPath.h"
egdaniele36914c2015-02-13 09:00:33 -080015#include "GrPipeline.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000016#include "GrRenderTarget.h"
bsalomonafbf2d62014-09-30 12:18:44 -070017#include "GrSurfacePriv.h"
bsalomon62c447d2014-08-08 08:08:50 -070018#include "GrTemplates.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000019#include "GrTexture.h"
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000020#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000021
sugoi@google.com5f74cf82012-12-17 21:16:45 +000022#include "SkStrokeRec.h"
sugoi@google.com12b4e272012-12-06 20:13:11 +000023
reed@google.comac10a2d2010-12-22 21:39:39 +000024////////////////////////////////////////////////////////////////////////////////
25
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000026GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
27 fPrimitiveType = di.fPrimitiveType;
28 fStartVertex = di.fStartVertex;
29 fStartIndex = di.fStartIndex;
30 fVertexCount = di.fVertexCount;
31 fIndexCount = di.fIndexCount;
32
33 fInstanceCount = di.fInstanceCount;
34 fVerticesPerInstance = di.fVerticesPerInstance;
35 fIndicesPerInstance = di.fIndicesPerInstance;
36
bsalomon49f085d2014-09-05 13:34:00 -070037 if (di.fDevBounds) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000038 SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000039 fDevBoundsStorage = di.fDevBoundsStorage;
40 fDevBounds = &fDevBoundsStorage;
41 } else {
42 fDevBounds = NULL;
43 }
bsalomon@google.com26e18b52013-03-29 19:22:36 +000044
joshualitt7eb8c7b2014-11-18 14:24:27 -080045 this->setVertexBuffer(di.vertexBuffer());
46 this->setIndexBuffer(di.indexBuffer());
47
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000048 return *this;
49}
50
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000051#ifdef SK_DEBUG
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000052bool GrDrawTarget::DrawInfo::isInstanced() const {
53 if (fInstanceCount > 0) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000054 SkASSERT(0 == fIndexCount % fIndicesPerInstance);
55 SkASSERT(0 == fVertexCount % fVerticesPerInstance);
56 SkASSERT(fIndexCount / fIndicesPerInstance == fInstanceCount);
57 SkASSERT(fVertexCount / fVerticesPerInstance == fInstanceCount);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000058 // there is no way to specify a non-zero start index to drawIndexedInstances().
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000059 SkASSERT(0 == fStartIndex);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000060 return true;
61 } else {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000062 SkASSERT(!fVerticesPerInstance);
63 SkASSERT(!fIndicesPerInstance);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000064 return false;
65 }
66}
67#endif
68
69void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000070 SkASSERT(this->isInstanced());
71 SkASSERT(instanceOffset + fInstanceCount >= 0);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000072 fInstanceCount += instanceOffset;
73 fVertexCount = fVerticesPerInstance * fInstanceCount;
74 fIndexCount = fIndicesPerInstance * fInstanceCount;
75}
76
77void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) {
78 fStartVertex += vertexOffset;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000079 SkASSERT(fStartVertex >= 0);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000080}
81
82void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000083 SkASSERT(this->isIndexed());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000084 fStartIndex += indexOffset;
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000085 SkASSERT(fStartIndex >= 0);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000086}
87
88////////////////////////////////////////////////////////////////////////////////
89
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000090#define DEBUG_INVAL_BUFFER 0xdeadcafe
91#define DEBUG_INVAL_START_IDX -1
92
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000093GrDrawTarget::GrDrawTarget(GrContext* context)
94 : fClip(NULL)
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +000095 , fContext(context)
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +000096 , fGpuTraceMarkerCount(0) {
bsalomon49f085d2014-09-05 13:34:00 -070097 SkASSERT(context);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000098 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000099#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000100 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
101 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
102 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
103 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
reed@google.comac10a2d2010-12-22 21:39:39 +0000104#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000105 geoSrc.fVertexSrc = kNone_GeometrySrcType;
106 geoSrc.fIndexSrc = kNone_GeometrySrcType;
107}
108
109GrDrawTarget::~GrDrawTarget() {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000110 SkASSERT(1 == fGeoSrcStateStack.count());
humper@google.com0e515772013-01-07 19:54:40 +0000111 SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000112 SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc);
113 SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com4a018bb2011-10-28 19:50:21 +0000114}
115
116void GrDrawTarget::releaseGeometry() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000117 int popCnt = fGeoSrcStateStack.count() - 1;
118 while (popCnt) {
119 this->popGeometrySource();
120 --popCnt;
121 }
bsalomon@google.com4a018bb2011-10-28 19:50:21 +0000122 this->resetVertexSource();
123 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000124}
125
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000126void GrDrawTarget::setClip(const GrClipData* clip) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000127 fClip = clip;
128}
129
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000130const GrClipData* GrDrawTarget::getClip() const {
reed@google.comac10a2d2010-12-22 21:39:39 +0000131 return fClip;
132}
133
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000134bool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000135 int vertexCount,
136 void** vertices) {
137 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
138 bool acquired = false;
139 if (vertexCount > 0) {
bsalomon49f085d2014-09-05 13:34:00 -0700140 SkASSERT(vertices);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000141 this->releasePreviousVertexSource();
142 geoSrc.fVertexSrc = kNone_GeometrySrcType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000143
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000144 acquired = this->onReserveVertexSpace(vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000145 vertexCount,
146 vertices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000147 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000148 if (acquired) {
149 geoSrc.fVertexSrc = kReserved_GeometrySrcType;
150 geoSrc.fVertexCount = vertexCount;
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000151 geoSrc.fVertexSize = vertexSize;
bsalomon49f085d2014-09-05 13:34:00 -0700152 } else if (vertices) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000153 *vertices = NULL;
154 }
155 return acquired;
156}
157
158bool GrDrawTarget::reserveIndexSpace(int indexCount,
159 void** indices) {
160 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
161 bool acquired = false;
162 if (indexCount > 0) {
bsalomon49f085d2014-09-05 13:34:00 -0700163 SkASSERT(indices);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000164 this->releasePreviousIndexSource();
165 geoSrc.fIndexSrc = kNone_GeometrySrcType;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000166
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000167 acquired = this->onReserveIndexSpace(indexCount, indices);
168 }
169 if (acquired) {
170 geoSrc.fIndexSrc = kReserved_GeometrySrcType;
171 geoSrc.fIndexCount = indexCount;
bsalomon49f085d2014-09-05 13:34:00 -0700172 } else if (indices) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000173 *indices = NULL;
174 }
175 return acquired;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000176
reed@google.comac10a2d2010-12-22 21:39:39 +0000177}
178
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000179bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
joshualitt9853cce2014-11-17 14:22:48 -0800180 size_t vertexStride,
bsalomon@google.come3d70952012-03-13 12:40:53 +0000181 int indexCount,
182 void** vertices,
183 void** indices) {
joshualitt9853cce2014-11-17 14:22:48 -0800184 this->willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
bsalomon@google.come3d70952012-03-13 12:40:53 +0000185 if (vertexCount) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700186 if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) {
bsalomon@google.come3d70952012-03-13 12:40:53 +0000187 if (indexCount) {
188 this->resetIndexSource();
189 }
190 return false;
191 }
192 }
193 if (indexCount) {
194 if (!this->reserveIndexSpace(indexCount, indices)) {
195 if (vertexCount) {
196 this->resetVertexSource();
197 }
198 return false;
199 }
200 }
201 return true;
202}
203
joshualitt9853cce2014-11-17 14:22:48 -0800204bool GrDrawTarget::geometryHints(size_t vertexStride,
205 int32_t* vertexCount,
reed@google.comac10a2d2010-12-22 21:39:39 +0000206 int32_t* indexCount) const {
bsalomon49f085d2014-09-05 13:34:00 -0700207 if (vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000208 *vertexCount = -1;
209 }
bsalomon49f085d2014-09-05 13:34:00 -0700210 if (indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000211 *indexCount = -1;
212 }
213 return false;
214}
215
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000216void GrDrawTarget::releasePreviousVertexSource() {
217 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
218 switch (geoSrc.fVertexSrc) {
219 case kNone_GeometrySrcType:
220 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000221 case kReserved_GeometrySrcType:
222 this->releaseReservedVertexSpace();
223 break;
224 case kBuffer_GeometrySrcType:
225 geoSrc.fVertexBuffer->unref();
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000226#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000227 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
228#endif
229 break;
230 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000231 SkFAIL("Unknown Vertex Source Type.");
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000232 break;
233 }
234}
235
236void GrDrawTarget::releasePreviousIndexSource() {
237 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
238 switch (geoSrc.fIndexSrc) {
239 case kNone_GeometrySrcType: // these two don't require
240 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000241 case kReserved_GeometrySrcType:
242 this->releaseReservedIndexSpace();
243 break;
244 case kBuffer_GeometrySrcType:
245 geoSrc.fIndexBuffer->unref();
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000246#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000247 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
248#endif
249 break;
250 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000251 SkFAIL("Unknown Index Source Type.");
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000252 break;
253 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000254}
255
joshualitt9853cce2014-11-17 14:22:48 -0800256void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000257 this->releasePreviousVertexSource();
258 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
259 geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
260 geoSrc.fVertexBuffer = buffer;
261 buffer->ref();
joshualitt9853cce2014-11-17 14:22:48 -0800262 geoSrc.fVertexSize = vertexStride;
reed@google.comac10a2d2010-12-22 21:39:39 +0000263}
264
265void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000266 this->releasePreviousIndexSource();
267 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
268 geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
269 geoSrc.fIndexBuffer = buffer;
270 buffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000271}
272
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000273void GrDrawTarget::resetVertexSource() {
274 this->releasePreviousVertexSource();
275 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
276 geoSrc.fVertexSrc = kNone_GeometrySrcType;
277}
278
279void GrDrawTarget::resetIndexSource() {
280 this->releasePreviousIndexSource();
281 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
282 geoSrc.fIndexSrc = kNone_GeometrySrcType;
283}
284
285void GrDrawTarget::pushGeometrySource() {
286 this->geometrySourceWillPush();
287 GeometrySrcState& newState = fGeoSrcStateStack.push_back();
288 newState.fIndexSrc = kNone_GeometrySrcType;
289 newState.fVertexSrc = kNone_GeometrySrcType;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000290#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000291 newState.fVertexCount = ~0;
292 newState.fVertexBuffer = (GrVertexBuffer*)~0;
293 newState.fIndexCount = ~0;
294 newState.fIndexBuffer = (GrIndexBuffer*)~0;
295#endif
296}
297
298void GrDrawTarget::popGeometrySource() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000299 // if popping last element then pops are unbalanced with pushes
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000300 SkASSERT(fGeoSrcStateStack.count() > 1);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000301
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000302 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
303 this->releasePreviousVertexSource();
304 this->releasePreviousIndexSource();
305 fGeoSrcStateStack.pop_back();
306}
307
308////////////////////////////////////////////////////////////////////////////////
309
egdaniel8dd688b2015-01-22 10:16:09 -0800310bool GrDrawTarget::checkDraw(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800311 const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800312 GrPrimitiveType type,
313 int startVertex,
314 int startIndex,
315 int vertexCount,
bsalomon@google.come8262622011-11-07 02:30:51 +0000316 int indexCount) const {
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000317#ifdef SK_DEBUG
bsalomon@google.come8262622011-11-07 02:30:51 +0000318 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000319 int maxVertex = startVertex + vertexCount;
320 int maxValidVertex;
321 switch (geoSrc.fVertexSrc) {
322 case kNone_GeometrySrcType:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000323 SkFAIL("Attempting to draw without vertex src.");
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000324 case kReserved_GeometrySrcType: // fallthrough
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000325 maxValidVertex = geoSrc.fVertexCount;
326 break;
327 case kBuffer_GeometrySrcType:
egdaniel8dd688b2015-01-22 10:16:09 -0800328 maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->gpuMemorySize() /
329 geoSrc.fVertexSize);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000330 break;
331 }
332 if (maxVertex > maxValidVertex) {
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000333 SkFAIL("Drawing outside valid vertex range.");
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000334 }
bsalomon@google.come8262622011-11-07 02:30:51 +0000335 if (indexCount > 0) {
336 int maxIndex = startIndex + indexCount;
337 int maxValidIndex;
338 switch (geoSrc.fIndexSrc) {
339 case kNone_GeometrySrcType:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000340 SkFAIL("Attempting to draw indexed geom without index src.");
bsalomon@google.come8262622011-11-07 02:30:51 +0000341 case kReserved_GeometrySrcType: // fallthrough
bsalomon@google.come8262622011-11-07 02:30:51 +0000342 maxValidIndex = geoSrc.fIndexCount;
343 break;
344 case kBuffer_GeometrySrcType:
egdaniel8dd688b2015-01-22 10:16:09 -0800345 maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->gpuMemorySize() /
346 sizeof(uint16_t));
bsalomon@google.come8262622011-11-07 02:30:51 +0000347 break;
348 }
349 if (maxIndex > maxValidIndex) {
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000350 SkFAIL("Index reads outside valid index range.");
bsalomon@google.come8262622011-11-07 02:30:51 +0000351 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000352 }
bsalomon@google.comb4725b42012-03-30 17:24:17 +0000353
egdaniel8dd688b2015-01-22 10:16:09 -0800354 SkASSERT(pipelineBuilder.getRenderTarget());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000355
joshualitt56995b52014-12-11 15:44:02 -0800356 if (gp) {
joshualittb0a8a372014-09-23 09:50:21 -0700357 int numTextures = gp->numTextures();
joshualittbd769d02014-09-04 08:56:46 -0700358 for (int t = 0; t < numTextures; ++t) {
joshualittb0a8a372014-09-23 09:50:21 -0700359 GrTexture* texture = gp->texture(t);
egdaniel8dd688b2015-01-22 10:16:09 -0800360 SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarget());
joshualittbd769d02014-09-04 08:56:46 -0700361 }
362 }
363
egdaniel8dd688b2015-01-22 10:16:09 -0800364 for (int s = 0; s < pipelineBuilder.numColorStages(); ++s) {
365 const GrProcessor* effect = pipelineBuilder.getColorStage(s).processor();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000366 int numTextures = effect->numTextures();
367 for (int t = 0; t < numTextures; ++t) {
368 GrTexture* texture = effect->texture(t);
egdaniel8dd688b2015-01-22 10:16:09 -0800369 SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarget());
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000370 }
371 }
egdaniel8dd688b2015-01-22 10:16:09 -0800372 for (int s = 0; s < pipelineBuilder.numCoverageStages(); ++s) {
373 const GrProcessor* effect = pipelineBuilder.getCoverageStage(s).processor();
bsalomon@google.comeb6879f2013-06-13 19:34:18 +0000374 int numTextures = effect->numTextures();
375 for (int t = 0; t < numTextures; ++t) {
376 GrTexture* texture = effect->texture(t);
egdaniel8dd688b2015-01-22 10:16:09 -0800377 SkASSERT(texture->asRenderTarget() != pipelineBuilder.getRenderTarget());
bsalomon@google.comb4725b42012-03-30 17:24:17 +0000378 }
379 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000380
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000381#endif
egdaniel8dd688b2015-01-22 10:16:09 -0800382 if (NULL == pipelineBuilder.getRenderTarget()) {
bsalomon@google.com0ba52fc2011-11-10 22:16:06 +0000383 return false;
384 }
bsalomon@google.come8262622011-11-07 02:30:51 +0000385 return true;
386}
387
bsalomon50785a32015-02-06 07:02:37 -0800388bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
egdaniele36914c2015-02-13 09:00:33 -0800389 const GrProcOptInfo& colorPOI,
390 const GrProcOptInfo& coveragePOI,
joshualitt9853cce2014-11-17 14:22:48 -0800391 GrDeviceCoordTexture* dstCopy,
392 const SkRect* drawBounds) {
egdaniele36914c2015-02-13 09:00:33 -0800393 if (!pipelineBuilder.willXPNeedDstCopy(*this->caps(), colorPOI, coveragePOI)) {
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000394 return true;
395 }
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000396 SkIRect copyRect;
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000397 const GrClipData* clip = this->getClip();
bsalomon50785a32015-02-06 07:02:37 -0800398 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000399 clip->getConservativeBounds(rt, &copyRect);
400
bsalomon49f085d2014-09-05 13:34:00 -0700401 if (drawBounds) {
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000402 SkIRect drawIBounds;
403 drawBounds->roundOut(&drawIBounds);
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +0000404 if (!copyRect.intersect(drawIBounds)) {
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000405#ifdef SK_DEBUG
tfarina38406c82014-10-31 07:11:12 -0700406 SkDebugf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +0000407#endif
408 return false;
409 }
410 } else {
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000411#ifdef SK_DEBUG
tfarina38406c82014-10-31 07:11:12 -0700412 //SkDebugf("No dev bounds when dst copy is made.\n");
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +0000413#endif
414 }
skia.committer@gmail.com05a2ee02013-04-02 07:01:34 +0000415
commit-bot@chromium.org63150af2013-04-11 22:00:22 +0000416 // MSAA consideration: When there is support for reading MSAA samples in the shader we could
417 // have per-sample dst values by making the copy multisampled.
bsalomonf2703d82014-10-28 14:33:06 -0700418 GrSurfaceDesc desc;
bsalomon@google.comeb851172013-04-15 13:51:00 +0000419 this->initCopySurfaceDstDesc(rt, &desc);
commit-bot@chromium.orgbb5c4652013-04-01 12:49:31 +0000420 desc.fWidth = copyRect.width();
421 desc.fHeight = copyRect.height();
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000422
bsalomone3059732014-10-14 11:47:22 -0700423 SkAutoTUnref<GrTexture> copy(
424 fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000425
bsalomone3059732014-10-14 11:47:22 -0700426 if (!copy) {
tfarina38406c82014-10-31 07:11:12 -0700427 SkDebugf("Failed to create temporary copy of destination texture.\n");
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000428 return false;
429 }
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000430 SkIPoint dstPoint = {0, 0};
bsalomone3059732014-10-14 11:47:22 -0700431 if (this->copySurface(copy, rt, copyRect, dstPoint)) {
432 dstCopy->setTexture(copy);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000433 dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000434 return true;
435 } else {
436 return false;
437 }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000438}
439
egdaniel8dd688b2015-01-22 10:16:09 -0800440void GrDrawTarget::drawIndexed(GrPipelineBuilder* pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800441 const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800442 GrPrimitiveType type,
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000443 int startVertex,
444 int startIndex,
445 int vertexCount,
446 int indexCount,
447 const SkRect* devBounds) {
egdaniel8dd688b2015-01-22 10:16:09 -0800448 SkASSERT(pipelineBuilder);
joshualitt9853cce2014-11-17 14:22:48 -0800449 if (indexCount > 0 &&
egdaniel8dd688b2015-01-22 10:16:09 -0800450 this->checkDraw(*pipelineBuilder, gp, type, startVertex, startIndex, vertexCount,
451 indexCount)) {
joshualitt9853cce2014-11-17 14:22:48 -0800452
joshualitt2c93efe2014-11-06 12:57:13 -0800453 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800454 GrScissorState scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800455 GrPipelineBuilder::AutoRestoreEffects are;
456 GrPipelineBuilder::AutoRestoreStencil ars;
457 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800458 return;
459 }
460
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000461 DrawInfo info;
462 info.fPrimitiveType = type;
463 info.fStartVertex = startVertex;
464 info.fStartIndex = startIndex;
465 info.fVertexCount = vertexCount;
466 info.fIndexCount = indexCount;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000467
468 info.fInstanceCount = 0;
469 info.fVerticesPerInstance = 0;
470 info.fIndicesPerInstance = 0;
471
bsalomon49f085d2014-09-05 13:34:00 -0700472 if (devBounds) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000473 info.setDevBounds(*devBounds);
474 }
joshualitt9176e2c2014-11-20 07:28:52 -0800475
egdaniele36914c2015-02-13 09:00:33 -0800476 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds,
477 this);
478 if (pipelineInfo.mustSkipDraw()) {
479 return;
480 }
481
joshualitt2e3b3e32014-12-09 13:31:14 -0800482 this->setDrawBuffers(&info, gp->getVertexStride());
joshualitt7eb8c7b2014-11-18 14:24:27 -0800483
egdaniele36914c2015-02-13 09:00:33 -0800484 this->onDraw(gp, info, pipelineInfo);
bsalomon@google.com82145872011-08-23 14:32:40 +0000485 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000486}
487
egdaniel8dd688b2015-01-22 10:16:09 -0800488void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800489 const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800490 GrPrimitiveType type,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000491 int startVertex,
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000492 int vertexCount,
493 const SkRect* devBounds) {
egdaniel8dd688b2015-01-22 10:16:09 -0800494 SkASSERT(pipelineBuilder);
495 if (vertexCount > 0 && this->checkDraw(*pipelineBuilder, gp, type, startVertex, -1, vertexCount,
496 -1)) {
joshualitt9853cce2014-11-17 14:22:48 -0800497
joshualitt2c93efe2014-11-06 12:57:13 -0800498 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800499 GrScissorState scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800500 GrPipelineBuilder::AutoRestoreEffects are;
501 GrPipelineBuilder::AutoRestoreStencil ars;
502 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800503 return;
504 }
505
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000506 DrawInfo info;
507 info.fPrimitiveType = type;
508 info.fStartVertex = startVertex;
509 info.fStartIndex = 0;
510 info.fVertexCount = vertexCount;
511 info.fIndexCount = 0;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000512
513 info.fInstanceCount = 0;
514 info.fVerticesPerInstance = 0;
515 info.fIndicesPerInstance = 0;
516
bsalomon49f085d2014-09-05 13:34:00 -0700517 if (devBounds) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000518 info.setDevBounds(*devBounds);
519 }
joshualitt2c93efe2014-11-06 12:57:13 -0800520
egdaniele36914c2015-02-13 09:00:33 -0800521 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds,
522 this);
523 if (pipelineInfo.mustSkipDraw()) {
524 return;
525 }
526
joshualitt2e3b3e32014-12-09 13:31:14 -0800527 this->setDrawBuffers(&info, gp->getVertexStride());
joshualitt7eb8c7b2014-11-18 14:24:27 -0800528
egdaniele36914c2015-02-13 09:00:33 -0800529 this->onDraw(gp, info, pipelineInfo);
bsalomon@google.com82145872011-08-23 14:32:40 +0000530 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000531}
532
joshualitt4d8da812015-01-28 12:53:54 -0800533
534void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder,
535 GrBatch* batch,
536 const SkRect* devBounds) {
537 SkASSERT(pipelineBuilder);
538 // TODO some kind of checkdraw, but not at this level
539
540 // Setup clip
541 GrScissorState scissorState;
542 GrPipelineBuilder::AutoRestoreEffects are;
543 GrPipelineBuilder::AutoRestoreStencil ars;
544 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
545 return;
546 }
547
egdaniele36914c2015-02-13 09:00:33 -0800548 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, batch, devBounds, this);
549 if (pipelineInfo.mustSkipDraw()) {
550 return;
551 }
552
553 this->onDrawBatch(batch, pipelineInfo);
joshualitt4d8da812015-01-28 12:53:54 -0800554}
555
joshualitt2c93efe2014-11-06 12:57:13 -0800556static const GrStencilSettings& winding_path_stencil_settings() {
557 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
558 kIncClamp_StencilOp,
559 kIncClamp_StencilOp,
560 kAlwaysIfInClip_StencilFunc,
561 0xFFFF, 0xFFFF, 0xFFFF);
562 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
563}
564
565static const GrStencilSettings& even_odd_path_stencil_settings() {
566 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
567 kInvert_StencilOp,
568 kInvert_StencilOp,
569 kAlwaysIfInClip_StencilFunc,
570 0xFFFF, 0xFFFF, 0xFFFF);
571 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
572}
573
574void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType fill,
joshualitt9853cce2014-11-17 14:22:48 -0800575 const GrStencilBuffer* sb,
joshualitt2c93efe2014-11-06 12:57:13 -0800576 GrStencilSettings* outStencilSettings) {
577
578 switch (fill) {
579 default:
580 SkFAIL("Unexpected path fill.");
581 case GrPathRendering::kWinding_FillType:
582 *outStencilSettings = winding_path_stencil_settings();
583 break;
584 case GrPathRendering::kEvenOdd_FillType:
585 *outStencilSettings = even_odd_path_stencil_settings();
586 break;
587 }
joshualitt9853cce2014-11-17 14:22:48 -0800588 this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800589}
590
egdaniel8dd688b2015-01-22 10:16:09 -0800591void GrDrawTarget::stencilPath(GrPipelineBuilder* pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800592 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800593 const GrPath* path,
594 GrPathRendering::FillType fill) {
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000595 // TODO: extract portions of checkDraw that are relevant to path stenciling.
bsalomon49f085d2014-09-05 13:34:00 -0700596 SkASSERT(path);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000597 SkASSERT(this->caps()->pathRenderingSupport());
egdaniel8dd688b2015-01-22 10:16:09 -0800598 SkASSERT(pipelineBuilder);
joshualitt2c93efe2014-11-06 12:57:13 -0800599
600 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800601 GrScissorState scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800602 GrPipelineBuilder::AutoRestoreEffects are;
603 GrPipelineBuilder::AutoRestoreStencil ars;
604 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800605 return;
606 }
607
608 // set stencil settings for path
609 GrStencilSettings stencilSettings;
joshualitt9853cce2014-11-17 14:22:48 -0800610 this->getPathStencilSettingsForFilltype(fill,
egdaniel8dd688b2015-01-22 10:16:09 -0800611 pipelineBuilder->getRenderTarget()->getStencilBuffer(),
joshualitt9853cce2014-11-17 14:22:48 -0800612 &stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800613
egdaniel8dd688b2015-01-22 10:16:09 -0800614 this->onStencilPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings);
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000615}
616
egdaniel8dd688b2015-01-22 10:16:09 -0800617void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800618 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800619 const GrPath* path,
620 GrPathRendering::FillType fill) {
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000621 // TODO: extract portions of checkDraw that are relevant to path rendering.
bsalomon49f085d2014-09-05 13:34:00 -0700622 SkASSERT(path);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000623 SkASSERT(this->caps()->pathRenderingSupport());
egdaniel8dd688b2015-01-22 10:16:09 -0800624 SkASSERT(pipelineBuilder);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000625
joshualitt92e496f2014-10-31 13:56:50 -0700626 SkRect devBounds = path->getBounds();
joshualitt8059eb92014-12-29 15:10:07 -0800627 pathProc->viewMatrix().mapRect(&devBounds);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000628
joshualitt2c93efe2014-11-06 12:57:13 -0800629 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800630 GrScissorState scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800631 GrPipelineBuilder::AutoRestoreEffects are;
632 GrPipelineBuilder::AutoRestoreStencil ars;
633 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, &devBounds)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800634 return;
635 }
636
637 // set stencil settings for path
638 GrStencilSettings stencilSettings;
joshualitt9853cce2014-11-17 14:22:48 -0800639 this->getPathStencilSettingsForFilltype(fill,
egdaniel8dd688b2015-01-22 10:16:09 -0800640 pipelineBuilder->getRenderTarget()->getStencilBuffer(),
joshualitt9853cce2014-11-17 14:22:48 -0800641 &stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800642
egdaniele36914c2015-02-13 09:00:33 -0800643 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, &devBounds,
644 this);
645 if (pipelineInfo.mustSkipDraw()) {
646 return;
647 }
648
649 this->onDrawPath(pathProc, path, stencilSettings, pipelineInfo);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000650}
651
egdaniel8dd688b2015-01-22 10:16:09 -0800652void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800653 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800654 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800655 const void* indices,
656 PathIndexType indexType,
657 const float transformValues[],
658 PathTransformType transformType,
joshualitt9853cce2014-11-17 14:22:48 -0800659 int count,
joshualitt92e496f2014-10-31 13:56:50 -0700660 GrPathRendering::FillType fill) {
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000661 SkASSERT(this->caps()->pathRenderingSupport());
bsalomon49f085d2014-09-05 13:34:00 -0700662 SkASSERT(pathRange);
663 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800664 SkASSERT(0 == reinterpret_cast<long>(indices) % GrPathRange::PathIndexSizeInBytes(indexType));
665 SkASSERT(transformValues);
egdaniel8dd688b2015-01-22 10:16:09 -0800666 SkASSERT(pipelineBuilder);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000667
joshualitt2c93efe2014-11-06 12:57:13 -0800668 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800669 GrScissorState scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800670 GrPipelineBuilder::AutoRestoreEffects are;
671 GrPipelineBuilder::AutoRestoreStencil ars;
joshualitt2c93efe2014-11-06 12:57:13 -0800672
egdaniel8dd688b2015-01-22 10:16:09 -0800673 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800674 return;
675 }
676
677 // set stencil settings for path
678 GrStencilSettings stencilSettings;
joshualitt9853cce2014-11-17 14:22:48 -0800679 this->getPathStencilSettingsForFilltype(fill,
egdaniel8dd688b2015-01-22 10:16:09 -0800680 pipelineBuilder->getRenderTarget()->getStencilBuffer(),
joshualitt9853cce2014-11-17 14:22:48 -0800681 &stencilSettings);
joshualitt2c93efe2014-11-06 12:57:13 -0800682
bsalomon50785a32015-02-06 07:02:37 -0800683 // Don't compute a bounding box for dst copy texture, we'll opt
cdaltonb85a0aa2014-07-21 15:32:44 -0700684 // instead for it to just copy the entire dst. Realistically this is a moot
685 // point, because any context that supports NV_path_rendering will also
686 // support NV_blend_equation_advanced.
egdaniele36914c2015-02-13 09:00:33 -0800687 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, NULL, this);
688 if (pipelineInfo.mustSkipDraw()) {
689 return;
690 }
691
692 this->onDrawPaths(pathProc, pathRange, indices, indexType, transformValues,
693 transformType, count, stencilSettings, pipelineInfo);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000694}
695
joshualitt9853cce2014-11-17 14:22:48 -0800696void GrDrawTarget::clear(const SkIRect* rect,
697 GrColor color,
698 bool canIgnoreRect,
bsalomon63b21962014-11-05 07:05:34 -0800699 GrRenderTarget* renderTarget) {
700 if (fCaps->useDrawInsteadOfClear()) {
701 // This works around a driver bug with clear by drawing a rect instead.
702 // The driver will ignore a clear if it is the only thing rendered to a
703 // target before the target is read.
704 SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height());
705 if (NULL == rect || canIgnoreRect || rect->contains(rtRect)) {
706 rect = &rtRect;
707 // We first issue a discard() since that may help tilers.
708 this->discard(renderTarget);
709 }
bsalomon63b21962014-11-05 07:05:34 -0800710
egdaniel8dd688b2015-01-22 10:16:09 -0800711 GrPipelineBuilder pipelineBuilder;
712 pipelineBuilder.setRenderTarget(renderTarget);
joshualitt9853cce2014-11-17 14:22:48 -0800713
egdaniel8dd688b2015-01-22 10:16:09 -0800714 this->drawSimpleRect(&pipelineBuilder, color, SkMatrix::I(), *rect);
bsalomon63b21962014-11-05 07:05:34 -0800715 } else {
716 this->onClear(rect, color, canIgnoreRect, renderTarget);
717 }
718}
719
egdaniel3eee3832014-06-18 13:09:11 -0700720typedef GrTraceMarkerSet::Iter TMIter;
721void GrDrawTarget::saveActiveTraceMarkers() {
722 if (this->caps()->gpuTracingSupport()) {
723 SkASSERT(0 == fStoredTraceMarkers.count());
724 fStoredTraceMarkers.addSet(fActiveTraceMarkers);
725 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
726 this->removeGpuTraceMarker(&(*iter));
727 }
728 }
729}
730
731void GrDrawTarget::restoreActiveTraceMarkers() {
732 if (this->caps()->gpuTracingSupport()) {
733 SkASSERT(0 == fActiveTraceMarkers.count());
734 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
735 this->addGpuTraceMarker(&(*iter));
736 }
737 for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
738 this->fStoredTraceMarkers.remove(*iter);
739 }
740 }
741}
742
743void GrDrawTarget::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000744 if (this->caps()->gpuTracingSupport()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000745 SkASSERT(fGpuTraceMarkerCount >= 0);
746 this->fActiveTraceMarkers.add(*marker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000747 ++fGpuTraceMarkerCount;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000748 }
749}
750
egdaniel3eee3832014-06-18 13:09:11 -0700751void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000752 if (this->caps()->gpuTracingSupport()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000753 SkASSERT(fGpuTraceMarkerCount >= 1);
754 this->fActiveTraceMarkers.remove(*marker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000755 --fGpuTraceMarkerCount;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +0000756 }
757}
758
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000759////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000760
egdaniel8dd688b2015-01-22 10:16:09 -0800761void GrDrawTarget::drawIndexedInstances(GrPipelineBuilder* pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800762 const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800763 GrPrimitiveType type,
bsalomon@google.com934c5702012-03-20 21:17:58 +0000764 int instanceCount,
765 int verticesPerInstance,
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000766 int indicesPerInstance,
767 const SkRect* devBounds) {
egdaniel8dd688b2015-01-22 10:16:09 -0800768 SkASSERT(pipelineBuilder);
joshualitt9853cce2014-11-17 14:22:48 -0800769
bsalomon@google.com934c5702012-03-20 21:17:58 +0000770 if (!verticesPerInstance || !indicesPerInstance) {
771 return;
772 }
773
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000774 int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
775 if (!maxInstancesPerDraw) {
bsalomon@google.com934c5702012-03-20 21:17:58 +0000776 return;
777 }
778
joshualitt2c93efe2014-11-06 12:57:13 -0800779 // Setup clip
bsalomon3e791242014-12-17 13:43:13 -0800780 GrScissorState scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800781 GrPipelineBuilder::AutoRestoreEffects are;
782 GrPipelineBuilder::AutoRestoreStencil ars;
783 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds)) {
joshualitt2c93efe2014-11-06 12:57:13 -0800784 return;
785 }
786
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000787 DrawInfo info;
788 info.fPrimitiveType = type;
789 info.fStartIndex = 0;
790 info.fStartVertex = 0;
791 info.fIndicesPerInstance = indicesPerInstance;
792 info.fVerticesPerInstance = verticesPerInstance;
793
794 // Set the same bounds for all the draws.
bsalomon49f085d2014-09-05 13:34:00 -0700795 if (devBounds) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000796 info.setDevBounds(*devBounds);
797 }
joshualitt9176e2c2014-11-20 07:28:52 -0800798
bsalomon@google.com934c5702012-03-20 21:17:58 +0000799 while (instanceCount) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000800 info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000801 info.fVertexCount = info.fInstanceCount * verticesPerInstance;
802 info.fIndexCount = info.fInstanceCount * indicesPerInstance;
803
egdaniel8dd688b2015-01-22 10:16:09 -0800804 if (this->checkDraw(*pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800805 gp,
joshualitt9853cce2014-11-17 14:22:48 -0800806 type,
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000807 info.fStartVertex,
808 info.fStartIndex,
809 info.fVertexCount,
810 info.fIndexCount)) {
egdaniele36914c2015-02-13 09:00:33 -0800811
812 GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, gp, devBounds,
813 this);
814 if (pipelineInfo.mustSkipDraw()) {
815 return;
816 }
817
joshualitt2e3b3e32014-12-09 13:31:14 -0800818 this->setDrawBuffers(&info, gp->getVertexStride());
egdaniele36914c2015-02-13 09:00:33 -0800819 this->onDraw(gp, info, pipelineInfo);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000820 }
821 info.fStartVertex += info.fVertexCount;
822 instanceCount -= info.fInstanceCount;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000823 }
824}
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000825
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000826////////////////////////////////////////////////////////////////////////////////
827
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000828GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
829 GrDrawTarget* target,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000830 int vertexCount,
joshualitt9853cce2014-11-17 14:22:48 -0800831 size_t vertexStride,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000832 int indexCount) {
833 fTarget = NULL;
joshualitt9853cce2014-11-17 14:22:48 -0800834 this->set(target, vertexCount, vertexStride, indexCount);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000835}
rmistry@google.comd6176b02012-08-23 18:14:13 +0000836
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000837GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
838 fTarget = NULL;
839}
840
841GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
842 this->reset();
843}
844
845bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000846 int vertexCount,
joshualitt9853cce2014-11-17 14:22:48 -0800847 size_t vertexStride,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000848 int indexCount) {
849 this->reset();
850 fTarget = target;
851 bool success = true;
bsalomon49f085d2014-09-05 13:34:00 -0700852 if (fTarget) {
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000853 success = target->reserveVertexAndIndexSpace(vertexCount,
joshualitt9853cce2014-11-17 14:22:48 -0800854 vertexStride,
bsalomon@google.come3d70952012-03-13 12:40:53 +0000855 indexCount,
856 &fVertices,
857 &fIndices);
858 if (!success) {
859 fTarget = NULL;
860 this->reset();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000861 }
862 }
bsalomon49f085d2014-09-05 13:34:00 -0700863 SkASSERT(success == SkToBool(fTarget));
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000864 return success;
865}
866
867void GrDrawTarget::AutoReleaseGeometry::reset() {
bsalomon49f085d2014-09-05 13:34:00 -0700868 if (fTarget) {
869 if (fVertices) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000870 fTarget->resetVertexSource();
871 }
bsalomon49f085d2014-09-05 13:34:00 -0700872 if (fIndices) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000873 fTarget->resetIndexSource();
874 }
875 fTarget = NULL;
876 }
bsalomon@google.comcb0c5ab2011-06-29 17:48:17 +0000877 fVertices = NULL;
878 fIndices = NULL;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000879}
880
bsalomon@google.com8d67c072012-12-13 20:38:14 +0000881GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
882 fTarget = target;
883 fClip = fTarget->getClip();
884 fStack.init();
885 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
joshualittde358a92015-02-05 08:19:35 -0800886 fReplacementClip.fClipStack.reset(SkRef(fStack.get()));
bsalomon@google.com8d67c072012-12-13 20:38:14 +0000887 target->setClip(&fReplacementClip);
888}
889
bsalomon@google.com116ad842013-04-09 15:38:19 +0000890namespace {
891// returns true if the read/written rect intersects the src/dst and false if not.
892bool clip_srcrect_and_dstpoint(const GrSurface* dst,
893 const GrSurface* src,
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000894 const SkIRect& srcRect,
bsalomon@google.com116ad842013-04-09 15:38:19 +0000895 const SkIPoint& dstPoint,
896 SkIRect* clippedSrcRect,
897 SkIPoint* clippedDstPoint) {
898 *clippedSrcRect = srcRect;
899 *clippedDstPoint = dstPoint;
skia.committer@gmail.coma9493a32013-04-04 07:01:12 +0000900
bsalomon@google.com116ad842013-04-09 15:38:19 +0000901 // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
902 if (clippedSrcRect->fLeft < 0) {
903 clippedDstPoint->fX -= clippedSrcRect->fLeft;
904 clippedSrcRect->fLeft = 0;
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000905 }
bsalomon@google.com116ad842013-04-09 15:38:19 +0000906 if (clippedDstPoint->fX < 0) {
907 clippedSrcRect->fLeft -= clippedDstPoint->fX;
908 clippedDstPoint->fX = 0;
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000909 }
910
bsalomon@google.com116ad842013-04-09 15:38:19 +0000911 // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
912 if (clippedSrcRect->fTop < 0) {
913 clippedDstPoint->fY -= clippedSrcRect->fTop;
914 clippedSrcRect->fTop = 0;
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000915 }
bsalomon@google.com116ad842013-04-09 15:38:19 +0000916 if (clippedDstPoint->fY < 0) {
917 clippedSrcRect->fTop -= clippedDstPoint->fY;
918 clippedDstPoint->fY = 0;
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000919 }
skia.committer@gmail.coma9493a32013-04-04 07:01:12 +0000920
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000921 // clip the right edge to the src and dst bounds.
bsalomon@google.com116ad842013-04-09 15:38:19 +0000922 if (clippedSrcRect->fRight > src->width()) {
923 clippedSrcRect->fRight = src->width();
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000924 }
bsalomon@google.com116ad842013-04-09 15:38:19 +0000925 if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) {
926 clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX;
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000927 }
928
929 // clip the bottom edge to the src and dst bounds.
bsalomon@google.com116ad842013-04-09 15:38:19 +0000930 if (clippedSrcRect->fBottom > src->height()) {
931 clippedSrcRect->fBottom = src->height();
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000932 }
bsalomon@google.com116ad842013-04-09 15:38:19 +0000933 if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) {
934 clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY;
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000935 }
skia.committer@gmail.coma9493a32013-04-04 07:01:12 +0000936
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000937 // The above clipping steps may have inverted the rect if it didn't intersect either the src or
938 // dst bounds.
bsalomon@google.com116ad842013-04-09 15:38:19 +0000939 return !clippedSrcRect->isEmpty();
940}
941}
942
943bool GrDrawTarget::copySurface(GrSurface* dst,
944 GrSurface* src,
945 const SkIRect& srcRect,
946 const SkIPoint& dstPoint) {
bsalomon49f085d2014-09-05 13:34:00 -0700947 SkASSERT(dst);
948 SkASSERT(src);
bsalomon@google.com116ad842013-04-09 15:38:19 +0000949
950 SkIRect clippedSrcRect;
951 SkIPoint clippedDstPoint;
952 // If the rect is outside the src or dst then we've already succeeded.
953 if (!clip_srcrect_and_dstpoint(dst,
954 src,
955 srcRect,
956 dstPoint,
957 &clippedSrcRect,
958 &clippedDstPoint)) {
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000959 return true;
960 }
961
bsalomonf90a02b2014-11-26 12:28:00 -0800962 if (this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint)) {
963 return true;
joshualitta7024152014-11-03 14:16:35 -0800964 }
965
966 GrRenderTarget* rt = dst->asRenderTarget();
967 GrTexture* tex = src->asTexture();
968
bsalomonf90a02b2014-11-26 12:28:00 -0800969 if ((dst == src) || !rt || !tex) {
970 return false;
971 }
972
egdaniel8dd688b2015-01-22 10:16:09 -0800973 GrPipelineBuilder pipelineBuilder;
974 pipelineBuilder.setRenderTarget(rt);
joshualitta7024152014-11-03 14:16:35 -0800975 SkMatrix matrix;
976 matrix.setTranslate(SkIntToScalar(clippedSrcRect.fLeft - clippedDstPoint.fX),
977 SkIntToScalar(clippedSrcRect.fTop - clippedDstPoint.fY));
978 matrix.postIDiv(tex->width(), tex->height());
egdaniel8dd688b2015-01-22 10:16:09 -0800979 pipelineBuilder.addColorTextureProcessor(tex, matrix);
joshualitta7024152014-11-03 14:16:35 -0800980 SkIRect dstRect = SkIRect::MakeXYWH(clippedDstPoint.fX,
981 clippedDstPoint.fY,
982 clippedSrcRect.width(),
983 clippedSrcRect.height());
egdaniel8dd688b2015-01-22 10:16:09 -0800984 this->drawSimpleRect(&pipelineBuilder, GrColor_WHITE, SkMatrix::I(), dstRect);
joshualitta7024152014-11-03 14:16:35 -0800985 return true;
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000986}
987
joshualitt9853cce2014-11-17 14:22:48 -0800988bool GrDrawTarget::canCopySurface(const GrSurface* dst,
989 const GrSurface* src,
bsalomon@google.come4617bf2013-04-03 14:56:40 +0000990 const SkIRect& srcRect,
991 const SkIPoint& dstPoint) {
bsalomon49f085d2014-09-05 13:34:00 -0700992 SkASSERT(dst);
993 SkASSERT(src);
bsalomon@google.com116ad842013-04-09 15:38:19 +0000994
995 SkIRect clippedSrcRect;
996 SkIPoint clippedDstPoint;
997 // If the rect is outside the src or dst then we're guaranteed success
998 if (!clip_srcrect_and_dstpoint(dst,
999 src,
1000 srcRect,
1001 dstPoint,
1002 &clippedSrcRect,
1003 &clippedDstPoint)) {
1004 return true;
1005 }
bsalomonf90a02b2014-11-26 12:28:00 -08001006 return this->internalCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
1007}
bsalomon@google.com116ad842013-04-09 15:38:19 +00001008
bsalomonf90a02b2014-11-26 12:28:00 -08001009bool GrDrawTarget::internalCanCopySurface(const GrSurface* dst,
1010 const GrSurface* src,
1011 const SkIRect& clippedSrcRect,
1012 const SkIPoint& clippedDstPoint) {
bsalomon@google.come4617bf2013-04-03 14:56:40 +00001013 // Check that the read/write rects are contained within the src/dst bounds.
joshualitta7024152014-11-03 14:16:35 -08001014 SkASSERT(!clippedSrcRect.isEmpty());
1015 SkASSERT(SkIRect::MakeWH(src->width(), src->height()).contains(clippedSrcRect));
1016 SkASSERT(clippedDstPoint.fX >= 0 && clippedDstPoint.fY >= 0);
1017 SkASSERT(clippedDstPoint.fX + clippedSrcRect.width() <= dst->width() &&
1018 clippedDstPoint.fY + clippedSrcRect.height() <= dst->height());
bsalomon@google.come4617bf2013-04-03 14:56:40 +00001019
bsalomonf90a02b2014-11-26 12:28:00 -08001020 // The base class can do it as a draw or the subclass may be able to handle it.
1021 return ((dst != src) && dst->asRenderTarget() && src->asTexture()) ||
1022 this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
bsalomon@google.comeb851172013-04-15 13:51:00 +00001023}
1024
egdaniele36914c2015-02-13 09:00:33 -08001025void GrDrawTarget::setupPipeline(const PipelineInfo& pipelineInfo,
1026 GrPipeline* pipeline) {
1027 SkNEW_PLACEMENT_ARGS(pipeline, GrPipeline, (*pipelineInfo.fPipelineBuilder,
1028 pipelineInfo.fColorPOI,
1029 pipelineInfo.fCoveragePOI,
1030 *this->caps(),
1031 *pipelineInfo.fScissor,
1032 &pipelineInfo.fDstCopy));
1033}
1034///////////////////////////////////////////////////////////////////////////////
1035
1036GrDrawTarget::PipelineInfo::PipelineInfo(GrPipelineBuilder* pipelineBuilder,
1037 GrScissorState* scissor,
1038 const GrPrimitiveProcessor* primProc,
1039 const SkRect* devBounds,
1040 GrDrawTarget* target)
1041 : fPipelineBuilder(pipelineBuilder)
1042 , fScissor(scissor) {
1043 fColorPOI = fPipelineBuilder->colorProcInfo(primProc);
1044 fCoveragePOI = fPipelineBuilder->coverageProcInfo(primProc);
1045 if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI,
1046 &fDstCopy, devBounds)) {
1047 fPipelineBuilder = NULL;
1048 }
1049}
1050
1051GrDrawTarget::PipelineInfo::PipelineInfo(GrPipelineBuilder* pipelineBuilder,
1052 GrScissorState* scissor,
1053 const GrBatch* batch,
1054 const SkRect* devBounds,
1055 GrDrawTarget* target)
1056 : fPipelineBuilder(pipelineBuilder)
1057 , fScissor(scissor) {
1058 fColorPOI = fPipelineBuilder->colorProcInfo(batch);
1059 fCoveragePOI = fPipelineBuilder->coverageProcInfo(batch);
1060 if (!target->setupDstReadIfNecessary(*fPipelineBuilder, fColorPOI, fCoveragePOI,
1061 &fDstCopy, devBounds)) {
1062 fPipelineBuilder = NULL;
1063 }
1064}
1065
bsalomon@google.combcce8922013-03-25 15:38:39 +00001066///////////////////////////////////////////////////////////////////////////////
1067
bsalomon@google.comc26d94f2013-03-25 18:19:00 +00001068void GrDrawTargetCaps::reset() {
commit-bot@chromium.org47442312013-12-19 16:18:01 +00001069 fMipMapSupport = false;
bsalomon@google.combcce8922013-03-25 15:38:39 +00001070 fNPOTTextureTileSupport = false;
1071 fTwoSidedStencilSupport = false;
1072 fStencilWrapOpsSupport = false;
1073 fHWAALineSupport = false;
1074 fShaderDerivativeSupport = false;
1075 fGeometryShaderSupport = false;
skia.committer@gmail.come60ed082013-03-26 07:01:04 +00001076 fDualSourceBlendingSupport = false;
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +00001077 fPathRenderingSupport = false;
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +00001078 fDstReadInShaderSupport = false;
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +00001079 fDiscardRenderTargetSupport = false;
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +00001080 fReuseScratchTextures = true;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +00001081 fGpuTracingSupport = false;
krajcevski786978162014-07-30 11:25:44 -07001082 fCompressedTexSubImageSupport = false;
bsalomon@google.combcce8922013-03-25 15:38:39 +00001083
bsalomon63b21962014-11-05 07:05:34 -08001084 fUseDrawInsteadOfClear = false;
1085
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001086 fMapBufferFlags = kNone_MapFlags;
1087
bsalomon@google.combcce8922013-03-25 15:38:39 +00001088 fMaxRenderTargetSize = 0;
1089 fMaxTextureSize = 0;
1090 fMaxSampleCount = 0;
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001091
bsalomon17168df2014-12-09 09:00:49 -08001092 fShaderPrecisionVaries = false;
1093
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001094 memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +00001095 memset(fConfigTextureSupport, 0, sizeof(fConfigTextureSupport));
bsalomon@google.combcce8922013-03-25 15:38:39 +00001096}
1097
bsalomon@google.comc26d94f2013-03-25 18:19:00 +00001098GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
commit-bot@chromium.org47442312013-12-19 16:18:01 +00001099 fMipMapSupport = other.fMipMapSupport;
bsalomon@google.combcce8922013-03-25 15:38:39 +00001100 fNPOTTextureTileSupport = other.fNPOTTextureTileSupport;
1101 fTwoSidedStencilSupport = other.fTwoSidedStencilSupport;
1102 fStencilWrapOpsSupport = other.fStencilWrapOpsSupport;
1103 fHWAALineSupport = other.fHWAALineSupport;
1104 fShaderDerivativeSupport = other.fShaderDerivativeSupport;
1105 fGeometryShaderSupport = other.fGeometryShaderSupport;
1106 fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +00001107 fPathRenderingSupport = other.fPathRenderingSupport;
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +00001108 fDstReadInShaderSupport = other.fDstReadInShaderSupport;
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +00001109 fDiscardRenderTargetSupport = other.fDiscardRenderTargetSupport;
commit-bot@chromium.orgb8356522013-07-18 22:26:39 +00001110 fReuseScratchTextures = other.fReuseScratchTextures;
commit-bot@chromium.orga3baf3b2014-02-21 18:45:30 +00001111 fGpuTracingSupport = other.fGpuTracingSupport;
krajcevski786978162014-07-30 11:25:44 -07001112 fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport;
bsalomon@google.combcce8922013-03-25 15:38:39 +00001113
bsalomon63b21962014-11-05 07:05:34 -08001114 fUseDrawInsteadOfClear = other.fUseDrawInsteadOfClear;
1115
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001116 fMapBufferFlags = other.fMapBufferFlags;
1117
bsalomon@google.combcce8922013-03-25 15:38:39 +00001118 fMaxRenderTargetSize = other.fMaxRenderTargetSize;
1119 fMaxTextureSize = other.fMaxTextureSize;
1120 fMaxSampleCount = other.fMaxSampleCount;
1121
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001122 memcpy(fConfigRenderSupport, other.fConfigRenderSupport, sizeof(fConfigRenderSupport));
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +00001123 memcpy(fConfigTextureSupport, other.fConfigTextureSupport, sizeof(fConfigTextureSupport));
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001124
bsalomon17168df2014-12-09 09:00:49 -08001125 fShaderPrecisionVaries = other.fShaderPrecisionVaries;
1126 for (int s = 0; s < kGrShaderTypeCount; ++s) {
bsalomonc0bd6482014-12-09 10:04:14 -08001127 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
bsalomon17168df2014-12-09 09:00:49 -08001128 fFloatPrecisions[s][p] = other.fFloatPrecisions[s][p];
1129 }
1130 }
bsalomon@google.combcce8922013-03-25 15:38:39 +00001131 return *this;
1132}
1133
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001134static SkString map_flags_to_string(uint32_t flags) {
1135 SkString str;
1136 if (GrDrawTargetCaps::kNone_MapFlags == flags) {
1137 str = "none";
1138 } else {
1139 SkASSERT(GrDrawTargetCaps::kCanMap_MapFlag & flags);
1140 SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kCanMap_MapFlag);
1141 str = "can_map";
1142
1143 if (GrDrawTargetCaps::kSubset_MapFlag & flags) {
1144 str.append(" partial");
1145 } else {
1146 str.append(" full");
1147 }
1148 SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kSubset_MapFlag);
1149 }
1150 SkASSERT(0 == flags); // Make sure we handled all the flags.
1151 return str;
1152}
1153
bsalomon17168df2014-12-09 09:00:49 -08001154static const char* shader_type_to_string(GrShaderType type) {
1155 switch (type) {
1156 case kVertex_GrShaderType:
1157 return "vertex";
1158 case kGeometry_GrShaderType:
1159 return "geometry";
1160 case kFragment_GrShaderType:
1161 return "fragment";
1162 }
1163 return "";
1164}
1165
bsalomonc0bd6482014-12-09 10:04:14 -08001166static const char* precision_to_string(GrSLPrecision p) {
bsalomon17168df2014-12-09 09:00:49 -08001167 switch (p) {
bsalomonc0bd6482014-12-09 10:04:14 -08001168 case kLow_GrSLPrecision:
bsalomon17168df2014-12-09 09:00:49 -08001169 return "low";
bsalomonc0bd6482014-12-09 10:04:14 -08001170 case kMedium_GrSLPrecision:
bsalomon17168df2014-12-09 09:00:49 -08001171 return "medium";
bsalomonc0bd6482014-12-09 10:04:14 -08001172 case kHigh_GrSLPrecision:
bsalomon17168df2014-12-09 09:00:49 -08001173 return "high";
1174 }
1175 return "";
1176}
1177
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001178SkString GrDrawTargetCaps::dump() const {
1179 SkString r;
bsalomon@google.com18c9c192011-09-22 21:01:31 +00001180 static const char* gNY[] = {"NO", "YES"};
bsalomon63b21962014-11-05 07:05:34 -08001181 r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]);
1182 r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
1183 r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
1184 r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
1185 r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
1186 r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
1187 r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
1188 r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
1189 r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
1190 r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
1191 r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]);
1192 r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
1193 r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]);
1194 r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]);
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001195
bsalomon63b21962014-11-05 07:05:34 -08001196 r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]);
1197
1198 r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
1199 r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
1200 r.appendf("Max Sample Count : %d\n", fMaxSampleCount);
1201
1202 r.appendf("Map Buffer Support : %s\n",
1203 map_flags_to_string(fMapBufferFlags).c_str());
commit-bot@chromium.org160b4782014-05-05 12:32:37 +00001204
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001205 static const char* kConfigNames[] = {
1206 "Unknown", // kUnknown_GrPixelConfig
1207 "Alpha8", // kAlpha_8_GrPixelConfig,
1208 "Index8", // kIndex_8_GrPixelConfig,
1209 "RGB565", // kRGB_565_GrPixelConfig,
1210 "RGBA444", // kRGBA_4444_GrPixelConfig,
1211 "RGBA8888", // kRGBA_8888_GrPixelConfig,
1212 "BGRA8888", // kBGRA_8888_GrPixelConfig,
jvanverthfa1e8a72014-12-22 08:31:49 -08001213 "SRGBA8888",// kSRGBA_8888_GrPixelConfig,
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +00001214 "ETC1", // kETC1_GrPixelConfig,
1215 "LATC", // kLATC_GrPixelConfig,
krajcevski238b4562014-06-30 09:09:22 -07001216 "R11EAC", // kR11_EAC_GrPixelConfig,
krajcevski7ef21622014-07-16 15:21:13 -07001217 "ASTC12x12",// kASTC_12x12_GrPixelConfig,
jvanverth28f9c602014-12-05 13:06:35 -08001218 "RGBAFloat",// kRGBA_float_GrPixelConfig
1219 "AlphaHalf",// kAlpha_half_GrPixelConfig
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001220 };
krajcevski7ef21622014-07-16 15:21:13 -07001221 GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
1222 GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
1223 GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
1224 GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
1225 GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
1226 GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
1227 GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
jvanverthfa1e8a72014-12-22 08:31:49 -08001228 GR_STATIC_ASSERT(7 == kSRGBA_8888_GrPixelConfig);
1229 GR_STATIC_ASSERT(8 == kETC1_GrPixelConfig);
1230 GR_STATIC_ASSERT(9 == kLATC_GrPixelConfig);
1231 GR_STATIC_ASSERT(10 == kR11_EAC_GrPixelConfig);
1232 GR_STATIC_ASSERT(11 == kASTC_12x12_GrPixelConfig);
1233 GR_STATIC_ASSERT(12 == kRGBA_float_GrPixelConfig);
1234 GR_STATIC_ASSERT(13 == kAlpha_half_GrPixelConfig);
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001235 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
1236
commit-bot@chromium.org99017272013-11-08 18:45:27 +00001237 SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]);
1238 SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][1]);
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +00001239
1240 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) {
1241 r.appendf("%s is renderable: %s, with MSAA: %s\n",
1242 kConfigNames[i],
1243 gNY[fConfigRenderSupport[i][0]],
1244 gNY[fConfigRenderSupport[i][1]]);
commit-bot@chromium.org73880512013-10-14 15:33:45 +00001245 }
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +00001246
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +00001247 SkASSERT(!fConfigTextureSupport[kUnknown_GrPixelConfig]);
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +00001248
commit-bot@chromium.org6e7ddaa2014-05-30 13:55:58 +00001249 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) {
1250 r.appendf("%s is uploadable to a texture: %s\n",
1251 kConfigNames[i],
1252 gNY[fConfigTextureSupport[i]]);
commit-bot@chromium.org42dc8132014-05-27 19:26:59 +00001253 }
1254
bsalomon17168df2014-12-09 09:00:49 -08001255 r.appendf("Shader Float Precisions (varies: %s):\n", gNY[fShaderPrecisionVaries]);
1256
1257 for (int s = 0; s < kGrShaderTypeCount; ++s) {
1258 GrShaderType shaderType = static_cast<GrShaderType>(s);
1259 r.appendf("\t%s:\n", shader_type_to_string(shaderType));
bsalomonc0bd6482014-12-09 10:04:14 -08001260 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
bsalomon17168df2014-12-09 09:00:49 -08001261 if (fFloatPrecisions[s][p].supported()) {
bsalomonc0bd6482014-12-09 10:04:14 -08001262 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
bsalomon17168df2014-12-09 09:00:49 -08001263 r.appendf("\t\t%s: log_low: %d log_high: %d bits: %d\n",
1264 precision_to_string(precision),
1265 fFloatPrecisions[s][p].fLogRangeLow,
1266 fFloatPrecisions[s][p].fLogRangeHigh,
1267 fFloatPrecisions[s][p].fBits);
1268 }
1269 }
1270 }
1271
commit-bot@chromium.org8b656c62013-11-21 15:23:15 +00001272 return r;
bsalomon@google.com18c9c192011-09-22 21:01:31 +00001273}
egdanielbc127a32014-09-19 12:07:43 -07001274
1275uint32_t GrDrawTargetCaps::CreateUniqueID() {
1276 static int32_t gUniqueID = SK_InvalidUniqueID;
1277 uint32_t id;
1278 do {
1279 id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
1280 } while (id == SK_InvalidUniqueID);
1281 return id;
1282}
1283
joshualitt2c93efe2014-11-06 12:57:13 -08001284///////////////////////////////////////////////////////////////////////////////////////////////////
1285
egdaniel8dd688b2015-01-22 10:16:09 -08001286bool GrClipTarget::setupClip(GrPipelineBuilder* pipelineBuilder,
1287 GrPipelineBuilder::AutoRestoreEffects* are,
1288 GrPipelineBuilder::AutoRestoreStencil* ars,
joshualitt8059eb92014-12-29 15:10:07 -08001289 GrScissorState* scissorState,
1290 const SkRect* devBounds) {
egdaniel8dd688b2015-01-22 10:16:09 -08001291 return fClipMaskManager.setupClipping(pipelineBuilder,
joshualitt2c93efe2014-11-06 12:57:13 -08001292 are,
1293 ars,
joshualitt9853cce2014-11-17 14:22:48 -08001294 scissorState,
1295 this->getClip(),
1296 devBounds);
joshualitt2c93efe2014-11-06 12:57:13 -08001297}