Chromium Code Reviews| 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 for (int i = 0; i < this->numColorStages(); ++i) { | 72 for (int i = 0; i < this->numColorStages(); ++i) { |
| 58 fColorStages[i].localCoordChange(preConcatMatrix); | 73 fColorStages[i].localCoordChange(preConcatMatrix); |
| 59 } | 74 } |
| 60 for (int i = 0; i < this->numCoverageStages(); ++i) { | 75 for (int i = 0; i < this->numCoverageStages(); ++i) { |
| 61 fCoverageStages[i].localCoordChange(preConcatMatrix); | 76 fCoverageStages[i].localCoordChange(preConcatMatrix); |
| 62 } | 77 } |
| 63 this->invalidateBlendOptFlags(); | 78 this->invalidateOptState(); |
| 64 } | 79 } |
| 65 } | 80 } |
| 66 | 81 |
| 67 GrDrawState& GrDrawState::operator=(const GrDrawState& that) { | 82 GrDrawState& GrDrawState::operator=(const GrDrawState& that) { |
| 68 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 83 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
| 69 this->setRenderTarget(that.fRenderTarget.get()); | 84 this->setRenderTarget(that.fRenderTarget.get()); |
| 70 fColor = that.fColor; | 85 fColor = that.fColor; |
| 71 fViewMatrix = that.fViewMatrix; | 86 fViewMatrix = that.fViewMatrix; |
| 72 fSrcBlend = that.fSrcBlend; | 87 fSrcBlend = that.fSrcBlend; |
| 73 fDstBlend = that.fDstBlend; | 88 fDstBlend = that.fDstBlend; |
| 74 fBlendConstant = that.fBlendConstant; | 89 fBlendConstant = that.fBlendConstant; |
| 75 fFlagBits = that.fFlagBits; | 90 fFlagBits = that.fFlagBits; |
| 76 fVACount = that.fVACount; | 91 fVACount = that.fVACount; |
| 77 fVAPtr = that.fVAPtr; | 92 fVAPtr = that.fVAPtr; |
| 78 fVertexSize = that.fVertexSize; | 93 fVertexSize = that.fVertexSize; |
| 79 fStencilSettings = that.fStencilSettings; | 94 fStencilSettings = that.fStencilSettings; |
| 80 fCoverage = that.fCoverage; | 95 fCoverage = that.fCoverage; |
| 81 fDrawFace = that.fDrawFace; | 96 fDrawFace = that.fDrawFace; |
| 82 fColorStages = that.fColorStages; | 97 fColorStages = that.fColorStages; |
| 83 fCoverageStages = that.fCoverageStages; | 98 fCoverageStages = that.fCoverageStages; |
| 84 fOptSrcBlend = that.fOptSrcBlend; | 99 fOptSrcBlend = that.fOptSrcBlend; |
| 85 fOptDstBlend = that.fOptDstBlend; | 100 fOptDstBlend = that.fOptDstBlend; |
| 86 fBlendOptFlags = that.fBlendOptFlags; | 101 fBlendOptFlags = that.fBlendOptFlags; |
| 87 | 102 |
| 88 fHints = that.fHints; | 103 fHints = that.fHints; |
| 89 | 104 |
| 105 SkRefCnt_SafeAssign(fCachedOptState, that.fCachedOptState); | |
| 106 | |
| 90 memcpy(fFixedFunctionVertexAttribIndices, | 107 memcpy(fFixedFunctionVertexAttribIndices, |
| 91 that.fFixedFunctionVertexAttribIndices, | 108 that.fFixedFunctionVertexAttribIndices, |
| 92 sizeof(fFixedFunctionVertexAttribIndices)); | 109 sizeof(fFixedFunctionVertexAttribIndices)); |
| 93 return *this; | 110 return *this; |
| 94 } | 111 } |
| 95 | 112 |
| 96 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { | 113 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { |
| 97 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 114 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
| 98 fColorStages.reset(); | 115 fColorStages.reset(); |
| 99 fCoverageStages.reset(); | 116 fCoverageStages.reset(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 111 fSrcBlend = kOne_GrBlendCoeff; | 128 fSrcBlend = kOne_GrBlendCoeff; |
| 112 fDstBlend = kZero_GrBlendCoeff; | 129 fDstBlend = kZero_GrBlendCoeff; |
| 113 fBlendConstant = 0x0; | 130 fBlendConstant = 0x0; |
| 114 fFlagBits = 0x0; | 131 fFlagBits = 0x0; |
| 115 fStencilSettings.setDisabled(); | 132 fStencilSettings.setDisabled(); |
| 116 fCoverage = 0xff; | 133 fCoverage = 0xff; |
| 117 fDrawFace = kBoth_DrawFace; | 134 fDrawFace = kBoth_DrawFace; |
| 118 | 135 |
| 119 fHints = 0; | 136 fHints = 0; |
| 120 | 137 |
| 121 this->invalidateBlendOptFlags(); | 138 this->invalidateOptState(); |
| 122 } | 139 } |
| 123 | 140 |
| 124 bool GrDrawState::setIdentityViewMatrix() { | 141 bool GrDrawState::setIdentityViewMatrix() { |
| 125 if (this->numTotalStages()) { | 142 if (this->numTotalStages()) { |
| 126 SkMatrix invVM; | 143 SkMatrix invVM; |
| 127 if (!fViewMatrix.invert(&invVM)) { | 144 if (!fViewMatrix.invert(&invVM)) { |
| 128 // sad trombone sound | 145 // sad trombone sound |
| 129 return false; | 146 return false; |
| 130 } | 147 } |
| 131 for (int s = 0; s < this->numColorStages(); ++s) { | 148 for (int s = 0; s < this->numColorStages(); ++s) { |
| 132 fColorStages[s].localCoordChange(invVM); | 149 fColorStages[s].localCoordChange(invVM); |
| 133 } | 150 } |
| 134 for (int s = 0; s < this->numCoverageStages(); ++s) { | 151 for (int s = 0; s < this->numCoverageStages(); ++s) { |
| 135 fCoverageStages[s].localCoordChange(invVM); | 152 fCoverageStages[s].localCoordChange(invVM); |
| 136 } | 153 } |
| 137 } | 154 } |
| 138 fViewMatrix.reset(); | 155 fViewMatrix.reset(); |
|
bsalomon
2014/08/28 13:49:27
Does this not invalidate the opt state? This is a
egdaniel
2014/08/28 14:39:38
Yeah it will invalidate the opt. In regards to cop
bsalomon
2014/08/28 15:05:02
I think a future evolution could remove GrEffectSt
| |
| 139 return true; | 156 return true; |
| 140 } | 157 } |
| 141 | 158 |
| 142 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende rTarget* rt) { | 159 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende rTarget* rt) { |
| 143 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 160 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
| 144 | 161 |
| 145 fColorStages.reset(); | 162 fColorStages.reset(); |
| 146 fCoverageStages.reset(); | 163 fCoverageStages.reset(); |
| 147 | 164 |
| 148 for (int i = 0; i < paint.numColorStages(); ++i) { | 165 for (int i = 0; i < paint.numColorStages(); ++i) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 166 | 183 |
| 167 // Enable the clip bit | 184 // Enable the clip bit |
| 168 this->enableState(GrDrawState::kClip_StateBit); | 185 this->enableState(GrDrawState::kClip_StateBit); |
| 169 | 186 |
| 170 this->setColor(paint.getColor()); | 187 this->setColor(paint.getColor()); |
| 171 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | 188 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
| 172 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | 189 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
| 173 | 190 |
| 174 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); | 191 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
| 175 this->setCoverage(paint.getCoverage()); | 192 this->setCoverage(paint.getCoverage()); |
| 176 this->invalidateBlendOptFlags(); | 193 this->invalidateOptState(); |
| 177 } | 194 } |
| 178 | 195 |
| 179 //////////////////////////////////////////////////////////////////////////////// | 196 //////////////////////////////////////////////////////////////////////////////// |
| 180 | 197 |
| 181 static size_t vertex_size(const GrVertexAttrib* attribs, int count) { | 198 static size_t vertex_size(const GrVertexAttrib* attribs, int count) { |
| 182 // this works as long as we're 4 byte-aligned | 199 // this works as long as we're 4 byte-aligned |
| 183 #ifdef SK_DEBUG | 200 #ifdef SK_DEBUG |
| 184 uint32_t overlapCheck = 0; | 201 uint32_t overlapCheck = 0; |
| 185 #endif | 202 #endif |
| 186 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); | 203 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i; | 241 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i; |
| 225 } | 242 } |
| 226 #ifdef SK_DEBUG | 243 #ifdef SK_DEBUG |
| 227 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2; | 244 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2; |
| 228 uint32_t mask = (1 << dwordCount)-1; | 245 uint32_t mask = (1 << dwordCount)-1; |
| 229 size_t offsetShift = attribs[i].fOffset >> 2; | 246 size_t offsetShift = attribs[i].fOffset >> 2; |
| 230 SkASSERT(!(overlapCheck & (mask << offsetShift))); | 247 SkASSERT(!(overlapCheck & (mask << offsetShift))); |
| 231 overlapCheck |= (mask << offsetShift); | 248 overlapCheck |= (mask << offsetShift); |
| 232 #endif | 249 #endif |
| 233 } | 250 } |
| 234 this->invalidateBlendOptFlags(); | 251 this->invalidateOptState(); |
| 235 // Positions must be specified. | 252 // Positions must be specified. |
| 236 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBin ding]); | 253 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBin ding]); |
| 237 } | 254 } |
| 238 | 255 |
| 239 //////////////////////////////////////////////////////////////////////////////// | 256 //////////////////////////////////////////////////////////////////////////////// |
| 240 | 257 |
| 241 void GrDrawState::setDefaultVertexAttribs() { | 258 void GrDrawState::setDefaultVertexAttribs() { |
| 242 static const GrVertexAttrib kPositionAttrib = | 259 static const GrVertexAttrib kPositionAttrib = |
| 243 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}; | 260 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}; |
| 244 | 261 |
| 245 fVAPtr = &kPositionAttrib; | 262 fVAPtr = &kPositionAttrib; |
| 246 fVACount = 1; | 263 fVACount = 1; |
| 247 fVertexSize = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); | 264 fVertexSize = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); |
| 248 | 265 |
| 249 // set all the fixed function indices to -1 except position. | 266 // set all the fixed function indices to -1 except position. |
| 250 memset(fFixedFunctionVertexAttribIndices, | 267 memset(fFixedFunctionVertexAttribIndices, |
| 251 0xff, | 268 0xff, |
| 252 sizeof(fFixedFunctionVertexAttribIndices)); | 269 sizeof(fFixedFunctionVertexAttribIndices)); |
| 253 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; | 270 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; |
| 254 this->invalidateBlendOptFlags(); | 271 this->invalidateOptState(); |
| 255 } | 272 } |
| 256 | 273 |
| 257 //////////////////////////////////////////////////////////////////////////////// | 274 //////////////////////////////////////////////////////////////////////////////// |
| 258 | 275 |
| 259 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { | 276 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
| 260 if (caps.dualSourceBlendingSupport()) { | 277 if (caps.dualSourceBlendingSupport()) { |
| 261 return true; | 278 return true; |
| 262 } | 279 } |
| 263 // we can correctly apply coverage if a) we have dual source blending | 280 // we can correctly apply coverage if a) we have dual source blending |
| 264 // or b) one of our blend optimizations applies | 281 // or b) one of our blend optimizations applies |
| 265 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color | 282 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color |
| 266 GrBlendCoeff srcCoeff; | 283 GrBlendCoeff srcCoeff; |
| 267 GrBlendCoeff dstCoeff; | 284 GrBlendCoeff dstCoeff; |
| 268 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dst Coeff); | 285 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dst Coeff); |
| 269 return GrRODrawState::kNone_BlendOpt != flag || | 286 return GrRODrawState::kNone_BlendOpt != flag || |
| 270 (this->willEffectReadDstColor() && | 287 (this->willEffectReadDstColor() && |
| 271 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); | 288 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
| 272 } | 289 } |
| 273 | 290 |
| 274 ////////////////////////////////////////////////////////////////////////////// | 291 ////////////////////////////////////////////////////////////////////////////// |
| 275 | 292 |
| 276 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( | 293 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawS tate) { |
| 277 GrDrawState* drawState) { | |
| 278 SkASSERT(NULL != drawState); | 294 SkASSERT(NULL != drawState); |
| 279 fDrawState = drawState; | 295 fDrawState = drawState; |
| 280 fVAPtr = drawState->fVAPtr; | 296 fVAPtr = drawState->fVAPtr; |
| 281 fVACount = drawState->fVACount; | 297 fVACount = drawState->fVACount; |
| 282 fDrawState->setDefaultVertexAttribs(); | 298 fDrawState->setDefaultVertexAttribs(); |
| 283 } | 299 } |
| 284 | 300 |
| 285 //////////////////////////////////////////////////////////////////////////////s | 301 //////////////////////////////////////////////////////////////////////////////s |
| 286 | 302 |
| 287 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { | 303 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
| 288 if (NULL != fDrawState) { | 304 if (NULL != fDrawState) { |
| 289 int m = fDrawState->numColorStages() - fColorEffectCnt; | 305 int m = fDrawState->numColorStages() - fColorEffectCnt; |
| 290 SkASSERT(m >= 0); | 306 SkASSERT(m >= 0); |
| 291 fDrawState->fColorStages.pop_back_n(m); | 307 fDrawState->fColorStages.pop_back_n(m); |
| 292 | 308 |
| 293 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; | 309 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; |
| 294 SkASSERT(n >= 0); | 310 SkASSERT(n >= 0); |
| 295 fDrawState->fCoverageStages.pop_back_n(n); | 311 fDrawState->fCoverageStages.pop_back_n(n); |
| 296 if (m + n > 0) { | 312 if (m + n > 0) { |
| 297 fDrawState->invalidateBlendOptFlags(); | 313 fDrawState->invalidateOptState(); |
| 298 } | 314 } |
| 299 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 315 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
| 300 } | 316 } |
| 301 fDrawState = ds; | 317 fDrawState = ds; |
| 302 if (NULL != ds) { | 318 if (NULL != ds) { |
| 303 fColorEffectCnt = ds->numColorStages(); | 319 fColorEffectCnt = ds->numColorStages(); |
| 304 fCoverageEffectCnt = ds->numCoverageStages(); | 320 fCoverageEffectCnt = ds->numCoverageStages(); |
| 305 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) | 321 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
| 306 } | 322 } |
| 307 } | 323 } |
| 308 | 324 |
| 309 //////////////////////////////////////////////////////////////////////////////// | 325 //////////////////////////////////////////////////////////////////////////////// |
| 310 | 326 |
| 311 GrRODrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, | |
| 312 GrBlendCoeff* srcCoeff, | |
| 313 GrBlendCoeff* dstCoeff) c onst { | |
| 314 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; | |
| 315 if (NULL == srcCoeff) { | |
| 316 srcCoeff = &bogusSrcCoeff; | |
| 317 } | |
| 318 if (NULL == dstCoeff) { | |
| 319 dstCoeff = &bogusDstCoeff; | |
| 320 } | |
| 321 | |
| 322 if (forceCoverage) { | |
| 323 return this->calcBlendOpts(true, srcCoeff, dstCoeff); | |
| 324 } | |
| 325 | |
| 326 if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) { | |
| 327 *srcCoeff = fOptSrcBlend; | |
| 328 *dstCoeff = fOptDstBlend; | |
| 329 return fBlendOptFlags; | |
| 330 } | |
| 331 | |
| 332 fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff); | |
| 333 fOptSrcBlend = *srcCoeff; | |
| 334 fOptDstBlend = *dstCoeff; | |
| 335 | |
| 336 return fBlendOptFlags; | |
| 337 } | |
| 338 | |
| 339 GrRODrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage, | |
| 340 GrBlendCoeff* srcCoeff , | |
| 341 GrBlendCoeff* dstCoeff ) const { | |
| 342 *srcCoeff = this->getSrcBlendCoeff(); | |
| 343 *dstCoeff = this->getDstBlendCoeff(); | |
| 344 | |
| 345 if (this->isColorWriteDisabled()) { | |
| 346 *srcCoeff = kZero_GrBlendCoeff; | |
| 347 *dstCoeff = kOne_GrBlendCoeff; | |
| 348 } | |
| 349 | |
| 350 bool srcAIsOne = this->srcAlphaWillBeOne(); | |
| 351 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || | |
| 352 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); | |
| 353 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || | |
| 354 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); | |
| 355 | |
| 356 // When coeffs are (0,1) there is no reason to draw at all, unless | |
| 357 // stenciling is enabled. Having color writes disabled is effectively | |
| 358 // (0,1). | |
| 359 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { | |
| 360 if (this->getStencil().doesWrite()) { | |
| 361 return kEmitCoverage_BlendOptFlag; | |
| 362 } else { | |
| 363 return kSkipDraw_BlendOptFlag; | |
| 364 } | |
| 365 } | |
| 366 | |
| 367 bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); | |
| 368 | |
| 369 // if we don't have coverage we can check whether the dst | |
| 370 // has to read at all. If not, we'll disable blending. | |
| 371 if (!hasCoverage) { | |
| 372 if (dstCoeffIsZero) { | |
| 373 if (kOne_GrBlendCoeff == *srcCoeff) { | |
| 374 // if there is no coverage and coeffs are (1,0) then we | |
| 375 // won't need to read the dst at all, it gets replaced by src | |
| 376 *dstCoeff = kZero_GrBlendCoeff; | |
| 377 return kNone_BlendOpt; | |
| 378 } else if (kZero_GrBlendCoeff == *srcCoeff) { | |
| 379 // if the op is "clear" then we don't need to emit a color | |
| 380 // or blend, just write transparent black into the dst. | |
| 381 *srcCoeff = kOne_GrBlendCoeff; | |
| 382 *dstCoeff = kZero_GrBlendCoeff; | |
| 383 return kEmitTransBlack_BlendOptFlag; | |
| 384 } | |
| 385 } | |
| 386 } else if (this->isCoverageDrawing()) { | |
| 387 // we have coverage but we aren't distinguishing it from alpha by reques t. | |
| 388 return kCoverageAsAlpha_BlendOptFlag; | |
| 389 } else { | |
| 390 // check whether coverage can be safely rolled into alpha | |
| 391 // of if we can skip color computation and just emit coverage | |
| 392 if (this->canTweakAlphaForCoverage()) { | |
| 393 return kCoverageAsAlpha_BlendOptFlag; | |
| 394 } | |
| 395 if (dstCoeffIsZero) { | |
| 396 if (kZero_GrBlendCoeff == *srcCoeff) { | |
| 397 // the source color is not included in the blend | |
| 398 // the dst coeff is effectively zero so blend works out to: | |
| 399 // (c)(0)D + (1-c)D = (1-c)D. | |
| 400 *dstCoeff = kISA_GrBlendCoeff; | |
| 401 return kEmitCoverage_BlendOptFlag; | |
| 402 } else if (srcAIsOne) { | |
| 403 // the dst coeff is effectively zero so blend works out to: | |
| 404 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. | |
| 405 // If Sa is 1 then we can replace Sa with c | |
| 406 // and set dst coeff to 1-Sa. | |
| 407 *dstCoeff = kISA_GrBlendCoeff; | |
| 408 return kCoverageAsAlpha_BlendOptFlag; | |
| 409 } | |
| 410 } else if (dstCoeffIsOne) { | |
| 411 // the dst coeff is effectively one so blend works out to: | |
| 412 // cS + (c)(1)D + (1-c)D = cS + D. | |
| 413 *dstCoeff = kOne_GrBlendCoeff; | |
| 414 return kCoverageAsAlpha_BlendOptFlag; | |
| 415 } | |
| 416 } | |
| 417 | |
| 418 return kNone_BlendOpt; | |
| 419 } | |
| 420 | |
| 421 //////////////////////////////////////////////////////////////////////////////// | |
| 422 | |
| 423 void GrDrawState::AutoViewMatrixRestore::restore() { | 327 void GrDrawState::AutoViewMatrixRestore::restore() { |
| 424 if (NULL != fDrawState) { | 328 if (NULL != fDrawState) { |
| 425 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 329 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
| 426 fDrawState->fViewMatrix = fViewMatrix; | 330 fDrawState->fViewMatrix = fViewMatrix; |
| 427 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); | 331 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); |
| 428 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; | 332 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; |
| 429 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); | 333 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); |
| 430 | 334 |
| 431 int i = 0; | 335 int i = 0; |
| 432 for (int s = 0; s < fNumColorStages; ++s, ++i) { | 336 for (int s = 0; s < fNumColorStages; ++s, ++i) { |
| 433 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i] ); | 337 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i] ); |
| 434 } | 338 } |
| 435 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 339 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
| 436 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges [i]); | 340 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges [i]); |
| 437 } | 341 } |
| 342 fDrawState->invalidateOptState(); | |
|
bsalomon
2014/08/28 13:49:27
Again, could be more optimal here... There are pro
egdaniel
2014/08/28 14:39:38
Again feel like this one doesn't gain much from si
bsalomon
2014/08/28 15:05:02
See comment above, but definitely don't want to do
| |
| 438 fDrawState = NULL; | 343 fDrawState = NULL; |
| 439 } | 344 } |
| 440 } | 345 } |
| 441 | 346 |
| 442 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, | 347 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, |
| 443 const SkMatrix& preconcatMatrix) { | 348 const SkMatrix& preconcatMatrix) { |
| 444 this->restore(); | 349 this->restore(); |
| 445 | 350 |
| 446 SkASSERT(NULL == fDrawState); | 351 SkASSERT(NULL == fDrawState); |
| 447 if (NULL == drawState || preconcatMatrix.isIdentity()) { | 352 if (NULL == drawState || preconcatMatrix.isIdentity()) { |
| 448 return; | 353 return; |
| 449 } | 354 } |
| 450 fDrawState = drawState; | 355 fDrawState = drawState; |
| 451 | 356 |
| 452 fViewMatrix = drawState->getViewMatrix(); | 357 fViewMatrix = drawState->getViewMatrix(); |
| 453 drawState->fViewMatrix.preConcat(preconcatMatrix); | 358 drawState->fViewMatrix.preConcat(preconcatMatrix); |
| 454 | 359 |
| 455 this->doEffectCoordChanges(preconcatMatrix); | 360 this->doEffectCoordChanges(preconcatMatrix); |
| 456 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) | 361 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
| 362 drawState->invalidateOptState(); | |
| 457 } | 363 } |
| 458 | 364 |
| 459 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { | 365 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { |
| 460 this->restore(); | 366 this->restore(); |
| 461 | 367 |
| 462 if (NULL == drawState) { | 368 if (NULL == drawState) { |
| 463 return false; | 369 return false; |
| 464 } | 370 } |
| 465 | 371 |
| 466 if (drawState->getViewMatrix().isIdentity()) { | 372 if (drawState->getViewMatrix().isIdentity()) { |
| 467 return true; | 373 return true; |
| 468 } | 374 } |
| 469 | 375 |
| 376 drawState->invalidateOptState(); | |
| 470 fViewMatrix = drawState->getViewMatrix(); | 377 fViewMatrix = drawState->getViewMatrix(); |
| 471 if (0 == drawState->numTotalStages()) { | 378 if (0 == drawState->numTotalStages()) { |
| 472 drawState->fViewMatrix.reset(); | 379 drawState->fViewMatrix.reset(); |
| 473 fDrawState = drawState; | 380 fDrawState = drawState; |
| 474 fNumColorStages = 0; | 381 fNumColorStages = 0; |
| 475 fSavedCoordChanges.reset(0); | 382 fSavedCoordChanges.reset(0); |
| 476 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) | 383 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
| 477 return true; | 384 return true; |
| 478 } else { | 385 } else { |
| 479 SkMatrix inv; | 386 SkMatrix inv; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 498 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); | 405 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); |
| 499 } | 406 } |
| 500 | 407 |
| 501 int numCoverageStages = fDrawState->numCoverageStages(); | 408 int numCoverageStages = fDrawState->numCoverageStages(); |
| 502 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 409 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
| 503 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 410 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
| 504 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); | 411 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); |
| 505 } | 412 } |
| 506 } | 413 } |
| 507 | 414 |
| 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 |