| 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 |
| 10 #include "GrDrawTargetCaps.h" |
| 11 #include "GrOptDrawState.h" |
| 9 #include "GrPaint.h" | 12 #include "GrPaint.h" |
| 10 #include "GrDrawTargetCaps.h" | |
| 11 | 13 |
| 12 //////////////////////////////////////////////////////////////////////////////s | 14 //////////////////////////////////////////////////////////////////////////////s |
| 13 | 15 |
| 16 GrOptDrawState* GrDrawState::createOptState() const { |
| 17 if (NULL == fCachedOptState) { |
| 18 fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this)); |
| 19 } else { |
| 20 SkASSERT(GrOptDrawState(*this) == *fCachedOptState); |
| 21 } |
| 22 fCachedOptState->ref(); |
| 23 return fCachedOptState; |
| 24 } |
| 25 |
| 26 //////////////////////////////////////////////////////////////////////////////s |
| 27 |
| 14 GrDrawState::CombinedState GrDrawState::CombineIfPossible( | 28 GrDrawState::CombinedState GrDrawState::CombineIfPossible( |
| 15 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { | 29 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { |
| 16 | 30 |
| 17 if (!a.isEqual(b)) { | 31 if (!a.isEqual(b)) { |
| 18 return kIncompatible_CombinedState; | 32 return kIncompatible_CombinedState; |
| 19 } | 33 } |
| 20 | 34 |
| 21 // If the general draw states are equal (from check above) we know hasColorV
ertexAttribute() | 35 // If the general draw states are equal (from check above) we know hasColorV
ertexAttribute() |
| 22 // is equivalent for both a and b | 36 // is equivalent for both a and b |
| 23 if (a.hasColorVertexAttribute()) { | 37 if (a.hasColorVertexAttribute()) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 43 } | 57 } |
| 44 } | 58 } |
| 45 return aIsOpaque ? kB_CombinedState : kA_CombinedState; | 59 return aIsOpaque ? kB_CombinedState : kA_CombinedState; |
| 46 } | 60 } |
| 47 } | 61 } |
| 48 return kAOrB_CombinedState; | 62 return kAOrB_CombinedState; |
| 49 } | 63 } |
| 50 | 64 |
| 51 //////////////////////////////////////////////////////////////////////////////s | 65 //////////////////////////////////////////////////////////////////////////////s |
| 52 | 66 |
| 53 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
ix) { | 67 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
ix) |
| 68 : fCachedOptState(NULL) { |
| 54 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) | 69 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
| 55 *this = state; | 70 *this = state; |
| 56 if (!preConcatMatrix.isIdentity()) { | 71 if (!preConcatMatrix.isIdentity()) { |
| 57 if (this->hasGeometryProcessor()) { | 72 if (this->hasGeometryProcessor()) { |
| 58 fGeometryProcessor->localCoordChange(preConcatMatrix); | 73 fGeometryProcessor->localCoordChange(preConcatMatrix); |
| 59 } | 74 } |
| 60 for (int i = 0; i < this->numColorStages(); ++i) { | 75 for (int i = 0; i < this->numColorStages(); ++i) { |
| 61 fColorStages[i].localCoordChange(preConcatMatrix); | 76 fColorStages[i].localCoordChange(preConcatMatrix); |
| 62 } | 77 } |
| 63 for (int i = 0; i < this->numCoverageStages(); ++i) { | 78 for (int i = 0; i < this->numCoverageStages(); ++i) { |
| 64 fCoverageStages[i].localCoordChange(preConcatMatrix); | 79 fCoverageStages[i].localCoordChange(preConcatMatrix); |
| 65 } | 80 } |
| 66 this->invalidateBlendOptFlags(); | 81 this->invalidateOptState(); |
| 67 } | 82 } |
| 68 } | 83 } |
| 69 | 84 |
| 70 GrDrawState& GrDrawState::operator=(const GrDrawState& that) { | 85 GrDrawState& GrDrawState::operator=(const GrDrawState& that) { |
| 71 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 86 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
| 72 SkASSERT(!that.fRenderTarget.ownsPendingIO()); | 87 SkASSERT(!that.fRenderTarget.ownsPendingIO()); |
| 73 SkASSERT(!this->fRenderTarget.ownsPendingIO()); | 88 SkASSERT(!this->fRenderTarget.ownsPendingIO()); |
| 74 this->setRenderTarget(that.getRenderTarget()); | 89 this->setRenderTarget(that.getRenderTarget()); |
| 75 fColor = that.fColor; | 90 fColor = that.fColor; |
| 76 fViewMatrix = that.fViewMatrix; | 91 fViewMatrix = that.fViewMatrix; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 90 fGeometryProcessor.reset(NULL); | 105 fGeometryProcessor.reset(NULL); |
| 91 } | 106 } |
| 92 fColorStages = that.fColorStages; | 107 fColorStages = that.fColorStages; |
| 93 fCoverageStages = that.fCoverageStages; | 108 fCoverageStages = that.fCoverageStages; |
| 94 fOptSrcBlend = that.fOptSrcBlend; | 109 fOptSrcBlend = that.fOptSrcBlend; |
| 95 fOptDstBlend = that.fOptDstBlend; | 110 fOptDstBlend = that.fOptDstBlend; |
| 96 fBlendOptFlags = that.fBlendOptFlags; | 111 fBlendOptFlags = that.fBlendOptFlags; |
| 97 | 112 |
| 98 fHints = that.fHints; | 113 fHints = that.fHints; |
| 99 | 114 |
| 115 SkRefCnt_SafeAssign(fCachedOptState, that.fCachedOptState); |
| 116 |
| 100 memcpy(fFixedFunctionVertexAttribIndices, | 117 memcpy(fFixedFunctionVertexAttribIndices, |
| 101 that.fFixedFunctionVertexAttribIndices, | 118 that.fFixedFunctionVertexAttribIndices, |
| 102 sizeof(fFixedFunctionVertexAttribIndices)); | 119 sizeof(fFixedFunctionVertexAttribIndices)); |
| 103 return *this; | 120 return *this; |
| 104 } | 121 } |
| 105 | 122 |
| 106 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { | 123 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { |
| 107 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 124 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
| 108 SkASSERT(!fRenderTarget.ownsPendingIO()); | 125 SkASSERT(!fRenderTarget.ownsPendingIO()); |
| 109 | 126 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 124 fSrcBlend = kOne_GrBlendCoeff; | 141 fSrcBlend = kOne_GrBlendCoeff; |
| 125 fDstBlend = kZero_GrBlendCoeff; | 142 fDstBlend = kZero_GrBlendCoeff; |
| 126 fBlendConstant = 0x0; | 143 fBlendConstant = 0x0; |
| 127 fFlagBits = 0x0; | 144 fFlagBits = 0x0; |
| 128 fStencilSettings.setDisabled(); | 145 fStencilSettings.setDisabled(); |
| 129 fCoverage = 0xff; | 146 fCoverage = 0xff; |
| 130 fDrawFace = kBoth_DrawFace; | 147 fDrawFace = kBoth_DrawFace; |
| 131 | 148 |
| 132 fHints = 0; | 149 fHints = 0; |
| 133 | 150 |
| 134 this->invalidateBlendOptFlags(); | 151 this->invalidateOptState(); |
| 135 } | 152 } |
| 136 | 153 |
| 137 bool GrDrawState::setIdentityViewMatrix() { | 154 bool GrDrawState::setIdentityViewMatrix() { |
| 138 if (this->numTotalStages()) { | 155 if (this->numTotalStages()) { |
| 139 SkMatrix invVM; | 156 SkMatrix invVM; |
| 140 if (!fViewMatrix.invert(&invVM)) { | 157 if (!fViewMatrix.invert(&invVM)) { |
| 141 // sad trombone sound | 158 // sad trombone sound |
| 142 return false; | 159 return false; |
| 143 } | 160 } |
| 144 if (this->hasGeometryProcessor()) { | 161 if (this->hasGeometryProcessor()) { |
| 145 fGeometryProcessor->localCoordChange(invVM); | 162 fGeometryProcessor->localCoordChange(invVM); |
| 146 } | 163 } |
| 147 for (int s = 0; s < this->numColorStages(); ++s) { | 164 for (int s = 0; s < this->numColorStages(); ++s) { |
| 148 fColorStages[s].localCoordChange(invVM); | 165 fColorStages[s].localCoordChange(invVM); |
| 149 } | 166 } |
| 150 for (int s = 0; s < this->numCoverageStages(); ++s) { | 167 for (int s = 0; s < this->numCoverageStages(); ++s) { |
| 151 fCoverageStages[s].localCoordChange(invVM); | 168 fCoverageStages[s].localCoordChange(invVM); |
| 152 } | 169 } |
| 153 } | 170 } |
| 171 this->invalidateOptState(); |
| 154 fViewMatrix.reset(); | 172 fViewMatrix.reset(); |
| 155 return true; | 173 return true; |
| 156 } | 174 } |
| 157 | 175 |
| 158 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
rTarget* rt) { | 176 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
rTarget* rt) { |
| 159 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 177 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
| 160 | 178 |
| 161 fGeometryProcessor.reset(NULL); | 179 fGeometryProcessor.reset(NULL); |
| 162 fColorStages.reset(); | 180 fColorStages.reset(); |
| 163 fCoverageStages.reset(); | 181 fCoverageStages.reset(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 183 | 201 |
| 184 // Enable the clip bit | 202 // Enable the clip bit |
| 185 this->enableState(GrDrawState::kClip_StateBit); | 203 this->enableState(GrDrawState::kClip_StateBit); |
| 186 | 204 |
| 187 this->setColor(paint.getColor()); | 205 this->setColor(paint.getColor()); |
| 188 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | 206 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
| 189 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | 207 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
| 190 | 208 |
| 191 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); | 209 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
| 192 this->setCoverage(paint.getCoverage()); | 210 this->setCoverage(paint.getCoverage()); |
| 193 this->invalidateBlendOptFlags(); | 211 this->invalidateOptState(); |
| 194 } | 212 } |
| 195 | 213 |
| 196 //////////////////////////////////////////////////////////////////////////////// | 214 //////////////////////////////////////////////////////////////////////////////// |
| 197 | 215 |
| 198 static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, si
ze_t stride) { | 216 static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, si
ze_t stride) { |
| 199 // this works as long as we're 4 byte-aligned | 217 // this works as long as we're 4 byte-aligned |
| 200 #ifdef SK_DEBUG | 218 #ifdef SK_DEBUG |
| 201 uint32_t overlapCheck = 0; | 219 uint32_t overlapCheck = 0; |
| 202 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); | 220 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); |
| 203 for (int index = 0; index < count; ++index) { | 221 for (int index = 0; index < count; ++index) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i; | 258 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i; |
| 241 } | 259 } |
| 242 #ifdef SK_DEBUG | 260 #ifdef SK_DEBUG |
| 243 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2; | 261 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2; |
| 244 uint32_t mask = (1 << dwordCount)-1; | 262 uint32_t mask = (1 << dwordCount)-1; |
| 245 size_t offsetShift = attribs[i].fOffset >> 2; | 263 size_t offsetShift = attribs[i].fOffset >> 2; |
| 246 SkASSERT(!(overlapCheck & (mask << offsetShift))); | 264 SkASSERT(!(overlapCheck & (mask << offsetShift))); |
| 247 overlapCheck |= (mask << offsetShift); | 265 overlapCheck |= (mask << offsetShift); |
| 248 #endif | 266 #endif |
| 249 } | 267 } |
| 250 this->invalidateBlendOptFlags(); | 268 this->invalidateOptState(); |
| 251 // Positions must be specified. | 269 // Positions must be specified. |
| 252 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBin
ding]); | 270 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBin
ding]); |
| 253 } | 271 } |
| 254 | 272 |
| 255 //////////////////////////////////////////////////////////////////////////////// | 273 //////////////////////////////////////////////////////////////////////////////// |
| 256 | 274 |
| 257 void GrDrawState::setDefaultVertexAttribs() { | 275 void GrDrawState::setDefaultVertexAttribs() { |
| 258 static const GrVertexAttrib kPositionAttrib = | 276 static const GrVertexAttrib kPositionAttrib = |
| 259 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}; | 277 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}; |
| 260 | 278 |
| 261 fVAPtr = &kPositionAttrib; | 279 fVAPtr = &kPositionAttrib; |
| 262 fVACount = 1; | 280 fVACount = 1; |
| 263 fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); | 281 fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); |
| 264 | 282 |
| 265 // set all the fixed function indices to -1 except position. | 283 // set all the fixed function indices to -1 except position. |
| 266 memset(fFixedFunctionVertexAttribIndices, | 284 memset(fFixedFunctionVertexAttribIndices, |
| 267 0xff, | 285 0xff, |
| 268 sizeof(fFixedFunctionVertexAttribIndices)); | 286 sizeof(fFixedFunctionVertexAttribIndices)); |
| 269 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; | 287 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; |
| 270 this->invalidateBlendOptFlags(); | 288 this->invalidateOptState(); |
| 271 } | 289 } |
| 272 | 290 |
| 273 //////////////////////////////////////////////////////////////////////////////// | 291 //////////////////////////////////////////////////////////////////////////////// |
| 274 | 292 |
| 275 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { | 293 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
| 276 if (caps.dualSourceBlendingSupport()) { | 294 if (caps.dualSourceBlendingSupport()) { |
| 277 return true; | 295 return true; |
| 278 } | 296 } |
| 279 // we can correctly apply coverage if a) we have dual source blending | 297 // we can correctly apply coverage if a) we have dual source blending |
| 280 // or b) one of our blend optimizations applies | 298 // or b) one of our blend optimizations applies |
| 281 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color | 299 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color |
| 282 GrBlendCoeff srcCoeff; | 300 GrBlendCoeff srcCoeff; |
| 283 GrBlendCoeff dstCoeff; | 301 GrBlendCoeff dstCoeff; |
| 284 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dst
Coeff); | 302 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dst
Coeff); |
| 285 return GrRODrawState::kNone_BlendOpt != flag || | 303 return GrRODrawState::kNone_BlendOpt != flag || |
| 286 (this->willEffectReadDstColor() && | 304 (this->willEffectReadDstColor() && |
| 287 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); | 305 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
| 288 } | 306 } |
| 289 | 307 |
| 290 ////////////////////////////////////////////////////////////////////////////// | 308 ////////////////////////////////////////////////////////////////////////////// |
| 291 | 309 |
| 292 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( | 310 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawS
tate) { |
| 293 GrDrawState* drawState) { | |
| 294 SkASSERT(drawState); | 311 SkASSERT(drawState); |
| 295 fDrawState = drawState; | 312 fDrawState = drawState; |
| 296 fVAPtr = drawState->fVAPtr; | 313 fVAPtr = drawState->fVAPtr; |
| 297 fVACount = drawState->fVACount; | 314 fVACount = drawState->fVACount; |
| 298 fVAStride = drawState->fVAStride; | 315 fVAStride = drawState->fVAStride; |
| 299 fDrawState->setDefaultVertexAttribs(); | 316 fDrawState->setDefaultVertexAttribs(); |
| 300 } | 317 } |
| 301 | 318 |
| 302 //////////////////////////////////////////////////////////////////////////////s | 319 //////////////////////////////////////////////////////////////////////////////s |
| 303 | 320 |
| 304 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { | 321 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
| 305 if (fDrawState) { | 322 if (fDrawState) { |
| 306 // See the big comment on the class definition about GPs. | 323 // See the big comment on the class definition about GPs. |
| 307 if (SK_InvalidUniqueID == fOriginalGPID) { | 324 if (SK_InvalidUniqueID == fOriginalGPID) { |
| 308 fDrawState->fGeometryProcessor.reset(NULL); | 325 fDrawState->fGeometryProcessor.reset(NULL); |
| 309 } else { | 326 } else { |
| 310 SkASSERT(fDrawState->getGeometryProcessor()->getEffect()->getUniqueI
D() == | 327 SkASSERT(fDrawState->getGeometryProcessor()->getEffect()->getUniqueI
D() == |
| 311 fOriginalGPID); | 328 fOriginalGPID); |
| 312 fOriginalGPID = SK_InvalidUniqueID; | 329 fOriginalGPID = SK_InvalidUniqueID; |
| 313 } | 330 } |
| 314 | 331 |
| 315 int m = fDrawState->numColorStages() - fColorEffectCnt; | 332 int m = fDrawState->numColorStages() - fColorEffectCnt; |
| 316 SkASSERT(m >= 0); | 333 SkASSERT(m >= 0); |
| 317 fDrawState->fColorStages.pop_back_n(m); | 334 fDrawState->fColorStages.pop_back_n(m); |
| 318 | 335 |
| 319 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; | 336 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; |
| 320 SkASSERT(n >= 0); | 337 SkASSERT(n >= 0); |
| 321 fDrawState->fCoverageStages.pop_back_n(n); | 338 fDrawState->fCoverageStages.pop_back_n(n); |
| 322 if (m + n > 0) { | 339 if (m + n > 0) { |
| 323 fDrawState->invalidateBlendOptFlags(); | 340 fDrawState->invalidateOptState(); |
| 324 } | 341 } |
| 325 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 342 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
| 326 } | 343 } |
| 327 fDrawState = ds; | 344 fDrawState = ds; |
| 328 if (NULL != ds) { | 345 if (NULL != ds) { |
| 329 SkASSERT(SK_InvalidUniqueID == fOriginalGPID); | 346 SkASSERT(SK_InvalidUniqueID == fOriginalGPID); |
| 330 if (NULL != ds->getGeometryProcessor()) { | 347 if (NULL != ds->getGeometryProcessor()) { |
| 331 fOriginalGPID = ds->getGeometryProcessor()->getEffect()->getUniqueID
(); | 348 fOriginalGPID = ds->getGeometryProcessor()->getEffect()->getUniqueID
(); |
| 332 } | 349 } |
| 333 fColorEffectCnt = ds->numColorStages(); | 350 fColorEffectCnt = ds->numColorStages(); |
| 334 fCoverageEffectCnt = ds->numCoverageStages(); | 351 fCoverageEffectCnt = ds->numCoverageStages(); |
| 335 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) | 352 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
| 336 } | 353 } |
| 337 } | 354 } |
| 338 | 355 |
| 339 //////////////////////////////////////////////////////////////////////////////// | 356 //////////////////////////////////////////////////////////////////////////////// |
| 340 | 357 |
| 341 GrRODrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, | |
| 342 GrBlendCoeff* srcCoeff, | |
| 343 GrBlendCoeff* dstCoeff) c
onst { | |
| 344 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; | |
| 345 if (NULL == srcCoeff) { | |
| 346 srcCoeff = &bogusSrcCoeff; | |
| 347 } | |
| 348 if (NULL == dstCoeff) { | |
| 349 dstCoeff = &bogusDstCoeff; | |
| 350 } | |
| 351 | |
| 352 if (forceCoverage) { | |
| 353 return this->calcBlendOpts(true, srcCoeff, dstCoeff); | |
| 354 } | |
| 355 | |
| 356 if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) { | |
| 357 *srcCoeff = fOptSrcBlend; | |
| 358 *dstCoeff = fOptDstBlend; | |
| 359 return fBlendOptFlags; | |
| 360 } | |
| 361 | |
| 362 fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff); | |
| 363 fOptSrcBlend = *srcCoeff; | |
| 364 fOptDstBlend = *dstCoeff; | |
| 365 | |
| 366 return fBlendOptFlags; | |
| 367 } | |
| 368 | |
| 369 GrRODrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, | |
| 370 GrBlendCoeff* srcCoeff
, | |
| 371 GrBlendCoeff* dstCoeff
) const { | |
| 372 *srcCoeff = this->getSrcBlendCoeff(); | |
| 373 *dstCoeff = this->getDstBlendCoeff(); | |
| 374 | |
| 375 if (this->isColorWriteDisabled()) { | |
| 376 *srcCoeff = kZero_GrBlendCoeff; | |
| 377 *dstCoeff = kOne_GrBlendCoeff; | |
| 378 } | |
| 379 | |
| 380 bool srcAIsOne = this->srcAlphaWillBeOne(); | |
| 381 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || | |
| 382 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); | |
| 383 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || | |
| 384 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); | |
| 385 | |
| 386 // When coeffs are (0,1) there is no reason to draw at all, unless | |
| 387 // stenciling is enabled. Having color writes disabled is effectively | |
| 388 // (0,1). | |
| 389 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { | |
| 390 if (this->getStencil().doesWrite()) { | |
| 391 return kEmitCoverage_BlendOptFlag; | |
| 392 } else { | |
| 393 return kSkipDraw_BlendOptFlag; | |
| 394 } | |
| 395 } | |
| 396 | |
| 397 bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); | |
| 398 | |
| 399 // if we don't have coverage we can check whether the dst | |
| 400 // has to read at all. If not, we'll disable blending. | |
| 401 if (!hasCoverage) { | |
| 402 if (dstCoeffIsZero) { | |
| 403 if (kOne_GrBlendCoeff == *srcCoeff) { | |
| 404 // if there is no coverage and coeffs are (1,0) then we | |
| 405 // won't need to read the dst at all, it gets replaced by src | |
| 406 *dstCoeff = kZero_GrBlendCoeff; | |
| 407 return kNone_BlendOpt; | |
| 408 } else if (kZero_GrBlendCoeff == *srcCoeff) { | |
| 409 // if the op is "clear" then we don't need to emit a color | |
| 410 // or blend, just write transparent black into the dst. | |
| 411 *srcCoeff = kOne_GrBlendCoeff; | |
| 412 *dstCoeff = kZero_GrBlendCoeff; | |
| 413 return kEmitTransBlack_BlendOptFlag; | |
| 414 } | |
| 415 } | |
| 416 } else if (this->isCoverageDrawing()) { | |
| 417 // we have coverage but we aren't distinguishing it from alpha by reques
t. | |
| 418 return kCoverageAsAlpha_BlendOptFlag; | |
| 419 } else { | |
| 420 // check whether coverage can be safely rolled into alpha | |
| 421 // of if we can skip color computation and just emit coverage | |
| 422 if (this->canTweakAlphaForCoverage()) { | |
| 423 return kCoverageAsAlpha_BlendOptFlag; | |
| 424 } | |
| 425 if (dstCoeffIsZero) { | |
| 426 if (kZero_GrBlendCoeff == *srcCoeff) { | |
| 427 // the source color is not included in the blend | |
| 428 // the dst coeff is effectively zero so blend works out to: | |
| 429 // (c)(0)D + (1-c)D = (1-c)D. | |
| 430 *dstCoeff = kISA_GrBlendCoeff; | |
| 431 return kEmitCoverage_BlendOptFlag; | |
| 432 } else if (srcAIsOne) { | |
| 433 // the dst coeff is effectively zero so blend works out to: | |
| 434 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. | |
| 435 // If Sa is 1 then we can replace Sa with c | |
| 436 // and set dst coeff to 1-Sa. | |
| 437 *dstCoeff = kISA_GrBlendCoeff; | |
| 438 return kCoverageAsAlpha_BlendOptFlag; | |
| 439 } | |
| 440 } else if (dstCoeffIsOne) { | |
| 441 // the dst coeff is effectively one so blend works out to: | |
| 442 // cS + (c)(1)D + (1-c)D = cS + D. | |
| 443 *dstCoeff = kOne_GrBlendCoeff; | |
| 444 return kCoverageAsAlpha_BlendOptFlag; | |
| 445 } | |
| 446 } | |
| 447 | |
| 448 return kNone_BlendOpt; | |
| 449 } | |
| 450 | |
| 451 //////////////////////////////////////////////////////////////////////////////// | |
| 452 | |
| 453 void GrDrawState::AutoViewMatrixRestore::restore() { | 358 void GrDrawState::AutoViewMatrixRestore::restore() { |
| 454 if (fDrawState) { | 359 if (fDrawState) { |
| 455 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 360 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
| 456 fDrawState->fViewMatrix = fViewMatrix; | 361 fDrawState->fViewMatrix = fViewMatrix; |
| 457 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); | 362 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); |
| 458 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; | 363 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; |
| 459 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); | 364 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); |
| 460 | 365 |
| 461 int i = 0; | 366 int i = 0; |
| 462 if (fHasGeometryProcessor) { | 367 if (fHasGeometryProcessor) { |
| 463 SkASSERT(fDrawState->hasGeometryProcessor()); | 368 SkASSERT(fDrawState->hasGeometryProcessor()); |
| 464 fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChange
s[i++]); | 369 fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChange
s[i++]); |
| 465 } | 370 } |
| 466 for (int s = 0; s < fNumColorStages; ++s, ++i) { | 371 for (int s = 0; s < fNumColorStages; ++s, ++i) { |
| 467 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]
); | 372 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]
); |
| 468 } | 373 } |
| 469 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 374 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
| 470 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges
[i]); | 375 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges
[i]); |
| 471 } | 376 } |
| 377 fDrawState->invalidateOptState(); |
| 472 fDrawState = NULL; | 378 fDrawState = NULL; |
| 473 } | 379 } |
| 474 } | 380 } |
| 475 | 381 |
| 476 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, | 382 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, |
| 477 const SkMatrix& preconcatMatrix) { | 383 const SkMatrix& preconcatMatrix) { |
| 478 this->restore(); | 384 this->restore(); |
| 479 | 385 |
| 480 SkASSERT(NULL == fDrawState); | 386 SkASSERT(NULL == fDrawState); |
| 481 if (NULL == drawState || preconcatMatrix.isIdentity()) { | 387 if (NULL == drawState || preconcatMatrix.isIdentity()) { |
| 482 return; | 388 return; |
| 483 } | 389 } |
| 484 fDrawState = drawState; | 390 fDrawState = drawState; |
| 485 | 391 |
| 486 fViewMatrix = drawState->getViewMatrix(); | 392 fViewMatrix = drawState->getViewMatrix(); |
| 487 drawState->fViewMatrix.preConcat(preconcatMatrix); | 393 drawState->fViewMatrix.preConcat(preconcatMatrix); |
| 488 | 394 |
| 489 this->doEffectCoordChanges(preconcatMatrix); | 395 this->doEffectCoordChanges(preconcatMatrix); |
| 490 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) | 396 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
| 397 drawState->invalidateOptState(); |
| 491 } | 398 } |
| 492 | 399 |
| 493 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { | 400 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { |
| 494 this->restore(); | 401 this->restore(); |
| 495 | 402 |
| 496 if (NULL == drawState) { | 403 if (NULL == drawState) { |
| 497 return false; | 404 return false; |
| 498 } | 405 } |
| 499 | 406 |
| 500 if (drawState->getViewMatrix().isIdentity()) { | 407 if (drawState->getViewMatrix().isIdentity()) { |
| 501 return true; | 408 return true; |
| 502 } | 409 } |
| 503 | 410 |
| 411 drawState->invalidateOptState(); |
| 504 fViewMatrix = drawState->getViewMatrix(); | 412 fViewMatrix = drawState->getViewMatrix(); |
| 505 if (0 == drawState->numTotalStages()) { | 413 if (0 == drawState->numTotalStages()) { |
| 506 drawState->fViewMatrix.reset(); | 414 drawState->fViewMatrix.reset(); |
| 507 fDrawState = drawState; | 415 fDrawState = drawState; |
| 508 fHasGeometryProcessor = false; | 416 fHasGeometryProcessor = false; |
| 509 fNumColorStages = 0; | 417 fNumColorStages = 0; |
| 510 fSavedCoordChanges.reset(0); | 418 fSavedCoordChanges.reset(0); |
| 511 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) | 419 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
| 512 return true; | 420 return true; |
| 513 } else { | 421 } else { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 540 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); | 448 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); |
| 541 } | 449 } |
| 542 | 450 |
| 543 int numCoverageStages = fDrawState->numCoverageStages(); | 451 int numCoverageStages = fDrawState->numCoverageStages(); |
| 544 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 452 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
| 545 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 453 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
| 546 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); | 454 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); |
| 547 } | 455 } |
| 548 } | 456 } |
| 549 | 457 |
| 550 bool GrDrawState::srcAlphaWillBeOne() const { | |
| 551 uint32_t validComponentFlags; | |
| 552 GrColor color; | |
| 553 // Check if per-vertex or constant color may have partial alpha | |
| 554 if (this->hasColorVertexAttribute()) { | |
| 555 if (fHints & kVertexColorsAreOpaque_Hint) { | |
| 556 validComponentFlags = kA_GrColorComponentFlag; | |
| 557 color = 0xFF << GrColor_SHIFT_A; | |
| 558 } else { | |
| 559 validComponentFlags = 0; | |
| 560 color = 0; // not strictly necessary but we get false alarms from to
ols about uninit. | |
| 561 } | |
| 562 } else { | |
| 563 validComponentFlags = kRGBA_GrColorComponentFlags; | |
| 564 color = this->getColor(); | |
| 565 } | |
| 566 | |
| 567 // Run through the color stages | |
| 568 for (int s = 0; s < this->numColorStages(); ++s) { | |
| 569 const GrEffect* effect = this->getColorStage(s).getEffect(); | |
| 570 effect->getConstantColorComponents(&color, &validComponentFlags); | |
| 571 } | |
| 572 | |
| 573 // Check whether coverage is treated as color. If so we run through the cove
rage computation. | |
| 574 if (this->isCoverageDrawing()) { | |
| 575 // The shader generated for coverage drawing runs the full coverage comp
utation and then | |
| 576 // makes the shader output be the multiplication of color and coverage.
We mirror that here. | |
| 577 GrColor coverage; | |
| 578 uint32_t coverageComponentFlags; | |
| 579 if (this->hasCoverageVertexAttribute()) { | |
| 580 coverageComponentFlags = 0; | |
| 581 coverage = 0; // suppresses any warnings. | |
| 582 } else { | |
| 583 coverageComponentFlags = kRGBA_GrColorComponentFlags; | |
| 584 coverage = this->getCoverageColor(); | |
| 585 } | |
| 586 | |
| 587 // Run through the coverage stages | |
| 588 if (this->hasGeometryProcessor()) { | |
| 589 const GrEffect* effect = fGeometryProcessor->getEffect(); | |
| 590 effect->getConstantColorComponents(&coverage, &coverageComponentFlag
s); | |
| 591 } | |
| 592 for (int s = 0; s < this->numCoverageStages(); ++s) { | |
| 593 const GrEffect* effect = this->getCoverageStage(s).getEffect(); | |
| 594 effect->getConstantColorComponents(&coverage, &coverageComponentFlag
s); | |
| 595 } | |
| 596 | |
| 597 // Since the shader will multiply coverage and color, the only way the f
inal A==1 is if | |
| 598 // coverage and color both have A==1. | |
| 599 return (kA_GrColorComponentFlag & validComponentFlags & coverageComponen
tFlags) && | |
| 600 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage
); | |
| 601 | |
| 602 } | |
| 603 | |
| 604 return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnp
ackA(color); | |
| 605 } | |
| 606 | |
| 607 //////////////////////////////////////////////////////////////////////////////// | |
| 608 | |
| 609 bool GrDrawState::canIgnoreColorAttribute() const { | |
| 610 if (fBlendOptFlags & kInvalid_BlendOptFlag) { | |
| 611 this->getBlendOpts(); | |
| 612 } | |
| 613 return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFla
g | | |
| 614 GrRODrawState::kEmitCoverage_BlendOptFlag)
); | |
| 615 } | |
| OLD | NEW |