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 fVAStride = that.fVAStride; | 93 fVAStride = that.fVAStride; |
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 } |
| 155 this->invalidateOptState(); |
138 fViewMatrix.reset(); | 156 fViewMatrix.reset(); |
139 return true; | 157 return true; |
140 } | 158 } |
141 | 159 |
142 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
rTarget* rt) { | 160 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
rTarget* rt) { |
143 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 161 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
144 | 162 |
145 fColorStages.reset(); | 163 fColorStages.reset(); |
146 fCoverageStages.reset(); | 164 fCoverageStages.reset(); |
147 | 165 |
(...skipping 18 matching lines...) Expand all Loading... |
166 | 184 |
167 // Enable the clip bit | 185 // Enable the clip bit |
168 this->enableState(GrDrawState::kClip_StateBit); | 186 this->enableState(GrDrawState::kClip_StateBit); |
169 | 187 |
170 this->setColor(paint.getColor()); | 188 this->setColor(paint.getColor()); |
171 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | 189 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
172 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | 190 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
173 | 191 |
174 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); | 192 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
175 this->setCoverage(paint.getCoverage()); | 193 this->setCoverage(paint.getCoverage()); |
176 this->invalidateBlendOptFlags(); | 194 this->invalidateOptState(); |
177 } | 195 } |
178 | 196 |
179 //////////////////////////////////////////////////////////////////////////////// | 197 //////////////////////////////////////////////////////////////////////////////// |
180 | 198 |
181 static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, si
ze_t stride) { | 199 static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, si
ze_t stride) { |
182 // this works as long as we're 4 byte-aligned | 200 // this works as long as we're 4 byte-aligned |
183 #ifdef SK_DEBUG | 201 #ifdef SK_DEBUG |
184 uint32_t overlapCheck = 0; | 202 uint32_t overlapCheck = 0; |
185 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); | 203 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); |
186 for (int index = 0; index < count; ++index) { | 204 for (int index = 0; index < count; ++index) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i; | 241 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i; |
224 } | 242 } |
225 #ifdef SK_DEBUG | 243 #ifdef SK_DEBUG |
226 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2; | 244 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2; |
227 uint32_t mask = (1 << dwordCount)-1; | 245 uint32_t mask = (1 << dwordCount)-1; |
228 size_t offsetShift = attribs[i].fOffset >> 2; | 246 size_t offsetShift = attribs[i].fOffset >> 2; |
229 SkASSERT(!(overlapCheck & (mask << offsetShift))); | 247 SkASSERT(!(overlapCheck & (mask << offsetShift))); |
230 overlapCheck |= (mask << offsetShift); | 248 overlapCheck |= (mask << offsetShift); |
231 #endif | 249 #endif |
232 } | 250 } |
233 this->invalidateBlendOptFlags(); | 251 this->invalidateOptState(); |
234 // Positions must be specified. | 252 // Positions must be specified. |
235 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBin
ding]); | 253 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBin
ding]); |
236 } | 254 } |
237 | 255 |
238 //////////////////////////////////////////////////////////////////////////////// | 256 //////////////////////////////////////////////////////////////////////////////// |
239 | 257 |
240 void GrDrawState::setDefaultVertexAttribs() { | 258 void GrDrawState::setDefaultVertexAttribs() { |
241 static const GrVertexAttrib kPositionAttrib = | 259 static const GrVertexAttrib kPositionAttrib = |
242 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}; | 260 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}; |
243 | 261 |
244 fVAPtr = &kPositionAttrib; | 262 fVAPtr = &kPositionAttrib; |
245 fVACount = 1; | 263 fVACount = 1; |
246 fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); | 264 fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType); |
247 | 265 |
248 // set all the fixed function indices to -1 except position. | 266 // set all the fixed function indices to -1 except position. |
249 memset(fFixedFunctionVertexAttribIndices, | 267 memset(fFixedFunctionVertexAttribIndices, |
250 0xff, | 268 0xff, |
251 sizeof(fFixedFunctionVertexAttribIndices)); | 269 sizeof(fFixedFunctionVertexAttribIndices)); |
252 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; | 270 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0; |
253 this->invalidateBlendOptFlags(); | 271 this->invalidateOptState(); |
254 } | 272 } |
255 | 273 |
256 //////////////////////////////////////////////////////////////////////////////// | 274 //////////////////////////////////////////////////////////////////////////////// |
257 | 275 |
258 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { | 276 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
259 if (caps.dualSourceBlendingSupport()) { | 277 if (caps.dualSourceBlendingSupport()) { |
260 return true; | 278 return true; |
261 } | 279 } |
262 // 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 |
263 // or b) one of our blend optimizations applies | 281 // or b) one of our blend optimizations applies |
264 // 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 |
265 GrBlendCoeff srcCoeff; | 283 GrBlendCoeff srcCoeff; |
266 GrBlendCoeff dstCoeff; | 284 GrBlendCoeff dstCoeff; |
267 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dst
Coeff); | 285 GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dst
Coeff); |
268 return GrRODrawState::kNone_BlendOpt != flag || | 286 return GrRODrawState::kNone_BlendOpt != flag || |
269 (this->willEffectReadDstColor() && | 287 (this->willEffectReadDstColor() && |
270 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); | 288 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
271 } | 289 } |
272 | 290 |
273 ////////////////////////////////////////////////////////////////////////////// | 291 ////////////////////////////////////////////////////////////////////////////// |
274 | 292 |
275 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore( | 293 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawS
tate) { |
276 GrDrawState* drawState) { | |
277 SkASSERT(NULL != drawState); | 294 SkASSERT(NULL != drawState); |
278 fDrawState = drawState; | 295 fDrawState = drawState; |
279 fVAPtr = drawState->fVAPtr; | 296 fVAPtr = drawState->fVAPtr; |
280 fVACount = drawState->fVACount; | 297 fVACount = drawState->fVACount; |
281 fVAStride = drawState->fVAStride; | 298 fVAStride = drawState->fVAStride; |
282 fDrawState->setDefaultVertexAttribs(); | 299 fDrawState->setDefaultVertexAttribs(); |
283 } | 300 } |
284 | 301 |
285 //////////////////////////////////////////////////////////////////////////////s | 302 //////////////////////////////////////////////////////////////////////////////s |
286 | 303 |
287 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { | 304 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
288 if (NULL != fDrawState) { | 305 if (NULL != fDrawState) { |
289 int m = fDrawState->numColorStages() - fColorEffectCnt; | 306 int m = fDrawState->numColorStages() - fColorEffectCnt; |
290 SkASSERT(m >= 0); | 307 SkASSERT(m >= 0); |
291 fDrawState->fColorStages.pop_back_n(m); | 308 fDrawState->fColorStages.pop_back_n(m); |
292 | 309 |
293 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; | 310 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; |
294 SkASSERT(n >= 0); | 311 SkASSERT(n >= 0); |
295 fDrawState->fCoverageStages.pop_back_n(n); | 312 fDrawState->fCoverageStages.pop_back_n(n); |
296 if (m + n > 0) { | 313 if (m + n > 0) { |
297 fDrawState->invalidateBlendOptFlags(); | 314 fDrawState->invalidateOptState(); |
298 } | 315 } |
299 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 316 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
300 } | 317 } |
301 fDrawState = ds; | 318 fDrawState = ds; |
302 if (NULL != ds) { | 319 if (NULL != ds) { |
303 fColorEffectCnt = ds->numColorStages(); | 320 fColorEffectCnt = ds->numColorStages(); |
304 fCoverageEffectCnt = ds->numCoverageStages(); | 321 fCoverageEffectCnt = ds->numCoverageStages(); |
305 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) | 322 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
306 } | 323 } |
307 } | 324 } |
308 | 325 |
309 //////////////////////////////////////////////////////////////////////////////// | 326 //////////////////////////////////////////////////////////////////////////////// |
310 | 327 |
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() { | 328 void GrDrawState::AutoViewMatrixRestore::restore() { |
424 if (NULL != fDrawState) { | 329 if (NULL != fDrawState) { |
425 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 330 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
426 fDrawState->fViewMatrix = fViewMatrix; | 331 fDrawState->fViewMatrix = fViewMatrix; |
427 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); | 332 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); |
428 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; | 333 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; |
429 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); | 334 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); |
430 | 335 |
431 int i = 0; | 336 int i = 0; |
432 for (int s = 0; s < fNumColorStages; ++s, ++i) { | 337 for (int s = 0; s < fNumColorStages; ++s, ++i) { |
433 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]
); | 338 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]
); |
434 } | 339 } |
435 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 340 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
436 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges
[i]); | 341 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges
[i]); |
437 } | 342 } |
| 343 fDrawState->invalidateOptState(); |
438 fDrawState = NULL; | 344 fDrawState = NULL; |
439 } | 345 } |
440 } | 346 } |
441 | 347 |
442 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, | 348 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, |
443 const SkMatrix& preconcatMatrix) { | 349 const SkMatrix& preconcatMatrix) { |
444 this->restore(); | 350 this->restore(); |
445 | 351 |
446 SkASSERT(NULL == fDrawState); | 352 SkASSERT(NULL == fDrawState); |
447 if (NULL == drawState || preconcatMatrix.isIdentity()) { | 353 if (NULL == drawState || preconcatMatrix.isIdentity()) { |
448 return; | 354 return; |
449 } | 355 } |
450 fDrawState = drawState; | 356 fDrawState = drawState; |
451 | 357 |
452 fViewMatrix = drawState->getViewMatrix(); | 358 fViewMatrix = drawState->getViewMatrix(); |
453 drawState->fViewMatrix.preConcat(preconcatMatrix); | 359 drawState->fViewMatrix.preConcat(preconcatMatrix); |
454 | 360 |
455 this->doEffectCoordChanges(preconcatMatrix); | 361 this->doEffectCoordChanges(preconcatMatrix); |
456 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) | 362 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
| 363 drawState->invalidateOptState(); |
457 } | 364 } |
458 | 365 |
459 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { | 366 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) { |
460 this->restore(); | 367 this->restore(); |
461 | 368 |
462 if (NULL == drawState) { | 369 if (NULL == drawState) { |
463 return false; | 370 return false; |
464 } | 371 } |
465 | 372 |
466 if (drawState->getViewMatrix().isIdentity()) { | 373 if (drawState->getViewMatrix().isIdentity()) { |
467 return true; | 374 return true; |
468 } | 375 } |
469 | 376 |
| 377 drawState->invalidateOptState(); |
470 fViewMatrix = drawState->getViewMatrix(); | 378 fViewMatrix = drawState->getViewMatrix(); |
471 if (0 == drawState->numTotalStages()) { | 379 if (0 == drawState->numTotalStages()) { |
472 drawState->fViewMatrix.reset(); | 380 drawState->fViewMatrix.reset(); |
473 fDrawState = drawState; | 381 fDrawState = drawState; |
474 fNumColorStages = 0; | 382 fNumColorStages = 0; |
475 fSavedCoordChanges.reset(0); | 383 fSavedCoordChanges.reset(0); |
476 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) | 384 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;) |
477 return true; | 385 return true; |
478 } else { | 386 } else { |
479 SkMatrix inv; | 387 SkMatrix inv; |
(...skipping 18 matching lines...) Expand all Loading... |
498 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); | 406 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix); |
499 } | 407 } |
500 | 408 |
501 int numCoverageStages = fDrawState->numCoverageStages(); | 409 int numCoverageStages = fDrawState->numCoverageStages(); |
502 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 410 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
503 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 411 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
504 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); | 412 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); |
505 } | 413 } |
506 } | 414 } |
507 | 415 |
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 |