blob: bfcc07de80d00a2f9d6e5d4fd147f62de287fe37 [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
bsalomon@google.comaeb21602011-08-30 18:13:44 +000066int num_tex_coords(GrVertexLayout layout) {
67 int cnt = 0;
68 // figure out how many tex coordinates are present
69 for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
70 if (tex_coord_idx_mask(t) & layout) {
71 ++cnt;
72 }
73 }
74 return cnt;
75}
76
junov@google.com6acc9b32011-05-16 18:32:07 +000077} //unnamed namespace
78
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000079size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
80 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +000081
82 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000083 sizeof(GrGpuTextVertex) :
84 sizeof(GrPoint);
85
86 size_t size = vecSize; // position
bsalomon@google.comaeb21602011-08-30 18:13:44 +000087 size += num_tex_coords(vertexLayout) * vecSize;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000088 if (vertexLayout & kColor_VertexLayoutBit) {
89 size += sizeof(GrColor);
90 }
bsalomon@google.comaeb21602011-08-30 18:13:44 +000091 if (vertexLayout & kEdge_VertexLayoutBit) {
92 size += 4 * sizeof(GrScalar);
93 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +000094 return size;
95}
96
97int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
98 GrAssert(check_layout(vertexLayout));
99 if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000100 return 0;
101 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000102 int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
103 if (tcIdx >= 0) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000104
105 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000106 sizeof(GrGpuTextVertex) :
107 sizeof(GrPoint);
108 int offset = vecSize; // position
109 // figure out how many tex coordinates are present and precede this one.
110 for (int t = 0; t < tcIdx; ++t) {
111 if (tex_coord_idx_mask(t) & vertexLayout) {
112 offset += vecSize;
113 }
114 }
115 return offset;
116 }
117
reed@google.comac10a2d2010-12-22 21:39:39 +0000118 return -1;
119}
120
121int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000122 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000123
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000124 // color is after the pos and tex coords
reed@google.comac10a2d2010-12-22 21:39:39 +0000125 if (vertexLayout & kColor_VertexLayoutBit) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000126 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000127 sizeof(GrGpuTextVertex) :
128 sizeof(GrPoint);
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000129 return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
130 }
131 return -1;
132}
133
134int GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) {
135 GrAssert(check_layout(vertexLayout));
136
137 // edge pts are after the pos, tex coords, and color
138 if (vertexLayout & kEdge_VertexLayoutBit) {
139 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
140 sizeof(GrGpuTextVertex) :
141 sizeof(GrPoint);
142 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
143 if (vertexLayout & kColor_VertexLayoutBit) {
144 offset += sizeof(GrColor);
reed@google.comac10a2d2010-12-22 21:39:39 +0000145 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000146 return offset;
reed@google.comac10a2d2010-12-22 21:39:39 +0000147 }
148 return -1;
149}
150
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000151int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
152 int texCoordOffsetsByIdx[kMaxTexCoords],
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000153 int* colorOffset,
154 int* edgeOffset) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000155 GrAssert(check_layout(vertexLayout));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000156
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000157 GrAssert(NULL != texCoordOffsetsByIdx);
reed@google.comac10a2d2010-12-22 21:39:39 +0000158 GrAssert(NULL != colorOffset);
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000159 GrAssert(NULL != edgeOffset);
reed@google.comac10a2d2010-12-22 21:39:39 +0000160
bsalomon@google.com5782d712011-01-21 21:03:59 +0000161 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000162 sizeof(GrGpuTextVertex) :
163 sizeof(GrPoint);
164 int size = vecSize; // position
bsalomon@google.com5782d712011-01-21 21:03:59 +0000165
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000166 for (int t = 0; t < kMaxTexCoords; ++t) {
167 if (tex_coord_idx_mask(t) & vertexLayout) {
168 texCoordOffsetsByIdx[t] = size;
169 size += vecSize;
reed@google.comac10a2d2010-12-22 21:39:39 +0000170 } else {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000171 texCoordOffsetsByIdx[t] = -1;
reed@google.comac10a2d2010-12-22 21:39:39 +0000172 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000173 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000174 if (kColor_VertexLayoutBit & vertexLayout) {
175 *colorOffset = size;
176 size += sizeof(GrColor);
177 } else {
178 *colorOffset = -1;
179 }
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000180 if (kEdge_VertexLayoutBit & vertexLayout) {
181 *edgeOffset = size;
182 size += 4 * sizeof(GrScalar);
183 } else {
184 *edgeOffset = -1;
185 }
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000186 return size;
reed@google.comac10a2d2010-12-22 21:39:39 +0000187}
188
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000189int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
190 int texCoordOffsetsByStage[kNumStages],
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000191 int* colorOffset,
192 int* edgeOffset) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000193 GrAssert(check_layout(vertexLayout));
194
195 GrAssert(NULL != texCoordOffsetsByStage);
196 GrAssert(NULL != colorOffset);
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000197 GrAssert(NULL != edgeOffset);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000198
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000199 int texCoordOffsetsByIdx[kMaxTexCoords];
bsalomon@google.com5782d712011-01-21 21:03:59 +0000200 int size = VertexSizeAndOffsetsByIdx(vertexLayout,
201 texCoordOffsetsByIdx,
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000202 colorOffset,
203 edgeOffset);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000204 for (int s = 0; s < kNumStages; ++s) {
205 int tcIdx;
206 if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
207 texCoordOffsetsByStage[s] = 0;
208 } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
209 texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
210 } else {
211 texCoordOffsetsByStage[s] = -1;
212 }
213 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000214 return size;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000215}
216
217bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
218 GrAssert(stage < kNumStages);
219 GrAssert(check_layout(vertexLayout));
220 return !!(stage_mask(stage) & vertexLayout);
221}
222
bsalomon@google.com5782d712011-01-21 21:03:59 +0000223bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000224 GrVertexLayout vertexLayout) {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000225 GrAssert(coordIndex < kMaxTexCoords);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000226 GrAssert(check_layout(vertexLayout));
227 return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
228}
229
230int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
231 GrAssert(stage < kNumStages);
232 GrAssert(check_layout(vertexLayout));
233 int bit = vertexLayout & stage_tex_coord_mask(stage);
234 if (bit) {
235 // figure out which set of texture coordates is used
236 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
237 // and start at bit 0.
238 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
239 return (32 - Gr_clz(bit) - 1) / kNumStages;
240 }
241 return -1;
242}
243
244void GrDrawTarget::VertexLayoutUnitTest() {
245 // not necessarily exhaustive
246 static bool run;
247 if (!run) {
248 run = true;
249 for (int s = 0; s < kNumStages; ++s) {
250
251 GrAssert(!VertexUsesStage(s, 0));
252 GrAssert(-1 == VertexStageCoordOffset(s, 0));
253 GrVertexLayout stageMask = 0;
254 for (int t = 0; t < kMaxTexCoords; ++t) {
255 stageMask |= StageTexCoordVertexLayoutBit(s,t);
256 }
bsalomon@google.com5782d712011-01-21 21:03:59 +0000257 GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000258 GrAssert(stage_tex_coord_mask(s) == stageMask);
259 stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
260 GrAssert(stage_mask(s) == stageMask);
261 GrAssert(!check_layout(stageMask));
262 }
263 for (int t = 0; t < kMaxTexCoords; ++t) {
264 GrVertexLayout tcMask = 0;
265 GrAssert(!VertexUsesTexCoordIdx(t, 0));
266 for (int s = 0; s < kNumStages; ++s) {
267 tcMask |= StageTexCoordVertexLayoutBit(s,t);
268 GrAssert(VertexUsesStage(s, tcMask));
269 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
270 GrAssert(VertexUsesTexCoordIdx(t, tcMask));
271 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
272 GrAssert(t == VertexTexCoordsForStage(s, tcMask));
273 for (int s2 = s + 1; s2 < kNumStages; ++s2) {
274 GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
275 GrAssert(!VertexUsesStage(s2, tcMask));
276 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000277
bsalomon@google.com19628322011-02-03 21:30:17 +0000278 #if GR_DEBUG
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000279 GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
bsalomon@google.com19628322011-02-03 21:30:17 +0000280 #endif
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000281 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
282 GrAssert(VertexUsesStage(s2, posAsTex));
283 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
284 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000285 GrAssert(-1 == VertexEdgeOffset(posAsTex));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000286 }
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000287 GrAssert(-1 == VertexEdgeOffset(tcMask));
288 GrAssert(-1 == VertexColorOffset(tcMask));
bsalomon@google.com19628322011-02-03 21:30:17 +0000289 #if GR_DEBUG
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000290 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
bsalomon@google.com19628322011-02-03 21:30:17 +0000291 #endif
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000292 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
293 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000294 #if GR_DEBUG
295 GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
296 #endif
297 GrAssert(-1 == VertexColorOffset(withEdge));
298 GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
299 GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
300 #if GR_DEBUG
301 GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
302 #endif
303 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
304 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
305 GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000306 }
307 GrAssert(tex_coord_idx_mask(t) == tcMask);
308 GrAssert(check_layout(tcMask));
bsalomon@google.com5782d712011-01-21 21:03:59 +0000309
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000310 int stageOffsets[kNumStages];
311 int colorOffset;
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000312 int edgeOffset;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000313 int size;
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000314 size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset, &edgeOffset);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000315 GrAssert(2*sizeof(GrPoint) == size);
316 GrAssert(-1 == colorOffset);
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000317 GrAssert(-1 == edgeOffset);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000318 for (int s = 0; s < kNumStages; ++s) {
319 GrAssert(VertexUsesStage(s, tcMask));
320 GrAssert(sizeof(GrPoint) == stageOffsets[s]);
321 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
322 }
323 }
324 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000325}
326
327////////////////////////////////////////////////////////////////////////////////
328
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000329#define DEBUG_INVAL_BUFFER 0xdeadcafe
330#define DEBUG_INVAL_START_IDX -1
331
332GrDrawTarget::GrDrawTarget()
333: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000334#if GR_DEBUG
335 VertexLayoutUnitTest();
336#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000337 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000338#if GR_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000339 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
340 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
341 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
342 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
reed@google.comac10a2d2010-12-22 21:39:39 +0000343#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000344 geoSrc.fVertexSrc = kNone_GeometrySrcType;
345 geoSrc.fIndexSrc = kNone_GeometrySrcType;
346}
347
348GrDrawTarget::~GrDrawTarget() {
349 int popCnt = fGeoSrcStateStack.count() - 1;
350 while (popCnt) {
351 this->popGeometrySource();
352 --popCnt;
353 }
354 this->releasePreviousVertexSource();
355 this->releasePreviousIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000356}
357
358void GrDrawTarget::setClip(const GrClip& clip) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000359 clipWillBeSet(clip);
reed@google.comac10a2d2010-12-22 21:39:39 +0000360 fClip = clip;
361}
362
363const GrClip& GrDrawTarget::getClip() const {
364 return fClip;
365}
366
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000367void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
368 GrAssert(stage >= 0 && stage < kNumStages);
369 fCurrDrawState.fTextures[stage] = tex;
reed@google.comac10a2d2010-12-22 21:39:39 +0000370}
371
bsalomon@google.com5782d712011-01-21 21:03:59 +0000372const GrTexture* GrDrawTarget::getTexture(int stage) const {
373 GrAssert(stage >= 0 && stage < kNumStages);
374 return fCurrDrawState.fTextures[stage];
375}
376
377GrTexture* GrDrawTarget::getTexture(int stage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000378 GrAssert(stage >= 0 && stage < kNumStages);
379 return fCurrDrawState.fTextures[stage];
reed@google.comac10a2d2010-12-22 21:39:39 +0000380}
381
382void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
383 fCurrDrawState.fRenderTarget = target;
384}
385
bsalomon@google.com5782d712011-01-21 21:03:59 +0000386const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
387 return fCurrDrawState.fRenderTarget;
388}
389
390GrRenderTarget* GrDrawTarget::getRenderTarget() {
reed@google.comac10a2d2010-12-22 21:39:39 +0000391 return fCurrDrawState.fRenderTarget;
392}
393
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000394void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
395 fCurrDrawState.fViewMatrix = m;
reed@google.comac10a2d2010-12-22 21:39:39 +0000396}
397
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000398void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000399 fCurrDrawState.fViewMatrix.preConcat(matrix);
400}
401
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000402void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
403 fCurrDrawState.fViewMatrix.postConcat(matrix);
404}
405
bsalomon@google.com5782d712011-01-21 21:03:59 +0000406const GrMatrix& GrDrawTarget::getViewMatrix() const {
407 return fCurrDrawState.fViewMatrix;
reed@google.comac10a2d2010-12-22 21:39:39 +0000408}
409
410bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000411 // Mike: Can we cache this somewhere?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000412 // Brian: Sure, do we use it often?
reed@google.comac10a2d2010-12-22 21:39:39 +0000413
414 GrMatrix inverse;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000415 if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000416 if (matrix) {
417 *matrix = inverse;
418 }
419 return true;
420 }
421 return false;
422}
423
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000424void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
425 GrAssert(stage >= 0 && stage < kNumStages);
426 fCurrDrawState.fSamplerStates[stage] = state;
427}
428
reed@google.comac10a2d2010-12-22 21:39:39 +0000429void GrDrawTarget::enableState(uint32_t bits) {
430 fCurrDrawState.fFlagBits |= bits;
431}
432
433void GrDrawTarget::disableState(uint32_t bits) {
434 fCurrDrawState.fFlagBits &= ~(bits);
435}
436
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000437void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
438 GrBlendCoeff dstCoeff) {
439 fCurrDrawState.fSrcBlend = srcCoeff;
440 fCurrDrawState.fDstBlend = dstCoeff;
441#if GR_DEBUG
442 switch (dstCoeff) {
443 case kDC_BlendCoeff:
444 case kIDC_BlendCoeff:
445 case kDA_BlendCoeff:
446 case kIDA_BlendCoeff:
447 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
448 "coverage stages.\n");
449 break;
450 default:
451 break;
452 }
453 switch (srcCoeff) {
454 case kSC_BlendCoeff:
455 case kISC_BlendCoeff:
456 case kSA_BlendCoeff:
457 case kISA_BlendCoeff:
458 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
459 "coverage stages.\n");
460 break;
461 default:
462 break;
463 }
464#endif
reed@google.comac10a2d2010-12-22 21:39:39 +0000465}
466
467void GrDrawTarget::setColor(GrColor c) {
468 fCurrDrawState.fColor = c;
469}
470
Scroggo97c88c22011-05-11 14:05:25 +0000471void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
472 fCurrDrawState.fColorFilterColor = c;
473 fCurrDrawState.fColorFilterXfermode = mode;
474}
475
reed@google.comac10a2d2010-12-22 21:39:39 +0000476void GrDrawTarget::setAlpha(uint8_t a) {
477 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
478}
479
480void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
481 state->fState = fCurrDrawState;
482}
483
484void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
485 fCurrDrawState = state.fState;
486}
487
488void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
489 fCurrDrawState = srcTarget.fCurrDrawState;
490}
491
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000492bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
493 int vertexCount,
494 void** vertices) {
495 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
496 bool acquired = false;
497 if (vertexCount > 0) {
498 GrAssert(NULL != vertices);
499 this->releasePreviousVertexSource();
500 geoSrc.fVertexSrc = kNone_GeometrySrcType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000501
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000502 acquired = this->onReserveVertexSpace(vertexLayout,
503 vertexCount,
504 vertices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000505 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000506 if (acquired) {
507 geoSrc.fVertexSrc = kReserved_GeometrySrcType;
508 geoSrc.fVertexCount = vertexCount;
509 geoSrc.fVertexLayout = vertexLayout;
510 } else if (NULL != vertices) {
511 *vertices = NULL;
512 }
513 return acquired;
514}
515
516bool GrDrawTarget::reserveIndexSpace(int indexCount,
517 void** indices) {
518 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
519 bool acquired = false;
520 if (indexCount > 0) {
521 GrAssert(NULL != indices);
522 this->releasePreviousIndexSource();
523 geoSrc.fIndexSrc = kNone_GeometrySrcType;
524
525 acquired = this->onReserveIndexSpace(indexCount, indices);
526 }
527 if (acquired) {
528 geoSrc.fIndexSrc = kReserved_GeometrySrcType;
529 geoSrc.fIndexCount = indexCount;
530 } else if (NULL != indices) {
531 *indices = NULL;
532 }
533 return acquired;
534
reed@google.comac10a2d2010-12-22 21:39:39 +0000535}
536
537bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
538 int32_t* vertexCount,
539 int32_t* indexCount) const {
reed@google.comac10a2d2010-12-22 21:39:39 +0000540 if (NULL != vertexCount) {
541 *vertexCount = -1;
542 }
543 if (NULL != indexCount) {
544 *indexCount = -1;
545 }
546 return false;
547}
548
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000549void GrDrawTarget::releasePreviousVertexSource() {
550 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
551 switch (geoSrc.fVertexSrc) {
552 case kNone_GeometrySrcType:
553 break;
554 case kArray_GeometrySrcType:
555 this->releaseVertexArray();
556 break;
557 case kReserved_GeometrySrcType:
558 this->releaseReservedVertexSpace();
559 break;
560 case kBuffer_GeometrySrcType:
561 geoSrc.fVertexBuffer->unref();
562#if GR_DEBUG
563 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
564#endif
565 break;
566 default:
567 GrCrash("Unknown Vertex Source Type.");
568 break;
569 }
570}
571
572void GrDrawTarget::releasePreviousIndexSource() {
573 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
574 switch (geoSrc.fIndexSrc) {
575 case kNone_GeometrySrcType: // these two don't require
576 break;
577 case kArray_GeometrySrcType:
578 this->releaseIndexArray();
579 break;
580 case kReserved_GeometrySrcType:
581 this->releaseReservedIndexSpace();
582 break;
583 case kBuffer_GeometrySrcType:
584 geoSrc.fIndexBuffer->unref();
585#if GR_DEBUG
586 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
587#endif
588 break;
589 default:
590 GrCrash("Unknown Index Source Type.");
591 break;
592 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000593}
594
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000595void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
596 const void* vertexArray,
597 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000598 this->releasePreviousVertexSource();
599 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
600 geoSrc.fVertexSrc = kArray_GeometrySrcType;
601 geoSrc.fVertexLayout = vertexLayout;
602 geoSrc.fVertexCount = vertexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000603 this->onSetVertexSourceToArray(vertexArray, vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000604}
605
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000606void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
607 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000608 this->releasePreviousIndexSource();
609 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
610 geoSrc.fIndexSrc = kArray_GeometrySrcType;
611 geoSrc.fIndexCount = indexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000612 this->onSetIndexSourceToArray(indexArray, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000613}
614
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000615void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
616 const GrVertexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000617 this->releasePreviousVertexSource();
618 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
619 geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
620 geoSrc.fVertexBuffer = buffer;
621 buffer->ref();
622 geoSrc.fVertexLayout = vertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +0000623}
624
625void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000626 this->releasePreviousIndexSource();
627 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
628 geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
629 geoSrc.fIndexBuffer = buffer;
630 buffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000631}
632
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000633void GrDrawTarget::resetVertexSource() {
634 this->releasePreviousVertexSource();
635 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
636 geoSrc.fVertexSrc = kNone_GeometrySrcType;
637}
638
639void GrDrawTarget::resetIndexSource() {
640 this->releasePreviousIndexSource();
641 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
642 geoSrc.fIndexSrc = kNone_GeometrySrcType;
643}
644
645void GrDrawTarget::pushGeometrySource() {
646 this->geometrySourceWillPush();
647 GeometrySrcState& newState = fGeoSrcStateStack.push_back();
648 newState.fIndexSrc = kNone_GeometrySrcType;
649 newState.fVertexSrc = kNone_GeometrySrcType;
650#if GR_DEBUG
651 newState.fVertexCount = ~0;
652 newState.fVertexBuffer = (GrVertexBuffer*)~0;
653 newState.fIndexCount = ~0;
654 newState.fIndexBuffer = (GrIndexBuffer*)~0;
655#endif
656}
657
658void GrDrawTarget::popGeometrySource() {
659 const GeometrySrcState& geoSrc = this->getGeomSrc();
660 // if popping last element then pops are unbalanced with pushes
661 GrAssert(fGeoSrcStateStack.count() > 1);
662
663 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
664 this->releasePreviousVertexSource();
665 this->releasePreviousIndexSource();
666 fGeoSrcStateStack.pop_back();
667}
668
669////////////////////////////////////////////////////////////////////////////////
670
671void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
672 int startIndex, int vertexCount,
673 int indexCount) {
674#if GR_DEBUG
675 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
676 int maxVertex = startVertex + vertexCount;
677 int maxValidVertex;
678 switch (geoSrc.fVertexSrc) {
679 case kNone_GeometrySrcType:
680 GrCrash("Attempting to draw indexed geom without vertex src.");
681 case kReserved_GeometrySrcType: // fallthrough
682 case kArray_GeometrySrcType:
683 maxValidVertex = geoSrc.fVertexCount;
684 break;
685 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000686 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000687 VertexSize(geoSrc.fVertexLayout);
688 break;
689 }
690 if (maxVertex > maxValidVertex) {
691 GrCrash("Indexed drawing outside valid vertex range.");
692 }
693 int maxIndex = startIndex + indexCount;
694 int maxValidIndex;
695 switch (geoSrc.fIndexSrc) {
696 case kNone_GeometrySrcType:
697 GrCrash("Attempting to draw indexed geom without index src.");
698 case kReserved_GeometrySrcType: // fallthrough
699 case kArray_GeometrySrcType:
700 maxValidIndex = geoSrc.fIndexCount;
701 break;
702 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000703 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000704 break;
705 }
706 if (maxIndex > maxValidIndex) {
707 GrCrash("Indexed drawing outside valid index range.");
708 }
709#endif
bsalomon@google.com82145872011-08-23 14:32:40 +0000710 if (indexCount > 0) {
711 this->onDrawIndexed(type, startVertex, startIndex,
712 vertexCount, indexCount);
713 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000714}
715
716
717void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
718 int startVertex,
719 int vertexCount) {
720#if GR_DEBUG
721 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
722 int maxVertex = startVertex + vertexCount;
723 int maxValidVertex;
724 switch (geoSrc.fVertexSrc) {
725 case kNone_GeometrySrcType:
726 GrCrash("Attempting to draw non-indexed geom without vertex src.");
727 case kReserved_GeometrySrcType: // fallthrough
728 case kArray_GeometrySrcType:
729 maxValidVertex = geoSrc.fVertexCount;
730 break;
731 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000732 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000733 VertexSize(geoSrc.fVertexLayout);
734 break;
735 }
736 if (maxVertex > maxValidVertex) {
737 GrCrash("Non-indexed drawing outside valid vertex range.");
738 }
739#endif
bsalomon@google.com82145872011-08-23 14:32:40 +0000740 if (vertexCount > 0) {
741 this->onDrawNonIndexed(type, startVertex, vertexCount);
742 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000743}
744
745////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000746
bsalomon@google.com471d4712011-08-23 15:45:25 +0000747bool GrDrawTarget::CanDisableBlend(GrVertexLayout layout, const DrState& state) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000748 // If we compute a coverage value (using edge AA or a coverage stage) then
749 // we can't force blending off.
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000750 if (state.fEdgeAANumEdges > 0 ||
751 layout & kEdge_VertexLayoutBit) {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000752 return false;
753 }
bsalomon@google.com471d4712011-08-23 15:45:25 +0000754 for (int s = state.fFirstCoverageStage; s < kNumStages; ++s) {
755 if (StageWillBeUsed(s, layout, state)) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000756 return false;
757 }
758 }
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000759
bsalomon@google.com471d4712011-08-23 15:45:25 +0000760 if ((kOne_BlendCoeff == state.fSrcBlend) &&
761 (kZero_BlendCoeff == state.fDstBlend)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000762 return true;
763 }
764
765 // If we have vertex color without alpha then we can't force blend off
bsalomon@google.com471d4712011-08-23 15:45:25 +0000766 if ((layout & kColor_VertexLayoutBit) ||
767 0xff != GrColorUnpackA(state.fColor)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000768 return false;
769 }
770
771 // If the src coef will always be 1...
bsalomon@google.com471d4712011-08-23 15:45:25 +0000772 if (kSA_BlendCoeff != state.fSrcBlend &&
773 kOne_BlendCoeff != state.fSrcBlend) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000774 return false;
775 }
776
777 // ...and the dst coef is always 0...
bsalomon@google.com471d4712011-08-23 15:45:25 +0000778 if (kISA_BlendCoeff != state.fDstBlend &&
779 kZero_BlendCoeff != state.fDstBlend) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000780 return false;
781 }
782
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000783 // ...and there isn't a texture stage with an alpha channel...
bsalomon@google.com471d4712011-08-23 15:45:25 +0000784 for (int s = 0; s < state.fFirstCoverageStage; ++s) {
785 if (StageWillBeUsed(s, layout, state)) {
786 GrAssert(NULL != state.fTextures[s]);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000787
bsalomon@google.com471d4712011-08-23 15:45:25 +0000788 GrPixelConfig config = state.fTextures[s]->config();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000789
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000790 if (!GrPixelConfigIsOpaque(config)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000791 return false;
792 }
793 }
794 }
795
Scroggo0bad6732011-05-11 20:25:01 +0000796 // ...and there isn't an interesting color filter...
797 // TODO: Consider being more aggressive with regards to disabling
798 // blending when a color filter is used.
bsalomon@google.com471d4712011-08-23 15:45:25 +0000799 if (SkXfermode::kDst_Mode != state.fColorFilterXfermode) {
Scroggo0bad6732011-05-11 20:25:01 +0000800 return false;
801 }
802
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000803 // ...then we disable blend.
804 return true;
805}
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000806
bsalomon@google.com471d4712011-08-23 15:45:25 +0000807bool GrDrawTarget::CanUseHWAALines(GrVertexLayout layout, const DrState& state) {
808 // there is a conflict between using smooth lines and our use of
809 // premultiplied alpha. Smooth lines tweak the incoming alpha value
810 // but not in a premul-alpha way. So we only use them when our alpha
811 // is 0xff.
812 return (kAntialias_StateBit & state.fFlagBits) &&
813 CanDisableBlend(layout, state);
814}
815
816bool GrDrawTarget::canDisableBlend() const {
817 return CanDisableBlend(this->getGeomSrc().fVertexLayout, fCurrDrawState);
818}
819
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000820///////////////////////////////////////////////////////////////////////////////
bsalomon@google.com471d4712011-08-23 15:45:25 +0000821
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000822void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
823 GrAssert(numEdges <= kMaxEdges);
824 memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge));
825 fCurrDrawState.fEdgeAANumEdges = numEdges;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000826}
827
828
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000829////////////////////////////////////////////////////////////////////////////////
830
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000831void GrDrawTarget::drawRect(const GrRect& rect,
832 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000833 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000834 const GrRect* srcRects[],
835 const GrMatrix* srcMatrices[]) {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000836 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000837
838 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000839 if (!geo.succeeded()) {
840 GrPrintf("Failed to get space for vertices!\n");
841 return;
842 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000843
844 SetRectVertices(rect, matrix, srcRects,
845 srcMatrices, layout, geo.vertices());
846
847 drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
848}
849
bsalomon@google.comffca4002011-02-22 20:34:01 +0000850GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000851 const GrRect* srcRects[]) {
852 GrVertexLayout layout = 0;
853
854 for (int i = 0; i < kNumStages; ++i) {
855 int numTC = 0;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000856 if (stageEnableBitfield & (1 << i)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000857 if (NULL != srcRects && NULL != srcRects[i]) {
858 layout |= StageTexCoordVertexLayoutBit(i, numTC);
859 ++numTC;
860 } else {
861 layout |= StagePosAsTexCoordVertexLayoutBit(i);
862 }
863 }
864 }
865 return layout;
866}
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000867
868void GrDrawTarget::clipWillBeSet(const GrClip& clip) {
869}
870
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000871void GrDrawTarget::SetRectVertices(const GrRect& rect,
872 const GrMatrix* matrix,
873 const GrRect* srcRects[],
874 const GrMatrix* srcMatrices[],
875 GrVertexLayout layout,
876 void* vertices) {
877#if GR_DEBUG
878 // check that the layout and srcRects agree
879 for (int i = 0; i < kNumStages; ++i) {
880 if (VertexTexCoordsForStage(i, layout) >= 0) {
881 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
882 } else {
883 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
884 }
885 }
886#endif
887
888 int stageOffsets[kNumStages];
889 int colorOffset;
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000890 int edgeOffset;
891 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets,
892 &colorOffset, &edgeOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000893 GrAssert(-1 == colorOffset);
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000894 GrAssert(-1 == edgeOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000895
896 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
897 rect.fRight, rect.fBottom,
898 vsize);
899 if (NULL != matrix) {
900 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
901 }
902
903 for (int i = 0; i < kNumStages; ++i) {
904 if (stageOffsets[i] > 0) {
905 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
906 stageOffsets[i]);
907 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
908 srcRects[i]->fRight, srcRects[i]->fBottom,
909 vsize);
910 if (NULL != srcMatrices && NULL != srcMatrices[i]) {
911 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
912 }
913 }
914 }
915}
916
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000917////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000918
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000919GrDrawTarget::AutoStateRestore::AutoStateRestore() {
920 fDrawTarget = NULL;
921}
reed@google.comac10a2d2010-12-22 21:39:39 +0000922
923GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
924 fDrawTarget = target;
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000925 if (NULL != fDrawTarget) {
926 fDrawTarget->saveCurrentDrawState(&fDrawState);
927 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000928}
929
930GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000931 if (NULL != fDrawTarget) {
932 fDrawTarget->restoreDrawState(fDrawState);
933 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000934}
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000935
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000936void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
937 if (target != fDrawTarget) {
938 if (NULL != fDrawTarget) {
939 fDrawTarget->restoreDrawState(fDrawState);
940 }
941 if (NULL != target) {
bsalomon@google.comd19aa272011-06-22 01:28:17 +0000942 target->saveCurrentDrawState(&fDrawState);
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000943 }
944 fDrawTarget = target;
945 }
946}
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000947
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000948////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000949
950GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
951 int stageMask) {
952 GrAssert(NULL != target);
953
954 fDrawTarget = target;
955 fViewMatrix = target->getViewMatrix();
956 fStageMask = stageMask;
957 if (fStageMask) {
958 GrMatrix invVM;
959 if (fViewMatrix.invert(&invVM)) {
960 for (int s = 0; s < kNumStages; ++s) {
961 if (fStageMask & (1 << s)) {
962 fSamplerMatrices[s] = target->getSamplerMatrix(s);
963 }
964 }
965 target->preConcatSamplerMatrices(fStageMask, invVM);
966 } else {
967 // sad trombone sound
968 fStageMask = 0;
969 }
970 }
971 target->setViewMatrix(GrMatrix::I());
972}
973
974GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
975 fDrawTarget->setViewMatrix(fViewMatrix);
976 for (int s = 0; s < kNumStages; ++s) {
977 if (fStageMask & (1 << s)) {
978 fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]);
979 }
980 }
981}
982
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000983////////////////////////////////////////////////////////////////////////////////
984
985GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
986 GrDrawTarget* target,
987 GrVertexLayout vertexLayout,
988 int vertexCount,
989 int indexCount) {
990 fTarget = NULL;
991 this->set(target, vertexLayout, vertexCount, indexCount);
992}
993
994GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
995 fTarget = NULL;
996}
997
998GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
999 this->reset();
1000}
1001
1002bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
1003 GrVertexLayout vertexLayout,
1004 int vertexCount,
1005 int indexCount) {
1006 this->reset();
1007 fTarget = target;
1008 bool success = true;
1009 if (NULL != fTarget) {
1010 fTarget = target;
1011 if (vertexCount > 0) {
1012 success = target->reserveVertexSpace(vertexLayout,
1013 vertexCount,
1014 &fVertices);
1015 if (!success) {
1016 this->reset();
1017 }
1018 }
1019 if (success && indexCount > 0) {
1020 success = target->reserveIndexSpace(indexCount, &fIndices);
1021 if (!success) {
1022 this->reset();
1023 }
1024 }
1025 }
1026 GrAssert(success == (NULL != fTarget));
1027 return success;
1028}
1029
1030void GrDrawTarget::AutoReleaseGeometry::reset() {
1031 if (NULL != fTarget) {
1032 if (NULL != fVertices) {
1033 fTarget->resetVertexSource();
1034 }
1035 if (NULL != fIndices) {
1036 fTarget->resetIndexSource();
1037 }
1038 fTarget = NULL;
1039 }
bsalomon@google.comcb0c5ab2011-06-29 17:48:17 +00001040 fVertices = NULL;
1041 fIndices = NULL;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001042}
1043
bsalomon@google.com18c9c192011-09-22 21:01:31 +00001044void GrDrawTarget::Caps::print() const {
1045 static const char* gNY[] = {"NO", "YES"};
1046 GrPrintf("8 Bit Palette Support : %s\n", gNY[f8BitPaletteSupport]);
1047 GrPrintf("NPOT Texture Support : %s\n", gNY[fNPOTTextureSupport]);
1048 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
1049 GrPrintf("NPOT Render Target Support : %s\n", gNY[fNPOTRenderTargetSupport]);
1050 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
1051 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
1052 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
1053 GrPrintf("Shader Support : %s\n", gNY[fShaderSupport]);
1054 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
1055 GrPrintf("FSAA Support : %s\n", gNY[fFSAASupport]);
1056 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
1057 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]);
1058 GrPrintf("Min Render Target Width : %d\n", fMinRenderTargetWidth);
1059 GrPrintf("Min Render Target Height : %d\n", fMinRenderTargetHeight);
1060 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize);
1061 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
1062}
1063