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 |