| 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 |