1 /* 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" 9 #include "GrPaint.h" 10 11 bool GrDrawState::setIdentityViewMatrix() { 12 if (fColorStages.count() || fCoverageStages.count()) { 13 SkMatrix invVM; 14 if (!fCommon.fViewMatrix.invert(&invVM)) { 15 // sad trombone sound 16 return false; 17 } 18 for (int s = 0; s < fColorStages.count(); ++s) { 19 fColorStages[s].localCoordChange(invVM); 20 } 21 for (int s = 0; s < fCoverageStages.count(); ++s) { 22 fCoverageStages[s].localCoordChange(invVM); 23 } 24 } 25 fCommon.fViewMatrix.reset(); 26 return true; 27 } 28 29 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) { 30 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); 31 32 fColorStages.reset(); 33 fCoverageStages.reset(); 34 35 for (int i = 0; i < paint.numColorStages(); ++i) { 36 fColorStages.push_back(paint.getColorStage(i)); 37 } 38 39 for (int i = 0; i < paint.numCoverageStages(); ++i) { 40 fCoverageStages.push_back(paint.getCoverageStage(i)); 41 } 42 43 this->setRenderTarget(rt); 44 45 fCommon.fViewMatrix = vm; 46 47 // These have no equivalent in GrPaint, set them to defaults 48 fCommon.fBlendConstant = 0x0; 49 fCommon.fDrawFace = kBoth_DrawFace; 50 fCommon.fStencilSettings.setDisabled(); 51 this->resetStateFlags(); 52 53 // Enable the clip bit 54 this->enableState(GrDrawState::kClip_StateBit); 55 56 this->setColor(paint.getColor()); 57 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); 58 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); 59 60 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); 61 this->setCoverage(paint.getCoverage()); 62 } 63 64 //////////////////////////////////////////////////////////////////////////////// 65 66 static size_t vertex_size(const GrVertexAttrib* attribs, int count) { 67 // this works as long as we're 4 byte-aligned 68 #ifdef SK_DEBUG 69 uint32_t overlapCheck = 0; 70 #endif 71 SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt); 72 size_t size = 0; 73 for (int index = 0; index < count; ++index) { 74 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType); 75 size += attribSize; 76 #ifdef SK_DEBUG 77 size_t dwordCount = attribSize >> 2; 78 uint32_t mask = (1 << dwordCount)-1; 79 size_t offsetShift = attribs[index].fOffset >> 2; 80 SkASSERT(!(overlapCheck & (mask << offsetShift))); 81 overlapCheck |= (mask << offsetShift); 82 #endif 83 } 84 return size; 85 } 86 87 size_t GrDrawState::getVertexSize() const { 88 return vertex_size(fCommon.fVAPtr, fCommon.fVACount); 89 } 90 91 //////////////////////////////////////////////////////////////////////////////// 92 93 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) { 94 SkASSERT(count <= kMaxVertexAttribCnt); 95 96 fCommon.fVAPtr = attribs; 97 fCommon.fVACount = count; 98 99 // Set all the indices to -1 100 memset(fCommon.fFixedFunctionVertexAttribIndices, 101 0xff, 102 sizeof(fCommon.fFixedFunctionVertexAttribIndices)); 103 #ifdef SK_DEBUG 104 uint32_t overlapCheck = 0; 105 #endif 106 for (int i = 0; i < count; ++i) { 107 if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) { 108 // The fixed function attribs can only be specified once 109 SkASSERT(-1 == fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding]); 110 SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) == 111 GrVertexAttribTypeVectorCount(attribs[i].fType)); 112 fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i; 113 } 114 #ifdef SK_DEBUG 115 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2; 116 uint32_t mask = (1 << dwordCount)-1; 117 size_t offsetShift = attribs[i].fOffset >> 2; 118 SkASSERT(!(overlapCheck & (mask << offsetShift))); 119 overlapCheck |= (mask << offsetShift); 120 #endif 121 } 122 // Positions must be specified. 123 SkASSERT(-1 != fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]); 124 } 125 126 //////////////////////////////////////////////////////////////////////////////// 127 128 void GrDrawState::setDefaultVertexAttribs() { 129 static const GrVertexAttrib kPositionAttrib = 130 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}; 131 132 fCommon.fVAPtr = &kPositionAttrib; 133 fCommon.fVACount = 1; 134 135 // set all the fixed function indices to -1 except position. 136 memset(fCommon.fFixedFunctionVertexAttribIndices, 137 0xff, 138 sizeof(fCommon.fFixedFunctionVertexAttribIndices)); 139 fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; 140 } 141 142 //////////////////////////////////////////////////////////////////////////////// 143 144 bool GrDrawState::validateVertexAttribs() const { 145 // check consistency of effects and attributes 146 GrSLType slTypes[kMaxVertexAttribCnt]; 147 for (int i = 0; i < kMaxVertexAttribCnt; ++i) { 148 slTypes[i] = static_cast<GrSLType>(-1); 149 } 150 int totalStages = fColorStages.count() + fCoverageStages.count(); 151 for (int s = 0; s < totalStages; ++s) { 152 int covIdx = s - fColorStages.count(); 153 const GrEffectStage& stage = covIdx < 0 ? fColorStages[s] : fCoverageStages[covIdx]; 154 const GrEffectRef* effect = stage.getEffect(); 155 SkASSERT(NULL != effect); 156 // make sure that any attribute indices have the correct binding type, that the attrib 157 // type and effect's shader lang type are compatible, and that attributes shared by 158 // multiple effects use the same shader lang type. 159 const int* attributeIndices = stage.getVertexAttribIndices(); 160 int numAttributes = stage.getVertexAttribIndexCount(); 161 for (int i = 0; i < numAttributes; ++i) { 162 int attribIndex = attributeIndices[i]; 163 if (attribIndex >= fCommon.fVACount || 164 kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) { 165 return false; 166 } 167 168 GrSLType effectSLType = (*effect)->vertexAttribType(i); 169 GrVertexAttribType attribType = fCommon.fVAPtr[attribIndex].fType; 170 int slVecCount = GrSLTypeVectorCount(effectSLType); 171 int attribVecCount = GrVertexAttribTypeVectorCount(attribType); 172 if (slVecCount != attribVecCount || 173 (static_cast<GrSLType>(-1) != slTypes[attribIndex] && 174 slTypes[attribIndex] != effectSLType)) { 175 return false; 176 } 177 slTypes[attribIndex] = effectSLType; 178 } 179 } 180 181 return true; 182 } 183 184 bool GrDrawState::willEffectReadDstColor() const { 185 if (!this->isColorWriteDisabled()) { 186 for (int s = 0; s < fColorStages.count(); ++s) { 187 if ((*fColorStages[s].getEffect())->willReadDstColor()) { 188 return true; 189 } 190 } 191 } 192 for (int s = 0; s < fCoverageStages.count(); ++s) { 193 if ((*fCoverageStages[s].getEffect())->willReadDstColor()) { 194 return true; 195 } 196 } 197 return false; 198 } 199 200 //////////////////////////////////////////////////////////////////////////////// 201 202 bool GrDrawState::srcAlphaWillBeOne() const { 203 uint32_t validComponentFlags; 204 GrColor color; 205 // Check if per-vertex or constant color may have partial alpha 206 if (this->hasColorVertexAttribute()) { 207 validComponentFlags = 0; 208 color = 0; // not strictly necessary but we get false alarms from tools about uninit. 209 } else { 210 validComponentFlags = kRGBA_GrColorComponentFlags; 211 color = this->getColor(); 212 } 213 214 // Run through the color stages 215 for (int s = 0; s < fColorStages.count(); ++s) { 216 const GrEffectRef* effect = fColorStages[s].getEffect(); 217 (*effect)->getConstantColorComponents(&color, &validComponentFlags); 218 } 219 220 // Check whether coverage is treated as color. If so we run through the coverage computation. 221 if (this->isCoverageDrawing()) { 222 GrColor coverageColor = this->getCoverageColor(); 223 GrColor oldColor = color; 224 color = 0; 225 for (int c = 0; c < 4; ++c) { 226 if (validComponentFlags & (1 << c)) { 227 U8CPU a = (oldColor >> (c * 8)) & 0xff; 228 U8CPU b = (coverageColor >> (c * 8)) & 0xff; 229 color |= (SkMulDiv255Round(a, b) << (c * 8)); 230 } 231 } 232 for (int s = 0; s < fCoverageStages.count(); ++s) { 233 const GrEffectRef* effect = fCoverageStages[s].getEffect(); 234 (*effect)->getConstantColorComponents(&color, &validComponentFlags); 235 } 236 } 237 return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color); 238 } 239 240 bool GrDrawState::hasSolidCoverage() const { 241 // If we're drawing coverage directly then coverage is effectively treated as color. 242 if (this->isCoverageDrawing()) { 243 return true; 244 } 245 246 GrColor coverage; 247 uint32_t validComponentFlags; 248 // Initialize to an unknown starting coverage if per-vertex coverage is specified. 249 if (this->hasCoverageVertexAttribute()) { 250 validComponentFlags = 0; 251 } else { 252 coverage = fCommon.fCoverage; 253 validComponentFlags = kRGBA_GrColorComponentFlags; 254 } 255 256 // Run through the coverage stages and see if the coverage will be all ones at the end. 257 for (int s = 0; s < fCoverageStages.count(); ++s) { 258 const GrEffectRef* effect = fCoverageStages[s].getEffect(); 259 (*effect)->getConstantColorComponents(&coverage, &validComponentFlags); 260 } 261 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage); 262 } 263 264 //////////////////////////////////////////////////////////////////////////////// 265 266 // Some blend modes allow folding a fractional coverage value into the color's alpha channel, while 267 // others will blend incorrectly. 268 bool GrDrawState::canTweakAlphaForCoverage() const { 269 /* 270 The fractional coverage is f. 271 The src and dst coeffs are Cs and Cd. 272 The dst and src colors are S and D. 273 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha 274 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second 275 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we 276 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D. 277 Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as 278 color by definition. 279 */ 280 return kOne_GrBlendCoeff == fCommon.fDstBlend || 281 kISA_GrBlendCoeff == fCommon.fDstBlend || 282 kISC_GrBlendCoeff == fCommon.fDstBlend || 283 this->isCoverageDrawing(); 284 } 285 286 GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, 287 GrBlendCoeff* srcCoeff, 288 GrBlendCoeff* dstCoeff) const { 289 290 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; 291 if (NULL == srcCoeff) { 292 srcCoeff = &bogusSrcCoeff; 293 } 294 *srcCoeff = this->getSrcBlendCoeff(); 295 296 if (NULL == dstCoeff) { 297 dstCoeff = &bogusDstCoeff; 298 } 299 *dstCoeff = this->getDstBlendCoeff(); 300 301 if (this->isColorWriteDisabled()) { 302 *srcCoeff = kZero_GrBlendCoeff; 303 *dstCoeff = kOne_GrBlendCoeff; 304 } 305 306 bool srcAIsOne = this->srcAlphaWillBeOne(); 307 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || 308 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); 309 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || 310 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); 311 312 bool covIsZero = !this->isCoverageDrawing() && 313 !this->hasCoverageVertexAttribute() && 314 0 == this->getCoverageColor(); 315 // When coeffs are (0,1) there is no reason to draw at all, unless 316 // stenciling is enabled. Having color writes disabled is effectively 317 // (0,1). The same applies when coverage is known to be 0. 318 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { 319 if (this->getStencil().doesWrite()) { 320 return kDisableBlend_BlendOptFlag | 321 kEmitCoverage_BlendOptFlag; 322 } else { 323 return kSkipDraw_BlendOptFlag; 324 } 325 } 326 327 // check for coverage due to constant coverage, per-vertex coverage, or coverage stage 328 bool hasCoverage = forceCoverage || 329 0xffffffff != this->getCoverageColor() || 330 this->hasCoverageVertexAttribute() || 331 fCoverageStages.count() > 0; 332 333 // if we don't have coverage we can check whether the dst 334 // has to read at all. If not, we'll disable blending. 335 if (!hasCoverage) { 336 if (dstCoeffIsZero) { 337 if (kOne_GrBlendCoeff == *srcCoeff) { 338 // if there is no coverage and coeffs are (1,0) then we 339 // won't need to read the dst at all, it gets replaced by src 340 return kDisableBlend_BlendOptFlag; 341 } else if (kZero_GrBlendCoeff == *srcCoeff) { 342 // if the op is "clear" then we don't need to emit a color 343 // or blend, just write transparent black into the dst. 344 *srcCoeff = kOne_GrBlendCoeff; 345 *dstCoeff = kZero_GrBlendCoeff; 346 return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; 347 } 348 } 349 } else if (this->isCoverageDrawing()) { 350 // we have coverage but we aren't distinguishing it from alpha by request. 351 return kCoverageAsAlpha_BlendOptFlag; 352 } else { 353 // check whether coverage can be safely rolled into alpha 354 // of if we can skip color computation and just emit coverage 355 if (this->canTweakAlphaForCoverage()) { 356 return kCoverageAsAlpha_BlendOptFlag; 357 } 358 if (dstCoeffIsZero) { 359 if (kZero_GrBlendCoeff == *srcCoeff) { 360 // the source color is not included in the blend 361 // the dst coeff is effectively zero so blend works out to: 362 // (c)(0)D + (1-c)D = (1-c)D. 363 *dstCoeff = kISA_GrBlendCoeff; 364 return kEmitCoverage_BlendOptFlag; 365 } else if (srcAIsOne) { 366 // the dst coeff is effectively zero so blend works out to: 367 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. 368 // If Sa is 1 then we can replace Sa with c 369 // and set dst coeff to 1-Sa. 370 *dstCoeff = kISA_GrBlendCoeff; 371 return kCoverageAsAlpha_BlendOptFlag; 372 } 373 } else if (dstCoeffIsOne) { 374 // the dst coeff is effectively one so blend works out to: 375 // cS + (c)(1)D + (1-c)D = cS + D. 376 *dstCoeff = kOne_GrBlendCoeff; 377 return kCoverageAsAlpha_BlendOptFlag; 378 } 379 } 380 if (kOne_GrBlendCoeff == *srcCoeff && 381 kZero_GrBlendCoeff == *dstCoeff && 382 this->willEffectReadDstColor()) { 383 // In this case the shader will fully resolve the color, coverage, and dst and we don't 384 // need blending. 385 return kDisableBlend_BlendOptFlag; 386 } 387 return kNone_BlendOpt; 388 } 389 390 //////////////////////////////////////////////////////////////////////////////// 391 392 void GrDrawState::AutoViewMatrixRestore::restore() { 393 if (NULL != fDrawState) { 394 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) 395 fDrawState->fCommon.fViewMatrix = fViewMatrix; 396 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); 397 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; 398 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); 399 400 int i = 0; 401 for (int s = 0; s < fNumColorStages; ++s, ++i) { 402 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]); 403 } 404 for (int s = 0; s < numCoverageStages; ++s, ++i) { 405 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]); 406 } 407 fDrawState = NULL; 408 } 409 } 410 411 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, 412 const SkMatrix& preconcatMatrix) { 413 this->restore(); 414 415 SkASSERT(NULL == fDrawState); 416 if (NULL == drawState || preconcatMatrix.isIdentity()) { 417 return; 418 } 419 fDrawState = drawState; 420 421 fViewMatrix = drawState->getViewMatrix(); 422 drawState->fCommon.fViewMatrix.preConcat(preconcatMatrix); 423 424 this->doEffectCoordChanges(preconcatMatrix); 425 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) 426 } 427 428 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { 429 this->restore(); 430 431 if (NULL == drawState) { 432 return false; 433 } 434 435 if (drawState->getViewMatrix().isIdentity()) { 436 return true; 437 } 438 439 fViewMatrix = drawState->getViewMatrix(); 440 if (0 == drawState->numTotalStages()) { 441 drawState->fCommon.fViewMatrix.reset(); 442 fDrawState = drawState; 443 fNumColorStages = 0; 444 fSavedCoordChanges.reset(0); 445 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) 446 return true; 447 } else { 448 SkMatrix inv; 449 if (!fViewMatrix.invert(&inv)) { 450 return false; 451 } 452 drawState->fCommon.fViewMatrix.reset(); 453 fDrawState = drawState; 454 this->doEffectCoordChanges(inv); 455 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) 456 return true; 457 } 458 } 459 460 void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) { 461 fSavedCoordChanges.reset(fDrawState->numTotalStages()); 462 int i = 0; 463 464 fNumColorStages = fDrawState->numColorStages(); 465 for (int s = 0; s < fNumColorStages; ++s, ++i) { 466 fDrawState->fColorStages[s].saveCoordChange(&fSavedCoordChanges[i]); 467 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); 468 } 469 470 int numCoverageStages = fDrawState->numCoverageStages(); 471 for (int s = 0; s < numCoverageStages; ++s, ++i) { 472 fDrawState->fCoverageStages[s].saveCoordChange(&fSavedCoordChanges[i]); 473 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); 474 } 475 } 476