1
2 /*
3 * 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.
7 */
8
9
10
11 #include "GrDrawTarget.h"
12 #include "GrGpuVertex.h"
13 #include "GrIndexBuffer.h"
14 #include "GrRenderTarget.h"
15 #include "GrTexture.h"
16 #include "GrVertexBuffer.h"
17
18 namespace {
19
20 /**
21 * This function generates some masks that we like to have known at compile
22 * time. When the number of stages or tex coords is bumped or the way bits
23 * are defined in GrDrawTarget.h changes this funcion should be rerun to
24 * generate the new masks. (We attempted to force the compiler to generate the
25 * masks using recursive templates but always wound up with static initializers
26 * under gcc, even if they were just a series of immediate->memory moves.)
27 *
28 */
gen_mask_arrays(GrVertexLayout * stageTexCoordMasks,GrVertexLayout * stageMasks,GrVertexLayout * texCoordMasks)29 void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks,
30 GrVertexLayout* stageMasks,
31 GrVertexLayout* texCoordMasks) {
32 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
33 stageTexCoordMasks[s] = 0;
34 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
35 stageTexCoordMasks[s] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t);
36 }
37 stageMasks[s] = stageTexCoordMasks[s] | GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
38 }
39 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
40 texCoordMasks[t] = 0;
41 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
42 texCoordMasks[t] |= GrDrawTarget::StageTexCoordVertexLayoutBit(s, t);
43 }
44 }
45 }
46
47 /**
48 * Run this function to generate the code that declares the global masks.
49 */
gen_globals()50 void gen_globals() {
51 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
52 GrVertexLayout stageMasks[GrDrawState::kNumStages];
53 GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
54 gen_mask_arrays(stageTexCoordMasks, stageMasks, texCoordMasks);
55
56 GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n");
57 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
58 GrPrintf(" 0x%x,\n", stageTexCoordMasks[s]);
59 }
60 GrPrintf("};\n");
61 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n");
62 GrPrintf("const GrVertexLayout gStageMasks[] = {\n");
63 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
64 GrPrintf(" 0x%x,\n", stageMasks[s]);
65 }
66 GrPrintf("};\n");
67 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageMasks));\n\n");
68 GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n");
69 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
70 GrPrintf(" 0x%x,\n", texCoordMasks[t]);
71 }
72 GrPrintf("};\n");
73 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n");
74 }
75
76 /* These values were generated by the above function */
77 const GrVertexLayout gStageTexCoordMasks[] = {
78 0x49,
79 0x92,
80 0x124
81 };
82
83 GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));
84 const GrVertexLayout gStageMasks[] = {
85 0x249,
86 0x492,
87 0x924
88 };
89
90 GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageMasks));
91 const GrVertexLayout gTexCoordMasks[] = {
92 0x7,
93 0x38,
94 0x1c0,
95 };
96 GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));
97
check_layout(GrVertexLayout layout)98 bool check_layout(GrVertexLayout layout) {
99 // can only have 1 or 0 bits set for each stage.
100 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
101 int stageBits = layout & gStageMasks[s];
102 if (stageBits && !GrIsPow2(stageBits)) {
103 return false;
104 }
105 }
106 return true;
107 }
108
num_tex_coords(GrVertexLayout layout)109 int num_tex_coords(GrVertexLayout layout) {
110 int cnt = 0;
111 // figure out how many tex coordinates are present
112 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
113 if (gTexCoordMasks[t] & layout) {
114 ++cnt;
115 }
116 }
117 return cnt;
118 }
119
120 } //unnamed namespace
121
VertexSize(GrVertexLayout vertexLayout)122 size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
123 GrAssert(check_layout(vertexLayout));
124
125 size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
126 sizeof(GrGpuTextVertex) :
127 sizeof(GrPoint);
128
129 size_t size = vecSize; // position
130 size += num_tex_coords(vertexLayout) * vecSize;
131 if (vertexLayout & kColor_VertexLayoutBit) {
132 size += sizeof(GrColor);
133 }
134 if (vertexLayout & kCoverage_VertexLayoutBit) {
135 size += sizeof(GrColor);
136 }
137 if (vertexLayout & kEdge_VertexLayoutBit) {
138 size += 4 * sizeof(GrScalar);
139 }
140 return size;
141 }
142
143 ////////////////////////////////////////////////////////////////////////////////
144
145 /**
146 * Functions for computing offsets of various components from the layout
147 * bitfield.
148 *
149 * Order of vertex components:
150 * Position
151 * Tex Coord 0
152 * ...
153 * Tex Coord GrDrawState::kMaxTexCoords-1
154 * Color
155 * Coverage
156 */
157
VertexStageCoordOffset(int stage,GrVertexLayout vertexLayout)158 int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
159 GrAssert(check_layout(vertexLayout));
160 if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
161 return 0;
162 }
163 int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
164 if (tcIdx >= 0) {
165
166 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
167 sizeof(GrGpuTextVertex) :
168 sizeof(GrPoint);
169 int offset = vecSize; // position
170 // figure out how many tex coordinates are present and precede this one.
171 for (int t = 0; t < tcIdx; ++t) {
172 if (gTexCoordMasks[t] & vertexLayout) {
173 offset += vecSize;
174 }
175 }
176 return offset;
177 }
178
179 return -1;
180 }
181
VertexColorOffset(GrVertexLayout vertexLayout)182 int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
183 GrAssert(check_layout(vertexLayout));
184
185 if (vertexLayout & kColor_VertexLayoutBit) {
186 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
187 sizeof(GrGpuTextVertex) :
188 sizeof(GrPoint);
189 return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
190 }
191 return -1;
192 }
193
VertexCoverageOffset(GrVertexLayout vertexLayout)194 int GrDrawTarget::VertexCoverageOffset(GrVertexLayout vertexLayout) {
195 GrAssert(check_layout(vertexLayout));
196
197 if (vertexLayout & kCoverage_VertexLayoutBit) {
198 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
199 sizeof(GrGpuTextVertex) :
200 sizeof(GrPoint);
201
202 int offset = vecSize * (num_tex_coords(vertexLayout) + 1);
203 if (vertexLayout & kColor_VertexLayoutBit) {
204 offset += sizeof(GrColor);
205 }
206 return offset;
207 }
208 return -1;
209 }
210
VertexEdgeOffset(GrVertexLayout vertexLayout)211 int GrDrawTarget::VertexEdgeOffset(GrVertexLayout vertexLayout) {
212 GrAssert(check_layout(vertexLayout));
213
214 // edge pts are after the pos, tex coords, and color
215 if (vertexLayout & kEdge_VertexLayoutBit) {
216 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
217 sizeof(GrGpuTextVertex) :
218 sizeof(GrPoint);
219 int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
220 if (vertexLayout & kColor_VertexLayoutBit) {
221 offset += sizeof(GrColor);
222 }
223 if (vertexLayout & kCoverage_VertexLayoutBit) {
224 offset += sizeof(GrColor);
225 }
226 return offset;
227 }
228 return -1;
229 }
230
VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords],int * colorOffset,int * coverageOffset,int * edgeOffset)231 int GrDrawTarget::VertexSizeAndOffsetsByIdx(
232 GrVertexLayout vertexLayout,
233 int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords],
234 int* colorOffset,
235 int* coverageOffset,
236 int* edgeOffset) {
237 GrAssert(check_layout(vertexLayout));
238
239 int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
240 sizeof(GrGpuTextVertex) :
241 sizeof(GrPoint);
242 int size = vecSize; // position
243
244 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
245 if (gTexCoordMasks[t] & vertexLayout) {
246 if (NULL != texCoordOffsetsByIdx) {
247 texCoordOffsetsByIdx[t] = size;
248 }
249 size += vecSize;
250 } else {
251 if (NULL != texCoordOffsetsByIdx) {
252 texCoordOffsetsByIdx[t] = -1;
253 }
254 }
255 }
256 if (kColor_VertexLayoutBit & vertexLayout) {
257 if (NULL != colorOffset) {
258 *colorOffset = size;
259 }
260 size += sizeof(GrColor);
261 } else {
262 if (NULL != colorOffset) {
263 *colorOffset = -1;
264 }
265 }
266 if (kCoverage_VertexLayoutBit & vertexLayout) {
267 if (NULL != coverageOffset) {
268 *coverageOffset = size;
269 }
270 size += sizeof(GrColor);
271 } else {
272 if (NULL != coverageOffset) {
273 *coverageOffset = -1;
274 }
275 }
276 if (kEdge_VertexLayoutBit & vertexLayout) {
277 if (NULL != edgeOffset) {
278 *edgeOffset = size;
279 }
280 size += 4 * sizeof(GrScalar);
281 } else {
282 if (NULL != edgeOffset) {
283 *edgeOffset = -1;
284 }
285 }
286 return size;
287 }
288
VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,int texCoordOffsetsByStage[GrDrawState::kNumStages],int * colorOffset,int * coverageOffset,int * edgeOffset)289 int GrDrawTarget::VertexSizeAndOffsetsByStage(
290 GrVertexLayout vertexLayout,
291 int texCoordOffsetsByStage[GrDrawState::kNumStages],
292 int* colorOffset,
293 int* coverageOffset,
294 int* edgeOffset) {
295 GrAssert(check_layout(vertexLayout));
296
297 int texCoordOffsetsByIdx[GrDrawState::kMaxTexCoords];
298 int size = VertexSizeAndOffsetsByIdx(vertexLayout,
299 (NULL == texCoordOffsetsByStage) ?
300 NULL :
301 texCoordOffsetsByIdx,
302 colorOffset,
303 coverageOffset,
304 edgeOffset);
305 if (NULL != texCoordOffsetsByStage) {
306 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
307 int tcIdx;
308 if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
309 texCoordOffsetsByStage[s] = 0;
310 } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
311 texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
312 } else {
313 texCoordOffsetsByStage[s] = -1;
314 }
315 }
316 }
317 return size;
318 }
319
320 ////////////////////////////////////////////////////////////////////////////////
321
VertexUsesStage(int stage,GrVertexLayout vertexLayout)322 bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
323 GrAssert(stage < GrDrawState::kNumStages);
324 GrAssert(check_layout(vertexLayout));
325 return !!(gStageMasks[stage] & vertexLayout);
326 }
327
VertexUsesTexCoordIdx(int coordIndex,GrVertexLayout vertexLayout)328 bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
329 GrVertexLayout vertexLayout) {
330 GrAssert(coordIndex < GrDrawState::kMaxTexCoords);
331 GrAssert(check_layout(vertexLayout));
332 return !!(gTexCoordMasks[coordIndex] & vertexLayout);
333 }
334
VertexTexCoordsForStage(int stage,GrVertexLayout vertexLayout)335 int GrDrawTarget::VertexTexCoordsForStage(int stage,
336 GrVertexLayout vertexLayout) {
337 GrAssert(stage < GrDrawState::kNumStages);
338 GrAssert(check_layout(vertexLayout));
339 int bit = vertexLayout & gStageTexCoordMasks[stage];
340 if (bit) {
341 // figure out which set of texture coordates is used
342 // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
343 // and start at bit 0.
344 GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
345 return (32 - Gr_clz(bit) - 1) / GrDrawState::kNumStages;
346 }
347 return -1;
348 }
349
350 ////////////////////////////////////////////////////////////////////////////////
351
VertexLayoutUnitTest()352 void GrDrawTarget::VertexLayoutUnitTest() {
353 // Ensure that our globals mask arrays are correct
354 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
355 GrVertexLayout stageMasks[GrDrawState::kNumStages];
356 GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
357 gen_mask_arrays(stageTexCoordMasks, stageMasks, texCoordMasks);
358 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
359 GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]);
360 GrAssert(stageMasks[s] == gStageMasks[s]);
361 }
362 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
363 GrAssert(texCoordMasks[t] == gTexCoordMasks[t]);
364 }
365
366 // not necessarily exhaustive
367 static bool run;
368 if (!run) {
369 run = true;
370 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
371
372 GrAssert(!VertexUsesStage(s, 0));
373 GrAssert(-1 == VertexStageCoordOffset(s, 0));
374 GrVertexLayout stageMask = 0;
375 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
376 stageMask |= StageTexCoordVertexLayoutBit(s,t);
377 }
378 GrAssert(1 == GrDrawState::kMaxTexCoords ||
379 !check_layout(stageMask));
380 GrAssert(gStageTexCoordMasks[s] == stageMask);
381 stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
382 GrAssert(gStageMasks[s] == stageMask);
383 GrAssert(!check_layout(stageMask));
384 }
385 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
386 GrVertexLayout tcMask = 0;
387 GrAssert(!VertexUsesTexCoordIdx(t, 0));
388 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
389 tcMask |= StageTexCoordVertexLayoutBit(s,t);
390 GrAssert(VertexUsesStage(s, tcMask));
391 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
392 GrAssert(VertexUsesTexCoordIdx(t, tcMask));
393 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
394 GrAssert(t == VertexTexCoordsForStage(s, tcMask));
395 for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
396 GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
397 GrAssert(!VertexUsesStage(s2, tcMask));
398 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
399
400 #if GR_DEBUG
401 GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
402 #endif
403 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
404 GrAssert(VertexUsesStage(s2, posAsTex));
405 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
406 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
407 GrAssert(-1 == VertexEdgeOffset(posAsTex));
408 }
409 GrAssert(-1 == VertexEdgeOffset(tcMask));
410 GrAssert(-1 == VertexColorOffset(tcMask));
411 GrAssert(-1 == VertexCoverageOffset(tcMask));
412 #if GR_DEBUG
413 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
414 #endif
415 GrAssert(-1 == VertexCoverageOffset(withColor));
416 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
417 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
418 #if GR_DEBUG
419 GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
420 #endif
421 GrAssert(-1 == VertexColorOffset(withEdge));
422 GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
423 GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
424 #if GR_DEBUG
425 GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
426 #endif
427 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
428 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
429 GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
430 #if GR_DEBUG
431 GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
432 #endif
433 GrAssert(-1 == VertexColorOffset(withCoverage));
434 GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
435 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
436 #if GR_DEBUG
437 GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
438 kColor_VertexLayoutBit;
439 #endif
440 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
441 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
442 GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
443 }
444 GrAssert(gTexCoordMasks[t] == tcMask);
445 GrAssert(check_layout(tcMask));
446
447 int stageOffsets[GrDrawState::kNumStages];
448 int colorOffset;
449 int edgeOffset;
450 int coverageOffset;
451 int size;
452 size = VertexSizeAndOffsetsByStage(tcMask,
453 stageOffsets, &colorOffset,
454 &coverageOffset, &edgeOffset);
455 GrAssert(2*sizeof(GrPoint) == size);
456 GrAssert(-1 == colorOffset);
457 GrAssert(-1 == coverageOffset);
458 GrAssert(-1 == edgeOffset);
459 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
460 GrAssert(VertexUsesStage(s, tcMask));
461 GrAssert(sizeof(GrPoint) == stageOffsets[s]);
462 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
463 }
464 }
465 }
466 }
467
468 ////////////////////////////////////////////////////////////////////////////////
469
470 #define DEBUG_INVAL_BUFFER 0xdeadcafe
471 #define DEBUG_INVAL_START_IDX -1
472
GrDrawTarget()473 GrDrawTarget::GrDrawTarget() {
474 #if GR_DEBUG
475 VertexLayoutUnitTest();
476 #endif
477 GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
478 #if GR_DEBUG
479 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
480 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
481 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
482 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
483 #endif
484 geoSrc.fVertexSrc = kNone_GeometrySrcType;
485 geoSrc.fIndexSrc = kNone_GeometrySrcType;
486 }
487
~GrDrawTarget()488 GrDrawTarget::~GrDrawTarget() {
489 GrAssert(1 == fGeoSrcStateStack.count());
490 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
491 GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc);
492 GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc);
493 }
494
releaseGeometry()495 void GrDrawTarget::releaseGeometry() {
496 int popCnt = fGeoSrcStateStack.count() - 1;
497 while (popCnt) {
498 this->popGeometrySource();
499 --popCnt;
500 }
501 this->resetVertexSource();
502 this->resetIndexSource();
503 }
504
setClip(const GrClip & clip)505 void GrDrawTarget::setClip(const GrClip& clip) {
506 clipWillBeSet(clip);
507 fClip = clip;
508 }
509
getClip() const510 const GrClip& GrDrawTarget::getClip() const {
511 return fClip;
512 }
513
saveCurrentDrawState(SavedDrawState * state) const514 void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
515 state->fState.set(fCurrDrawState);
516 }
517
restoreDrawState(const SavedDrawState & state)518 void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
519 fCurrDrawState = *state.fState.get();
520 }
521
copyDrawState(const GrDrawTarget & srcTarget)522 void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
523 fCurrDrawState = srcTarget.fCurrDrawState;
524 }
525
reserveVertexSpace(GrVertexLayout vertexLayout,int vertexCount,void ** vertices)526 bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
527 int vertexCount,
528 void** vertices) {
529 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
530 bool acquired = false;
531 if (vertexCount > 0) {
532 GrAssert(NULL != vertices);
533 this->releasePreviousVertexSource();
534 geoSrc.fVertexSrc = kNone_GeometrySrcType;
535
536 acquired = this->onReserveVertexSpace(vertexLayout,
537 vertexCount,
538 vertices);
539 }
540 if (acquired) {
541 geoSrc.fVertexSrc = kReserved_GeometrySrcType;
542 geoSrc.fVertexCount = vertexCount;
543 geoSrc.fVertexLayout = vertexLayout;
544 } else if (NULL != vertices) {
545 *vertices = NULL;
546 }
547 return acquired;
548 }
549
reserveIndexSpace(int indexCount,void ** indices)550 bool GrDrawTarget::reserveIndexSpace(int indexCount,
551 void** indices) {
552 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
553 bool acquired = false;
554 if (indexCount > 0) {
555 GrAssert(NULL != indices);
556 this->releasePreviousIndexSource();
557 geoSrc.fIndexSrc = kNone_GeometrySrcType;
558
559 acquired = this->onReserveIndexSpace(indexCount, indices);
560 }
561 if (acquired) {
562 geoSrc.fIndexSrc = kReserved_GeometrySrcType;
563 geoSrc.fIndexCount = indexCount;
564 } else if (NULL != indices) {
565 *indices = NULL;
566 }
567 return acquired;
568
569 }
570
geometryHints(GrVertexLayout vertexLayout,int32_t * vertexCount,int32_t * indexCount) const571 bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
572 int32_t* vertexCount,
573 int32_t* indexCount) const {
574 if (NULL != vertexCount) {
575 *vertexCount = -1;
576 }
577 if (NULL != indexCount) {
578 *indexCount = -1;
579 }
580 return false;
581 }
582
releasePreviousVertexSource()583 void GrDrawTarget::releasePreviousVertexSource() {
584 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
585 switch (geoSrc.fVertexSrc) {
586 case kNone_GeometrySrcType:
587 break;
588 case kArray_GeometrySrcType:
589 this->releaseVertexArray();
590 break;
591 case kReserved_GeometrySrcType:
592 this->releaseReservedVertexSpace();
593 break;
594 case kBuffer_GeometrySrcType:
595 geoSrc.fVertexBuffer->unref();
596 #if GR_DEBUG
597 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
598 #endif
599 break;
600 default:
601 GrCrash("Unknown Vertex Source Type.");
602 break;
603 }
604 }
605
releasePreviousIndexSource()606 void GrDrawTarget::releasePreviousIndexSource() {
607 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
608 switch (geoSrc.fIndexSrc) {
609 case kNone_GeometrySrcType: // these two don't require
610 break;
611 case kArray_GeometrySrcType:
612 this->releaseIndexArray();
613 break;
614 case kReserved_GeometrySrcType:
615 this->releaseReservedIndexSpace();
616 break;
617 case kBuffer_GeometrySrcType:
618 geoSrc.fIndexBuffer->unref();
619 #if GR_DEBUG
620 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
621 #endif
622 break;
623 default:
624 GrCrash("Unknown Index Source Type.");
625 break;
626 }
627 }
628
setVertexSourceToArray(GrVertexLayout vertexLayout,const void * vertexArray,int vertexCount)629 void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
630 const void* vertexArray,
631 int vertexCount) {
632 this->releasePreviousVertexSource();
633 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
634 geoSrc.fVertexSrc = kArray_GeometrySrcType;
635 geoSrc.fVertexLayout = vertexLayout;
636 geoSrc.fVertexCount = vertexCount;
637 this->onSetVertexSourceToArray(vertexArray, vertexCount);
638 }
639
setIndexSourceToArray(const void * indexArray,int indexCount)640 void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
641 int indexCount) {
642 this->releasePreviousIndexSource();
643 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
644 geoSrc.fIndexSrc = kArray_GeometrySrcType;
645 geoSrc.fIndexCount = indexCount;
646 this->onSetIndexSourceToArray(indexArray, indexCount);
647 }
648
setVertexSourceToBuffer(GrVertexLayout vertexLayout,const GrVertexBuffer * buffer)649 void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
650 const GrVertexBuffer* buffer) {
651 this->releasePreviousVertexSource();
652 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
653 geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
654 geoSrc.fVertexBuffer = buffer;
655 buffer->ref();
656 geoSrc.fVertexLayout = vertexLayout;
657 }
658
setIndexSourceToBuffer(const GrIndexBuffer * buffer)659 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
660 this->releasePreviousIndexSource();
661 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
662 geoSrc.fIndexSrc = kBuffer_GeometrySrcType;
663 geoSrc.fIndexBuffer = buffer;
664 buffer->ref();
665 }
666
resetVertexSource()667 void GrDrawTarget::resetVertexSource() {
668 this->releasePreviousVertexSource();
669 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
670 geoSrc.fVertexSrc = kNone_GeometrySrcType;
671 }
672
resetIndexSource()673 void GrDrawTarget::resetIndexSource() {
674 this->releasePreviousIndexSource();
675 GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
676 geoSrc.fIndexSrc = kNone_GeometrySrcType;
677 }
678
pushGeometrySource()679 void GrDrawTarget::pushGeometrySource() {
680 this->geometrySourceWillPush();
681 GeometrySrcState& newState = fGeoSrcStateStack.push_back();
682 newState.fIndexSrc = kNone_GeometrySrcType;
683 newState.fVertexSrc = kNone_GeometrySrcType;
684 #if GR_DEBUG
685 newState.fVertexCount = ~0;
686 newState.fVertexBuffer = (GrVertexBuffer*)~0;
687 newState.fIndexCount = ~0;
688 newState.fIndexBuffer = (GrIndexBuffer*)~0;
689 #endif
690 }
691
popGeometrySource()692 void GrDrawTarget::popGeometrySource() {
693 const GeometrySrcState& geoSrc = this->getGeomSrc();
694 // if popping last element then pops are unbalanced with pushes
695 GrAssert(fGeoSrcStateStack.count() > 1);
696
697 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
698 this->releasePreviousVertexSource();
699 this->releasePreviousIndexSource();
700 fGeoSrcStateStack.pop_back();
701 }
702
703 ////////////////////////////////////////////////////////////////////////////////
704
checkDraw(GrPrimitiveType type,int startVertex,int startIndex,int vertexCount,int indexCount) const705 bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
706 int startIndex, int vertexCount,
707 int indexCount) const {
708 #if GR_DEBUG
709 const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
710 int maxVertex = startVertex + vertexCount;
711 int maxValidVertex;
712 switch (geoSrc.fVertexSrc) {
713 case kNone_GeometrySrcType:
714 GrCrash("Attempting to draw without vertex src.");
715 case kReserved_GeometrySrcType: // fallthrough
716 case kArray_GeometrySrcType:
717 maxValidVertex = geoSrc.fVertexCount;
718 break;
719 case kBuffer_GeometrySrcType:
720 maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() /
721 VertexSize(geoSrc.fVertexLayout);
722 break;
723 }
724 if (maxVertex > maxValidVertex) {
725 GrCrash("Drawing outside valid vertex range.");
726 }
727 if (indexCount > 0) {
728 int maxIndex = startIndex + indexCount;
729 int maxValidIndex;
730 switch (geoSrc.fIndexSrc) {
731 case kNone_GeometrySrcType:
732 GrCrash("Attempting to draw indexed geom without index src.");
733 case kReserved_GeometrySrcType: // fallthrough
734 case kArray_GeometrySrcType:
735 maxValidIndex = geoSrc.fIndexCount;
736 break;
737 case kBuffer_GeometrySrcType:
738 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
739 break;
740 }
741 if (maxIndex > maxValidIndex) {
742 GrCrash("Index reads outside valid index range.");
743 }
744 }
745 #endif
746 const GrDrawState& drawState = this->getDrawState();
747 if (NULL == drawState.getRenderTarget()) {
748 return false;
749 }
750 if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
751 if (kOne_BlendCoeff != drawState.getSrcBlendCoeff() ||
752 kZero_BlendCoeff != drawState.getDstBlendCoeff()) {
753 return false;
754 }
755 }
756 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
757 // We don't support using unpremultiplied textures with filters (other
758 // than nearest). Alpha-premulling is not distributive WRT to filtering.
759 // We'd have to filter each texel before filtering. We could do this for
760 // our custom filters but we would also have to disable bilerp and do
761 // a custom bilerp in the shader. Until Skia itself supports unpremul
762 // configs there is no pressure to implement this.
763 if (this->isStageEnabled(s) &&
764 GrPixelConfigIsUnpremultiplied(drawState.getTexture(s)->config()) &&
765 GrSamplerState::kNearest_Filter !=
766 drawState.getSampler(s).getFilter()) {
767 return false;
768 }
769 }
770 return true;
771 }
772
drawIndexed(GrPrimitiveType type,int startVertex,int startIndex,int vertexCount,int indexCount)773 void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
774 int startIndex, int vertexCount,
775 int indexCount) {
776 if (indexCount > 0 &&
777 this->checkDraw(type, startVertex, startIndex,
778 vertexCount, indexCount)) {
779 this->onDrawIndexed(type, startVertex, startIndex,
780 vertexCount, indexCount);
781 }
782 }
783
drawNonIndexed(GrPrimitiveType type,int startVertex,int vertexCount)784 void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
785 int startVertex,
786 int vertexCount) {
787 if (vertexCount > 0 &&
788 this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
789 this->onDrawNonIndexed(type, startVertex, vertexCount);
790 }
791 }
792
793 ////////////////////////////////////////////////////////////////////////////////
794
795 // Some blend modes allow folding a partial coverage value into the color's
796 // alpha channel, while others will blend incorrectly.
canTweakAlphaForCoverage() const797 bool GrDrawTarget::canTweakAlphaForCoverage() const {
798 /**
799 * The fractional coverage is f
800 * The src and dst coeffs are Cs and Cd
801 * The dst and src colors are S and D
802 * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D
803 * By tweaking the source color's alpha we're replacing S with S'=fS. It's
804 * obvious that that first term will always be ok. The second term can be
805 * rearranged as [1-(1-Cd)f]D. By substituing in the various possbilities
806 * for Cd we find that only 1, ISA, and ISC produce the correct depth
807 * coeffecient in terms of S' and D.
808 */
809 GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff();
810 return kOne_BlendCoeff == dstCoeff ||
811 kISA_BlendCoeff == dstCoeff ||
812 kISC_BlendCoeff == dstCoeff;
813 }
814
815
srcAlphaWillBeOne() const816 bool GrDrawTarget::srcAlphaWillBeOne() const {
817 const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout;
818 const GrDrawState& drawState = this->getDrawState();
819
820 // Check if per-vertex or constant color may have partial alpha
821 if ((layout & kColor_VertexLayoutBit) ||
822 0xff != GrColorUnpackA(drawState.getColor())) {
823 return false;
824 }
825 // Check if color filter could introduce an alpha
826 // (TODO: Consider being more aggressive with regards to detecting 0xff
827 // final alpha from color filter).
828 if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) {
829 return false;
830 }
831 // Check if a color stage could create a partial alpha
832 for (int s = 0; s < drawState.getFirstCoverageStage(); ++s) {
833 if (StageWillBeUsed(s, layout, fCurrDrawState)) {
834 GrAssert(NULL != drawState.getTexture(s));
835 GrPixelConfig config = drawState.getTexture(s)->config();
836 if (!GrPixelConfigIsOpaque(config)) {
837 return false;
838 }
839 }
840 }
841 return true;
842 }
843
844 GrDrawTarget::BlendOptFlags
getBlendOpts(bool forceCoverage,GrBlendCoeff * srcCoeff,GrBlendCoeff * dstCoeff) const845 GrDrawTarget::getBlendOpts(bool forceCoverage,
846 GrBlendCoeff* srcCoeff,
847 GrBlendCoeff* dstCoeff) const {
848
849 const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout;
850 const GrDrawState& drawState = this->getDrawState();
851
852 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
853 if (NULL == srcCoeff) {
854 srcCoeff = &bogusSrcCoeff;
855 }
856 *srcCoeff = drawState.getSrcBlendCoeff();
857
858 if (NULL == dstCoeff) {
859 dstCoeff = &bogusDstCoeff;
860 }
861 *dstCoeff = drawState.getDstBlendCoeff();
862
863 // We don't ever expect source coeffecients to reference the source
864 GrAssert(kSA_BlendCoeff != *srcCoeff &&
865 kISA_BlendCoeff != *srcCoeff &&
866 kSC_BlendCoeff != *srcCoeff &&
867 kISC_BlendCoeff != *srcCoeff);
868 // same for dst
869 GrAssert(kDA_BlendCoeff != *dstCoeff &&
870 kIDA_BlendCoeff != *dstCoeff &&
871 kDC_BlendCoeff != *dstCoeff &&
872 kIDC_BlendCoeff != *dstCoeff);
873
874 if (drawState.isColorWriteDisabled()) {
875 *srcCoeff = kZero_BlendCoeff;
876 *dstCoeff = kOne_BlendCoeff;
877 }
878
879 bool srcAIsOne = this->srcAlphaWillBeOne();
880 bool dstCoeffIsOne = kOne_BlendCoeff == *dstCoeff ||
881 (kSA_BlendCoeff == *dstCoeff && srcAIsOne);
882 bool dstCoeffIsZero = kZero_BlendCoeff == *dstCoeff ||
883 (kISA_BlendCoeff == *dstCoeff && srcAIsOne);
884
885
886 // When coeffs are (0,1) there is no reason to draw at all, unless
887 // stenciling is enabled. Having color writes disabled is effectively
888 // (0,1). The same applies when coverage is known to be 0.
889 if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne) ||
890 (!(layout & kCoverage_VertexLayoutBit) &&
891 0 == drawState.getCoverage())) {
892 if (drawState.getStencil().doesWrite()) {
893 return kDisableBlend_BlendOptFlag |
894 kEmitTransBlack_BlendOptFlag;
895 } else {
896 return kSkipDraw_BlendOptFlag;
897 }
898 }
899
900 // check for coverage due to constant coverage, per-vertex coverage,
901 // edge aa or coverage texture stage
902 bool hasCoverage = forceCoverage ||
903 0xffffffff != drawState.getCoverage() ||
904 drawState.getNumAAEdges() > 0 ||
905 (layout & kCoverage_VertexLayoutBit) ||
906 (layout & kEdge_VertexLayoutBit);
907 for (int s = drawState.getFirstCoverageStage();
908 !hasCoverage && s < GrDrawState::kNumStages;
909 ++s) {
910 if (StageWillBeUsed(s, layout, fCurrDrawState)) {
911 hasCoverage = true;
912 }
913 }
914
915 // if we don't have coverage we can check whether the dst
916 // has to read at all. If not, we'll disable blending.
917 if (!hasCoverage) {
918 if (dstCoeffIsZero) {
919 if (kOne_BlendCoeff == *srcCoeff) {
920 // if there is no coverage and coeffs are (1,0) then we
921 // won't need to read the dst at all, it gets replaced by src
922 return kDisableBlend_BlendOptFlag;
923 } else if (kZero_BlendCoeff == *srcCoeff) {
924 // if the op is "clear" then we don't need to emit a color
925 // or blend, just write transparent black into the dst.
926 *srcCoeff = kOne_BlendCoeff;
927 *dstCoeff = kZero_BlendCoeff;
928 return kDisableBlend_BlendOptFlag |
929 kEmitTransBlack_BlendOptFlag;
930 }
931 }
932 } else {
933 // check whether coverage can be safely rolled into alpha
934 // of if we can skip color computation and just emit coverage
935 if (this->canTweakAlphaForCoverage()) {
936 return kCoverageAsAlpha_BlendOptFlag;
937 }
938 if (dstCoeffIsZero) {
939 if (kZero_BlendCoeff == *srcCoeff) {
940 // the source color is not included in the blend
941 // the dst coeff is effectively zero so blend works out to:
942 // (c)(0)D + (1-c)D = (1-c)D.
943 *dstCoeff = kISA_BlendCoeff;
944 return kEmitCoverage_BlendOptFlag;
945 } else if (srcAIsOne) {
946 // the dst coeff is effectively zero so blend works out to:
947 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
948 // If Sa is 1 then we can replace Sa with c
949 // and set dst coeff to 1-Sa.
950 *dstCoeff = kISA_BlendCoeff;
951 return kCoverageAsAlpha_BlendOptFlag;
952 }
953 } else if (dstCoeffIsOne) {
954 // the dst coeff is effectively one so blend works out to:
955 // cS + (c)(1)D + (1-c)D = cS + D.
956 *dstCoeff = kOne_BlendCoeff;
957 return kCoverageAsAlpha_BlendOptFlag;
958 }
959 }
960 return kNone_BlendOpt;
961 }
962
willUseHWAALines() const963 bool GrDrawTarget::willUseHWAALines() const {
964 // there is a conflict between using smooth lines and our use of
965 // premultiplied alpha. Smooth lines tweak the incoming alpha value
966 // but not in a premul-alpha way. So we only use them when our alpha
967 // is 0xff and tweaking the color for partial coverage is OK
968 if (!fCaps.fHWAALineSupport ||
969 !this->getDrawState().isHWAntialiasState()) {
970 return false;
971 }
972 BlendOptFlags opts = this->getBlendOpts();
973 return (kDisableBlend_BlendOptFlag & opts) &&
974 (kCoverageAsAlpha_BlendOptFlag & opts);
975 }
976
canApplyCoverage() const977 bool GrDrawTarget::canApplyCoverage() const {
978 // we can correctly apply coverage if a) we have dual source blending
979 // or b) one of our blend optimizations applies.
980 return this->getCaps().fDualSourceBlendingSupport ||
981 kNone_BlendOpt != this->getBlendOpts(true);
982 }
983
drawWillReadDst() const984 bool GrDrawTarget::drawWillReadDst() const {
985 return SkToBool((kDisableBlend_BlendOptFlag | kSkipDraw_BlendOptFlag) &
986 this->getBlendOpts());
987 }
988
989
990 ////////////////////////////////////////////////////////////////////////////////
991
drawRect(const GrRect & rect,const GrMatrix * matrix,StageMask stageMask,const GrRect * srcRects[],const GrMatrix * srcMatrices[])992 void GrDrawTarget::drawRect(const GrRect& rect,
993 const GrMatrix* matrix,
994 StageMask stageMask,
995 const GrRect* srcRects[],
996 const GrMatrix* srcMatrices[]) {
997 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
998
999 AutoReleaseGeometry geo(this, layout, 4, 0);
1000 if (!geo.succeeded()) {
1001 GrPrintf("Failed to get space for vertices!\n");
1002 return;
1003 }
1004
1005 SetRectVertices(rect, matrix, srcRects,
1006 srcMatrices, layout, geo.vertices());
1007
1008 drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
1009 }
1010
GetRectVertexLayout(StageMask stageMask,const GrRect * srcRects[])1011 GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageMask stageMask,
1012 const GrRect* srcRects[]) {
1013 GrVertexLayout layout = 0;
1014
1015 for (int i = 0; i < GrDrawState::kNumStages; ++i) {
1016 int numTC = 0;
1017 if (stageMask & (1 << i)) {
1018 if (NULL != srcRects && NULL != srcRects[i]) {
1019 layout |= StageTexCoordVertexLayoutBit(i, numTC);
1020 ++numTC;
1021 } else {
1022 layout |= StagePosAsTexCoordVertexLayoutBit(i);
1023 }
1024 }
1025 }
1026 return layout;
1027 }
1028
clipWillBeSet(const GrClip & clip)1029 void GrDrawTarget::clipWillBeSet(const GrClip& clip) {
1030 }
1031
SetRectVertices(const GrRect & rect,const GrMatrix * matrix,const GrRect * srcRects[],const GrMatrix * srcMatrices[],GrVertexLayout layout,void * vertices)1032 void GrDrawTarget::SetRectVertices(const GrRect& rect,
1033 const GrMatrix* matrix,
1034 const GrRect* srcRects[],
1035 const GrMatrix* srcMatrices[],
1036 GrVertexLayout layout,
1037 void* vertices) {
1038 #if GR_DEBUG
1039 // check that the layout and srcRects agree
1040 for (int i = 0; i < GrDrawState::kNumStages; ++i) {
1041 if (VertexTexCoordsForStage(i, layout) >= 0) {
1042 GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
1043 } else {
1044 GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
1045 }
1046 }
1047 #endif
1048
1049 int stageOffsets[GrDrawState::kNumStages];
1050 int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets,
1051 NULL, NULL, NULL);
1052
1053 GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
1054 rect.fRight, rect.fBottom,
1055 vsize);
1056 if (NULL != matrix) {
1057 matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
1058 }
1059
1060 for (int i = 0; i < GrDrawState::kNumStages; ++i) {
1061 if (stageOffsets[i] > 0) {
1062 GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
1063 stageOffsets[i]);
1064 coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
1065 srcRects[i]->fRight, srcRects[i]->fBottom,
1066 vsize);
1067 if (NULL != srcMatrices && NULL != srcMatrices[i]) {
1068 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
1069 }
1070 }
1071 }
1072 }
1073
1074 ////////////////////////////////////////////////////////////////////////////////
1075
AutoStateRestore()1076 GrDrawTarget::AutoStateRestore::AutoStateRestore() {
1077 fDrawTarget = NULL;
1078 }
1079
AutoStateRestore(GrDrawTarget * target)1080 GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
1081 fDrawTarget = target;
1082 if (NULL != fDrawTarget) {
1083 fDrawTarget->saveCurrentDrawState(&fDrawState);
1084 }
1085 }
1086
~AutoStateRestore()1087 GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
1088 if (NULL != fDrawTarget) {
1089 fDrawTarget->restoreDrawState(fDrawState);
1090 }
1091 }
1092
set(GrDrawTarget * target)1093 void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
1094 if (target != fDrawTarget) {
1095 if (NULL != fDrawTarget) {
1096 fDrawTarget->restoreDrawState(fDrawState);
1097 }
1098 if (NULL != target) {
1099 target->saveCurrentDrawState(&fDrawState);
1100 }
1101 fDrawTarget = target;
1102 }
1103 }
1104
1105 ////////////////////////////////////////////////////////////////////////////////
1106
AutoDeviceCoordDraw(GrDrawTarget * target,GrDrawState::StageMask stageMask)1107 GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(
1108 GrDrawTarget* target,
1109 GrDrawState::StageMask stageMask) {
1110 GrAssert(NULL != target);
1111 GrDrawState* drawState = target->drawState();
1112
1113 fDrawTarget = target;
1114 fViewMatrix = drawState->getViewMatrix();
1115 fStageMask = stageMask;
1116 if (fStageMask) {
1117 GrMatrix invVM;
1118 if (fViewMatrix.invert(&invVM)) {
1119 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
1120 if (fStageMask & (1 << s)) {
1121 fSamplerMatrices[s] = drawState->getSampler(s).getMatrix();
1122 }
1123 }
1124 drawState->preConcatSamplerMatrices(fStageMask, invVM);
1125 } else {
1126 // sad trombone sound
1127 fStageMask = 0;
1128 }
1129 }
1130 drawState->setViewMatrix(GrMatrix::I());
1131 }
1132
~AutoDeviceCoordDraw()1133 GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
1134 GrDrawState* drawState = fDrawTarget->drawState();
1135 drawState->setViewMatrix(fViewMatrix);
1136 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
1137 if (fStageMask & (1 << s)) {
1138 *drawState->sampler(s)->matrix() = fSamplerMatrices[s];
1139 }
1140 }
1141 }
1142
1143 ////////////////////////////////////////////////////////////////////////////////
1144
AutoReleaseGeometry(GrDrawTarget * target,GrVertexLayout vertexLayout,int vertexCount,int indexCount)1145 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
1146 GrDrawTarget* target,
1147 GrVertexLayout vertexLayout,
1148 int vertexCount,
1149 int indexCount) {
1150 fTarget = NULL;
1151 this->set(target, vertexLayout, vertexCount, indexCount);
1152 }
1153
AutoReleaseGeometry()1154 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
1155 fTarget = NULL;
1156 }
1157
~AutoReleaseGeometry()1158 GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
1159 this->reset();
1160 }
1161
set(GrDrawTarget * target,GrVertexLayout vertexLayout,int vertexCount,int indexCount)1162 bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
1163 GrVertexLayout vertexLayout,
1164 int vertexCount,
1165 int indexCount) {
1166 this->reset();
1167 fTarget = target;
1168 bool success = true;
1169 if (NULL != fTarget) {
1170 fTarget = target;
1171 if (vertexCount > 0) {
1172 success = target->reserveVertexSpace(vertexLayout,
1173 vertexCount,
1174 &fVertices);
1175 if (!success) {
1176 this->reset();
1177 }
1178 }
1179 if (success && indexCount > 0) {
1180 success = target->reserveIndexSpace(indexCount, &fIndices);
1181 if (!success) {
1182 this->reset();
1183 }
1184 }
1185 }
1186 GrAssert(success == (NULL != fTarget));
1187 return success;
1188 }
1189
reset()1190 void GrDrawTarget::AutoReleaseGeometry::reset() {
1191 if (NULL != fTarget) {
1192 if (NULL != fVertices) {
1193 fTarget->resetVertexSource();
1194 }
1195 if (NULL != fIndices) {
1196 fTarget->resetIndexSource();
1197 }
1198 fTarget = NULL;
1199 }
1200 fVertices = NULL;
1201 fIndices = NULL;
1202 }
1203
print() const1204 void GrDrawTarget::Caps::print() const {
1205 static const char* gNY[] = {"NO", "YES"};
1206 GrPrintf("8 Bit Palette Support : %s\n", gNY[f8BitPaletteSupport]);
1207 GrPrintf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
1208 GrPrintf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
1209 GrPrintf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
1210 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
1211 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
1212 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
1213 GrPrintf("FSAA Support : %s\n", gNY[fFSAASupport]);
1214 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
1215 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]);
1216 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize);
1217 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
1218 }
1219
1220