OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrDrawState.h" | 8 #include "GrDrawState.h" |
9 #include "GrPaint.h" | 9 #include "GrPaint.h" |
10 #include "GrDrawTargetCaps.h" | 10 #include "GrDrawTargetCaps.h" |
11 | 11 |
12 //////////////////////////////////////////////////////////////////////////////s | 12 //////////////////////////////////////////////////////////////////////////////s |
13 | 13 |
14 GrDrawState::CombinedState GrDrawState::CombineIfPossible( | 14 GrDrawState::CombinedState GrDrawState::CombineIfPossible( |
15 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { | 15 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { |
16 | 16 |
17 bool usingVertexColors = a.hasColorVertexAttribute(); | 17 if (!a.isEqual(b)) { |
18 if (!usingVertexColors && a.fColor != b.fColor) { | |
19 return kIncompatible_CombinedState; | 18 return kIncompatible_CombinedState; |
20 } | 19 } |
21 | 20 |
22 if (a.fRenderTarget.get() != b.fRenderTarget.get() || | 21 // If the general draw states are equal (from check above) we know hasColorV
ertexAttribute() |
23 a.fColorStages.count() != b.fColorStages.count() || | 22 // is equivalent for both a and b |
24 a.fCoverageStages.count() != b.fCoverageStages.count() || | 23 if (a.hasColorVertexAttribute()) { |
25 !a.fViewMatrix.cheapEqualTo(b.fViewMatrix) || | |
26 a.fSrcBlend != b.fSrcBlend || | |
27 a.fDstBlend != b.fDstBlend || | |
28 a.fBlendConstant != b.fBlendConstant || | |
29 a.fFlagBits != b.fFlagBits || | |
30 a.fVACount != b.fVACount || | |
31 memcmp(a.fVAPtr, b.fVAPtr, a.fVACount * sizeof(GrVertexAttrib)) || | |
32 a.fStencilSettings != b.fStencilSettings || | |
33 a.fDrawFace != b.fDrawFace) { | |
34 return kIncompatible_CombinedState; | |
35 } | |
36 | |
37 bool usingVertexCoverage = a.hasCoverageVertexAttribute(); | |
38 if (!usingVertexCoverage && a.fCoverage != b.fCoverage) { | |
39 return kIncompatible_CombinedState; | |
40 } | |
41 | |
42 bool explicitLocalCoords = a.hasLocalCoordAttribute(); | |
43 for (int i = 0; i < a.numColorStages(); i++) { | |
44 if (!GrEffectStage::AreCompatible(a.getColorStage(i), b.getColorStage(i)
, | |
45 explicitLocalCoords)) { | |
46 return kIncompatible_CombinedState; | |
47 } | |
48 } | |
49 for (int i = 0; i < a.numCoverageStages(); i++) { | |
50 if (!GrEffectStage::AreCompatible(a.getCoverageStage(i), b.getCoverageSt
age(i), | |
51 explicitLocalCoords)) { | |
52 return kIncompatible_CombinedState; | |
53 } | |
54 } | |
55 | |
56 SkASSERT(a.fVertexSize == b.fVertexSize); | |
57 SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices, | |
58 b.fFixedFunctionVertexAttribIndices, | |
59 sizeof(a.fFixedFunctionVertexAttribIndices))); | |
60 | |
61 if (usingVertexColors) { | |
62 // If one is opaque and the other is not then the combined state is not
opaque. Moreover, | 24 // If one is opaque and the other is not then the combined state is not
opaque. Moreover, |
63 // if the opaqueness affects the ability to get color/coverage blending
correct then we | 25 // if the opaqueness affects the ability to get color/coverage blending
correct then we |
64 // don't combine the draw states. | 26 // don't combine the draw states. |
65 bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints); | 27 bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints); |
66 bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints); | 28 bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints); |
67 if (aIsOpaque != bIsOpaque) { | 29 if (aIsOpaque != bIsOpaque) { |
68 const GrDrawState* opaque; | 30 const GrDrawState* opaque; |
69 const GrDrawState* nonOpaque; | 31 const GrDrawState* nonOpaque; |
70 if (aIsOpaque) { | 32 if (aIsOpaque) { |
71 opaque = &a; | 33 opaque = &a; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 this->invalidateBlendOptFlags(); | 176 this->invalidateBlendOptFlags(); |
215 } | 177 } |
216 | 178 |
217 //////////////////////////////////////////////////////////////////////////////// | 179 //////////////////////////////////////////////////////////////////////////////// |
218 | 180 |
219 static size_t vertex_size(const GrVertexAttrib* attribs, int count) { | 181 static size_t vertex_size(const GrVertexAttrib* attribs, int count) { |
220 // this works as long as we're 4 byte-aligned | 182 // this works as long as we're 4 byte-aligned |
221 #ifdef SK_DEBUG | 183 #ifdef SK_DEBUG |
222 uint32_t overlapCheck = 0; | 184 uint32_t overlapCheck = 0; |
223 #endif | 185 #endif |
224 SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt); | 186 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); |
225 size_t size = 0; | 187 size_t size = 0; |
226 for (int index = 0; index < count; ++index) { | 188 for (int index = 0; index < count; ++index) { |
227 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType); | 189 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType); |
228 size += attribSize; | 190 size += attribSize; |
229 #ifdef SK_DEBUG | 191 #ifdef SK_DEBUG |
230 size_t dwordCount = attribSize >> 2; | 192 size_t dwordCount = attribSize >> 2; |
231 uint32_t mask = (1 << dwordCount)-1; | 193 uint32_t mask = (1 << dwordCount)-1; |
232 size_t offsetShift = attribs[index].fOffset >> 2; | 194 size_t offsetShift = attribs[index].fOffset >> 2; |
233 SkASSERT(!(overlapCheck & (mask << offsetShift))); | 195 SkASSERT(!(overlapCheck & (mask << offsetShift))); |
234 overlapCheck |= (mask << offsetShift); | 196 overlapCheck |= (mask << offsetShift); |
235 #endif | 197 #endif |
236 } | 198 } |
237 return size; | 199 return size; |
238 } | 200 } |
239 | 201 |
240 size_t GrDrawState::getVertexSize() const { | |
241 return fVertexSize; | |
242 } | |
243 | |
244 //////////////////////////////////////////////////////////////////////////////// | 202 //////////////////////////////////////////////////////////////////////////////// |
245 | 203 |
246 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) { | 204 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) { |
247 SkASSERT(count <= kMaxVertexAttribCnt); | 205 SkASSERT(count <= kMaxVertexAttribCnt); |
248 | 206 |
249 fVAPtr = attribs; | 207 fVAPtr = attribs; |
250 fVACount = count; | 208 fVACount = count; |
251 fVertexSize = vertex_size(fVAPtr, fVACount); | 209 fVertexSize = vertex_size(fVAPtr, fVACount); |
252 | 210 |
253 // Set all the indices to -1 | 211 // Set all the indices to -1 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // set all the fixed function indices to -1 except position. | 249 // set all the fixed function indices to -1 except position. |
292 memset(fFixedFunctionVertexAttribIndices, | 250 memset(fFixedFunctionVertexAttribIndices, |
293 0xff, | 251 0xff, |
294 sizeof(fFixedFunctionVertexAttribIndices)); | 252 sizeof(fFixedFunctionVertexAttribIndices)); |
295 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; | 253 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; |
296 this->invalidateBlendOptFlags(); | 254 this->invalidateBlendOptFlags(); |
297 } | 255 } |
298 | 256 |
299 //////////////////////////////////////////////////////////////////////////////// | 257 //////////////////////////////////////////////////////////////////////////////// |
300 | 258 |
301 bool GrDrawState::validateVertexAttribs() const { | |
302 // check consistency of effects and attributes | |
303 GrSLType slTypes[kMaxVertexAttribCnt]; | |
304 for (int i = 0; i < kMaxVertexAttribCnt; ++i) { | |
305 slTypes[i] = static_cast<GrSLType>(-1); | |
306 } | |
307 int totalStages = this->numTotalStages(); | |
308 for (int s = 0; s < totalStages; ++s) { | |
309 int covIdx = s - this->numColorStages(); | |
310 const GrEffectStage& stage = covIdx < 0 ? this->getColorStage(s) : | |
311 this->getCoverageStage(covIdx)
; | |
312 const GrEffect* effect = stage.getEffect(); | |
313 SkASSERT(NULL != effect); | |
314 // make sure that any attribute indices have the correct binding type, t
hat the attrib | |
315 // type and effect's shader lang type are compatible, and that attribute
s shared by | |
316 // multiple effects use the same shader lang type. | |
317 const int* attributeIndices = stage.getVertexAttribIndices(); | |
318 int numAttributes = stage.getVertexAttribIndexCount(); | |
319 for (int i = 0; i < numAttributes; ++i) { | |
320 int attribIndex = attributeIndices[i]; | |
321 if (attribIndex >= fVACount || | |
322 kEffect_GrVertexAttribBinding != fVAPtr[attribIndex].fBinding) { | |
323 return false; | |
324 } | |
325 | |
326 GrSLType effectSLType = effect->vertexAttribType(i); | |
327 GrVertexAttribType attribType = fVAPtr[attribIndex].fType; | |
328 int slVecCount = GrSLTypeVectorCount(effectSLType); | |
329 int attribVecCount = GrVertexAttribTypeVectorCount(attribType); | |
330 if (slVecCount != attribVecCount || | |
331 (static_cast<GrSLType>(-1) != slTypes[attribIndex] && | |
332 slTypes[attribIndex] != effectSLType)) { | |
333 return false; | |
334 } | |
335 slTypes[attribIndex] = effectSLType; | |
336 } | |
337 } | |
338 | |
339 return true; | |
340 } | |
341 | |
342 bool GrDrawState::willEffectReadDstColor() const { | |
343 if (!this->isColorWriteDisabled()) { | |
344 for (int s = 0; s < this->numColorStages(); ++s) { | |
345 if (this->getColorStage(s).getEffect()->willReadDstColor()) { | |
346 return true; | |
347 } | |
348 } | |
349 } | |
350 for (int s = 0; s < this->numCoverageStages(); ++s) { | |
351 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) { | |
352 return true; | |
353 } | |
354 } | |
355 return false; | |
356 } | |
357 | |
358 //////////////////////////////////////////////////////////////////////////////// | |
359 | |
360 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { | 259 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
361 if (caps.dualSourceBlendingSupport()) { | 260 if (caps.dualSourceBlendingSupport()) { |
362 return true; | 261 return true; |
363 } | 262 } |
364 // we can correctly apply coverage if a) we have dual source blending | 263 // we can correctly apply coverage if a) we have dual source blending |
365 // or b) one of our blend optimizations applies | 264 // or b) one of our blend optimizations applies |
366 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color | 265 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color |
367 GrBlendCoeff srcCoeff; | 266 GrBlendCoeff srcCoeff; |
368 GrBlendCoeff dstCoeff; | 267 GrBlendCoeff dstCoeff; |
369 GrDrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCo
eff); | 268 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dst
Coeff); |
370 return GrDrawState::kNone_BlendOpt != flag || | 269 return GrRODrawState::kNone_BlendOpt != flag || |
371 (this->willEffectReadDstColor() && | 270 (this->willEffectReadDstColor() && |
372 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); | 271 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
373 } | 272 } |
374 | 273 |
375 bool GrDrawState::srcAlphaWillBeOne() const { | 274 ////////////////////////////////////////////////////////////////////////////// |
376 uint32_t validComponentFlags; | |
377 GrColor color; | |
378 // Check if per-vertex or constant color may have partial alpha | |
379 if (this->hasColorVertexAttribute()) { | |
380 if (fHints & kVertexColorsAreOpaque_Hint) { | |
381 validComponentFlags = kA_GrColorComponentFlag; | |
382 color = 0xFF << GrColor_SHIFT_A; | |
383 } else { | |
384 validComponentFlags = 0; | |
385 color = 0; // not strictly necessary but we get false alarms from to
ols about uninit. | |
386 } | |
387 } else { | |
388 validComponentFlags = kRGBA_GrColorComponentFlags; | |
389 color = this->getColor(); | |
390 } | |
391 | 275 |
392 // Run through the color stages | 276 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( |
393 for (int s = 0; s < this->numColorStages(); ++s) { | 277 GrDrawState* drawState) { |
394 const GrEffect* effect = this->getColorStage(s).getEffect(); | 278 SkASSERT(NULL != drawState); |
395 effect->getConstantColorComponents(&color, &validComponentFlags); | 279 fDrawState = drawState; |
396 } | 280 fVAPtr = drawState->fVAPtr; |
397 | 281 fVACount = drawState->fVACount; |
398 // Check whether coverage is treated as color. If so we run through the cove
rage computation. | 282 fDrawState->setDefaultVertexAttribs(); |
399 if (this->isCoverageDrawing()) { | |
400 // The shader generated for coverage drawing runs the full coverage comp
utation and then | |
401 // makes the shader output be the multiplication of color and coverage.
We mirror that here. | |
402 GrColor coverage; | |
403 uint32_t coverageComponentFlags; | |
404 if (this->hasCoverageVertexAttribute()) { | |
405 coverageComponentFlags = 0; | |
406 coverage = 0; // suppresses any warnings. | |
407 } else { | |
408 coverageComponentFlags = kRGBA_GrColorComponentFlags; | |
409 coverage = this->getCoverageColor(); | |
410 } | |
411 | |
412 // Run through the coverage stages | |
413 for (int s = 0; s < this->numCoverageStages(); ++s) { | |
414 const GrEffect* effect = this->getCoverageStage(s).getEffect(); | |
415 effect->getConstantColorComponents(&coverage, &coverageComponentFlag
s); | |
416 } | |
417 | |
418 // Since the shader will multiply coverage and color, the only way the f
inal A==1 is if | |
419 // coverage and color both have A==1. | |
420 return (kA_GrColorComponentFlag & validComponentFlags & coverageComponen
tFlags) && | |
421 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage
); | |
422 | |
423 } | |
424 | |
425 return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnp
ackA(color); | |
426 } | 283 } |
427 | 284 |
428 bool GrDrawState::hasSolidCoverage() const { | 285 //////////////////////////////////////////////////////////////////////////////s |
429 // If we're drawing coverage directly then coverage is effectively treated a
s color. | 286 |
430 if (this->isCoverageDrawing()) { | 287 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
431 return true; | 288 if (NULL != fDrawState) { |
| 289 int m = fDrawState->numColorStages() - fColorEffectCnt; |
| 290 SkASSERT(m >= 0); |
| 291 fDrawState->fColorStages.pop_back_n(m); |
| 292 |
| 293 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; |
| 294 SkASSERT(n >= 0); |
| 295 fDrawState->fCoverageStages.pop_back_n(n); |
| 296 if (m + n > 0) { |
| 297 fDrawState->invalidateBlendOptFlags(); |
| 298 } |
| 299 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
432 } | 300 } |
433 | 301 fDrawState = ds; |
434 GrColor coverage; | 302 if (NULL != ds) { |
435 uint32_t validComponentFlags; | 303 fColorEffectCnt = ds->numColorStages(); |
436 // Initialize to an unknown starting coverage if per-vertex coverage is spec
ified. | 304 fCoverageEffectCnt = ds->numCoverageStages(); |
437 if (this->hasCoverageVertexAttribute()) { | 305 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
438 validComponentFlags = 0; | |
439 } else { | |
440 coverage = this->getCoverageColor(); | |
441 validComponentFlags = kRGBA_GrColorComponentFlags; | |
442 } | 306 } |
443 | |
444 // Run through the coverage stages and see if the coverage will be all ones
at the end. | |
445 for (int s = 0; s < this->numCoverageStages(); ++s) { | |
446 const GrEffect* effect = this->getCoverageStage(s).getEffect(); | |
447 effect->getConstantColorComponents(&coverage, &validComponentFlags); | |
448 } | |
449 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff =
= coverage); | |
450 } | 307 } |
451 | 308 |
452 //////////////////////////////////////////////////////////////////////////////// | 309 //////////////////////////////////////////////////////////////////////////////// |
453 | 310 |
454 // Some blend modes allow folding a fractional coverage value into the color's a
lpha channel, while | 311 GrRODrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
455 // others will blend incorrectly. | 312 GrBlendCoeff* srcCoeff, |
456 bool GrDrawState::canTweakAlphaForCoverage() const { | 313 GrBlendCoeff* dstCoeff) c
onst { |
457 /* | |
458 The fractional coverage is f. | |
459 The src and dst coeffs are Cs and Cd. | |
460 The dst and src colors are S and D. | |
461 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou
rce color's alpha | |
462 we're replacing S with S'=fS. It's obvious that that first term will always
be ok. The second | |
463 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss
ibilities for Cd we | |
464 find that only 1, ISA, and ISC produce the correct destination when applied
to S' and D. | |
465 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag
e is treated as | |
466 color by definition. | |
467 */ | |
468 return kOne_GrBlendCoeff == fDstBlend || | |
469 kISA_GrBlendCoeff == fDstBlend || | |
470 kISC_GrBlendCoeff == fDstBlend || | |
471 this->isCoverageDrawing(); | |
472 } | |
473 | |
474 GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, | |
475 GrBlendCoeff* srcCoeff, | |
476 GrBlendCoeff* dstCoeff) con
st { | |
477 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; | 314 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; |
478 if (NULL == srcCoeff) { | 315 if (NULL == srcCoeff) { |
479 srcCoeff = &bogusSrcCoeff; | 316 srcCoeff = &bogusSrcCoeff; |
480 } | 317 } |
481 if (NULL == dstCoeff) { | 318 if (NULL == dstCoeff) { |
482 dstCoeff = &bogusDstCoeff; | 319 dstCoeff = &bogusDstCoeff; |
483 } | 320 } |
484 | 321 |
485 if (forceCoverage) { | 322 if (forceCoverage) { |
486 return this->calcBlendOpts(true, srcCoeff, dstCoeff); | 323 return this->calcBlendOpts(true, srcCoeff, dstCoeff); |
487 } | 324 } |
488 | 325 |
489 if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) { | 326 if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) { |
490 *srcCoeff = fOptSrcBlend; | 327 *srcCoeff = fOptSrcBlend; |
491 *dstCoeff = fOptDstBlend; | 328 *dstCoeff = fOptDstBlend; |
492 return fBlendOptFlags; | 329 return fBlendOptFlags; |
493 } | 330 } |
494 | 331 |
495 fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff); | 332 fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff); |
496 fOptSrcBlend = *srcCoeff; | 333 fOptSrcBlend = *srcCoeff; |
497 fOptDstBlend = *dstCoeff; | 334 fOptDstBlend = *dstCoeff; |
498 | 335 |
499 return fBlendOptFlags; | 336 return fBlendOptFlags; |
500 } | 337 } |
501 | 338 |
502 GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, | 339 GrRODrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, |
503 GrBlendCoeff* srcCoeff, | 340 GrBlendCoeff* srcCoeff
, |
504 GrBlendCoeff* dstCoeff) co
nst { | 341 GrBlendCoeff* dstCoeff
) const { |
505 *srcCoeff = this->getSrcBlendCoeff(); | 342 *srcCoeff = this->getSrcBlendCoeff(); |
506 *dstCoeff = this->getDstBlendCoeff(); | 343 *dstCoeff = this->getDstBlendCoeff(); |
507 | 344 |
508 if (this->isColorWriteDisabled()) { | 345 if (this->isColorWriteDisabled()) { |
509 *srcCoeff = kZero_GrBlendCoeff; | 346 *srcCoeff = kZero_GrBlendCoeff; |
510 *dstCoeff = kOne_GrBlendCoeff; | 347 *dstCoeff = kOne_GrBlendCoeff; |
511 } | 348 } |
512 | 349 |
513 bool srcAIsOne = this->srcAlphaWillBeOne(); | 350 bool srcAIsOne = this->srcAlphaWillBeOne(); |
514 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || | 351 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 // the dst coeff is effectively one so blend works out to: | 411 // the dst coeff is effectively one so blend works out to: |
575 // cS + (c)(1)D + (1-c)D = cS + D. | 412 // cS + (c)(1)D + (1-c)D = cS + D. |
576 *dstCoeff = kOne_GrBlendCoeff; | 413 *dstCoeff = kOne_GrBlendCoeff; |
577 return kCoverageAsAlpha_BlendOptFlag; | 414 return kCoverageAsAlpha_BlendOptFlag; |
578 } | 415 } |
579 } | 416 } |
580 | 417 |
581 return kNone_BlendOpt; | 418 return kNone_BlendOpt; |
582 } | 419 } |
583 | 420 |
584 bool GrDrawState::canIgnoreColorAttribute() const { | |
585 if (fBlendOptFlags & kInvalid_BlendOptFlag) { | |
586 this->getBlendOpts(); | |
587 } | |
588 return SkToBool(fBlendOptFlags & (GrDrawState::kEmitTransBlack_BlendOptFlag
| | |
589 GrDrawState::kEmitCoverage_BlendOptFlag)); | |
590 } | |
591 | |
592 ////////////////////////////////////////////////////////////////////////////// | |
593 | |
594 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( | |
595 GrDrawState* drawState) { | |
596 SkASSERT(NULL != drawState); | |
597 fDrawState = drawState; | |
598 fVAPtr = drawState->fVAPtr; | |
599 fVACount = drawState->fVACount; | |
600 fDrawState->setDefaultVertexAttribs(); | |
601 } | |
602 | |
603 //////////////////////////////////////////////////////////////////////////////s | |
604 | |
605 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { | |
606 if (NULL != fDrawState) { | |
607 int m = fDrawState->numColorStages() - fColorEffectCnt; | |
608 SkASSERT(m >= 0); | |
609 fDrawState->fColorStages.pop_back_n(m); | |
610 | |
611 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; | |
612 SkASSERT(n >= 0); | |
613 fDrawState->fCoverageStages.pop_back_n(n); | |
614 if (m + n > 0) { | |
615 fDrawState->invalidateBlendOptFlags(); | |
616 } | |
617 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | |
618 } | |
619 fDrawState = ds; | |
620 if (NULL != ds) { | |
621 fColorEffectCnt = ds->numColorStages(); | |
622 fCoverageEffectCnt = ds->numCoverageStages(); | |
623 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) | |
624 } | |
625 } | |
626 | |
627 //////////////////////////////////////////////////////////////////////////////// | 421 //////////////////////////////////////////////////////////////////////////////// |
628 | 422 |
629 void GrDrawState::AutoViewMatrixRestore::restore() { | 423 void GrDrawState::AutoViewMatrixRestore::restore() { |
630 if (NULL != fDrawState) { | 424 if (NULL != fDrawState) { |
631 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 425 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
632 fDrawState->fViewMatrix = fViewMatrix; | 426 fDrawState->fViewMatrix = fViewMatrix; |
633 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); | 427 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); |
634 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; | 428 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; |
635 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); | 429 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); |
636 | 430 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 497 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
704 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); | 498 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); |
705 } | 499 } |
706 | 500 |
707 int numCoverageStages = fDrawState->numCoverageStages(); | 501 int numCoverageStages = fDrawState->numCoverageStages(); |
708 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 502 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
709 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 503 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
710 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); | 504 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); |
711 } | 505 } |
712 } | 506 } |
| 507 |
| 508 bool GrDrawState::srcAlphaWillBeOne() const { |
| 509 uint32_t validComponentFlags; |
| 510 GrColor color; |
| 511 // Check if per-vertex or constant color may have partial alpha |
| 512 if (this->hasColorVertexAttribute()) { |
| 513 if (fHints & kVertexColorsAreOpaque_Hint) { |
| 514 validComponentFlags = kA_GrColorComponentFlag; |
| 515 color = 0xFF << GrColor_SHIFT_A; |
| 516 } else { |
| 517 validComponentFlags = 0; |
| 518 color = 0; // not strictly necessary but we get false alarms from to
ols about uninit. |
| 519 } |
| 520 } else { |
| 521 validComponentFlags = kRGBA_GrColorComponentFlags; |
| 522 color = this->getColor(); |
| 523 } |
| 524 |
| 525 // Run through the color stages |
| 526 for (int s = 0; s < this->numColorStages(); ++s) { |
| 527 const GrEffect* effect = this->getColorStage(s).getEffect(); |
| 528 effect->getConstantColorComponents(&color, &validComponentFlags); |
| 529 } |
| 530 |
| 531 // Check whether coverage is treated as color. If so we run through the cove
rage computation. |
| 532 if (this->isCoverageDrawing()) { |
| 533 // The shader generated for coverage drawing runs the full coverage comp
utation and then |
| 534 // makes the shader output be the multiplication of color and coverage.
We mirror that here. |
| 535 GrColor coverage; |
| 536 uint32_t coverageComponentFlags; |
| 537 if (this->hasCoverageVertexAttribute()) { |
| 538 coverageComponentFlags = 0; |
| 539 coverage = 0; // suppresses any warnings. |
| 540 } else { |
| 541 coverageComponentFlags = kRGBA_GrColorComponentFlags; |
| 542 coverage = this->getCoverageColor(); |
| 543 } |
| 544 |
| 545 // Run through the coverage stages |
| 546 for (int s = 0; s < this->numCoverageStages(); ++s) { |
| 547 const GrEffect* effect = this->getCoverageStage(s).getEffect(); |
| 548 effect->getConstantColorComponents(&coverage, &coverageComponentFlag
s); |
| 549 } |
| 550 |
| 551 // Since the shader will multiply coverage and color, the only way the f
inal A==1 is if |
| 552 // coverage and color both have A==1. |
| 553 return (kA_GrColorComponentFlag & validComponentFlags & coverageComponen
tFlags) && |
| 554 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage
); |
| 555 |
| 556 } |
| 557 |
| 558 return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnp
ackA(color); |
| 559 } |
| 560 |
| 561 //////////////////////////////////////////////////////////////////////////////// |
| 562 |
| 563 bool GrDrawState::canIgnoreColorAttribute() const { |
| 564 if (fBlendOptFlags & kInvalid_BlendOptFlag) { |
| 565 this->getBlendOpts(); |
| 566 } |
| 567 return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFla
g | |
| 568 GrRODrawState::kEmitCoverage_BlendOptFlag)
); |
| 569 } |
| 570 |
OLD | NEW |