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