blob: 51e6fdd037f4922b2bbedfbb09bf02549a0eac7a [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
bsalomon@google.com92669012011-09-27 19:10:05 +0000332GrDrawTarget::GrDrawTarget() {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000333#if GR_DEBUG
334 VertexLayoutUnitTest();
335#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000336 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000337#if GR_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000338 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
339 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
340 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
341 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
reed@google.comac10a2d2010-12-22 21:39:39 +0000342#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000343 geoSrc.fVertexSrc = kNone_GeometrySrcType;
344 geoSrc.fIndexSrc = kNone_GeometrySrcType;
345}
346
347GrDrawTarget::~GrDrawTarget() {
348 int popCnt = fGeoSrcStateStack.count() - 1;
349 while (popCnt) {
350 this->popGeometrySource();
351 --popCnt;
352 }
353 this->releasePreviousVertexSource();
354 this->releasePreviousIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000355}
356
357void GrDrawTarget::setClip(const GrClip& clip) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000358 clipWillBeSet(clip);
reed@google.comac10a2d2010-12-22 21:39:39 +0000359 fClip = clip;
360}
361
362const GrClip& GrDrawTarget::getClip() const {
363 return fClip;
364}
365
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000366void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
367 GrAssert(stage >= 0 && stage < kNumStages);
368 fCurrDrawState.fTextures[stage] = tex;
reed@google.comac10a2d2010-12-22 21:39:39 +0000369}
370
bsalomon@google.com5782d712011-01-21 21:03:59 +0000371const GrTexture* GrDrawTarget::getTexture(int stage) const {
372 GrAssert(stage >= 0 && stage < kNumStages);
373 return fCurrDrawState.fTextures[stage];
374}
375
376GrTexture* GrDrawTarget::getTexture(int stage) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000377 GrAssert(stage >= 0 && stage < kNumStages);
378 return fCurrDrawState.fTextures[stage];
reed@google.comac10a2d2010-12-22 21:39:39 +0000379}
380
381void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
382 fCurrDrawState.fRenderTarget = target;
383}
384
bsalomon@google.com5782d712011-01-21 21:03:59 +0000385const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
386 return fCurrDrawState.fRenderTarget;
387}
388
389GrRenderTarget* GrDrawTarget::getRenderTarget() {
reed@google.comac10a2d2010-12-22 21:39:39 +0000390 return fCurrDrawState.fRenderTarget;
391}
392
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000393void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
394 fCurrDrawState.fViewMatrix = m;
reed@google.comac10a2d2010-12-22 21:39:39 +0000395}
396
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000397void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000398 fCurrDrawState.fViewMatrix.preConcat(matrix);
399}
400
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000401void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
402 fCurrDrawState.fViewMatrix.postConcat(matrix);
403}
404
bsalomon@google.com5782d712011-01-21 21:03:59 +0000405const GrMatrix& GrDrawTarget::getViewMatrix() const {
406 return fCurrDrawState.fViewMatrix;
reed@google.comac10a2d2010-12-22 21:39:39 +0000407}
408
409bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
bsalomon@google.com5782d712011-01-21 21:03:59 +0000410 // Mike: Can we cache this somewhere?
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000411 // Brian: Sure, do we use it often?
reed@google.comac10a2d2010-12-22 21:39:39 +0000412
413 GrMatrix inverse;
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000414 if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000415 if (matrix) {
416 *matrix = inverse;
417 }
418 return true;
419 }
420 return false;
421}
422
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000423void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
424 GrAssert(stage >= 0 && stage < kNumStages);
425 fCurrDrawState.fSamplerStates[stage] = state;
426}
427
reed@google.comac10a2d2010-12-22 21:39:39 +0000428void GrDrawTarget::enableState(uint32_t bits) {
429 fCurrDrawState.fFlagBits |= bits;
430}
431
432void GrDrawTarget::disableState(uint32_t bits) {
433 fCurrDrawState.fFlagBits &= ~(bits);
434}
435
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000436void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
437 GrBlendCoeff dstCoeff) {
438 fCurrDrawState.fSrcBlend = srcCoeff;
439 fCurrDrawState.fDstBlend = dstCoeff;
440#if GR_DEBUG
441 switch (dstCoeff) {
442 case kDC_BlendCoeff:
443 case kIDC_BlendCoeff:
444 case kDA_BlendCoeff:
445 case kIDA_BlendCoeff:
446 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
447 "coverage stages.\n");
448 break;
449 default:
450 break;
451 }
452 switch (srcCoeff) {
453 case kSC_BlendCoeff:
454 case kISC_BlendCoeff:
455 case kSA_BlendCoeff:
456 case kISA_BlendCoeff:
457 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
458 "coverage stages.\n");
459 break;
460 default:
461 break;
462 }
463#endif
reed@google.comac10a2d2010-12-22 21:39:39 +0000464}
465
466void GrDrawTarget::setColor(GrColor c) {
467 fCurrDrawState.fColor = c;
468}
469
Scroggo97c88c22011-05-11 14:05:25 +0000470void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
471 fCurrDrawState.fColorFilterColor = c;
472 fCurrDrawState.fColorFilterXfermode = mode;
473}
474
reed@google.comac10a2d2010-12-22 21:39:39 +0000475void GrDrawTarget::setAlpha(uint8_t a) {
476 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
477}
478
479void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
480 state->fState = fCurrDrawState;
481}
482
483void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
484 fCurrDrawState = state.fState;
485}
486
487void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
488 fCurrDrawState = srcTarget.fCurrDrawState;
489}
490
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000491bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
492 int vertexCount,
493 void** vertices) {
494 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
495 bool acquired = false;
496 if (vertexCount > 0) {
497 GrAssert(NULL != vertices);
498 this->releasePreviousVertexSource();
499 geoSrc.fVertexSrc = kNone_GeometrySrcType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000500
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000501 acquired = this->onReserveVertexSpace(vertexLayout,
502 vertexCount,
503 vertices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000504 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000505 if (acquired) {
506 geoSrc.fVertexSrc = kReserved_GeometrySrcType;
507 geoSrc.fVertexCount = vertexCount;
508 geoSrc.fVertexLayout = vertexLayout;
509 } else if (NULL != vertices) {
510 *vertices = NULL;
511 }
512 return acquired;
513}
514
515bool GrDrawTarget::reserveIndexSpace(int indexCount,
516 void** indices) {
517 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
518 bool acquired = false;
519 if (indexCount > 0) {
520 GrAssert(NULL != indices);
521 this->releasePreviousIndexSource();
522 geoSrc.fIndexSrc = kNone_GeometrySrcType;
523
524 acquired = this->onReserveIndexSpace(indexCount, indices);
525 }
526 if (acquired) {
527 geoSrc.fIndexSrc = kReserved_GeometrySrcType;
528 geoSrc.fIndexCount = indexCount;
529 } else if (NULL != indices) {
530 *indices = NULL;
531 }
532 return acquired;
533
reed@google.comac10a2d2010-12-22 21:39:39 +0000534}
535
536bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
537 int32_t* vertexCount,
538 int32_t* indexCount) const {
reed@google.comac10a2d2010-12-22 21:39:39 +0000539 if (NULL != vertexCount) {
540 *vertexCount = -1;
541 }
542 if (NULL != indexCount) {
543 *indexCount = -1;
544 }
545 return false;
546}
547
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000548void GrDrawTarget::releasePreviousVertexSource() {
549 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
550 switch (geoSrc.fVertexSrc) {
551 case kNone_GeometrySrcType:
552 break;
553 case kArray_GeometrySrcType:
554 this->releaseVertexArray();
555 break;
556 case kReserved_GeometrySrcType:
557 this->releaseReservedVertexSpace();
558 break;
559 case kBuffer_GeometrySrcType:
560 geoSrc.fVertexBuffer->unref();
561#if GR_DEBUG
562 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
563#endif
564 break;
565 default:
566 GrCrash("Unknown Vertex Source Type.");
567 break;
568 }
569}
570
571void GrDrawTarget::releasePreviousIndexSource() {
572 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
573 switch (geoSrc.fIndexSrc) {
574 case kNone_GeometrySrcType: // these two don't require
575 break;
576 case kArray_GeometrySrcType:
577 this->releaseIndexArray();
578 break;
579 case kReserved_GeometrySrcType:
580 this->releaseReservedIndexSpace();
581 break;
582 case kBuffer_GeometrySrcType:
583 geoSrc.fIndexBuffer->unref();
584#if GR_DEBUG
585 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
586#endif
587 break;
588 default:
589 GrCrash("Unknown Index Source Type.");
590 break;
591 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000592}
593
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000594void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
595 const void* vertexArray,
596 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000597 this->releasePreviousVertexSource();
598 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
599 geoSrc.fVertexSrc = kArray_GeometrySrcType;
600 geoSrc.fVertexLayout = vertexLayout;
601 geoSrc.fVertexCount = vertexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000602 this->onSetVertexSourceToArray(vertexArray, vertexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000603}
604
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000605void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
606 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000607 this->releasePreviousIndexSource();
608 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
609 geoSrc.fIndexSrc = kArray_GeometrySrcType;
610 geoSrc.fIndexCount = indexCount;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000611 this->onSetIndexSourceToArray(indexArray, indexCount);
reed@google.comac10a2d2010-12-22 21:39:39 +0000612}
613
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000614void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
615 const GrVertexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000616 this->releasePreviousVertexSource();
617 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
618 geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
619 geoSrc.fVertexBuffer = buffer;
620 buffer->ref();
621 geoSrc.fVertexLayout = vertexLayout;
reed@google.comac10a2d2010-12-22 21:39:39 +0000622}
623
624void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000625 this->releasePreviousIndexSource();
626 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
627 geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
628 geoSrc.fIndexBuffer = buffer;
629 buffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000630}
631
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000632void GrDrawTarget::resetVertexSource() {
633 this->releasePreviousVertexSource();
634 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
635 geoSrc.fVertexSrc = kNone_GeometrySrcType;
636}
637
638void GrDrawTarget::resetIndexSource() {
639 this->releasePreviousIndexSource();
640 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
641 geoSrc.fIndexSrc = kNone_GeometrySrcType;
642}
643
644void GrDrawTarget::pushGeometrySource() {
645 this->geometrySourceWillPush();
646 GeometrySrcState& newState = fGeoSrcStateStack.push_back();
647 newState.fIndexSrc = kNone_GeometrySrcType;
648 newState.fVertexSrc = kNone_GeometrySrcType;
649#if GR_DEBUG
650 newState.fVertexCount = ~0;
651 newState.fVertexBuffer = (GrVertexBuffer*)~0;
652 newState.fIndexCount = ~0;
653 newState.fIndexBuffer = (GrIndexBuffer*)~0;
654#endif
655}
656
657void GrDrawTarget::popGeometrySource() {
658 const GeometrySrcState& geoSrc = this->getGeomSrc();
659 // if popping last element then pops are unbalanced with pushes
660 GrAssert(fGeoSrcStateStack.count() > 1);
661
662 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
663 this->releasePreviousVertexSource();
664 this->releasePreviousIndexSource();
665 fGeoSrcStateStack.pop_back();
666}
667
668////////////////////////////////////////////////////////////////////////////////
669
670void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
671 int startIndex, int vertexCount,
672 int indexCount) {
673#if GR_DEBUG
674 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
675 int maxVertex = startVertex + vertexCount;
676 int maxValidVertex;
677 switch (geoSrc.fVertexSrc) {
678 case kNone_GeometrySrcType:
679 GrCrash("Attempting to draw indexed geom without vertex src.");
680 case kReserved_GeometrySrcType: // fallthrough
681 case kArray_GeometrySrcType:
682 maxValidVertex = geoSrc.fVertexCount;
683 break;
684 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000685 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000686 VertexSize(geoSrc.fVertexLayout);
687 break;
688 }
689 if (maxVertex > maxValidVertex) {
690 GrCrash("Indexed drawing outside valid vertex range.");
691 }
692 int maxIndex = startIndex + indexCount;
693 int maxValidIndex;
694 switch (geoSrc.fIndexSrc) {
695 case kNone_GeometrySrcType:
696 GrCrash("Attempting to draw indexed geom without index src.");
697 case kReserved_GeometrySrcType: // fallthrough
698 case kArray_GeometrySrcType:
699 maxValidIndex = geoSrc.fIndexCount;
700 break;
701 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000702 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000703 break;
704 }
705 if (maxIndex > maxValidIndex) {
706 GrCrash("Indexed drawing outside valid index range.");
707 }
708#endif
bsalomon@google.com82145872011-08-23 14:32:40 +0000709 if (indexCount > 0) {
710 this->onDrawIndexed(type, startVertex, startIndex,
711 vertexCount, indexCount);
712 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000713}
714
715
716void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
717 int startVertex,
718 int vertexCount) {
719#if GR_DEBUG
720 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
721 int maxVertex = startVertex + vertexCount;
722 int maxValidVertex;
723 switch (geoSrc.fVertexSrc) {
724 case kNone_GeometrySrcType:
725 GrCrash("Attempting to draw non-indexed geom without vertex src.");
726 case kReserved_GeometrySrcType: // fallthrough
727 case kArray_GeometrySrcType:
728 maxValidVertex = geoSrc.fVertexCount;
729 break;
730 case kBuffer_GeometrySrcType:
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000731 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000732 VertexSize(geoSrc.fVertexLayout);
733 break;
734 }
735 if (maxVertex > maxValidVertex) {
736 GrCrash("Non-indexed drawing outside valid vertex range.");
737 }
738#endif
bsalomon@google.com82145872011-08-23 14:32:40 +0000739 if (vertexCount > 0) {
740 this->onDrawNonIndexed(type, startVertex, vertexCount);
741 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000742}
743
744////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000745
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000746// Some blend modes allow folding a partial coverage value into the color's
747// alpha channel, while others will blend incorrectly.
748bool GrDrawTarget::CanTweakAlphaForCoverage(GrBlendCoeff dstCoeff) {
749 /**
750 * The fractional coverage is f
751 * The src and dst coeffs are Cs and Cd
752 * The dst and src colors are S and D
753 * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D
754 * By tweaking the source color's alpha we're replacing S with S'=fS. It's
755 * obvious that that first term will always be ok. The second term can be
756 * rearranged as [1-(1-Cd)f]D. By substituing in the various possbilities
757 * for Cd we find that only 1, ISA, and ISC produce the correct depth
758 * coeffecient in terms of S' and D.
759 */
760 return kOne_BlendCoeff == dstCoeff ||
761 kISA_BlendCoeff == dstCoeff ||
762 kISC_BlendCoeff == dstCoeff;
763}
764
bsalomon@google.com471d4712011-08-23 15:45:25 +0000765bool GrDrawTarget::CanDisableBlend(GrVertexLayout layout, const DrState& state) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000766 // If we compute a coverage value (using edge AA or a coverage stage) then
767 // we can't force blending off.
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000768 if (state.fEdgeAANumEdges > 0 ||
769 layout & kEdge_VertexLayoutBit) {
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000770 return false;
771 }
bsalomon@google.com471d4712011-08-23 15:45:25 +0000772 for (int s = state.fFirstCoverageStage; s < kNumStages; ++s) {
773 if (StageWillBeUsed(s, layout, state)) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000774 return false;
775 }
776 }
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000777
bsalomon@google.com471d4712011-08-23 15:45:25 +0000778 if ((kOne_BlendCoeff == state.fSrcBlend) &&
779 (kZero_BlendCoeff == state.fDstBlend)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000780 return true;
781 }
782
783 // If we have vertex color without alpha then we can't force blend off
bsalomon@google.com471d4712011-08-23 15:45:25 +0000784 if ((layout & kColor_VertexLayoutBit) ||
785 0xff != GrColorUnpackA(state.fColor)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000786 return false;
787 }
788
789 // If the src coef will always be 1...
bsalomon@google.com471d4712011-08-23 15:45:25 +0000790 if (kSA_BlendCoeff != state.fSrcBlend &&
791 kOne_BlendCoeff != state.fSrcBlend) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000792 return false;
793 }
794
795 // ...and the dst coef is always 0...
bsalomon@google.com471d4712011-08-23 15:45:25 +0000796 if (kISA_BlendCoeff != state.fDstBlend &&
797 kZero_BlendCoeff != state.fDstBlend) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000798 return false;
799 }
800
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000801 // ...and there isn't a texture stage with an alpha channel...
bsalomon@google.com471d4712011-08-23 15:45:25 +0000802 for (int s = 0; s < state.fFirstCoverageStage; ++s) {
803 if (StageWillBeUsed(s, layout, state)) {
804 GrAssert(NULL != state.fTextures[s]);
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000805
bsalomon@google.com471d4712011-08-23 15:45:25 +0000806 GrPixelConfig config = state.fTextures[s]->config();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000807
bsalomon@google.coma47a48d2011-04-26 20:22:11 +0000808 if (!GrPixelConfigIsOpaque(config)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000809 return false;
810 }
811 }
812 }
813
Scroggo0bad6732011-05-11 20:25:01 +0000814 // ...and there isn't an interesting color filter...
815 // TODO: Consider being more aggressive with regards to disabling
816 // blending when a color filter is used.
bsalomon@google.com471d4712011-08-23 15:45:25 +0000817 if (SkXfermode::kDst_Mode != state.fColorFilterXfermode) {
Scroggo0bad6732011-05-11 20:25:01 +0000818 return false;
819 }
820
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000821 // ...then we disable blend.
822 return true;
823}
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000824
bsalomon@google.com471d4712011-08-23 15:45:25 +0000825bool GrDrawTarget::CanUseHWAALines(GrVertexLayout layout, const DrState& state) {
826 // there is a conflict between using smooth lines and our use of
827 // premultiplied alpha. Smooth lines tweak the incoming alpha value
828 // but not in a premul-alpha way. So we only use them when our alpha
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000829 // is 0xff and tweaking the color for partial coverage is OK
bsalomon@google.com471d4712011-08-23 15:45:25 +0000830 return (kAntialias_StateBit & state.fFlagBits) &&
bsalomon@google.comd46e2422011-09-23 17:40:07 +0000831 CanDisableBlend(layout, state) &&
832 CanTweakAlphaForCoverage(state.fDstBlend);
833}
834
835bool GrDrawTarget::canApplyCoverage() const {
836 return this->getCaps().fDualSourceBlendingSupport ||
837 CanTweakAlphaForCoverage(fCurrDrawState.fDstBlend);
bsalomon@google.com471d4712011-08-23 15:45:25 +0000838}
839
840bool GrDrawTarget::canDisableBlend() const {
841 return CanDisableBlend(this->getGeomSrc().fVertexLayout, fCurrDrawState);
842}
843
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000844///////////////////////////////////////////////////////////////////////////////
bsalomon@google.com471d4712011-08-23 15:45:25 +0000845
senorblanco@chromium.orgef3913b2011-05-19 17:11:07 +0000846void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
847 GrAssert(numEdges <= kMaxEdges);
848 memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge));
849 fCurrDrawState.fEdgeAANumEdges = numEdges;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000850}
851
852
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000853////////////////////////////////////////////////////////////////////////////////
854
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000855void GrDrawTarget::drawRect(const GrRect& rect,
856 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +0000857 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000858 const GrRect* srcRects[],
859 const GrMatrix* srcMatrices[]) {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000860 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000861
862 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000863 if (!geo.succeeded()) {
864 GrPrintf("Failed to get space for vertices!\n");
865 return;
866 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000867
868 SetRectVertices(rect, matrix, srcRects,
869 srcMatrices, layout, geo.vertices());
870
871 drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
872}
873
bsalomon@google.comffca4002011-02-22 20:34:01 +0000874GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000875 const GrRect* srcRects[]) {
876 GrVertexLayout layout = 0;
877
878 for (int i = 0; i < kNumStages; ++i) {
879 int numTC = 0;
bsalomon@google.comffca4002011-02-22 20:34:01 +0000880 if (stageEnableBitfield & (1 << i)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000881 if (NULL != srcRects && NULL != srcRects[i]) {
882 layout |= StageTexCoordVertexLayoutBit(i, numTC);
883 ++numTC;
884 } else {
885 layout |= StagePosAsTexCoordVertexLayoutBit(i);
886 }
887 }
888 }
889 return layout;
890}
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000891
892void GrDrawTarget::clipWillBeSet(const GrClip& clip) {
893}
894
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000895void GrDrawTarget::SetRectVertices(const GrRect& rect,
896 const GrMatrix* matrix,
897 const GrRect* srcRects[],
898 const GrMatrix* srcMatrices[],
899 GrVertexLayout layout,
900 void* vertices) {
901#if GR_DEBUG
902 // check that the layout and srcRects agree
903 for (int i = 0; i < kNumStages; ++i) {
904 if (VertexTexCoordsForStage(i, layout) >= 0) {
905 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
906 } else {
907 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
908 }
909 }
910#endif
911
912 int stageOffsets[kNumStages];
913 int colorOffset;
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000914 int edgeOffset;
915 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets,
916 &colorOffset, &edgeOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000917 GrAssert(-1 == colorOffset);
bsalomon@google.comaeb21602011-08-30 18:13:44 +0000918 GrAssert(-1 == edgeOffset);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000919
920 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
921 rect.fRight, rect.fBottom,
922 vsize);
923 if (NULL != matrix) {
924 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
925 }
926
927 for (int i = 0; i < kNumStages; ++i) {
928 if (stageOffsets[i] > 0) {
929 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
930 stageOffsets[i]);
931 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
932 srcRects[i]->fRight, srcRects[i]->fBottom,
933 vsize);
934 if (NULL != srcMatrices && NULL != srcMatrices[i]) {
935 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
936 }
937 }
938 }
939}
940
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000941////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000942
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000943GrDrawTarget::AutoStateRestore::AutoStateRestore() {
944 fDrawTarget = NULL;
945}
reed@google.comac10a2d2010-12-22 21:39:39 +0000946
947GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
948 fDrawTarget = target;
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000949 if (NULL != fDrawTarget) {
950 fDrawTarget->saveCurrentDrawState(&fDrawState);
951 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000952}
953
954GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000955 if (NULL != fDrawTarget) {
956 fDrawTarget->restoreDrawState(fDrawState);
957 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000958}
bsalomon@google.com7d34d2e2011-01-24 17:41:47 +0000959
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000960void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
961 if (target != fDrawTarget) {
962 if (NULL != fDrawTarget) {
963 fDrawTarget->restoreDrawState(fDrawState);
964 }
965 if (NULL != target) {
bsalomon@google.comd19aa272011-06-22 01:28:17 +0000966 target->saveCurrentDrawState(&fDrawState);
bsalomon@google.com06afe7b2011-04-26 15:31:40 +0000967 }
968 fDrawTarget = target;
969 }
970}
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000971
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000972////////////////////////////////////////////////////////////////////////////////
bsalomon@google.com7ac249b2011-06-14 18:46:24 +0000973
974GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target,
975 int stageMask) {
976 GrAssert(NULL != target);
977
978 fDrawTarget = target;
979 fViewMatrix = target->getViewMatrix();
980 fStageMask = stageMask;
981 if (fStageMask) {
982 GrMatrix invVM;
983 if (fViewMatrix.invert(&invVM)) {
984 for (int s = 0; s < kNumStages; ++s) {
985 if (fStageMask & (1 << s)) {
986 fSamplerMatrices[s] = target->getSamplerMatrix(s);
987 }
988 }
989 target->preConcatSamplerMatrices(fStageMask, invVM);
990 } else {
991 // sad trombone sound
992 fStageMask = 0;
993 }
994 }
995 target->setViewMatrix(GrMatrix::I());
996}
997
998GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
999 fDrawTarget->setViewMatrix(fViewMatrix);
1000 for (int s = 0; s < kNumStages; ++s) {
1001 if (fStageMask & (1 << s)) {
1002 fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]);
1003 }
1004 }
1005}
1006
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001007////////////////////////////////////////////////////////////////////////////////
1008
1009GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
1010 GrDrawTarget* target,
1011 GrVertexLayout vertexLayout,
1012 int vertexCount,
1013 int indexCount) {
1014 fTarget = NULL;
1015 this->set(target, vertexLayout, vertexCount, indexCount);
1016}
1017
1018GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
1019 fTarget = NULL;
1020}
1021
1022GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
1023 this->reset();
1024}
1025
1026bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
1027 GrVertexLayout vertexLayout,
1028 int vertexCount,
1029 int indexCount) {
1030 this->reset();
1031 fTarget = target;
1032 bool success = true;
1033 if (NULL != fTarget) {
1034 fTarget = target;
1035 if (vertexCount > 0) {
1036 success = target->reserveVertexSpace(vertexLayout,
1037 vertexCount,
1038 &fVertices);
1039 if (!success) {
1040 this->reset();
1041 }
1042 }
1043 if (success && indexCount > 0) {
1044 success = target->reserveIndexSpace(indexCount, &fIndices);
1045 if (!success) {
1046 this->reset();
1047 }
1048 }
1049 }
1050 GrAssert(success == (NULL != fTarget));
1051 return success;
1052}
1053
1054void GrDrawTarget::AutoReleaseGeometry::reset() {
1055 if (NULL != fTarget) {
1056 if (NULL != fVertices) {
1057 fTarget->resetVertexSource();
1058 }
1059 if (NULL != fIndices) {
1060 fTarget->resetIndexSource();
1061 }
1062 fTarget = NULL;
1063 }
bsalomon@google.comcb0c5ab2011-06-29 17:48:17 +00001064 fVertices = NULL;
1065 fIndices = NULL;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +00001066}
1067
bsalomon@google.com18c9c192011-09-22 21:01:31 +00001068void GrDrawTarget::Caps::print() const {
1069 static const char* gNY[] = {"NO", "YES"};
1070 GrPrintf("8 Bit Palette Support : %s\n", gNY[f8BitPaletteSupport]);
1071 GrPrintf("NPOT Texture Support : %s\n", gNY[fNPOTTextureSupport]);
1072 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
1073 GrPrintf("NPOT Render Target Support : %s\n", gNY[fNPOTRenderTargetSupport]);
1074 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
1075 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
1076 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
1077 GrPrintf("Shader Support : %s\n", gNY[fShaderSupport]);
1078 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
1079 GrPrintf("FSAA Support : %s\n", gNY[fFSAASupport]);
1080 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
1081 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]);
1082 GrPrintf("Min Render Target Width : %d\n", fMinRenderTargetWidth);
1083 GrPrintf("Min Render Target Height : %d\n", fMinRenderTargetHeight);
1084 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize);
1085 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
1086}
1087