blob: 5b434c3d7f1127897ee60c0fb5de4d5d7a195061 [file] [log] [blame]
bsalomon@google.comaf84e742012-10-05 13:23:24 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrDrawState.h"
bsalomon@google.comaf84e742012-10-05 13:23:24 +00009#include "GrPaint.h"
10
11void GrDrawState::setFromPaint(const GrPaint& paint) {
bsalomon@google.com88becf42012-10-05 14:54:42 +000012 for (int i = 0; i < GrPaint::kMaxColorStages; ++i) {
13 int s = i + GrPaint::kFirstColorStage;
14 if (paint.isColorStageEnabled(i)) {
bsalomon@google.comadc65362013-01-28 14:26:09 +000015 fStages[s] = paint.getColorStage(i);
16 } else {
17 fStages[s].setEffect(NULL);
bsalomon@google.comaf84e742012-10-05 13:23:24 +000018 }
19 }
20
bsalomon@google.com88becf42012-10-05 14:54:42 +000021 this->setFirstCoverageStage(GrPaint::kFirstCoverageStage);
bsalomon@google.comaf84e742012-10-05 13:23:24 +000022
bsalomon@google.com88becf42012-10-05 14:54:42 +000023 for (int i = 0; i < GrPaint::kMaxCoverageStages; ++i) {
24 int s = i + GrPaint::kFirstCoverageStage;
25 if (paint.isCoverageStageEnabled(i)) {
bsalomon@google.comadc65362013-01-28 14:26:09 +000026 fStages[s] = paint.getCoverageStage(i);
27 } else {
28 fStages[s].setEffect(NULL);
bsalomon@google.comaf84e742012-10-05 13:23:24 +000029 }
30 }
31
32 // disable all stages not accessible via the paint
33 for (int s = GrPaint::kTotalStages; s < GrDrawState::kNumStages; ++s) {
34 this->disableStage(s);
35 }
36
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000037 this->setColor(paint.getColor());
bsalomon@google.comaf84e742012-10-05 13:23:24 +000038
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000039 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
40 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
bsalomon@google.comaf84e742012-10-05 13:23:24 +000041
bsalomon@google.comc7448ce2012-10-05 19:04:13 +000042 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
43 this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode());
44 this->setCoverage(paint.getCoverage());
bsalomon@google.comaf84e742012-10-05 13:23:24 +000045}
bsalomon@google.com5b3e8902012-10-05 20:13:28 +000046
47////////////////////////////////////////////////////////////////////////////////
48
jvanverth@google.comcc782382013-01-28 20:39:48 +000049namespace {
50
51/**
52 * This function generates some masks that we like to have known at compile
53 * time. When the number of stages or tex coords is bumped or the way bits
54 * are defined in GrDrawState.h changes this function should be rerun to
55 * generate the new masks. (We attempted to force the compiler to generate the
56 * masks using recursive templates but always wound up with static initializers
57 * under gcc, even if they were just a series of immediate->memory moves.)
58 *
59 */
60void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks,
61 GrVertexLayout* texCoordMasks) {
62 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
63 stageTexCoordMasks[s] = 0;
64 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
65 stageTexCoordMasks[s] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t);
66 }
67 }
68 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
69 texCoordMasks[t] = 0;
70 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
71 texCoordMasks[t] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t);
72 }
73 }
74}
75
76/**
77 * Uncomment and run the gen_globals function to generate
78 * the code that declares the global masks.
79 *
80 * #if 0'ed out to avoid unused function warning.
81 */
82
83#if 0
84void gen_globals() {
85 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
86 GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
87 gen_mask_arrays(stageTexCoordMasks, texCoordMasks);
88
89 GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n");
90 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
91 GrPrintf(" 0x%x,\n", stageTexCoordMasks[s]);
92 }
93 GrPrintf("};\n");
94 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n");
95 GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n");
96 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
97 GrPrintf(" 0x%x,\n", texCoordMasks[t]);
98 }
99 GrPrintf("};\n");
100 GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n");
101}
102#endif
103
104/* These values were generated by the above function */
105
106const GrVertexLayout gStageTexCoordMasks[] = {
107 0x108421,
108 0x210842,
109 0x421084,
110 0x842108,
111 0x1084210,
112};
113GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));
114
115const GrVertexLayout gTexCoordMasks[] = {
116 0x1f,
117 0x3e0,
118 0x7c00,
119 0xf8000,
120 0x1f00000,
121};
122GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));
123
124#ifdef SK_DEBUG
125bool check_layout(GrVertexLayout layout) {
126 // can only have 1 or 0 bits set for each stage.
127 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
128 int stageBits = layout & gStageTexCoordMasks[s];
129 if (stageBits && !GrIsPow2(stageBits)) {
130 return false;
131 }
132 }
133 return true;
134}
135#endif
136
137int num_tex_coords(GrVertexLayout layout) {
138 int cnt = 0;
139 // figure out how many tex coordinates are present
140 for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
141 if (gTexCoordMasks[t] & layout) {
142 ++cnt;
143 }
144 }
145 return cnt;
146}
147
148} //unnamed namespace
149
bsalomon@google.com85983282013-02-07 22:00:29 +0000150static const size_t kVec2Size = sizeof(GrPoint);
151
jvanverth@google.comcc782382013-01-28 20:39:48 +0000152size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) {
153 GrAssert(check_layout(vertexLayout));
154
bsalomon@google.com85983282013-02-07 22:00:29 +0000155 size_t size = kVec2Size; // position
156 size += num_tex_coords(vertexLayout) * kVec2Size;
jvanverth@google.comcc782382013-01-28 20:39:48 +0000157 if (vertexLayout & kColor_VertexLayoutBit) {
158 size += sizeof(GrColor);
159 }
160 if (vertexLayout & kCoverage_VertexLayoutBit) {
161 size += sizeof(GrColor);
162 }
163 if (vertexLayout & kEdge_VertexLayoutBit) {
164 size += 4 * sizeof(SkScalar);
165 }
166 return size;
167}
168
169////////////////////////////////////////////////////////////////////////////////
170
171/**
172 * Functions for computing offsets of various components from the layout
173 * bitfield.
174 *
175 * Order of vertex components:
176 * Position
177 * Tex Coord 0
178 * ...
179 * Tex Coord GrDrawState::kMaxTexCoords-1
180 * Color
181 * Coverage
182 */
183
184int GrDrawState::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) {
185 GrAssert(check_layout(vertexLayout));
186
187 if (!StageUsesTexCoords(vertexLayout, stageIdx)) {
188 return 0;
189 }
190 int tcIdx = VertexTexCoordsForStage(stageIdx, vertexLayout);
191 if (tcIdx >= 0) {
192
bsalomon@google.com85983282013-02-07 22:00:29 +0000193 int offset = kVec2Size; // position
jvanverth@google.comcc782382013-01-28 20:39:48 +0000194 // figure out how many tex coordinates are present and precede this one.
195 for (int t = 0; t < tcIdx; ++t) {
196 if (gTexCoordMasks[t] & vertexLayout) {
bsalomon@google.com85983282013-02-07 22:00:29 +0000197 offset += kVec2Size;
jvanverth@google.comcc782382013-01-28 20:39:48 +0000198 }
199 }
200 return offset;
201 }
202
203 return -1;
204}
205
206int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) {
207 GrAssert(check_layout(vertexLayout));
208
209 if (vertexLayout & kColor_VertexLayoutBit) {
bsalomon@google.com85983282013-02-07 22:00:29 +0000210 return kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
jvanverth@google.comcc782382013-01-28 20:39:48 +0000211 }
212 return -1;
213}
214
215int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) {
216 GrAssert(check_layout(vertexLayout));
217
218 if (vertexLayout & kCoverage_VertexLayoutBit) {
bsalomon@google.com85983282013-02-07 22:00:29 +0000219 int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1);
jvanverth@google.comcc782382013-01-28 20:39:48 +0000220 if (vertexLayout & kColor_VertexLayoutBit) {
221 offset += sizeof(GrColor);
222 }
223 return offset;
224 }
225 return -1;
226}
227
228int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) {
229 GrAssert(check_layout(vertexLayout));
230
231 // edge pts are after the pos, tex coords, and color
232 if (vertexLayout & kEdge_VertexLayoutBit) {
bsalomon@google.com85983282013-02-07 22:00:29 +0000233 int offset = kVec2Size * (num_tex_coords(vertexLayout) + 1); //+1 for pos
jvanverth@google.comcc782382013-01-28 20:39:48 +0000234 if (vertexLayout & kColor_VertexLayoutBit) {
235 offset += sizeof(GrColor);
236 }
237 if (vertexLayout & kCoverage_VertexLayoutBit) {
238 offset += sizeof(GrColor);
239 }
240 return offset;
241 }
242 return -1;
243}
244
245int GrDrawState::VertexSizeAndOffsetsByIdx(
246 GrVertexLayout vertexLayout,
247 int texCoordOffsetsByIdx[kMaxTexCoords],
248 int* colorOffset,
249 int* coverageOffset,
250 int* edgeOffset) {
251 GrAssert(check_layout(vertexLayout));
252
bsalomon@google.com85983282013-02-07 22:00:29 +0000253 int size = kVec2Size; // position
jvanverth@google.comcc782382013-01-28 20:39:48 +0000254
255 for (int t = 0; t < kMaxTexCoords; ++t) {
256 if (gTexCoordMasks[t] & vertexLayout) {
257 if (NULL != texCoordOffsetsByIdx) {
258 texCoordOffsetsByIdx[t] = size;
259 }
bsalomon@google.com85983282013-02-07 22:00:29 +0000260 size += kVec2Size;
jvanverth@google.comcc782382013-01-28 20:39:48 +0000261 } else {
262 if (NULL != texCoordOffsetsByIdx) {
263 texCoordOffsetsByIdx[t] = -1;
264 }
265 }
266 }
267 if (kColor_VertexLayoutBit & vertexLayout) {
268 if (NULL != colorOffset) {
269 *colorOffset = size;
270 }
271 size += sizeof(GrColor);
272 } else {
273 if (NULL != colorOffset) {
274 *colorOffset = -1;
275 }
276 }
277 if (kCoverage_VertexLayoutBit & vertexLayout) {
278 if (NULL != coverageOffset) {
279 *coverageOffset = size;
280 }
281 size += sizeof(GrColor);
282 } else {
283 if (NULL != coverageOffset) {
284 *coverageOffset = -1;
285 }
286 }
287 if (kEdge_VertexLayoutBit & vertexLayout) {
288 if (NULL != edgeOffset) {
289 *edgeOffset = size;
290 }
291 size += 4 * sizeof(SkScalar);
292 } else {
293 if (NULL != edgeOffset) {
294 *edgeOffset = -1;
295 }
296 }
297 return size;
298}
299
300int GrDrawState::VertexSizeAndOffsetsByStage(
301 GrVertexLayout vertexLayout,
302 int texCoordOffsetsByStage[GrDrawState::kNumStages],
303 int* colorOffset,
304 int* coverageOffset,
305 int* edgeOffset) {
306 GrAssert(check_layout(vertexLayout));
307
308 int texCoordOffsetsByIdx[kMaxTexCoords];
309 int size = VertexSizeAndOffsetsByIdx(vertexLayout,
310 (NULL == texCoordOffsetsByStage) ?
311 NULL :
312 texCoordOffsetsByIdx,
313 colorOffset,
314 coverageOffset,
315 edgeOffset);
316 if (NULL != texCoordOffsetsByStage) {
317 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
318 int tcIdx = VertexTexCoordsForStage(s, vertexLayout);
319 texCoordOffsetsByStage[s] =
320 tcIdx < 0 ? 0 : texCoordOffsetsByIdx[tcIdx];
321 }
322 }
323 return size;
324}
325
326////////////////////////////////////////////////////////////////////////////////
327
328bool GrDrawState::VertexUsesTexCoordIdx(int coordIndex,
329 GrVertexLayout vertexLayout) {
330 GrAssert(coordIndex < kMaxTexCoords);
331 GrAssert(check_layout(vertexLayout));
332 return !!(gTexCoordMasks[coordIndex] & vertexLayout);
333}
334
335int GrDrawState::VertexTexCoordsForStage(int stageIdx,
336 GrVertexLayout vertexLayout) {
337 GrAssert(stageIdx < GrDrawState::kNumStages);
338 GrAssert(check_layout(vertexLayout));
339 int bit = vertexLayout & gStageTexCoordMasks[stageIdx];
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 - SkCLZ(bit) - 1) / GrDrawState::kNumStages;
346 }
347 return -1;
348}
349
350////////////////////////////////////////////////////////////////////////////////
351
352void GrDrawState::VertexLayoutUnitTest() {
353 // Ensure that our globals mask arrays are correct
354 GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
355 GrVertexLayout texCoordMasks[kMaxTexCoords];
356 gen_mask_arrays(stageTexCoordMasks, texCoordMasks);
357 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
358 GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]);
359 }
360 for (int t = 0; t < kMaxTexCoords; ++t) {
361 GrAssert(texCoordMasks[t] == gTexCoordMasks[t]);
362 }
363
364 // not necessarily exhaustive
365 static bool run;
366 if (!run) {
367 run = true;
368 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
369
370 GrVertexLayout stageMask = 0;
371 for (int t = 0; t < kMaxTexCoords; ++t) {
372 stageMask |= StageTexCoordVertexLayoutBit(s,t);
373 }
374 GrAssert(1 == kMaxTexCoords ||
375 !check_layout(stageMask));
376 GrAssert(gStageTexCoordMasks[s] == stageMask);
377 GrAssert(!check_layout(stageMask));
378 }
379 for (int t = 0; t < kMaxTexCoords; ++t) {
380 GrVertexLayout tcMask = 0;
381 GrAssert(!VertexUsesTexCoordIdx(t, 0));
382 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
383 tcMask |= StageTexCoordVertexLayoutBit(s,t);
384 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
385 GrAssert(VertexUsesTexCoordIdx(t, tcMask));
386 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
387 GrAssert(t == VertexTexCoordsForStage(s, tcMask));
388 for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
389 GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
390
391 #if GR_DEBUG
392 GrVertexLayout posAsTex = tcMask;
393 #endif
394 GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
395 GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
396 GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
397 GrAssert(-1 == VertexEdgeOffset(posAsTex));
398 }
399 GrAssert(-1 == VertexEdgeOffset(tcMask));
400 GrAssert(-1 == VertexColorOffset(tcMask));
401 GrAssert(-1 == VertexCoverageOffset(tcMask));
402 #if GR_DEBUG
403 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
404 #endif
405 GrAssert(-1 == VertexCoverageOffset(withColor));
406 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
407 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
408 #if GR_DEBUG
409 GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
410 #endif
411 GrAssert(-1 == VertexColorOffset(withEdge));
412 GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
413 GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
414 #if GR_DEBUG
415 GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
416 #endif
417 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
418 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
419 GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
420 #if GR_DEBUG
421 GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
422 #endif
423 GrAssert(-1 == VertexColorOffset(withCoverage));
424 GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
425 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
426 #if GR_DEBUG
427 GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
428 kColor_VertexLayoutBit;
429 #endif
430 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
431 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
432 GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
433 }
434 GrAssert(gTexCoordMasks[t] == tcMask);
435 GrAssert(check_layout(tcMask));
436
437 int stageOffsets[GrDrawState::kNumStages];
438 int colorOffset;
439 int edgeOffset;
440 int coverageOffset;
441 int size;
442 size = VertexSizeAndOffsetsByStage(tcMask,
443 stageOffsets, &colorOffset,
444 &coverageOffset, &edgeOffset);
445 GrAssert(2*sizeof(GrPoint) == size);
446 GrAssert(-1 == colorOffset);
447 GrAssert(-1 == coverageOffset);
448 GrAssert(-1 == edgeOffset);
449 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
450 GrAssert(sizeof(GrPoint) == stageOffsets[s]);
451 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
452 }
453 }
454 }
455}
456
457////////////////////////////////////////////////////////////////////////////////
458
459bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
460 return SkToBool(layout & gStageTexCoordMasks[stageIdx]);
461}
462
463bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const {
464
465 uint32_t validComponentFlags;
466 GrColor color;
467 // Check if per-vertex or constant color may have partial alpha
468 if (layout & kColor_VertexLayoutBit) {
469 validComponentFlags = 0;
470 } else {
471 validComponentFlags = GrEffect::kAll_ValidComponentFlags;
472 color = this->getColor();
473 }
474
475 // Run through the color stages
476 int stageCnt = getFirstCoverageStage();
477 for (int s = 0; s < stageCnt; ++s) {
478 const GrEffectRef* effect = this->getStage(s).getEffect();
479 if (NULL != effect) {
480 (*effect)->getConstantColorComponents(&color, &validComponentFlags);
481 }
482 }
483
484 // Check if the color filter could introduce an alpha.
485 // We could skip the above work when this is true, but it is rare and the right fix is to make
486 // the color filter a GrEffect and implement getConstantColorComponents() for it.
487 if (SkXfermode::kDst_Mode != this->getColorFilterMode()) {
488 validComponentFlags = 0;
489 }
490
491 // Check whether coverage is treated as color. If so we run through the coverage computation.
492 if (this->isCoverageDrawing()) {
493 GrColor coverageColor = this->getCoverage();
494 GrColor oldColor = color;
495 color = 0;
496 for (int c = 0; c < 4; ++c) {
497 if (validComponentFlags & (1 << c)) {
498 U8CPU a = (oldColor >> (c * 8)) & 0xff;
499 U8CPU b = (coverageColor >> (c * 8)) & 0xff;
500 color |= (SkMulDiv255Round(a, b) << (c * 8));
501 }
502 }
503 for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
504 const GrEffectRef* effect = this->getStage(s).getEffect();
505 if (NULL != effect) {
506 (*effect)->getConstantColorComponents(&color, &validComponentFlags);
507 }
508 }
509 }
510 return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
511}
512
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000513bool GrDrawState::hasSolidCoverage(GrVertexLayout layout) const {
514 // If we're drawing coverage directly then coverage is effectively treated as color.
515 if (this->isCoverageDrawing()) {
516 return true;
517 }
518
519 GrColor coverage;
520 uint32_t validComponentFlags;
521 // Initialize to an unknown starting coverage if per-vertex coverage is specified.
522 if (layout & kCoverage_VertexLayoutBit) {
523 validComponentFlags = 0;
524 } else {
525 coverage = fCommon.fCoverage;
526 validComponentFlags = GrEffect::kAll_ValidComponentFlags;
527 }
528
529 // Run through the coverage stages and see if the coverage will be all ones at the end.
530 for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
531 const GrEffectRef* effect = this->getStage(s).getEffect();
532 if (NULL != effect) {
533 (*effect)->getConstantColorComponents(&coverage, &validComponentFlags);
534 }
535 }
536 return (GrEffect::kAll_ValidComponentFlags == validComponentFlags) && (0xffffffff == coverage);
537}
538
jvanverth@google.comcc782382013-01-28 20:39:48 +0000539////////////////////////////////////////////////////////////////////////////////
540
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000541void GrDrawState::AutoViewMatrixRestore::restore() {
542 if (NULL != fDrawState) {
543 fDrawState->setViewMatrix(fViewMatrix);
544 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
545 if (fRestoreMask & (1 << s)) {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000546 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s]);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000547 }
548 }
549 }
550 fDrawState = NULL;
551}
552
553void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000554 const SkMatrix& preconcatMatrix,
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000555 uint32_t explicitCoordStageMask) {
556 this->restore();
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000557
558 fDrawState = drawState;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000559 if (NULL == drawState) {
560 return;
561 }
562
563 fRestoreMask = 0;
564 fViewMatrix = drawState->getViewMatrix();
565 drawState->preConcatViewMatrix(preconcatMatrix);
566 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
567 if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
568 fRestoreMask |= (1 << s);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000569 fDrawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]);
570 drawState->fStages[s].preConcatCoordChange(preconcatMatrix);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000571 }
572 }
573}
574
575////////////////////////////////////////////////////////////////////////////////
576
577void GrDrawState::AutoDeviceCoordDraw::restore() {
578 if (NULL != fDrawState) {
579 fDrawState->setViewMatrix(fViewMatrix);
580 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
581 if (fRestoreMask & (1 << s)) {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000582 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s]);
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000583 }
584 }
585 }
586 fDrawState = NULL;
587}
588
589bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
590 uint32_t explicitCoordStageMask) {
591 GrAssert(NULL != drawState);
592
593 this->restore();
594
595 fDrawState = drawState;
596 if (NULL == fDrawState) {
597 return false;
skia.committer@gmail.comf467ce72012-10-09 02:01:37 +0000598 }
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000599
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000600 fViewMatrix = drawState->getViewMatrix();
601 fRestoreMask = 0;
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000602 SkMatrix invVM;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000603 bool inverted = false;
604
605 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
606 if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
607 if (!inverted && !fViewMatrix.invert(&invVM)) {
608 // sad trombone sound
609 fDrawState = NULL;
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000610 return false;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000611 } else {
612 inverted = true;
613 }
614 fRestoreMask |= (1 << s);
bsalomon@google.comadc65362013-01-28 14:26:09 +0000615 GrEffectStage* stage = drawState->fStages + s;
bsalomon@google.com08283af2012-10-26 13:01:20 +0000616 stage->saveCoordChange(&fSavedCoordChanges[s]);
617 stage->preConcatCoordChange(invVM);
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000618 }
619 }
620 drawState->viewMatrix()->reset();
bsalomon@google.com2fdcdeb2012-10-08 17:15:55 +0000621 return true;
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000622}