blob: 3282f13263cee3c5dfe76d6bfe7dcfd624612d00 [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
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#include "GrDrawTarget.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000012#include "GrRenderTarget.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000013#include "GrTexture.h"
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000014#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000015
sugoi@google.com5f74cf82012-12-17 21:16:45 +000016#include "SkStrokeRec.h"
sugoi@google.com12b4e272012-12-06 20:13:11 +000017
reed@google.comfa35e3d2012-06-26 20:16:17 +000018SK_DEFINE_INST_COUNT(GrDrawTarget)
19
reed@google.comac10a2d2010-12-22 21:39:39 +000020////////////////////////////////////////////////////////////////////////////////
21
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000022GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
23 fPrimitiveType = di.fPrimitiveType;
24 fStartVertex = di.fStartVertex;
25 fStartIndex = di.fStartIndex;
26 fVertexCount = di.fVertexCount;
27 fIndexCount = di.fIndexCount;
28
29 fInstanceCount = di.fInstanceCount;
30 fVerticesPerInstance = di.fVerticesPerInstance;
31 fIndicesPerInstance = di.fIndicesPerInstance;
32
33 if (NULL != di.fDevBounds) {
34 GrAssert(di.fDevBounds == &di.fDevBoundsStorage);
35 fDevBoundsStorage = di.fDevBoundsStorage;
36 fDevBounds = &fDevBoundsStorage;
37 } else {
38 fDevBounds = NULL;
39 }
40 return *this;
41}
42
43#if GR_DEBUG
44bool GrDrawTarget::DrawInfo::isInstanced() const {
45 if (fInstanceCount > 0) {
46 GrAssert(0 == fIndexCount % fIndicesPerInstance);
47 GrAssert(0 == fVertexCount % fVerticesPerInstance);
48 GrAssert(fIndexCount / fIndicesPerInstance == fInstanceCount);
49 GrAssert(fVertexCount / fVerticesPerInstance == fInstanceCount);
50 // there is no way to specify a non-zero start index to drawIndexedInstances().
51 GrAssert(0 == fStartIndex);
52 return true;
53 } else {
54 GrAssert(!fVerticesPerInstance);
55 GrAssert(!fIndicesPerInstance);
56 return false;
57 }
58}
59#endif
60
61void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) {
62 GrAssert(this->isInstanced());
63 GrAssert(instanceOffset + fInstanceCount >= 0);
64 fInstanceCount += instanceOffset;
65 fVertexCount = fVerticesPerInstance * fInstanceCount;
66 fIndexCount = fIndicesPerInstance * fInstanceCount;
67}
68
69void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) {
70 fStartVertex += vertexOffset;
71 GrAssert(fStartVertex >= 0);
72}
73
74void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
75 GrAssert(this->isIndexed());
76 fStartIndex += indexOffset;
77 GrAssert(fStartIndex >= 0);
78}
79
80////////////////////////////////////////////////////////////////////////////////
81
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000082#define DEBUG_INVAL_BUFFER 0xdeadcafe
83#define DEBUG_INVAL_START_IDX -1
84
robertphillips@google.combeb1af72012-07-26 18:52:16 +000085GrDrawTarget::GrDrawTarget() : fClip(NULL) {
bsalomon@google.coma5d056a2012-03-27 15:59:58 +000086 fDrawState = &fDefaultDrawState;
87 // We assume that fDrawState always owns a ref to the object it points at.
88 fDefaultDrawState.ref();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000089 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +000090#if GR_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000091 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
92 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
93 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
94 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
reed@google.comac10a2d2010-12-22 21:39:39 +000095#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000096 geoSrc.fVertexSrc = kNone_GeometrySrcType;
97 geoSrc.fIndexSrc = kNone_GeometrySrcType;
98}
99
100GrDrawTarget::~GrDrawTarget() {
bsalomon@google.com4a018bb2011-10-28 19:50:21 +0000101 GrAssert(1 == fGeoSrcStateStack.count());
humper@google.com0e515772013-01-07 19:54:40 +0000102 SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
bsalomon@google.com4a018bb2011-10-28 19:50:21 +0000103 GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc);
104 GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000105 fDrawState->unref();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +0000106}
107
108void GrDrawTarget::releaseGeometry() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000109 int popCnt = fGeoSrcStateStack.count() - 1;
110 while (popCnt) {
111 this->popGeometrySource();
112 --popCnt;
113 }
bsalomon@google.com4a018bb2011-10-28 19:50:21 +0000114 this->resetVertexSource();
115 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000116}
117
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000118void GrDrawTarget::setClip(const GrClipData* clip) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000119 clipWillBeSet(clip);
reed@google.comac10a2d2010-12-22 21:39:39 +0000120 fClip = clip;
121}
122
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000123const GrClipData* GrDrawTarget::getClip() const {
reed@google.comac10a2d2010-12-22 21:39:39 +0000124 return fClip;
125}
126
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000127void GrDrawTarget::setDrawState(GrDrawState* drawState) {
128 GrAssert(NULL != fDrawState);
129 if (NULL == drawState) {
130 drawState = &fDefaultDrawState;
131 }
132 if (fDrawState != drawState) {
133 fDrawState->unref();
134 drawState->ref();
135 fDrawState = drawState;
136 }
137}
138
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000139bool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000140 int vertexCount,
141 void** vertices) {
142 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
143 bool acquired = false;
144 if (vertexCount > 0) {
145 GrAssert(NULL != vertices);
146 this->releasePreviousVertexSource();
147 geoSrc.fVertexSrc = kNone_GeometrySrcType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000148
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000149 acquired = this->onReserveVertexSpace(vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000150 vertexCount,
151 vertices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000152 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000153 if (acquired) {
154 geoSrc.fVertexSrc = kReserved_GeometrySrcType;
155 geoSrc.fVertexCount = vertexCount;
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000156 geoSrc.fVertexSize = vertexSize;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000157 } else if (NULL != vertices) {
158 *vertices = NULL;
159 }
160 return acquired;
161}
162
163bool GrDrawTarget::reserveIndexSpace(int indexCount,
164 void** indices) {
165 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
166 bool acquired = false;
167 if (indexCount > 0) {
168 GrAssert(NULL != indices);
169 this->releasePreviousIndexSource();
170 geoSrc.fIndexSrc = kNone_GeometrySrcType;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000171
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000172 acquired = this->onReserveIndexSpace(indexCount, indices);
173 }
174 if (acquired) {
175 geoSrc.fIndexSrc = kReserved_GeometrySrcType;
176 geoSrc.fIndexCount = indexCount;
177 } else if (NULL != indices) {
178 *indices = NULL;
179 }
180 return acquired;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000181
reed@google.comac10a2d2010-12-22 21:39:39 +0000182}
183
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000184bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
bsalomon@google.come3d70952012-03-13 12:40:53 +0000185 int indexCount,
186 void** vertices,
187 void** indices) {
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000188 size_t vertexSize = this->drawState()->getVertexSize();
189 this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
bsalomon@google.come3d70952012-03-13 12:40:53 +0000190 if (vertexCount) {
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000191 if (!this->reserveVertexSpace(vertexSize, vertexCount, vertices)) {
bsalomon@google.come3d70952012-03-13 12:40:53 +0000192 if (indexCount) {
193 this->resetIndexSource();
194 }
195 return false;
196 }
197 }
198 if (indexCount) {
199 if (!this->reserveIndexSpace(indexCount, indices)) {
200 if (vertexCount) {
201 this->resetVertexSource();
202 }
203 return false;
204 }
205 }
206 return true;
207}
208
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000209bool GrDrawTarget::geometryHints(int32_t* vertexCount,
reed@google.comac10a2d2010-12-22 21:39:39 +0000210 int32_t* indexCount) const {
reed@google.comac10a2d2010-12-22 21:39:39 +0000211 if (NULL != vertexCount) {
212 *vertexCount = -1;
213 }
214 if (NULL != indexCount) {
215 *indexCount = -1;
216 }
217 return false;
218}
219
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000220void GrDrawTarget::releasePreviousVertexSource() {
221 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
222 switch (geoSrc.fVertexSrc) {
223 case kNone_GeometrySrcType:
224 break;
225 case kArray_GeometrySrcType:
226 this->releaseVertexArray();
227 break;
228 case kReserved_GeometrySrcType:
229 this->releaseReservedVertexSpace();
230 break;
231 case kBuffer_GeometrySrcType:
232 geoSrc.fVertexBuffer->unref();
233#if GR_DEBUG
234 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
235#endif
236 break;
237 default:
238 GrCrash("Unknown Vertex Source Type.");
239 break;
240 }
241}
242
243void GrDrawTarget::releasePreviousIndexSource() {
244 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
245 switch (geoSrc.fIndexSrc) {
246 case kNone_GeometrySrcType: // these two don't require
247 break;
248 case kArray_GeometrySrcType:
249 this->releaseIndexArray();
250 break;
251 case kReserved_GeometrySrcType:
252 this->releaseReservedIndexSpace();
253 break;
254 case kBuffer_GeometrySrcType:
255 geoSrc.fIndexBuffer->unref();
256#if GR_DEBUG
257 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
258#endif
259 break;
260 default:
261 GrCrash("Unknown Index Source Type.");
262 break;
263 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000264}
265
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000266void GrDrawTarget::setVertexSourceToArray(const void* vertexArray,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000267 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000268 this->releasePreviousVertexSource();
269 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
270 geoSrc.fVertexSrc = kArray_GeometrySrcType;
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000271 geoSrc.fVertexSize = this->drawState()->getVertexSize();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000272 geoSrc.fVertexCount = vertexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000273 this->onSetVertexSourceToArray(vertexArray, vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000274}
275
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000276void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
277 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000278 this->releasePreviousIndexSource();
279 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
280 geoSrc.fIndexSrc = kArray_GeometrySrcType;
281 geoSrc.fIndexCount = indexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000282 this->onSetIndexSourceToArray(indexArray, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000283}
284
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000285void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000286 this->releasePreviousVertexSource();
287 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
288 geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
289 geoSrc.fVertexBuffer = buffer;
290 buffer->ref();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000291 geoSrc.fVertexSize = this->drawState()->getVertexSize();
reed@google.comac10a2d2010-12-22 21:39:39 +0000292}
293
294void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000295 this->releasePreviousIndexSource();
296 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
297 geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
298 geoSrc.fIndexBuffer = buffer;
299 buffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000300}
301
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000302void GrDrawTarget::resetVertexSource() {
303 this->releasePreviousVertexSource();
304 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
305 geoSrc.fVertexSrc = kNone_GeometrySrcType;
306}
307
308void GrDrawTarget::resetIndexSource() {
309 this->releasePreviousIndexSource();
310 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
311 geoSrc.fIndexSrc = kNone_GeometrySrcType;
312}
313
314void GrDrawTarget::pushGeometrySource() {
315 this->geometrySourceWillPush();
316 GeometrySrcState& newState = fGeoSrcStateStack.push_back();
317 newState.fIndexSrc = kNone_GeometrySrcType;
318 newState.fVertexSrc = kNone_GeometrySrcType;
319#if GR_DEBUG
320 newState.fVertexCount = ~0;
321 newState.fVertexBuffer = (GrVertexBuffer*)~0;
322 newState.fIndexCount = ~0;
323 newState.fIndexBuffer = (GrIndexBuffer*)~0;
324#endif
325}
326
327void GrDrawTarget::popGeometrySource() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000328 // if popping last element then pops are unbalanced with pushes
329 GrAssert(fGeoSrcStateStack.count() > 1);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000330
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000331 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
332 this->releasePreviousVertexSource();
333 this->releasePreviousIndexSource();
334 fGeoSrcStateStack.pop_back();
335}
336
337////////////////////////////////////////////////////////////////////////////////
338
bsalomon@google.come8262622011-11-07 02:30:51 +0000339bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
340 int startIndex, int vertexCount,
341 int indexCount) const {
bsalomon@google.comcddaf342012-07-30 13:09:05 +0000342 const GrDrawState& drawState = this->getDrawState();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000343#if GR_DEBUG
bsalomon@google.come8262622011-11-07 02:30:51 +0000344 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000345 int maxVertex = startVertex + vertexCount;
346 int maxValidVertex;
347 switch (geoSrc.fVertexSrc) {
348 case kNone_GeometrySrcType:
bsalomon@google.come8262622011-11-07 02:30:51 +0000349 GrCrash("Attempting to draw without vertex src.");
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000350 case kReserved_GeometrySrcType: // fallthrough
351 case kArray_GeometrySrcType:
352 maxValidVertex = geoSrc.fVertexCount;
353 break;
354 case kBuffer_GeometrySrcType:
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000355 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / geoSrc.fVertexSize;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000356 break;
357 }
358 if (maxVertex > maxValidVertex) {
bsalomon@google.come8262622011-11-07 02:30:51 +0000359 GrCrash("Drawing outside valid vertex range.");
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000360 }
bsalomon@google.come8262622011-11-07 02:30:51 +0000361 if (indexCount > 0) {
362 int maxIndex = startIndex + indexCount;
363 int maxValidIndex;
364 switch (geoSrc.fIndexSrc) {
365 case kNone_GeometrySrcType:
366 GrCrash("Attempting to draw indexed geom without index src.");
367 case kReserved_GeometrySrcType: // fallthrough
368 case kArray_GeometrySrcType:
369 maxValidIndex = geoSrc.fIndexCount;
370 break;
371 case kBuffer_GeometrySrcType:
372 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
373 break;
374 }
375 if (maxIndex > maxValidIndex) {
376 GrCrash("Index reads outside valid index range.");
377 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000378 }
bsalomon@google.comb4725b42012-03-30 17:24:17 +0000379
bsalomon@google.comcddaf342012-07-30 13:09:05 +0000380 GrAssert(NULL != drawState.getRenderTarget());
381 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
382 if (drawState.isStageEnabled(s)) {
bsalomon@google.com6340a412013-01-22 19:55:59 +0000383 const GrEffectRef& effect = *drawState.getStage(s).getEffect();
bsalomon@google.com021fc732012-10-25 12:47:42 +0000384 int numTextures = effect->numTextures();
bsalomon@google.comcddaf342012-07-30 13:09:05 +0000385 for (int t = 0; t < numTextures; ++t) {
bsalomon@google.com021fc732012-10-25 12:47:42 +0000386 GrTexture* texture = effect->texture(t);
bsalomon@google.comcddaf342012-07-30 13:09:05 +0000387 GrAssert(texture->asRenderTarget() != drawState.getRenderTarget());
388 }
bsalomon@google.comb4725b42012-03-30 17:24:17 +0000389 }
390 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000391#endif
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000392 if (NULL == drawState.getRenderTarget()) {
bsalomon@google.com0ba52fc2011-11-10 22:16:06 +0000393 return false;
394 }
bsalomon@google.come8262622011-11-07 02:30:51 +0000395 return true;
396}
397
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000398void GrDrawTarget::drawIndexed(GrPrimitiveType type,
399 int startVertex,
400 int startIndex,
401 int vertexCount,
402 int indexCount,
403 const SkRect* devBounds) {
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000404 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
405 DrawInfo info;
406 info.fPrimitiveType = type;
407 info.fStartVertex = startVertex;
408 info.fStartIndex = startIndex;
409 info.fVertexCount = vertexCount;
410 info.fIndexCount = indexCount;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000411
412 info.fInstanceCount = 0;
413 info.fVerticesPerInstance = 0;
414 info.fIndicesPerInstance = 0;
415
416 if (NULL != devBounds) {
417 info.setDevBounds(*devBounds);
418 }
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000419 this->onDraw(info);
bsalomon@google.com82145872011-08-23 14:32:40 +0000420 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000421}
422
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000423void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
424 int startVertex,
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000425 int vertexCount,
426 const SkRect* devBounds) {
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000427 if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
428 DrawInfo info;
429 info.fPrimitiveType = type;
430 info.fStartVertex = startVertex;
431 info.fStartIndex = 0;
432 info.fVertexCount = vertexCount;
433 info.fIndexCount = 0;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000434
435 info.fInstanceCount = 0;
436 info.fVerticesPerInstance = 0;
437 info.fIndicesPerInstance = 0;
438
439 if (NULL != devBounds) {
440 info.setDevBounds(*devBounds);
441 }
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000442 this->onDraw(info);
bsalomon@google.com82145872011-08-23 14:32:40 +0000443 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000444}
445
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000446void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) {
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000447 // TODO: extract portions of checkDraw that are relevant to path stenciling.
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000448 GrAssert(NULL != path);
bsalomon@google.comf6601872012-08-28 21:11:35 +0000449 GrAssert(fCaps.pathStencilingSupport());
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000450 GrAssert(!stroke.isHairlineStyle());
451 GrAssert(!SkPath::IsInverseFillType(fill));
sugoi@google.com12b4e272012-12-06 20:13:11 +0000452 this->onStencilPath(path, stroke, fill);
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000453}
454
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000455////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000456
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000457// Some blend modes allow folding a partial coverage value into the color's
458// alpha channel, while others will blend incorrectly.
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000459bool GrDrawTarget::canTweakAlphaForCoverage() const {
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000460 /**
461 * The fractional coverage is f
462 * The src and dst coeffs are Cs and Cd
463 * The dst and src colors are S and D
464 * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D
465 * By tweaking the source color's alpha we're replacing S with S'=fS. It's
466 * obvious that that first term will always be ok. The second term can be
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000467 * rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000468 * for Cd we find that only 1, ISA, and ISC produce the correct depth
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000469 * coefficient in terms of S' and D.
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000470 */
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000471 GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff();
bsalomon@google.com47059542012-06-06 20:51:20 +0000472 return kOne_GrBlendCoeff == dstCoeff ||
473 kISA_GrBlendCoeff == dstCoeff ||
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000474 kISC_GrBlendCoeff == dstCoeff ||
475 this->getDrawState().isCoverageDrawing();
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000476}
477
bsalomon@google.come79c8152012-03-29 19:07:12 +0000478namespace {
479GrVertexLayout default_blend_opts_vertex_layout() {
480 GrVertexLayout layout = 0;
bsalomon@google.come79c8152012-03-29 19:07:12 +0000481 return layout;
482}
483}
484
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000485GrDrawTarget::BlendOptFlags
486GrDrawTarget::getBlendOpts(bool forceCoverage,
487 GrBlendCoeff* srcCoeff,
488 GrBlendCoeff* dstCoeff) const {
489
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000490 const GrDrawState& drawState = this->getDrawState();
491
bsalomon@google.come79c8152012-03-29 19:07:12 +0000492 GrVertexLayout layout;
493 if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
494 layout = default_blend_opts_vertex_layout();
495 } else {
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000496 layout = drawState.getVertexLayout();
bsalomon@google.come79c8152012-03-29 19:07:12 +0000497 }
498
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000499 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
500 if (NULL == srcCoeff) {
501 srcCoeff = &bogusSrcCoeff;
502 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000503 *srcCoeff = drawState.getSrcBlendCoeff();
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000504
505 if (NULL == dstCoeff) {
506 dstCoeff = &bogusDstCoeff;
507 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000508 *dstCoeff = drawState.getDstBlendCoeff();
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000509
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000510 if (drawState.isColorWriteDisabled()) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000511 *srcCoeff = kZero_GrBlendCoeff;
512 *dstCoeff = kOne_GrBlendCoeff;
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000513 }
514
jvanverth@google.comcc782382013-01-28 20:39:48 +0000515 bool srcAIsOne = drawState.srcAlphaWillBeOne(layout);
bsalomon@google.com47059542012-06-06 20:51:20 +0000516 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
517 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
518 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
519 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000520
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000521 bool covIsZero = !drawState.isCoverageDrawing() &&
jvanverth@google.comcc782382013-01-28 20:39:48 +0000522 !(layout & GrDrawState::kCoverage_VertexLayoutBit) &&
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000523 0 == drawState.getCoverage();
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000524 // When coeffs are (0,1) there is no reason to draw at all, unless
525 // stenciling is enabled. Having color writes disabled is effectively
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000526 // (0,1). The same applies when coverage is known to be 0.
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000527 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000528 if (drawState.getStencil().doesWrite()) {
bsalomon@google.comdafde9e2012-01-11 18:45:39 +0000529 return kDisableBlend_BlendOptFlag |
530 kEmitTransBlack_BlendOptFlag;
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000531 } else {
532 return kSkipDraw_BlendOptFlag;
533 }
534 }
535
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000536 // check for coverage due to constant coverage, per-vertex coverage,
bsalomon@google.com021fc732012-10-25 12:47:42 +0000537 // edge aa or coverage stage
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000538 bool hasCoverage = forceCoverage ||
rmistry@google.comd6176b02012-08-23 18:14:13 +0000539 0xffffffff != drawState.getCoverage() ||
jvanverth@google.comcc782382013-01-28 20:39:48 +0000540 (layout & GrDrawState::kCoverage_VertexLayoutBit) ||
541 (layout & GrDrawState::kEdge_VertexLayoutBit);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000542 for (int s = drawState.getFirstCoverageStage();
tomhudson@google.com93813632011-10-27 20:21:16 +0000543 !hasCoverage && s < GrDrawState::kNumStages;
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000544 ++s) {
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000545 if (drawState.isStageEnabled(s)) {
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000546 hasCoverage = true;
547 }
548 }
549
550 // if we don't have coverage we can check whether the dst
551 // has to read at all. If not, we'll disable blending.
552 if (!hasCoverage) {
553 if (dstCoeffIsZero) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000554 if (kOne_GrBlendCoeff == *srcCoeff) {
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000555 // if there is no coverage and coeffs are (1,0) then we
556 // won't need to read the dst at all, it gets replaced by src
557 return kDisableBlend_BlendOptFlag;
bsalomon@google.com47059542012-06-06 20:51:20 +0000558 } else if (kZero_GrBlendCoeff == *srcCoeff) {
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000559 // if the op is "clear" then we don't need to emit a color
560 // or blend, just write transparent black into the dst.
bsalomon@google.com47059542012-06-06 20:51:20 +0000561 *srcCoeff = kOne_GrBlendCoeff;
562 *dstCoeff = kZero_GrBlendCoeff;
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000563 return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000564 }
565 }
bsalomon@google.comcf939ae2012-12-13 19:59:23 +0000566 } else if (drawState.isCoverageDrawing()) {
567 // we have coverage but we aren't distinguishing it from alpha by request.
568 return kCoverageAsAlpha_BlendOptFlag;
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000569 } else {
570 // check whether coverage can be safely rolled into alpha
571 // of if we can skip color computation and just emit coverage
572 if (this->canTweakAlphaForCoverage()) {
573 return kCoverageAsAlpha_BlendOptFlag;
574 }
bsalomon@google.comdafde9e2012-01-11 18:45:39 +0000575 if (dstCoeffIsZero) {
bsalomon@google.com47059542012-06-06 20:51:20 +0000576 if (kZero_GrBlendCoeff == *srcCoeff) {
bsalomon@google.comdafde9e2012-01-11 18:45:39 +0000577 // the source color is not included in the blend
578 // the dst coeff is effectively zero so blend works out to:
579 // (c)(0)D + (1-c)D = (1-c)D.
bsalomon@google.com47059542012-06-06 20:51:20 +0000580 *dstCoeff = kISA_GrBlendCoeff;
bsalomon@google.comdafde9e2012-01-11 18:45:39 +0000581 return kEmitCoverage_BlendOptFlag;
582 } else if (srcAIsOne) {
583 // the dst coeff is effectively zero so blend works out to:
584 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
rmistry@google.comd6176b02012-08-23 18:14:13 +0000585 // If Sa is 1 then we can replace Sa with c
bsalomon@google.comdafde9e2012-01-11 18:45:39 +0000586 // and set dst coeff to 1-Sa.
bsalomon@google.com47059542012-06-06 20:51:20 +0000587 *dstCoeff = kISA_GrBlendCoeff;
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000588 return kCoverageAsAlpha_BlendOptFlag;
589 }
bsalomon@google.comdafde9e2012-01-11 18:45:39 +0000590 } else if (dstCoeffIsOne) {
591 // the dst coeff is effectively one so blend works out to:
592 // cS + (c)(1)D + (1-c)D = cS + D.
bsalomon@google.com47059542012-06-06 20:51:20 +0000593 *dstCoeff = kOne_GrBlendCoeff;
bsalomon@google.comdafde9e2012-01-11 18:45:39 +0000594 return kCoverageAsAlpha_BlendOptFlag;
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000595 }
596 }
597 return kNone_BlendOpt;
598}
599
600bool GrDrawTarget::willUseHWAALines() const {
bsalomon@google.com471d4712011-08-23 15:45:25 +0000601 // there is a conflict between using smooth lines and our use of
602 // premultiplied alpha. Smooth lines tweak the incoming alpha value
603 // but not in a premul-alpha way. So we only use them when our alpha
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000604 // is 0xff and tweaking the color for partial coverage is OK
bsalomon@google.comf6601872012-08-28 21:11:35 +0000605 if (!fCaps.hwAALineSupport() ||
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000606 !this->getDrawState().isHWAntialiasState()) {
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000607 return false;
608 }
609 BlendOptFlags opts = this->getBlendOpts();
610 return (kDisableBlend_BlendOptFlag & opts) &&
611 (kCoverageAsAlpha_BlendOptFlag & opts);
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000612}
613
614bool GrDrawTarget::canApplyCoverage() const {
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000615 // we can correctly apply coverage if a) we have dual source blending
616 // or b) one of our blend optimizations applies.
bsalomon@google.comf6601872012-08-28 21:11:35 +0000617 return this->getCaps().dualSourceBlendingSupport() ||
bsalomon@google.com86c1f712011-10-12 14:54:26 +0000618 kNone_BlendOpt != this->getBlendOpts(true);
bsalomon@google.com471d4712011-08-23 15:45:25 +0000619}
620
bsalomon@google.com934c5702012-03-20 21:17:58 +0000621////////////////////////////////////////////////////////////////////////////////
622
623void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
624 int instanceCount,
625 int verticesPerInstance,
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000626 int indicesPerInstance,
627 const SkRect* devBounds) {
bsalomon@google.com934c5702012-03-20 21:17:58 +0000628 if (!verticesPerInstance || !indicesPerInstance) {
629 return;
630 }
631
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000632 int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
633 if (!maxInstancesPerDraw) {
bsalomon@google.com934c5702012-03-20 21:17:58 +0000634 return;
635 }
636
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000637 DrawInfo info;
638 info.fPrimitiveType = type;
639 info.fStartIndex = 0;
640 info.fStartVertex = 0;
641 info.fIndicesPerInstance = indicesPerInstance;
642 info.fVerticesPerInstance = verticesPerInstance;
643
644 // Set the same bounds for all the draws.
645 if (NULL != devBounds) {
646 info.setDevBounds(*devBounds);
647 }
648
bsalomon@google.com934c5702012-03-20 21:17:58 +0000649 while (instanceCount) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000650 info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw);
651 info.fVertexCount = info.fInstanceCount * verticesPerInstance;
652 info.fIndexCount = info.fInstanceCount * indicesPerInstance;
653
654 if (this->checkDraw(type,
655 info.fStartVertex,
656 info.fStartIndex,
657 info.fVertexCount,
658 info.fIndexCount)) {
659 this->onDraw(info);
660 }
661 info.fStartVertex += info.fVertexCount;
662 instanceCount -= info.fInstanceCount;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000663 }
664}
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000665
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000666////////////////////////////////////////////////////////////////////////////////
667
rmistry@google.comd6176b02012-08-23 18:14:13 +0000668void GrDrawTarget::drawRect(const GrRect& rect,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000669 const SkMatrix* matrix,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000670 const GrRect* srcRects[],
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000671 const SkMatrix* srcMatrices[]) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000672 GrVertexLayout layout = 0;
673 uint32_t explicitCoordMask = 0;
674
675 if (NULL != srcRects) {
676 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
677 int numTC = 0;
678 if (NULL != srcRects[s]) {
679 layout |= GrDrawState::StageTexCoordVertexLayoutBit(s, numTC);
680 explicitCoordMask |= (1 << s);
681 ++numTC;
682 }
683 }
684 }
685
686 GrDrawState::AutoViewMatrixRestore avmr;
687 if (NULL != matrix) {
688 avmr.set(this->drawState(), *matrix, explicitCoordMask);
689 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000690
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000691 this->drawState()->setVertexLayout(layout);
692 AutoReleaseGeometry geo(this, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000693 if (!geo.succeeded()) {
694 GrPrintf("Failed to get space for vertices!\n");
695 return;
696 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000697
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000698 int stageOffsets[GrDrawState::kNumStages];
699 int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets, NULL, NULL, NULL);
700 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000701
tomhudson@google.com93813632011-10-27 20:21:16 +0000702 for (int i = 0; i < GrDrawState::kNumStages; ++i) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000703 if (explicitCoordMask & (1 << i)) {
reed@google.com009dfe22013-02-01 15:05:18 +0000704 GrAssert(0 != stageOffsets[i]);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000705 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000706 stageOffsets[i]);
707 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
bsalomon@google.coma3108262011-10-10 14:08:47 +0000708 srcRects[i]->fRight, srcRects[i]->fBottom,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000709 vsize);
710 if (NULL != srcMatrices && NULL != srcMatrices[i]) {
711 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
712 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000713 } else {
reed@google.com009dfe22013-02-01 15:05:18 +0000714 GrAssert(0 == stageOffsets[i]);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000715 }
716 }
robertphillips@google.com8b129aa2012-10-05 15:37:00 +0000717
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000718 this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000719}
720
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000721void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
722}
723
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000724////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000725
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000726GrDrawTarget::AutoStateRestore::AutoStateRestore() {
727 fDrawTarget = NULL;
728}
reed@google.comac10a2d2010-12-22 21:39:39 +0000729
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000730GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
731 ASRInit init) {
732 fDrawTarget = NULL;
733 this->set(target, init);
reed@google.comac10a2d2010-12-22 21:39:39 +0000734}
735
736GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000737 if (NULL != fDrawTarget) {
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000738 fDrawTarget->setDrawState(fSavedState);
739 fSavedState->unref();
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000740 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000741}
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000742
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000743void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) {
744 GrAssert(NULL == fDrawTarget);
745 fDrawTarget = target;
746 fSavedState = target->drawState();
747 GrAssert(fSavedState);
748 fSavedState->ref();
749 if (kReset_ASRInit == init) {
750 // calls the default cons
751 fTempState.init();
752 } else {
753 GrAssert(kPreserve_ASRInit == init);
754 // calls the copy cons
755 fTempState.set(*fSavedState);
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000756 }
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000757 target->setDrawState(fTempState.get());
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000758}
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000759
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000760////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000761
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000762GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
763 GrDrawTarget* target,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000764 int vertexCount,
765 int indexCount) {
766 fTarget = NULL;
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000767 this->set(target, vertexCount, indexCount);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000768}
rmistry@google.comd6176b02012-08-23 18:14:13 +0000769
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000770GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
771 fTarget = NULL;
772}
773
774GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
775 this->reset();
776}
777
778bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000779 int vertexCount,
780 int indexCount) {
781 this->reset();
782 fTarget = target;
783 bool success = true;
784 if (NULL != fTarget) {
785 fTarget = target;
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000786 success = target->reserveVertexAndIndexSpace(vertexCount,
bsalomon@google.come3d70952012-03-13 12:40:53 +0000787 indexCount,
788 &fVertices,
789 &fIndices);
790 if (!success) {
791 fTarget = NULL;
792 this->reset();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000793 }
794 }
795 GrAssert(success == (NULL != fTarget));
796 return success;
797}
798
799void GrDrawTarget::AutoReleaseGeometry::reset() {
800 if (NULL != fTarget) {
801 if (NULL != fVertices) {
802 fTarget->resetVertexSource();
803 }
804 if (NULL != fIndices) {
805 fTarget->resetIndexSource();
806 }
807 fTarget = NULL;
808 }
bsalomon@google.comcb0c5ab2011-06-29 17:48:17 +0000809 fVertices = NULL;
810 fIndices = NULL;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000811}
812
bsalomon@google.com8d67c072012-12-13 20:38:14 +0000813GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
814 fTarget = target;
815 fClip = fTarget->getClip();
816 fStack.init();
817 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
818 fReplacementClip.fClipStack = fStack.get();
819 target->setClip(&fReplacementClip);
820}
821
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000822void GrDrawTarget::Caps::print() const {
823 static const char* gNY[] = {"NO", "YES"};
bsalomon@google.comf6601872012-08-28 21:11:35 +0000824 GrPrintf("8 Bit Palette Support : %s\n", gNY[fInternals.f8BitPaletteSupport]);
825 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fInternals.fNPOTTextureTileSupport]);
826 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fInternals.fTwoSidedStencilSupport]);
827 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fInternals.fStencilWrapOpsSupport]);
828 GrPrintf("HW AA Lines Support : %s\n", gNY[fInternals.fHWAALineSupport]);
829 GrPrintf("Shader Derivative Support : %s\n", gNY[fInternals.fShaderDerivativeSupport]);
830 GrPrintf("Geometry Shader Support : %s\n", gNY[fInternals.fGeometryShaderSupport]);
831 GrPrintf("FSAA Support : %s\n", gNY[fInternals.fFSAASupport]);
832 GrPrintf("Dual Source Blending Support: %s\n", gNY[fInternals.fDualSourceBlendingSupport]);
833 GrPrintf("Buffer Lock Support : %s\n", gNY[fInternals.fBufferLockSupport]);
834 GrPrintf("Path Stenciling Support : %s\n", gNY[fInternals.fPathStencilingSupport]);
835 GrPrintf("Max Texture Size : %d\n", fInternals.fMaxTextureSize);
836 GrPrintf("Max Render Target Size : %d\n", fInternals.fMaxRenderTargetSize);
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000837}