• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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