• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright 2010 Google Inc.
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8          http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16 
17 
18 #include "GrDrawTarget.h"
19 #include "GrGpuVertex.h"
20 #include "GrTexture.h"
21 
22 namespace {
23 
24 // recursive helper for creating mask with all the tex coord bits set for
25 // one stage
26 template <int N>
stage_mask_recur(int stage)27 int stage_mask_recur(int stage) {
28     return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
29            stage_mask_recur<N+1>(stage);
30 }
31 template<>
stage_mask_recur(int)32 int stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
33 
34 // mask of all tex coord indices for one stage
stage_tex_coord_mask(int stage)35 int stage_tex_coord_mask(int stage) {
36     return stage_mask_recur<0>(stage);
37 }
38 
39 // mask of all bits relevant to one stage
stage_mask(int stage)40 int stage_mask(int stage) {
41     return stage_tex_coord_mask(stage) |
42            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
43 }
44 
45 // recursive helper for creating mask of with all bits set relevant to one
46 // texture coordinate index
47 template <int N>
tex_coord_mask_recur(int texCoordIdx)48 int tex_coord_mask_recur(int texCoordIdx) {
49     return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
50            tex_coord_mask_recur<N+1>(texCoordIdx);
51 }
52 template<>
tex_coord_mask_recur(int)53 int tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
54 
55 // mask of all bits relevant to one texture coordinate index
tex_coord_idx_mask(int texCoordIdx)56 int tex_coord_idx_mask(int texCoordIdx) {
57     return tex_coord_mask_recur<0>(texCoordIdx);
58 }
59 
check_layout(GrVertexLayout layout)60 bool check_layout(GrVertexLayout layout) {
61     // can only have 1 or 0 bits set for each stage.
62     for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
63         int stageBits = layout & stage_mask(s);
64         if (stageBits && !GrIsPow2(stageBits)) {
65             return false;
66         }
67     }
68     return true;
69 }
70 
71 } //unnamed namespace
72 
VertexSize(GrVertexLayout vertexLayout)73 size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
74     GrAssert(check_layout(vertexLayout));
75 
76     size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
77                         sizeof(GrGpuTextVertex) :
78                         sizeof(GrPoint);
79 
80     size_t size = vecSize; // position
81     for (int t = 0; t < kMaxTexCoords; ++t) {
82         if (tex_coord_idx_mask(t) & vertexLayout) {
83             size += vecSize;
84         }
85     }
86     if (vertexLayout & kColor_VertexLayoutBit) {
87         size += sizeof(GrColor);
88     }
89     return size;
90 }
91 
VertexStageCoordOffset(int stage,GrVertexLayout vertexLayout)92 int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
93     GrAssert(check_layout(vertexLayout));
94     if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
95         return 0;
96     }
97     int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
98     if (tcIdx >= 0) {
99 
100         int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
101                                     sizeof(GrGpuTextVertex) :
102                                     sizeof(GrPoint);
103         int offset = vecSize; // position
104         // figure out how many tex coordinates are present and precede this one.
105         for (int t = 0; t < tcIdx; ++t) {
106             if (tex_coord_idx_mask(t) & vertexLayout) {
107                 offset += vecSize;
108             }
109         }
110         return offset;
111     }
112 
113     return -1;
114 }
115 
VertexColorOffset(GrVertexLayout vertexLayout)116 int  GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
117     GrAssert(check_layout(vertexLayout));
118 
119     if (vertexLayout & kColor_VertexLayoutBit) {
120         int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
121                                     sizeof(GrGpuTextVertex) :
122                                     sizeof(GrPoint);
123         int offset = vecSize; // position
124         // figure out how many tex coordinates are present and precede this one.
125         for (int t = 0; t < kMaxTexCoords; ++t) {
126             if (tex_coord_idx_mask(t) & vertexLayout) {
127                 offset += vecSize;
128             }
129         }
130         return offset;
131     }
132     return -1;
133 }
134 
VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,int texCoordOffsetsByIdx[kMaxTexCoords],int * colorOffset)135 int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
136                                              int texCoordOffsetsByIdx[kMaxTexCoords],
137                                              int* colorOffset) {
138     GrAssert(check_layout(vertexLayout));
139 
140     GrAssert(NULL != texCoordOffsetsByIdx);
141     GrAssert(NULL != colorOffset);
142 
143     int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
144                                                     sizeof(GrGpuTextVertex) :
145                                                     sizeof(GrPoint);
146     int size = vecSize; // position
147 
148     for (int t = 0; t < kMaxTexCoords; ++t) {
149         if (tex_coord_idx_mask(t) & vertexLayout) {
150             texCoordOffsetsByIdx[t] = size;
151             size += vecSize;
152         } else {
153             texCoordOffsetsByIdx[t] = -1;
154         }
155     }
156     if (kColor_VertexLayoutBit & vertexLayout) {
157         *colorOffset = size;
158         size += sizeof(GrColor);
159     } else {
160         *colorOffset = -1;
161     }
162     return size;
163 }
164 
VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,int texCoordOffsetsByStage[kNumStages],int * colorOffset)165 int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
166                                               int texCoordOffsetsByStage[kNumStages],
167                                               int* colorOffset) {
168     GrAssert(check_layout(vertexLayout));
169 
170     GrAssert(NULL != texCoordOffsetsByStage);
171     GrAssert(NULL != colorOffset);
172 
173     int texCoordOffsetsByIdx[kMaxTexCoords];
174     int size = VertexSizeAndOffsetsByIdx(vertexLayout,
175                                          texCoordOffsetsByIdx,
176                                          colorOffset);
177     for (int s = 0; s < kNumStages; ++s) {
178         int tcIdx;
179         if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
180             texCoordOffsetsByStage[s] = 0;
181         } else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
182             texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
183         } else {
184             texCoordOffsetsByStage[s] = -1;
185         }
186     }
187     return size;
188 }
189 
VertexUsesStage(int stage,GrVertexLayout vertexLayout)190 bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
191     GrAssert(stage < kNumStages);
192     GrAssert(check_layout(vertexLayout));
193     return !!(stage_mask(stage) & vertexLayout);
194 }
195 
VertexUsesTexCoordIdx(int coordIndex,GrVertexLayout vertexLayout)196 bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
197                                          GrVertexLayout vertexLayout) {
198     GrAssert(coordIndex < kMaxTexCoords);
199     GrAssert(check_layout(vertexLayout));
200     return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
201 }
202 
VertexTexCoordsForStage(int stage,GrVertexLayout vertexLayout)203 int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
204     GrAssert(stage < kNumStages);
205     GrAssert(check_layout(vertexLayout));
206     int bit = vertexLayout & stage_tex_coord_mask(stage);
207     if (bit) {
208         // figure out which set of texture coordates is used
209         // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
210         // and start at bit 0.
211         GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
212         return (32 - Gr_clz(bit) - 1) / kNumStages;
213     }
214     return -1;
215 }
216 
VertexLayoutUnitTest()217 void GrDrawTarget::VertexLayoutUnitTest() {
218     // not necessarily exhaustive
219     static bool run;
220     if (!run) {
221         run = true;
222         for (int s = 0; s < kNumStages; ++s) {
223 
224             GrAssert(!VertexUsesStage(s, 0));
225             GrAssert(-1 == VertexStageCoordOffset(s, 0));
226             GrVertexLayout stageMask = 0;
227             for (int t = 0; t < kMaxTexCoords; ++t) {
228                 stageMask |= StageTexCoordVertexLayoutBit(s,t);
229             }
230             GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
231             GrAssert(stage_tex_coord_mask(s) == stageMask);
232             stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
233             GrAssert(stage_mask(s) == stageMask);
234             GrAssert(!check_layout(stageMask));
235         }
236         for (int t = 0; t < kMaxTexCoords; ++t) {
237             GrVertexLayout tcMask = 0;
238             GrAssert(!VertexUsesTexCoordIdx(t, 0));
239             for (int s = 0; s < kNumStages; ++s) {
240                 tcMask |= StageTexCoordVertexLayoutBit(s,t);
241                 GrAssert(VertexUsesStage(s, tcMask));
242                 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
243                 GrAssert(VertexUsesTexCoordIdx(t, tcMask));
244                 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
245                 GrAssert(t == VertexTexCoordsForStage(s, tcMask));
246                 for (int s2 = s + 1; s2 < kNumStages; ++s2) {
247                     GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
248                     GrAssert(!VertexUsesStage(s2, tcMask));
249                     GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
250 
251                 #if GR_DEBUG
252                     GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
253                 #endif
254                     GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
255                     GrAssert(VertexUsesStage(s2, posAsTex));
256                     GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
257                     GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
258                 }
259             #if GR_DEBUG
260                 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
261             #endif
262                 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
263                 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
264             }
265             GrAssert(tex_coord_idx_mask(t) == tcMask);
266             GrAssert(check_layout(tcMask));
267 
268             int stageOffsets[kNumStages];
269             int colorOffset;
270             int size;
271             size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset);
272             GrAssert(2*sizeof(GrPoint) == size);
273             GrAssert(-1 == colorOffset);
274             for (int s = 0; s < kNumStages; ++s) {
275                 GrAssert(VertexUsesStage(s, tcMask));
276                 GrAssert(sizeof(GrPoint) == stageOffsets[s]);
277                 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
278             }
279         }
280     }
281 }
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 
GrDrawTarget()285 GrDrawTarget::GrDrawTarget() {
286 #if GR_DEBUG
287     VertexLayoutUnitTest();
288 #endif
289     fReservedGeometry.fLocked = false;
290 #if GR_DEBUG
291     fReservedGeometry.fVertexCount  = ~0;
292     fReservedGeometry.fIndexCount   = ~0;
293 #endif
294     fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
295     fGeometrySrc.fIndexSrc  = kReserved_GeometrySrcType;
296 }
297 
setClip(const GrClip & clip)298 void GrDrawTarget::setClip(const GrClip& clip) {
299     clipWillBeSet(clip);
300     fClip = clip;
301 }
302 
getClip() const303 const GrClip& GrDrawTarget::getClip() const {
304     return fClip;
305 }
306 
setTexture(int stage,GrTexture * tex)307 void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
308     GrAssert(stage >= 0 && stage < kNumStages);
309     fCurrDrawState.fTextures[stage] = tex;
310 }
311 
getTexture(int stage) const312 const GrTexture* GrDrawTarget::getTexture(int stage) const {
313     GrAssert(stage >= 0 && stage < kNumStages);
314     return fCurrDrawState.fTextures[stage];
315 }
316 
getTexture(int stage)317 GrTexture* GrDrawTarget::getTexture(int stage) {
318     GrAssert(stage >= 0 && stage < kNumStages);
319     return fCurrDrawState.fTextures[stage];
320 }
321 
setRenderTarget(GrRenderTarget * target)322 void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
323     fCurrDrawState.fRenderTarget = target;
324 }
325 
getRenderTarget() const326 const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
327     return fCurrDrawState.fRenderTarget;
328 }
329 
getRenderTarget()330 GrRenderTarget* GrDrawTarget::getRenderTarget() {
331     return fCurrDrawState.fRenderTarget;
332 }
333 
setViewMatrix(const GrMatrix & m)334 void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
335     fCurrDrawState.fViewMatrix = m;
336 }
337 
preConcatViewMatrix(const GrMatrix & matrix)338 void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
339     fCurrDrawState.fViewMatrix.preConcat(matrix);
340 }
341 
postConcatViewMatrix(const GrMatrix & matrix)342 void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
343     fCurrDrawState.fViewMatrix.postConcat(matrix);
344 }
345 
getViewMatrix() const346 const GrMatrix& GrDrawTarget::getViewMatrix() const {
347     return fCurrDrawState.fViewMatrix;
348 }
349 
getViewInverse(GrMatrix * matrix) const350 bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
351     // Mike:  Can we cache this somewhere?
352     // Brian: Sure, do we use it often?
353 
354     GrMatrix inverse;
355     if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
356         if (matrix) {
357             *matrix = inverse;
358         }
359         return true;
360     }
361     return false;
362 }
363 
setSamplerState(int stage,const GrSamplerState & state)364 void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
365     GrAssert(stage >= 0 && stage < kNumStages);
366     fCurrDrawState.fSamplerStates[stage] = state;
367 }
368 
enableState(uint32_t bits)369 void GrDrawTarget::enableState(uint32_t bits) {
370     fCurrDrawState.fFlagBits |= bits;
371 }
372 
disableState(uint32_t bits)373 void GrDrawTarget::disableState(uint32_t bits) {
374     fCurrDrawState.fFlagBits &= ~(bits);
375 }
376 
setBlendFunc(GrBlendCoeff srcCoeff,GrBlendCoeff dstCoeff)377 void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
378                                 GrBlendCoeff dstCoeff) {
379     fCurrDrawState.fSrcBlend = srcCoeff;
380     fCurrDrawState.fDstBlend = dstCoeff;
381 #if GR_DEBUG
382     switch (dstCoeff) {
383     case kDC_BlendCoeff:
384     case kIDC_BlendCoeff:
385     case kDA_BlendCoeff:
386     case kIDA_BlendCoeff:
387         GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
388                  "coverage stages.\n");
389         break;
390     default:
391         break;
392     }
393     switch (srcCoeff) {
394     case kSC_BlendCoeff:
395     case kISC_BlendCoeff:
396     case kSA_BlendCoeff:
397     case kISA_BlendCoeff:
398         GrPrintf("Unexpected src blend coeff. Won't work correctly with"
399                  "coverage stages.\n");
400         break;
401     default:
402         break;
403     }
404 #endif
405 }
406 
setColor(GrColor c)407 void GrDrawTarget::setColor(GrColor c) {
408     fCurrDrawState.fColor = c;
409 }
410 
setColorFilter(GrColor c,SkXfermode::Mode mode)411 void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
412     fCurrDrawState.fColorFilterColor = c;
413     fCurrDrawState.fColorFilterXfermode = mode;
414 }
415 
setAlpha(uint8_t a)416 void GrDrawTarget::setAlpha(uint8_t a) {
417     this->setColor((a << 24) | (a << 16) | (a << 8) | a);
418 }
419 
saveCurrentDrawState(SavedDrawState * state) const420 void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
421     state->fState = fCurrDrawState;
422 }
423 
restoreDrawState(const SavedDrawState & state)424 void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
425     fCurrDrawState = state.fState;
426 }
427 
copyDrawState(const GrDrawTarget & srcTarget)428 void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
429     fCurrDrawState = srcTarget.fCurrDrawState;
430 }
431 
432 
reserveAndLockGeometry(GrVertexLayout vertexLayout,uint32_t vertexCount,uint32_t indexCount,void ** vertices,void ** indices)433 bool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout    vertexLayout,
434                                           uint32_t          vertexCount,
435                                           uint32_t          indexCount,
436                                           void**            vertices,
437                                           void**            indices) {
438     GrAssert(!fReservedGeometry.fLocked);
439     fReservedGeometry.fVertexCount  = vertexCount;
440     fReservedGeometry.fIndexCount   = indexCount;
441 
442     fReservedGeometry.fLocked = this->onAcquireGeometry(vertexLayout,
443                                                         vertices,
444                                                         indices);
445     if (fReservedGeometry.fLocked) {
446         if (vertexCount) {
447             fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
448             fGeometrySrc.fVertexLayout = vertexLayout;
449         } else if (NULL != vertices) {
450             *vertices = NULL;
451         }
452         if (indexCount) {
453             fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
454         } else if (NULL != indices) {
455             *indices = NULL;
456         }
457     }
458     return fReservedGeometry.fLocked;
459 }
460 
geometryHints(GrVertexLayout vertexLayout,int32_t * vertexCount,int32_t * indexCount) const461 bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
462                                  int32_t* vertexCount,
463                                  int32_t* indexCount) const {
464     GrAssert(!fReservedGeometry.fLocked);
465     if (NULL != vertexCount) {
466         *vertexCount = -1;
467     }
468     if (NULL != indexCount) {
469         *indexCount = -1;
470     }
471     return false;
472 }
473 
releaseReservedGeometry()474 void GrDrawTarget::releaseReservedGeometry() {
475     GrAssert(fReservedGeometry.fLocked);
476     this->onReleaseGeometry();
477     fReservedGeometry.fLocked = false;
478 }
479 
setVertexSourceToArray(GrVertexLayout vertexLayout,const void * vertexArray,int vertexCount)480 void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
481                                           const void* vertexArray,
482                                           int vertexCount) {
483     fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
484     fGeometrySrc.fVertexLayout = vertexLayout;
485     this->onSetVertexSourceToArray(vertexArray, vertexCount);
486 }
487 
setIndexSourceToArray(const void * indexArray,int indexCount)488 void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
489                                          int indexCount) {
490     fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
491     this->onSetIndexSourceToArray(indexArray, indexCount);
492 }
493 
setVertexSourceToBuffer(GrVertexLayout vertexLayout,const GrVertexBuffer * buffer)494 void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
495                                            const GrVertexBuffer* buffer) {
496     fGeometrySrc.fVertexSrc    = kBuffer_GeometrySrcType;
497     fGeometrySrc.fVertexBuffer = buffer;
498     fGeometrySrc.fVertexLayout = vertexLayout;
499 }
500 
setIndexSourceToBuffer(const GrIndexBuffer * buffer)501 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
502     fGeometrySrc.fIndexSrc     = kBuffer_GeometrySrcType;
503     fGeometrySrc.fIndexBuffer  = buffer;
504 }
505 
506 ///////////////////////////////////////////////////////////////////////////////
507 
canDisableBlend() const508 bool GrDrawTarget::canDisableBlend() const {
509     // If we compute a coverage value (using edge AA or a coverage stage) then
510     // we can't force blending off.
511     if (fCurrDrawState.fEdgeAANumEdges > 0) {
512         return false;
513     }
514     for (int s = fCurrDrawState.fFirstCoverageStage; s < kNumStages; ++s) {
515         if (this->isStageEnabled(s)) {
516             return false;
517         }
518     }
519 
520     if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) &&
521         (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) {
522             return true;
523     }
524 
525     // If we have vertex color without alpha then we can't force blend off
526     if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) ||
527          0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
528         return false;
529     }
530 
531     // If the src coef will always be 1...
532     if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend &&
533         kOne_BlendCoeff != fCurrDrawState.fSrcBlend) {
534         return false;
535     }
536 
537     // ...and the dst coef is always 0...
538     if (kISA_BlendCoeff != fCurrDrawState.fDstBlend &&
539         kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
540         return false;
541     }
542 
543     // ...and there isn't a texture stage with an alpha channel...
544     for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) {
545         if (this->isStageEnabled(s)) {
546             GrAssert(NULL != fCurrDrawState.fTextures[s]);
547 
548             GrPixelConfig config = fCurrDrawState.fTextures[s]->config();
549 
550             if (!GrPixelConfigIsOpaque(config)) {
551                 return false;
552             }
553         }
554     }
555 
556     // ...and there isn't an interesting color filter...
557     // TODO: Consider being more aggressive with regards to disabling
558     // blending when a color filter is used.
559     if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) {
560         return false;
561     }
562 
563     // ...then we disable blend.
564     return true;
565 }
566 
567 ///////////////////////////////////////////////////////////////////////////////
setEdgeAAData(const Edge * edges,int numEdges)568 void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
569     GrAssert(numEdges <= kMaxEdges);
570     memcpy(fCurrDrawState.fEdgeAAEdges, edges, numEdges * sizeof(Edge));
571     fCurrDrawState.fEdgeAANumEdges = numEdges;
572 }
573 
574 
575 ///////////////////////////////////////////////////////////////////////////////
drawRect(const GrRect & rect,const GrMatrix * matrix,StageBitfield stageEnableBitfield,const GrRect * srcRects[],const GrMatrix * srcMatrices[])576 void GrDrawTarget::drawRect(const GrRect& rect,
577                             const GrMatrix* matrix,
578                             StageBitfield stageEnableBitfield,
579                             const GrRect* srcRects[],
580                             const GrMatrix* srcMatrices[]) {
581     GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
582 
583     AutoReleaseGeometry geo(this, layout, 4, 0);
584 
585     SetRectVertices(rect, matrix, srcRects,
586                     srcMatrices, layout, geo.vertices());
587 
588     drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
589 }
590 
GetRectVertexLayout(StageBitfield stageEnableBitfield,const GrRect * srcRects[])591 GrVertexLayout GrDrawTarget::GetRectVertexLayout(StageBitfield stageEnableBitfield,
592                                                  const GrRect* srcRects[]) {
593     GrVertexLayout layout = 0;
594 
595     for (int i = 0; i < kNumStages; ++i) {
596         int numTC = 0;
597         if (stageEnableBitfield & (1 << i)) {
598             if (NULL != srcRects && NULL != srcRects[i]) {
599                 layout |= StageTexCoordVertexLayoutBit(i, numTC);
600                 ++numTC;
601             } else {
602                 layout |= StagePosAsTexCoordVertexLayoutBit(i);
603             }
604         }
605     }
606     return layout;
607 }
SetRectVertices(const GrRect & rect,const GrMatrix * matrix,const GrRect * srcRects[],const GrMatrix * srcMatrices[],GrVertexLayout layout,void * vertices)608 void GrDrawTarget::SetRectVertices(const GrRect& rect,
609                                    const GrMatrix* matrix,
610                                    const GrRect* srcRects[],
611                                    const GrMatrix* srcMatrices[],
612                                    GrVertexLayout layout,
613                                    void* vertices) {
614 #if GR_DEBUG
615     // check that the layout and srcRects agree
616     for (int i = 0; i < kNumStages; ++i) {
617         if (VertexTexCoordsForStage(i, layout) >= 0) {
618             GR_DEBUGASSERT(NULL != srcRects && NULL != srcRects[i]);
619         } else {
620             GR_DEBUGASSERT(NULL == srcRects || NULL == srcRects[i]);
621         }
622     }
623 #endif
624 
625     int stageOffsets[kNumStages];
626     int colorOffset;
627     int vsize = VertexSizeAndOffsetsByStage(layout, stageOffsets, &colorOffset);
628     GrAssert(-1 == colorOffset);
629 
630     GrTCast<GrPoint*>(vertices)->setRectFan(rect.fLeft, rect.fTop,
631                                             rect.fRight, rect.fBottom,
632                                             vsize);
633     if (NULL != matrix) {
634         matrix->mapPointsWithStride(GrTCast<GrPoint*>(vertices), vsize, 4);
635     }
636 
637     for (int i = 0; i < kNumStages; ++i) {
638         if (stageOffsets[i] > 0) {
639             GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(vertices) +
640                                                 stageOffsets[i]);
641             coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
642                                srcRects[i]->fRight, srcRects[i]->fBottom,
643                                vsize);
644             if (NULL != srcMatrices && NULL != srcMatrices[i]) {
645                 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
646             }
647         }
648     }
649 }
650 
651 ///////////////////////////////////////////////////////////////////////////////
AutoStateRestore()652 GrDrawTarget::AutoStateRestore::AutoStateRestore() {
653     fDrawTarget = NULL;
654 }
655 
AutoStateRestore(GrDrawTarget * target)656 GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
657     fDrawTarget = target;
658     if (NULL != fDrawTarget) {
659         fDrawTarget->saveCurrentDrawState(&fDrawState);
660     }
661 }
662 
~AutoStateRestore()663 GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
664     if (NULL != fDrawTarget) {
665         fDrawTarget->restoreDrawState(fDrawState);
666     }
667 }
668 
set(GrDrawTarget * target)669 void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
670     if (target != fDrawTarget) {
671         if (NULL != fDrawTarget) {
672             fDrawTarget->restoreDrawState(fDrawState);
673         }
674         if (NULL != target) {
675             fDrawTarget->saveCurrentDrawState(&fDrawState);
676         }
677         fDrawTarget = target;
678     }
679 }
680