blob: f1f113681b3d9c164367ed365ccfa8d96d2ad02b [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"
12#include "GrGpuVertex.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"
15#include "GrIndexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000016
junov@google.com6acc9b32011-05-16 18:32:07 +000017namespace {
18
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000019// recursive helper for creating mask with all the tex coord bits set for
20// one stage
21template <int N>
reed@google.com34cec242011-04-19 15:53:12 +000022int stage_mask_recur(int stage) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000023 return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000024 stage_mask_recur<N+1>(stage);
25}
junov@google.com6acc9b32011-05-16 18:32:07 +000026template<>
reed@google.comd728f6e2011-01-13 20:02:47 +000027int stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
reed@google.comac10a2d2010-12-22 21:39:39 +000028
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000029// mask of all tex coord indices for one stage
junov@google.com6acc9b32011-05-16 18:32:07 +000030int stage_tex_coord_mask(int stage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000031 return stage_mask_recur<0>(stage);
reed@google.comac10a2d2010-12-22 21:39:39 +000032}
33
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000034// mask of all bits relevant to one stage
junov@google.com6acc9b32011-05-16 18:32:07 +000035int stage_mask(int stage) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000036 return stage_tex_coord_mask(stage) |
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000037 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
38}
39
40// recursive helper for creating mask of with all bits set relevant to one
41// texture coordinate index
42template <int N>
reed@google.com34cec242011-04-19 15:53:12 +000043int tex_coord_mask_recur(int texCoordIdx) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000044 return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000045 tex_coord_mask_recur<N+1>(texCoordIdx);
46}
junov@google.com6acc9b32011-05-16 18:32:07 +000047template<>
reed@google.comd728f6e2011-01-13 20:02:47 +000048int tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000049
50// mask of all bits relevant to one texture coordinate index
junov@google.com6acc9b32011-05-16 18:32:07 +000051int tex_coord_idx_mask(int texCoordIdx) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000052 return tex_coord_mask_recur<0>(texCoordIdx);
53}
54
55bool check_layout(GrVertexLayout layout) {
56 // can only have 1 or 0 bits set for each stage.
57 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
58 int stageBits = layout & stage_mask(s);
59 if (stageBits && !GrIsPow2(stageBits)) {
60 return false;
61 }
62 }
63 return true;
64}
65
junov@google.com6acc9b32011-05-16 18:32:07 +000066} //unnamed namespace
67
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000068size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
69 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +000070
71 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000072 sizeof(GrGpuTextVertex) :
73 sizeof(GrPoint);
74
75 size_t size = vecSize; // position
76 for (int t = 0; t < kMaxTexCoords; ++t) {
77 if (tex_coord_idx_mask(t) & vertexLayout) {
78 size += vecSize;
79 }
80 }
81 if (vertexLayout & kColor_VertexLayoutBit) {
82 size += sizeof(GrColor);
83 }
84 return size;
85}
86
87int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
88 GrAssert(check_layout(vertexLayout));
89 if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
reed@google.comac10a2d2010-12-22 21:39:39 +000090 return 0;
91 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000092 int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
93 if (tcIdx >= 0) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000094
95 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000096 sizeof(GrGpuTextVertex) :
97 sizeof(GrPoint);
98 int offset = vecSize; // position
99 // figure out how many tex coordinates are present and precede this one.
100 for (int t = 0; t < tcIdx; ++t) {
101 if (tex_coord_idx_mask(t) & vertexLayout) {
102 offset += vecSize;
103 }
104 }
105 return offset;
106 }
107
reed@google.comac10a2d2010-12-22 21:39:39 +0000108 return -1;
109}
110
111int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000112 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000113
reed@google.comac10a2d2010-12-22 21:39:39 +0000114 if (vertexLayout & kColor_VertexLayoutBit) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000115 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000116 sizeof(GrGpuTextVertex) :
117 sizeof(GrPoint);
118 int offset = vecSize; // position
119 // figure out how many tex coordinates are present and precede this one.
120 for (int t = 0; t < kMaxTexCoords; ++t) {
121 if (tex_coord_idx_mask(t) & vertexLayout) {
122 offset += vecSize;
123 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000124 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000125 return offset;
reed@google.comac10a2d2010-12-22 21:39:39 +0000126 }
127 return -1;
128}
129
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000130int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
131 int texCoordOffsetsByIdx[kMaxTexCoords],
132 int* colorOffset) {
133 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000134
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000135 GrAssert(NULL != texCoordOffsetsByIdx);
reed@google.comac10a2d2010-12-22 21:39:39 +0000136 GrAssert(NULL != colorOffset);
137
bsalomon@google.com5782d712011-01-21 21:03:59 +0000138 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000139 sizeof(GrGpuTextVertex) :
140 sizeof(GrPoint);
141 int size = vecSize; // position
bsalomon@google.com5782d712011-01-21 21:03:59 +0000142
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000143 for (int t = 0; t < kMaxTexCoords; ++t) {
144 if (tex_coord_idx_mask(t) & vertexLayout) {
145 texCoordOffsetsByIdx[t] = size;
146 size += vecSize;
reed@google.comac10a2d2010-12-22 21:39:39 +0000147 } else {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000148 texCoordOffsetsByIdx[t] = -1;
reed@google.comac10a2d2010-12-22 21:39:39 +0000149 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000150 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000151 if (kColor_VertexLayoutBit & vertexLayout) {
152 *colorOffset = size;
153 size += sizeof(GrColor);
154 } else {
155 *colorOffset = -1;
156 }
157 return size;
reed@google.comac10a2d2010-12-22 21:39:39 +0000158}
159
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000160int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
161 int texCoordOffsetsByStage[kNumStages],
162 int* colorOffset) {
163 GrAssert(check_layout(vertexLayout));
164
165 GrAssert(NULL != texCoordOffsetsByStage);
166 GrAssert(NULL != colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000167
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000168 int texCoordOffsetsByIdx[kMaxTexCoords];
bsalomon@google.com5782d712011-01-21 21:03:59 +0000169 int size = VertexSizeAndOffsetsByIdx(vertexLayout,
170 texCoordOffsetsByIdx,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000171 colorOffset);
172 for (int s = 0; s < kNumStages; ++s) {
173 int tcIdx;
174 if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
175 texCoordOffsetsByStage[s] = 0;
176 } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
177 texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
178 } else {
179 texCoordOffsetsByStage[s] = -1;
180 }
181 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000182 return size;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000183}
184
185bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
186 GrAssert(stage < kNumStages);
187 GrAssert(check_layout(vertexLayout));
188 return !!(stage_mask(stage) & vertexLayout);
189}
190
bsalomon@google.com5782d712011-01-21 21:03:59 +0000191bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000192 GrVertexLayout vertexLayout) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000193 GrAssert(coordIndex < kMaxTexCoords);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000194 GrAssert(check_layout(vertexLayout));
195 return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
196}
197
198int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
199 GrAssert(stage < kNumStages);
200 GrAssert(check_layout(vertexLayout));
201 int bit = vertexLayout & stage_tex_coord_mask(stage);
202 if (bit) {
203 // figure out which set of texture coordates is used
204 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
205 // and start at bit 0.
206 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
207 return (32 - Gr_clz(bit) - 1) / kNumStages;
208 }
209 return -1;
210}
211
212void GrDrawTarget::VertexLayoutUnitTest() {
213 // not necessarily exhaustive
214 static bool run;
215 if (!run) {
216 run = true;
217 for (int s = 0; s < kNumStages; ++s) {
218
219 GrAssert(!VertexUsesStage(s, 0));
220 GrAssert(-1 == VertexStageCoordOffset(s, 0));
221 GrVertexLayout stageMask = 0;
222 for (int t = 0; t < kMaxTexCoords; ++t) {
223 stageMask |= StageTexCoordVertexLayoutBit(s,t);
224 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000225 GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000226 GrAssert(stage_tex_coord_mask(s) == stageMask);
227 stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
228 GrAssert(stage_mask(s) == stageMask);
229 GrAssert(!check_layout(stageMask));
230 }
231 for (int t = 0; t < kMaxTexCoords; ++t) {
232 GrVertexLayout tcMask = 0;
233 GrAssert(!VertexUsesTexCoordIdx(t, 0));
234 for (int s = 0; s < kNumStages; ++s) {
235 tcMask |= StageTexCoordVertexLayoutBit(s,t);
236 GrAssert(VertexUsesStage(s, tcMask));
237 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
238 GrAssert(VertexUsesTexCoordIdx(t, tcMask));
239 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
240 GrAssert(t == VertexTexCoordsForStage(s, tcMask));
241 for (int s2 = s + 1; s2 < kNumStages; ++s2) {
242 GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
243 GrAssert(!VertexUsesStage(s2, tcMask));
244 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000245
bsalomon@google.com19628322011-02-03 21:30:17 +0000246 #if GR_DEBUG
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000247 GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
bsalomon@google.com19628322011-02-03 21:30:17 +0000248 #endif
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000249 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
250 GrAssert(VertexUsesStage(s2, posAsTex));
251 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
252 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
253 }
bsalomon@google.com19628322011-02-03 21:30:17 +0000254 #if GR_DEBUG
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000255 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
bsalomon@google.com19628322011-02-03 21:30:17 +0000256 #endif
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000257 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
258 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
259 }
260 GrAssert(tex_coord_idx_mask(t) == tcMask);
261 GrAssert(check_layout(tcMask));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000262
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000263 int stageOffsets[kNumStages];
264 int colorOffset;
265 int size;
266 size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset);
267 GrAssert(2*sizeof(GrPoint) == size);
268 GrAssert(-1 == colorOffset);
269 for (int s = 0; s < kNumStages; ++s) {
270 GrAssert(VertexUsesStage(s, tcMask));
271 GrAssert(sizeof(GrPoint) == stageOffsets[s]);
272 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
273 }
274 }
275 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000276}
277
278////////////////////////////////////////////////////////////////////////////////
279
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000280#define DEBUG_INVAL_BUFFER 0xdeadcafe
281#define DEBUG_INVAL_START_IDX -1
282
283GrDrawTarget::GrDrawTarget()
284: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000285#if GR_DEBUG
286 VertexLayoutUnitTest();
287#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000288 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000289#if GR_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000290 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
291 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
292 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
293 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
reed@google.comac10a2d2010-12-22 21:39:39 +0000294#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000295 geoSrc.fVertexSrc = kNone_GeometrySrcType;
296 geoSrc.fIndexSrc = kNone_GeometrySrcType;
297}
298
299GrDrawTarget::~GrDrawTarget() {
300 int popCnt = fGeoSrcStateStack.count() - 1;
301 while (popCnt) {
302 this->popGeometrySource();
303 --popCnt;
304 }
305 this->releasePreviousVertexSource();
306 this->releasePreviousIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000307}
308
309void GrDrawTarget::setClip(const GrClip& clip) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000310 clipWillBeSet(clip);
reed@google.comac10a2d2010-12-22 21:39:39 +0000311 fClip = clip;
312}
313
314const GrClip& GrDrawTarget::getClip() const {
315 return fClip;
316}
317
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000318void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
319 GrAssert(stage >= 0 && stage < kNumStages);
320 fCurrDrawState.fTextures[stage] = tex;
reed@google.comac10a2d2010-12-22 21:39:39 +0000321}
322
bsalomon@google.com5782d712011-01-21 21:03:59 +0000323const GrTexture* GrDrawTarget::getTexture(int stage) const {
324 GrAssert(stage >= 0 && stage < kNumStages);
325 return fCurrDrawState.fTextures[stage];
326}
327
328GrTexture* GrDrawTarget::getTexture(int stage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000329 GrAssert(stage >= 0 && stage < kNumStages);
330 return fCurrDrawState.fTextures[stage];
reed@google.comac10a2d2010-12-22 21:39:39 +0000331}
332
333void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
334 fCurrDrawState.fRenderTarget = target;
335}
336
bsalomon@google.com5782d712011-01-21 21:03:59 +0000337const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
338 return fCurrDrawState.fRenderTarget;
339}
340
341GrRenderTarget* GrDrawTarget::getRenderTarget() {
reed@google.comac10a2d2010-12-22 21:39:39 +0000342 return fCurrDrawState.fRenderTarget;
343}
344
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000345void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
346 fCurrDrawState.fViewMatrix = m;
reed@google.comac10a2d2010-12-22 21:39:39 +0000347}
348
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000349void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000350 fCurrDrawState.fViewMatrix.preConcat(matrix);
351}
352
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000353void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
354 fCurrDrawState.fViewMatrix.postConcat(matrix);
355}
356
bsalomon@google.com5782d712011-01-21 21:03:59 +0000357const GrMatrix& GrDrawTarget::getViewMatrix() const {
358 return fCurrDrawState.fViewMatrix;
reed@google.comac10a2d2010-12-22 21:39:39 +0000359}
360
361bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000362 // Mike: Can we cache this somewhere?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000363 // Brian: Sure, do we use it often?
reed@google.comac10a2d2010-12-22 21:39:39 +0000364
365 GrMatrix inverse;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000366 if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000367 if (matrix) {
368 *matrix = inverse;
369 }
370 return true;
371 }
372 return false;
373}
374
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000375void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
376 GrAssert(stage >= 0 && stage < kNumStages);
377 fCurrDrawState.fSamplerStates[stage] = state;
378}
379
reed@google.comac10a2d2010-12-22 21:39:39 +0000380void GrDrawTarget::enableState(uint32_t bits) {
381 fCurrDrawState.fFlagBits |= bits;
382}
383
384void GrDrawTarget::disableState(uint32_t bits) {
385 fCurrDrawState.fFlagBits &= ~(bits);
386}
387
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000388void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
389 GrBlendCoeff dstCoeff) {
390 fCurrDrawState.fSrcBlend = srcCoeff;
391 fCurrDrawState.fDstBlend = dstCoeff;
392#if GR_DEBUG
393 switch (dstCoeff) {
394 case kDC_BlendCoeff:
395 case kIDC_BlendCoeff:
396 case kDA_BlendCoeff:
397 case kIDA_BlendCoeff:
398 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
399 "coverage stages.\n");
400 break;
401 default:
402 break;
403 }
404 switch (srcCoeff) {
405 case kSC_BlendCoeff:
406 case kISC_BlendCoeff:
407 case kSA_BlendCoeff:
408 case kISA_BlendCoeff:
409 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
410 "coverage stages.\n");
411 break;
412 default:
413 break;
414 }
415#endif
reed@google.comac10a2d2010-12-22 21:39:39 +0000416}
417
418void GrDrawTarget::setColor(GrColor c) {
419 fCurrDrawState.fColor = c;
420}
421
Scroggo97c88c22011-05-11 14:05:25 +0000422void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
423 fCurrDrawState.fColorFilterColor = c;
424 fCurrDrawState.fColorFilterXfermode = mode;
425}
426
reed@google.comac10a2d2010-12-22 21:39:39 +0000427void GrDrawTarget::setAlpha(uint8_t a) {
428 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
429}
430
431void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
432 state->fState = fCurrDrawState;
433}
434
435void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
436 fCurrDrawState = state.fState;
437}
438
439void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
440 fCurrDrawState = srcTarget.fCurrDrawState;
441}
442
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000443bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
444 int vertexCount,
445 void** vertices) {
446 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
447 bool acquired = false;
448 if (vertexCount > 0) {
449 GrAssert(NULL != vertices);
450 this->releasePreviousVertexSource();
451 geoSrc.fVertexSrc = kNone_GeometrySrcType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000452
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000453 acquired = this->onReserveVertexSpace(vertexLayout,
454 vertexCount,
455 vertices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000456 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000457 if (acquired) {
458 geoSrc.fVertexSrc = kReserved_GeometrySrcType;
459 geoSrc.fVertexCount = vertexCount;
460 geoSrc.fVertexLayout = vertexLayout;
461 } else if (NULL != vertices) {
462 *vertices = NULL;
463 }
464 return acquired;
465}
466
467bool GrDrawTarget::reserveIndexSpace(int indexCount,
468 void** indices) {
469 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
470 bool acquired = false;
471 if (indexCount > 0) {
472 GrAssert(NULL != indices);
473 this->releasePreviousIndexSource();
474 geoSrc.fIndexSrc = kNone_GeometrySrcType;
475
476 acquired = this->onReserveIndexSpace(indexCount, indices);
477 }
478 if (acquired) {
479 geoSrc.fIndexSrc = kReserved_GeometrySrcType;
480 geoSrc.fIndexCount = indexCount;
481 } else if (NULL != indices) {
482 *indices = NULL;
483 }
484 return acquired;
485
reed@google.comac10a2d2010-12-22 21:39:39 +0000486}
487
488bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
489 int32_t* vertexCount,
490 int32_t* indexCount) const {
reed@google.comac10a2d2010-12-22 21:39:39 +0000491 if (NULL != vertexCount) {
492 *vertexCount = -1;
493 }
494 if (NULL != indexCount) {
495 *indexCount = -1;
496 }
497 return false;
498}
499
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000500void GrDrawTarget::releasePreviousVertexSource() {
501 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
502 switch (geoSrc.fVertexSrc) {
503 case kNone_GeometrySrcType:
504 break;
505 case kArray_GeometrySrcType:
506 this->releaseVertexArray();
507 break;
508 case kReserved_GeometrySrcType:
509 this->releaseReservedVertexSpace();
510 break;
511 case kBuffer_GeometrySrcType:
512 geoSrc.fVertexBuffer->unref();
513#if GR_DEBUG
514 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
515#endif
516 break;
517 default:
518 GrCrash("Unknown Vertex Source Type.");
519 break;
520 }
521}
522
523void GrDrawTarget::releasePreviousIndexSource() {
524 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
525 switch (geoSrc.fIndexSrc) {
526 case kNone_GeometrySrcType: // these two don't require
527 break;
528 case kArray_GeometrySrcType:
529 this->releaseIndexArray();
530 break;
531 case kReserved_GeometrySrcType:
532 this->releaseReservedIndexSpace();
533 break;
534 case kBuffer_GeometrySrcType:
535 geoSrc.fIndexBuffer->unref();
536#if GR_DEBUG
537 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
538#endif
539 break;
540 default:
541 GrCrash("Unknown Index Source Type.");
542 break;
543 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000544}
545
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000546void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
547 const void* vertexArray,
548 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000549 this->releasePreviousVertexSource();
550 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
551 geoSrc.fVertexSrc = kArray_GeometrySrcType;
552 geoSrc.fVertexLayout = vertexLayout;
553 geoSrc.fVertexCount = vertexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000554 this->onSetVertexSourceToArray(vertexArray, vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000555}
556
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000557void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
558 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000559 this->releasePreviousIndexSource();
560 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
561 geoSrc.fIndexSrc = kArray_GeometrySrcType;
562 geoSrc.fIndexCount = indexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000563 this->onSetIndexSourceToArray(indexArray, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000564}
565
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000566void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
567 const GrVertexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000568 this->releasePreviousVertexSource();
569 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
570 geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
571 geoSrc.fVertexBuffer = buffer;
572 buffer->ref();
573 geoSrc.fVertexLayout = vertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +0000574}
575
576void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000577 this->releasePreviousIndexSource();
578 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
579 geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
580 geoSrc.fIndexBuffer = buffer;
581 buffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000582}
583
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000584void GrDrawTarget::resetVertexSource() {
585 this->releasePreviousVertexSource();
586 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
587 geoSrc.fVertexSrc = kNone_GeometrySrcType;
588}
589
590void GrDrawTarget::resetIndexSource() {
591 this->releasePreviousIndexSource();
592 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
593 geoSrc.fIndexSrc = kNone_GeometrySrcType;
594}
595
596void GrDrawTarget::pushGeometrySource() {
597 this->geometrySourceWillPush();
598 GeometrySrcState& newState = fGeoSrcStateStack.push_back();
599 newState.fIndexSrc = kNone_GeometrySrcType;
600 newState.fVertexSrc = kNone_GeometrySrcType;
601#if GR_DEBUG
602 newState.fVertexCount = ~0;
603 newState.fVertexBuffer = (GrVertexBuffer*)~0;
604 newState.fIndexCount = ~0;
605 newState.fIndexBuffer = (GrIndexBuffer*)~0;
606#endif
607}
608
609void GrDrawTarget::popGeometrySource() {
610 const GeometrySrcState& geoSrc = this->getGeomSrc();
611 // if popping last element then pops are unbalanced with pushes
612 GrAssert(fGeoSrcStateStack.count() > 1);
613
614 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
615 this->releasePreviousVertexSource();
616 this->releasePreviousIndexSource();
617 fGeoSrcStateStack.pop_back();
618}
619
620////////////////////////////////////////////////////////////////////////////////
621
622void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
623 int startIndex, int vertexCount,
624 int indexCount) {
625#if GR_DEBUG
626 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
627 int maxVertex = startVertex + vertexCount;
628 int maxValidVertex;
629 switch (geoSrc.fVertexSrc) {
630 case kNone_GeometrySrcType:
631 GrCrash("Attempting to draw indexed geom without vertex src.");
632 case kReserved_GeometrySrcType: // fallthrough
633 case kArray_GeometrySrcType:
634 maxValidVertex = geoSrc.fVertexCount;
635 break;
636 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000637 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000638 VertexSize(geoSrc.fVertexLayout);
639 break;
640 }
641 if (maxVertex > maxValidVertex) {
642 GrCrash("Indexed drawing outside valid vertex range.");
643 }
644 int maxIndex = startIndex + indexCount;
645 int maxValidIndex;
646 switch (geoSrc.fIndexSrc) {
647 case kNone_GeometrySrcType:
648 GrCrash("Attempting to draw indexed geom without index src.");
649 case kReserved_GeometrySrcType: // fallthrough
650 case kArray_GeometrySrcType:
651 maxValidIndex = geoSrc.fIndexCount;
652 break;
653 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000654 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000655 break;
656 }
657 if (maxIndex > maxValidIndex) {
658 GrCrash("Indexed drawing outside valid index range.");
659 }
660#endif
661 this->onDrawIndexed(type, startVertex, startIndex,
662 vertexCount, indexCount);
663}
664
665
666void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
667 int startVertex,
668 int vertexCount) {
669#if GR_DEBUG
670 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
671 int maxVertex = startVertex + vertexCount;
672 int maxValidVertex;
673 switch (geoSrc.fVertexSrc) {
674 case kNone_GeometrySrcType:
675 GrCrash("Attempting to draw non-indexed geom without vertex src.");
676 case kReserved_GeometrySrcType: // fallthrough
677 case kArray_GeometrySrcType:
678 maxValidVertex = geoSrc.fVertexCount;
679 break;
680 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000681 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000682 VertexSize(geoSrc.fVertexLayout);
683 break;
684 }
685 if (maxVertex > maxValidVertex) {
686 GrCrash("Non-indexed drawing outside valid vertex range.");
687 }
688#endif
689 this->onDrawNonIndexed(type, startVertex, vertexCount);
690}
691
692////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000693
694bool GrDrawTarget::canDisableBlend() const {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000695 // If we compute a coverage value (using edge AA or a coverage stage) then
696 // we can't force blending off.
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000697 if (fCurrDrawState.fEdgeAANumEdges > 0) {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000698 return false;
699 }
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000700 for (int s = fCurrDrawState.fFirstCoverageStage; s < kNumStages; ++s) {
701 if (this->isStageEnabled(s)) {
702 return false;
703 }
704 }
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000705
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000706 if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) &&
707 (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) {
708 return true;
709 }
710
711 // If we have vertex color without alpha then we can't force blend off
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000712 if ((this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000713 0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
714 return false;
715 }
716
717 // If the src coef will always be 1...
718 if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend &&
719 kOne_BlendCoeff != fCurrDrawState.fSrcBlend) {
720 return false;
721 }
722
723 // ...and the dst coef is always 0...
724 if (kISA_BlendCoeff != fCurrDrawState.fDstBlend &&
725 kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
726 return false;
727 }
728
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000729 // ...and there isn't a texture stage with an alpha channel...
730 for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000731 if (this->isStageEnabled(s)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000732 GrAssert(NULL != fCurrDrawState.fTextures[s]);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000733
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000734 GrPixelConfig config = fCurrDrawState.fTextures[s]->config();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000735
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000736 if (!GrPixelConfigIsOpaque(config)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000737 return false;
738 }
739 }
740 }
741
Scroggo0bad6732011-05-11 20:25:01 +0000742 // ...and there isn't an interesting color filter...
743 // TODO: Consider being more aggressive with regards to disabling
744 // blending when a color filter is used.
745 if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) {
746 return false;
747 }
748
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000749 // ...then we disable blend.
750 return true;
751}
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000752
753///////////////////////////////////////////////////////////////////////////////
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000754void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
755 GrAssert(numEdges <= kMaxEdges);
756 memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge));
757 fCurrDrawState.fEdgeAANumEdges = numEdges;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000758}
759
760
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000761////////////////////////////////////////////////////////////////////////////////
762
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000763void GrDrawTarget::drawRect(const GrRect& rect,
764 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000765 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000766 const GrRect* srcRects[],
767 const GrMatrix* srcMatrices[]) {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000768 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000769
770 AutoReleaseGeometry geo(this, layout, 4, 0);
771
772 SetRectVertices(rect, matrix, srcRects,
773 srcMatrices, layout, geo.vertices());
774
775 drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
776}
777
bsalomon@google.comffca4002011-02-22 20:34:01 +0000778GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000779 const GrRect* srcRects[]) {
780 GrVertexLayout layout = 0;
781
782 for (int i = 0; i < kNumStages; ++i) {
783 int numTC = 0;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000784 if (stageEnableBitfield & (1 << i)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000785 if (NULL != srcRects && NULL != srcRects[i]) {
786 layout |= StageTexCoordVertexLayoutBit(i, numTC);
787 ++numTC;
788 } else {
789 layout |= StagePosAsTexCoordVertexLayoutBit(i);
790 }
791 }
792 }
793 return layout;
794}
795void GrDrawTarget::SetRectVertices(const GrRect& rect,
796 const GrMatrix* matrix,
797 const GrRect* srcRects[],
798 const GrMatrix* srcMatrices[],
799 GrVertexLayout layout,
800 void* vertices) {
801#if GR_DEBUG
802 // check that the layout and srcRects agree
803 for (int i = 0; i < kNumStages; ++i) {
804 if (VertexTexCoordsForStage(i, layout) >= 0) {
805 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
806 } else {
807 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
808 }
809 }
810#endif
811
812 int stageOffsets[kNumStages];
813 int colorOffset;
814 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset);
815 GrAssert(-1 == colorOffset);
816
817 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
818 rect.fRight, rect.fBottom,
819 vsize);
820 if (NULL != matrix) {
821 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
822 }
823
824 for (int i = 0; i < kNumStages; ++i) {
825 if (stageOffsets[i] > 0) {
826 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
827 stageOffsets[i]);
828 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
829 srcRects[i]->fRight, srcRects[i]->fBottom,
830 vsize);
831 if (NULL != srcMatrices && NULL != srcMatrices[i]) {
832 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
833 }
834 }
835 }
836}
837
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000838////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000839
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000840GrDrawTarget::AutoStateRestore::AutoStateRestore() {
841 fDrawTarget = NULL;
842}
reed@google.comac10a2d2010-12-22 21:39:39 +0000843
844GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
845 fDrawTarget = target;
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000846 if (NULL != fDrawTarget) {
847 fDrawTarget->saveCurrentDrawState(&fDrawState);
848 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000849}
850
851GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000852 if (NULL != fDrawTarget) {
853 fDrawTarget->restoreDrawState(fDrawState);
854 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000855}
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000856
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000857void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
858 if (target != fDrawTarget) {
859 if (NULL != fDrawTarget) {
860 fDrawTarget->restoreDrawState(fDrawState);
861 }
862 if (NULL != target) {
bsalomon@google.comd19aa272011-06-22 01:28:17 +0000863 target->saveCurrentDrawState(&fDrawState);
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000864 }
865 fDrawTarget = target;
866 }
867}
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000868
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000869////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000870
871GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
872 int stageMask) {
873 GrAssert(NULL != target);
874
875 fDrawTarget = target;
876 fViewMatrix = target->getViewMatrix();
877 fStageMask = stageMask;
878 if (fStageMask) {
879 GrMatrix invVM;
880 if (fViewMatrix.invert(&invVM)) {
881 for (int s = 0; s < kNumStages; ++s) {
882 if (fStageMask & (1 << s)) {
883 fSamplerMatrices[s] = target->getSamplerMatrix(s);
884 }
885 }
886 target->preConcatSamplerMatrices(fStageMask, invVM);
887 } else {
888 // sad trombone sound
889 fStageMask = 0;
890 }
891 }
892 target->setViewMatrix(GrMatrix::I());
893}
894
895GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
896 fDrawTarget->setViewMatrix(fViewMatrix);
897 for (int s = 0; s < kNumStages; ++s) {
898 if (fStageMask & (1 << s)) {
899 fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]);
900 }
901 }
902}
903
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000904////////////////////////////////////////////////////////////////////////////////
905
906GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
907 GrDrawTarget* target,
908 GrVertexLayout vertexLayout,
909 int vertexCount,
910 int indexCount) {
911 fTarget = NULL;
912 this->set(target, vertexLayout, vertexCount, indexCount);
913}
914
915GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
916 fTarget = NULL;
917}
918
919GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
920 this->reset();
921}
922
923bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
924 GrVertexLayout vertexLayout,
925 int vertexCount,
926 int indexCount) {
927 this->reset();
928 fTarget = target;
929 bool success = true;
930 if (NULL != fTarget) {
931 fTarget = target;
932 if (vertexCount > 0) {
933 success = target->reserveVertexSpace(vertexLayout,
934 vertexCount,
935 &fVertices);
936 if (!success) {
937 this->reset();
938 }
939 }
940 if (success && indexCount > 0) {
941 success = target->reserveIndexSpace(indexCount, &fIndices);
942 if (!success) {
943 this->reset();
944 }
945 }
946 }
947 GrAssert(success == (NULL != fTarget));
948 return success;
949}
950
951void GrDrawTarget::AutoReleaseGeometry::reset() {
952 if (NULL != fTarget) {
953 if (NULL != fVertices) {
954 fTarget->resetVertexSource();
955 }
956 if (NULL != fIndices) {
957 fTarget->resetIndexSource();
958 }
959 fTarget = NULL;
960 }
bsalomon@google.comcb0c5ab2011-06-29 17:48:17 +0000961 fVertices = NULL;
962 fIndices = NULL;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000963}
964