blob: cc64058465fa838ca5dc50a00be0a7241966c2c4 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#include "GrDrawTarget.h"
19#include "GrGpuVertex.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000020#include "GrTexture.h"
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000021#include "GrVertexBuffer.h"
22#include "GrIndexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000023
junov@google.com6acc9b32011-05-16 18:32:07 +000024namespace {
25
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000026// recursive helper for creating mask with all the tex coord bits set for
27// one stage
28template <int N>
reed@google.com34cec242011-04-19 15:53:12 +000029int stage_mask_recur(int stage) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000030 return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000031 stage_mask_recur<N+1>(stage);
32}
junov@google.com6acc9b32011-05-16 18:32:07 +000033template<>
reed@google.comd728f6e2011-01-13 20:02:47 +000034int stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
reed@google.comac10a2d2010-12-22 21:39:39 +000035
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000036// mask of all tex coord indices for one stage
junov@google.com6acc9b32011-05-16 18:32:07 +000037int stage_tex_coord_mask(int stage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000038 return stage_mask_recur<0>(stage);
reed@google.comac10a2d2010-12-22 21:39:39 +000039}
40
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000041// mask of all bits relevant to one stage
junov@google.com6acc9b32011-05-16 18:32:07 +000042int stage_mask(int stage) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000043 return stage_tex_coord_mask(stage) |
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000044 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
45}
46
47// recursive helper for creating mask of with all bits set relevant to one
48// texture coordinate index
49template <int N>
reed@google.com34cec242011-04-19 15:53:12 +000050int tex_coord_mask_recur(int texCoordIdx) {
bsalomon@google.com5782d712011-01-21 21:03:59 +000051 return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000052 tex_coord_mask_recur<N+1>(texCoordIdx);
53}
junov@google.com6acc9b32011-05-16 18:32:07 +000054template<>
reed@google.comd728f6e2011-01-13 20:02:47 +000055int tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000056
57// mask of all bits relevant to one texture coordinate index
junov@google.com6acc9b32011-05-16 18:32:07 +000058int tex_coord_idx_mask(int texCoordIdx) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000059 return tex_coord_mask_recur<0>(texCoordIdx);
60}
61
62bool check_layout(GrVertexLayout layout) {
63 // can only have 1 or 0 bits set for each stage.
64 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
65 int stageBits = layout & stage_mask(s);
66 if (stageBits && !GrIsPow2(stageBits)) {
67 return false;
68 }
69 }
70 return true;
71}
72
junov@google.com6acc9b32011-05-16 18:32:07 +000073} //unnamed namespace
74
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000075size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
76 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +000077
78 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000079 sizeof(GrGpuTextVertex) :
80 sizeof(GrPoint);
81
82 size_t size = vecSize; // position
83 for (int t = 0; t < kMaxTexCoords; ++t) {
84 if (tex_coord_idx_mask(t) & vertexLayout) {
85 size += vecSize;
86 }
87 }
88 if (vertexLayout & kColor_VertexLayoutBit) {
89 size += sizeof(GrColor);
90 }
91 return size;
92}
93
94int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
95 GrAssert(check_layout(vertexLayout));
96 if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
reed@google.comac10a2d2010-12-22 21:39:39 +000097 return 0;
98 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000099 int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
100 if (tcIdx >= 0) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000101
102 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000103 sizeof(GrGpuTextVertex) :
104 sizeof(GrPoint);
105 int offset = vecSize; // position
106 // figure out how many tex coordinates are present and precede this one.
107 for (int t = 0; t < tcIdx; ++t) {
108 if (tex_coord_idx_mask(t) & vertexLayout) {
109 offset += vecSize;
110 }
111 }
112 return offset;
113 }
114
reed@google.comac10a2d2010-12-22 21:39:39 +0000115 return -1;
116}
117
118int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000119 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000120
reed@google.comac10a2d2010-12-22 21:39:39 +0000121 if (vertexLayout & kColor_VertexLayoutBit) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000122 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000123 sizeof(GrGpuTextVertex) :
124 sizeof(GrPoint);
125 int offset = vecSize; // position
126 // figure out how many tex coordinates are present and precede this one.
127 for (int t = 0; t < kMaxTexCoords; ++t) {
128 if (tex_coord_idx_mask(t) & vertexLayout) {
129 offset += vecSize;
130 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000131 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000132 return offset;
reed@google.comac10a2d2010-12-22 21:39:39 +0000133 }
134 return -1;
135}
136
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000137int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
138 int texCoordOffsetsByIdx[kMaxTexCoords],
139 int* colorOffset) {
140 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000141
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000142 GrAssert(NULL != texCoordOffsetsByIdx);
reed@google.comac10a2d2010-12-22 21:39:39 +0000143 GrAssert(NULL != colorOffset);
144
bsalomon@google.com5782d712011-01-21 21:03:59 +0000145 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000146 sizeof(GrGpuTextVertex) :
147 sizeof(GrPoint);
148 int size = vecSize; // position
bsalomon@google.com5782d712011-01-21 21:03:59 +0000149
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000150 for (int t = 0; t < kMaxTexCoords; ++t) {
151 if (tex_coord_idx_mask(t) & vertexLayout) {
152 texCoordOffsetsByIdx[t] = size;
153 size += vecSize;
reed@google.comac10a2d2010-12-22 21:39:39 +0000154 } else {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000155 texCoordOffsetsByIdx[t] = -1;
reed@google.comac10a2d2010-12-22 21:39:39 +0000156 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000157 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000158 if (kColor_VertexLayoutBit & vertexLayout) {
159 *colorOffset = size;
160 size += sizeof(GrColor);
161 } else {
162 *colorOffset = -1;
163 }
164 return size;
reed@google.comac10a2d2010-12-22 21:39:39 +0000165}
166
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000167int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
168 int texCoordOffsetsByStage[kNumStages],
169 int* colorOffset) {
170 GrAssert(check_layout(vertexLayout));
171
172 GrAssert(NULL != texCoordOffsetsByStage);
173 GrAssert(NULL != colorOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000174
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000175 int texCoordOffsetsByIdx[kMaxTexCoords];
bsalomon@google.com5782d712011-01-21 21:03:59 +0000176 int size = VertexSizeAndOffsetsByIdx(vertexLayout,
177 texCoordOffsetsByIdx,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000178 colorOffset);
179 for (int s = 0; s < kNumStages; ++s) {
180 int tcIdx;
181 if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
182 texCoordOffsetsByStage[s] = 0;
183 } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
184 texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
185 } else {
186 texCoordOffsetsByStage[s] = -1;
187 }
188 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000189 return size;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000190}
191
192bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
193 GrAssert(stage < kNumStages);
194 GrAssert(check_layout(vertexLayout));
195 return !!(stage_mask(stage) & vertexLayout);
196}
197
bsalomon@google.com5782d712011-01-21 21:03:59 +0000198bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000199 GrVertexLayout vertexLayout) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000200 GrAssert(coordIndex < kMaxTexCoords);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000201 GrAssert(check_layout(vertexLayout));
202 return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
203}
204
205int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
206 GrAssert(stage < kNumStages);
207 GrAssert(check_layout(vertexLayout));
208 int bit = vertexLayout & stage_tex_coord_mask(stage);
209 if (bit) {
210 // figure out which set of texture coordates is used
211 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
212 // and start at bit 0.
213 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
214 return (32 - Gr_clz(bit) - 1) / kNumStages;
215 }
216 return -1;
217}
218
219void GrDrawTarget::VertexLayoutUnitTest() {
220 // not necessarily exhaustive
221 static bool run;
222 if (!run) {
223 run = true;
224 for (int s = 0; s < kNumStages; ++s) {
225
226 GrAssert(!VertexUsesStage(s, 0));
227 GrAssert(-1 == VertexStageCoordOffset(s, 0));
228 GrVertexLayout stageMask = 0;
229 for (int t = 0; t < kMaxTexCoords; ++t) {
230 stageMask |= StageTexCoordVertexLayoutBit(s,t);
231 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000232 GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000233 GrAssert(stage_tex_coord_mask(s) == stageMask);
234 stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
235 GrAssert(stage_mask(s) == stageMask);
236 GrAssert(!check_layout(stageMask));
237 }
238 for (int t = 0; t < kMaxTexCoords; ++t) {
239 GrVertexLayout tcMask = 0;
240 GrAssert(!VertexUsesTexCoordIdx(t, 0));
241 for (int s = 0; s < kNumStages; ++s) {
242 tcMask |= StageTexCoordVertexLayoutBit(s,t);
243 GrAssert(VertexUsesStage(s, tcMask));
244 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
245 GrAssert(VertexUsesTexCoordIdx(t, tcMask));
246 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
247 GrAssert(t == VertexTexCoordsForStage(s, tcMask));
248 for (int s2 = s + 1; s2 < kNumStages; ++s2) {
249 GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
250 GrAssert(!VertexUsesStage(s2, tcMask));
251 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000252
bsalomon@google.com19628322011-02-03 21:30:17 +0000253 #if GR_DEBUG
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000254 GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
bsalomon@google.com19628322011-02-03 21:30:17 +0000255 #endif
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000256 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
257 GrAssert(VertexUsesStage(s2, posAsTex));
258 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
259 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
260 }
bsalomon@google.com19628322011-02-03 21:30:17 +0000261 #if GR_DEBUG
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000262 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
bsalomon@google.com19628322011-02-03 21:30:17 +0000263 #endif
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000264 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
265 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
266 }
267 GrAssert(tex_coord_idx_mask(t) == tcMask);
268 GrAssert(check_layout(tcMask));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000269
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000270 int stageOffsets[kNumStages];
271 int colorOffset;
272 int size;
273 size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset);
274 GrAssert(2*sizeof(GrPoint) == size);
275 GrAssert(-1 == colorOffset);
276 for (int s = 0; s < kNumStages; ++s) {
277 GrAssert(VertexUsesStage(s, tcMask));
278 GrAssert(sizeof(GrPoint) == stageOffsets[s]);
279 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
280 }
281 }
282 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000283}
284
285////////////////////////////////////////////////////////////////////////////////
286
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000287#define DEBUG_INVAL_BUFFER 0xdeadcafe
288#define DEBUG_INVAL_START_IDX -1
289
290GrDrawTarget::GrDrawTarget()
291: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000292#if GR_DEBUG
293 VertexLayoutUnitTest();
294#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000295 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000296#if GR_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000297 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
298 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
299 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
300 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
reed@google.comac10a2d2010-12-22 21:39:39 +0000301#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000302 geoSrc.fVertexSrc = kNone_GeometrySrcType;
303 geoSrc.fIndexSrc = kNone_GeometrySrcType;
304}
305
306GrDrawTarget::~GrDrawTarget() {
307 int popCnt = fGeoSrcStateStack.count() - 1;
308 while (popCnt) {
309 this->popGeometrySource();
310 --popCnt;
311 }
312 this->releasePreviousVertexSource();
313 this->releasePreviousIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000314}
315
316void GrDrawTarget::setClip(const GrClip& clip) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000317 clipWillBeSet(clip);
reed@google.comac10a2d2010-12-22 21:39:39 +0000318 fClip = clip;
319}
320
321const GrClip& GrDrawTarget::getClip() const {
322 return fClip;
323}
324
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000325void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
326 GrAssert(stage >= 0 && stage < kNumStages);
327 fCurrDrawState.fTextures[stage] = tex;
reed@google.comac10a2d2010-12-22 21:39:39 +0000328}
329
bsalomon@google.com5782d712011-01-21 21:03:59 +0000330const GrTexture* GrDrawTarget::getTexture(int stage) const {
331 GrAssert(stage >= 0 && stage < kNumStages);
332 return fCurrDrawState.fTextures[stage];
333}
334
335GrTexture* GrDrawTarget::getTexture(int stage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000336 GrAssert(stage >= 0 && stage < kNumStages);
337 return fCurrDrawState.fTextures[stage];
reed@google.comac10a2d2010-12-22 21:39:39 +0000338}
339
340void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
341 fCurrDrawState.fRenderTarget = target;
342}
343
bsalomon@google.com5782d712011-01-21 21:03:59 +0000344const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
345 return fCurrDrawState.fRenderTarget;
346}
347
348GrRenderTarget* GrDrawTarget::getRenderTarget() {
reed@google.comac10a2d2010-12-22 21:39:39 +0000349 return fCurrDrawState.fRenderTarget;
350}
351
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000352void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
353 fCurrDrawState.fViewMatrix = m;
reed@google.comac10a2d2010-12-22 21:39:39 +0000354}
355
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000356void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000357 fCurrDrawState.fViewMatrix.preConcat(matrix);
358}
359
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000360void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
361 fCurrDrawState.fViewMatrix.postConcat(matrix);
362}
363
bsalomon@google.com5782d712011-01-21 21:03:59 +0000364const GrMatrix& GrDrawTarget::getViewMatrix() const {
365 return fCurrDrawState.fViewMatrix;
reed@google.comac10a2d2010-12-22 21:39:39 +0000366}
367
368bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000369 // Mike: Can we cache this somewhere?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000370 // Brian: Sure, do we use it often?
reed@google.comac10a2d2010-12-22 21:39:39 +0000371
372 GrMatrix inverse;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000373 if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000374 if (matrix) {
375 *matrix = inverse;
376 }
377 return true;
378 }
379 return false;
380}
381
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000382void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
383 GrAssert(stage >= 0 && stage < kNumStages);
384 fCurrDrawState.fSamplerStates[stage] = state;
385}
386
reed@google.comac10a2d2010-12-22 21:39:39 +0000387void GrDrawTarget::enableState(uint32_t bits) {
388 fCurrDrawState.fFlagBits |= bits;
389}
390
391void GrDrawTarget::disableState(uint32_t bits) {
392 fCurrDrawState.fFlagBits &= ~(bits);
393}
394
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000395void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
396 GrBlendCoeff dstCoeff) {
397 fCurrDrawState.fSrcBlend = srcCoeff;
398 fCurrDrawState.fDstBlend = dstCoeff;
399#if GR_DEBUG
400 switch (dstCoeff) {
401 case kDC_BlendCoeff:
402 case kIDC_BlendCoeff:
403 case kDA_BlendCoeff:
404 case kIDA_BlendCoeff:
405 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
406 "coverage stages.\n");
407 break;
408 default:
409 break;
410 }
411 switch (srcCoeff) {
412 case kSC_BlendCoeff:
413 case kISC_BlendCoeff:
414 case kSA_BlendCoeff:
415 case kISA_BlendCoeff:
416 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
417 "coverage stages.\n");
418 break;
419 default:
420 break;
421 }
422#endif
reed@google.comac10a2d2010-12-22 21:39:39 +0000423}
424
425void GrDrawTarget::setColor(GrColor c) {
426 fCurrDrawState.fColor = c;
427}
428
Scroggo97c88c22011-05-11 14:05:25 +0000429void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
430 fCurrDrawState.fColorFilterColor = c;
431 fCurrDrawState.fColorFilterXfermode = mode;
432}
433
reed@google.comac10a2d2010-12-22 21:39:39 +0000434void GrDrawTarget::setAlpha(uint8_t a) {
435 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
436}
437
438void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
439 state->fState = fCurrDrawState;
440}
441
442void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
443 fCurrDrawState = state.fState;
444}
445
446void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
447 fCurrDrawState = srcTarget.fCurrDrawState;
448}
449
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000450bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
451 int vertexCount,
452 void** vertices) {
453 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
454 bool acquired = false;
455 if (vertexCount > 0) {
456 GrAssert(NULL != vertices);
457 this->releasePreviousVertexSource();
458 geoSrc.fVertexSrc = kNone_GeometrySrcType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000459
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000460 acquired = this->onReserveVertexSpace(vertexLayout,
461 vertexCount,
462 vertices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000463 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000464 if (acquired) {
465 geoSrc.fVertexSrc = kReserved_GeometrySrcType;
466 geoSrc.fVertexCount = vertexCount;
467 geoSrc.fVertexLayout = vertexLayout;
468 } else if (NULL != vertices) {
469 *vertices = NULL;
470 }
471 return acquired;
472}
473
474bool GrDrawTarget::reserveIndexSpace(int indexCount,
475 void** indices) {
476 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
477 bool acquired = false;
478 if (indexCount > 0) {
479 GrAssert(NULL != indices);
480 this->releasePreviousIndexSource();
481 geoSrc.fIndexSrc = kNone_GeometrySrcType;
482
483 acquired = this->onReserveIndexSpace(indexCount, indices);
484 }
485 if (acquired) {
486 geoSrc.fIndexSrc = kReserved_GeometrySrcType;
487 geoSrc.fIndexCount = indexCount;
488 } else if (NULL != indices) {
489 *indices = NULL;
490 }
491 return acquired;
492
reed@google.comac10a2d2010-12-22 21:39:39 +0000493}
494
495bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
496 int32_t* vertexCount,
497 int32_t* indexCount) const {
reed@google.comac10a2d2010-12-22 21:39:39 +0000498 if (NULL != vertexCount) {
499 *vertexCount = -1;
500 }
501 if (NULL != indexCount) {
502 *indexCount = -1;
503 }
504 return false;
505}
506
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000507void GrDrawTarget::releasePreviousVertexSource() {
508 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
509 switch (geoSrc.fVertexSrc) {
510 case kNone_GeometrySrcType:
511 break;
512 case kArray_GeometrySrcType:
513 this->releaseVertexArray();
514 break;
515 case kReserved_GeometrySrcType:
516 this->releaseReservedVertexSpace();
517 break;
518 case kBuffer_GeometrySrcType:
519 geoSrc.fVertexBuffer->unref();
520#if GR_DEBUG
521 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
522#endif
523 break;
524 default:
525 GrCrash("Unknown Vertex Source Type.");
526 break;
527 }
528}
529
530void GrDrawTarget::releasePreviousIndexSource() {
531 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
532 switch (geoSrc.fIndexSrc) {
533 case kNone_GeometrySrcType: // these two don't require
534 break;
535 case kArray_GeometrySrcType:
536 this->releaseIndexArray();
537 break;
538 case kReserved_GeometrySrcType:
539 this->releaseReservedIndexSpace();
540 break;
541 case kBuffer_GeometrySrcType:
542 geoSrc.fIndexBuffer->unref();
543#if GR_DEBUG
544 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
545#endif
546 break;
547 default:
548 GrCrash("Unknown Index Source Type.");
549 break;
550 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000551}
552
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000553void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
554 const void* vertexArray,
555 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000556 this->releasePreviousVertexSource();
557 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
558 geoSrc.fVertexSrc = kArray_GeometrySrcType;
559 geoSrc.fVertexLayout = vertexLayout;
560 geoSrc.fVertexCount = vertexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000561 this->onSetVertexSourceToArray(vertexArray, vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000562}
563
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000564void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
565 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000566 this->releasePreviousIndexSource();
567 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
568 geoSrc.fIndexSrc = kArray_GeometrySrcType;
569 geoSrc.fIndexCount = indexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000570 this->onSetIndexSourceToArray(indexArray, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000571}
572
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000573void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
574 const GrVertexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000575 this->releasePreviousVertexSource();
576 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
577 geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
578 geoSrc.fVertexBuffer = buffer;
579 buffer->ref();
580 geoSrc.fVertexLayout = vertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +0000581}
582
583void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000584 this->releasePreviousIndexSource();
585 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
586 geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
587 geoSrc.fIndexBuffer = buffer;
588 buffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000589}
590
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000591void GrDrawTarget::resetVertexSource() {
592 this->releasePreviousVertexSource();
593 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
594 geoSrc.fVertexSrc = kNone_GeometrySrcType;
595}
596
597void GrDrawTarget::resetIndexSource() {
598 this->releasePreviousIndexSource();
599 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
600 geoSrc.fIndexSrc = kNone_GeometrySrcType;
601}
602
603void GrDrawTarget::pushGeometrySource() {
604 this->geometrySourceWillPush();
605 GeometrySrcState& newState = fGeoSrcStateStack.push_back();
606 newState.fIndexSrc = kNone_GeometrySrcType;
607 newState.fVertexSrc = kNone_GeometrySrcType;
608#if GR_DEBUG
609 newState.fVertexCount = ~0;
610 newState.fVertexBuffer = (GrVertexBuffer*)~0;
611 newState.fIndexCount = ~0;
612 newState.fIndexBuffer = (GrIndexBuffer*)~0;
613#endif
614}
615
616void GrDrawTarget::popGeometrySource() {
617 const GeometrySrcState& geoSrc = this->getGeomSrc();
618 // if popping last element then pops are unbalanced with pushes
619 GrAssert(fGeoSrcStateStack.count() > 1);
620
621 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
622 this->releasePreviousVertexSource();
623 this->releasePreviousIndexSource();
624 fGeoSrcStateStack.pop_back();
625}
626
627////////////////////////////////////////////////////////////////////////////////
628
629void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
630 int startIndex, int vertexCount,
631 int indexCount) {
632#if GR_DEBUG
633 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
634 int maxVertex = startVertex + vertexCount;
635 int maxValidVertex;
636 switch (geoSrc.fVertexSrc) {
637 case kNone_GeometrySrcType:
638 GrCrash("Attempting to draw indexed geom without vertex src.");
639 case kReserved_GeometrySrcType: // fallthrough
640 case kArray_GeometrySrcType:
641 maxValidVertex = geoSrc.fVertexCount;
642 break;
643 case kBuffer_GeometrySrcType:
644 maxValidVertex = geoSrc.fVertexBuffer->size() /
645 VertexSize(geoSrc.fVertexLayout);
646 break;
647 }
648 if (maxVertex > maxValidVertex) {
649 GrCrash("Indexed drawing outside valid vertex range.");
650 }
651 int maxIndex = startIndex + indexCount;
652 int maxValidIndex;
653 switch (geoSrc.fIndexSrc) {
654 case kNone_GeometrySrcType:
655 GrCrash("Attempting to draw indexed geom without index src.");
656 case kReserved_GeometrySrcType: // fallthrough
657 case kArray_GeometrySrcType:
658 maxValidIndex = geoSrc.fIndexCount;
659 break;
660 case kBuffer_GeometrySrcType:
661 maxValidIndex = geoSrc.fIndexBuffer->size() / sizeof(uint16_t);
662 break;
663 }
664 if (maxIndex > maxValidIndex) {
665 GrCrash("Indexed drawing outside valid index range.");
666 }
667#endif
668 this->onDrawIndexed(type, startVertex, startIndex,
669 vertexCount, indexCount);
670}
671
672
673void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
674 int startVertex,
675 int vertexCount) {
676#if GR_DEBUG
677 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
678 int maxVertex = startVertex + vertexCount;
679 int maxValidVertex;
680 switch (geoSrc.fVertexSrc) {
681 case kNone_GeometrySrcType:
682 GrCrash("Attempting to draw non-indexed geom without vertex src.");
683 case kReserved_GeometrySrcType: // fallthrough
684 case kArray_GeometrySrcType:
685 maxValidVertex = geoSrc.fVertexCount;
686 break;
687 case kBuffer_GeometrySrcType:
688 maxValidVertex = geoSrc.fVertexBuffer->size() /
689 VertexSize(geoSrc.fVertexLayout);
690 break;
691 }
692 if (maxVertex > maxValidVertex) {
693 GrCrash("Non-indexed drawing outside valid vertex range.");
694 }
695#endif
696 this->onDrawNonIndexed(type, startVertex, vertexCount);
697}
698
699////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000700
701bool GrDrawTarget::canDisableBlend() const {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000702 // If we compute a coverage value (using edge AA or a coverage stage) then
703 // we can't force blending off.
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000704 if (fCurrDrawState.fEdgeAANumEdges > 0) {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000705 return false;
706 }
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000707 for (int s = fCurrDrawState.fFirstCoverageStage; s < kNumStages; ++s) {
708 if (this->isStageEnabled(s)) {
709 return false;
710 }
711 }
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000712
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000713 if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) &&
714 (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) {
715 return true;
716 }
717
718 // If we have vertex color without alpha then we can't force blend off
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000719 if ((this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000720 0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
721 return false;
722 }
723
724 // If the src coef will always be 1...
725 if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend &&
726 kOne_BlendCoeff != fCurrDrawState.fSrcBlend) {
727 return false;
728 }
729
730 // ...and the dst coef is always 0...
731 if (kISA_BlendCoeff != fCurrDrawState.fDstBlend &&
732 kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
733 return false;
734 }
735
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000736 // ...and there isn't a texture stage with an alpha channel...
737 for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) {
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000738 if (this->isStageEnabled(s)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000739 GrAssert(NULL != fCurrDrawState.fTextures[s]);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000740
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000741 GrPixelConfig config = fCurrDrawState.fTextures[s]->config();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000742
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000743 if (!GrPixelConfigIsOpaque(config)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000744 return false;
745 }
746 }
747 }
748
Scroggo0bad6732011-05-11 20:25:01 +0000749 // ...and there isn't an interesting color filter...
750 // TODO: Consider being more aggressive with regards to disabling
751 // blending when a color filter is used.
752 if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) {
753 return false;
754 }
755
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000756 // ...then we disable blend.
757 return true;
758}
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000759
760///////////////////////////////////////////////////////////////////////////////
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000761void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
762 GrAssert(numEdges <= kMaxEdges);
763 memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge));
764 fCurrDrawState.fEdgeAANumEdges = numEdges;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000765}
766
767
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000768////////////////////////////////////////////////////////////////////////////////
769
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000770void GrDrawTarget::drawRect(const GrRect& rect,
771 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000772 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000773 const GrRect* srcRects[],
774 const GrMatrix* srcMatrices[]) {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000775 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000776
777 AutoReleaseGeometry geo(this, layout, 4, 0);
778
779 SetRectVertices(rect, matrix, srcRects,
780 srcMatrices, layout, geo.vertices());
781
782 drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
783}
784
bsalomon@google.comffca4002011-02-22 20:34:01 +0000785GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000786 const GrRect* srcRects[]) {
787 GrVertexLayout layout = 0;
788
789 for (int i = 0; i < kNumStages; ++i) {
790 int numTC = 0;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000791 if (stageEnableBitfield & (1 << i)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000792 if (NULL != srcRects && NULL != srcRects[i]) {
793 layout |= StageTexCoordVertexLayoutBit(i, numTC);
794 ++numTC;
795 } else {
796 layout |= StagePosAsTexCoordVertexLayoutBit(i);
797 }
798 }
799 }
800 return layout;
801}
802void GrDrawTarget::SetRectVertices(const GrRect& rect,
803 const GrMatrix* matrix,
804 const GrRect* srcRects[],
805 const GrMatrix* srcMatrices[],
806 GrVertexLayout layout,
807 void* vertices) {
808#if GR_DEBUG
809 // check that the layout and srcRects agree
810 for (int i = 0; i < kNumStages; ++i) {
811 if (VertexTexCoordsForStage(i, layout) >= 0) {
812 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
813 } else {
814 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
815 }
816 }
817#endif
818
819 int stageOffsets[kNumStages];
820 int colorOffset;
821 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset);
822 GrAssert(-1 == colorOffset);
823
824 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
825 rect.fRight, rect.fBottom,
826 vsize);
827 if (NULL != matrix) {
828 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
829 }
830
831 for (int i = 0; i < kNumStages; ++i) {
832 if (stageOffsets[i] > 0) {
833 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
834 stageOffsets[i]);
835 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
836 srcRects[i]->fRight, srcRects[i]->fBottom,
837 vsize);
838 if (NULL != srcMatrices && NULL != srcMatrices[i]) {
839 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
840 }
841 }
842 }
843}
844
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000845////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000846
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000847GrDrawTarget::AutoStateRestore::AutoStateRestore() {
848 fDrawTarget = NULL;
849}
reed@google.comac10a2d2010-12-22 21:39:39 +0000850
851GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
852 fDrawTarget = target;
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000853 if (NULL != fDrawTarget) {
854 fDrawTarget->saveCurrentDrawState(&fDrawState);
855 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000856}
857
858GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000859 if (NULL != fDrawTarget) {
860 fDrawTarget->restoreDrawState(fDrawState);
861 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000862}
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000863
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000864void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
865 if (target != fDrawTarget) {
866 if (NULL != fDrawTarget) {
867 fDrawTarget->restoreDrawState(fDrawState);
868 }
869 if (NULL != target) {
870 fDrawTarget->saveCurrentDrawState(&fDrawState);
871 }
872 fDrawTarget = target;
873 }
874}
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000875
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000876////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000877
878GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
879 int stageMask) {
880 GrAssert(NULL != target);
881
882 fDrawTarget = target;
883 fViewMatrix = target->getViewMatrix();
884 fStageMask = stageMask;
885 if (fStageMask) {
886 GrMatrix invVM;
887 if (fViewMatrix.invert(&invVM)) {
888 for (int s = 0; s < kNumStages; ++s) {
889 if (fStageMask & (1 << s)) {
890 fSamplerMatrices[s] = target->getSamplerMatrix(s);
891 }
892 }
893 target->preConcatSamplerMatrices(fStageMask, invVM);
894 } else {
895 // sad trombone sound
896 fStageMask = 0;
897 }
898 }
899 target->setViewMatrix(GrMatrix::I());
900}
901
902GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
903 fDrawTarget->setViewMatrix(fViewMatrix);
904 for (int s = 0; s < kNumStages; ++s) {
905 if (fStageMask & (1 << s)) {
906 fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]);
907 }
908 }
909}
910
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000911////////////////////////////////////////////////////////////////////////////////
912
913GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
914 GrDrawTarget* target,
915 GrVertexLayout vertexLayout,
916 int vertexCount,
917 int indexCount) {
918 fTarget = NULL;
919 this->set(target, vertexLayout, vertexCount, indexCount);
920}
921
922GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
923 fTarget = NULL;
924}
925
926GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
927 this->reset();
928}
929
930bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
931 GrVertexLayout vertexLayout,
932 int vertexCount,
933 int indexCount) {
934 this->reset();
935 fTarget = target;
936 bool success = true;
937 if (NULL != fTarget) {
938 fTarget = target;
939 if (vertexCount > 0) {
940 success = target->reserveVertexSpace(vertexLayout,
941 vertexCount,
942 &fVertices);
943 if (!success) {
944 this->reset();
945 }
946 }
947 if (success && indexCount > 0) {
948 success = target->reserveIndexSpace(indexCount, &fIndices);
949 if (!success) {
950 this->reset();
951 }
952 }
953 }
954 GrAssert(success == (NULL != fTarget));
955 return success;
956}
957
958void GrDrawTarget::AutoReleaseGeometry::reset() {
959 if (NULL != fTarget) {
960 if (NULL != fVertices) {
961 fTarget->resetVertexSource();
962 }
963 if (NULL != fIndices) {
964 fTarget->resetIndexSource();
965 }
966 fTarget = NULL;
967 }
968}
969