Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: src/gpu/GrDrawState.cpp

Issue 446953002: Add an opaqueness hint to GrDrawState. (Closed) Base URL: https://skia.googlesource.com/skia.git@greg
Patch Set: Address comments Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrDrawState.h ('k') | src/gpu/GrDrawTarget.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "GrPaint.h" 9 #include "GrPaint.h"
10 #include "GrDrawTargetCaps.h"
10 11
11 //////////////////////////////////////////////////////////////////////////////s 12 //////////////////////////////////////////////////////////////////////////////s
12 13
13 bool GrDrawState::State::HaveCompatibleState(const State& a, const State& b, 14 bool GrDrawState::State::HaveCompatibleState(const State& a, const State& b,
14 bool explicitLocalCoords) { 15 bool explicitLocalCoords) {
15 if (a.fColorStages.count() != b.fColorStages.count() || 16 if (a.fColorStages.count() != b.fColorStages.count() ||
16 a.fCoverageStages.count() != b.fCoverageStages.count() || 17 a.fCoverageStages.count() != b.fCoverageStages.count() ||
17 a.fSrcBlend != b.fSrcBlend || 18 a.fSrcBlend != b.fSrcBlend ||
18 a.fDstBlend != b.fDstBlend) { 19 a.fDstBlend != b.fDstBlend) {
19 return false; 20 return false;
20 } 21 }
21 for (int i = 0; i < a.fColorStages.count(); i++) { 22 for (int i = 0; i < a.fColorStages.count(); i++) {
22 if (!GrEffectStage::AreCompatible(a.fColorStages[i], b.fColorStages[i], 23 if (!GrEffectStage::AreCompatible(a.fColorStages[i], b.fColorStages[i],
23 explicitLocalCoords)) { 24 explicitLocalCoords)) {
24 return false; 25 return false;
25 } 26 }
26 } 27 }
27 for (int i = 0; i < a.fCoverageStages.count(); i++) { 28 for (int i = 0; i < a.fCoverageStages.count(); i++) {
28 if (!GrEffectStage::AreCompatible(a.fCoverageStages[i], b.fCoverageStage s[i], 29 if (!GrEffectStage::AreCompatible(a.fCoverageStages[i], b.fCoverageStage s[i],
29 explicitLocalCoords)) { 30 explicitLocalCoords)) {
30 return false; 31 return false;
31 } 32 }
32 } 33 }
33 return true; 34 return true;
34 } 35 }
35 //////////////////////////////////////////////////////////////////////////////s 36 //////////////////////////////////////////////////////////////////////////////s
36 GrDrawState::CombinedState GrDrawState::CombineIfPossible( 37 GrDrawState::CombinedState GrDrawState::CombineIfPossible(
37 const GrDrawState& a, const GrDrawState& b) { 38 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) {
38 39
39 bool usingVertexColors = a.hasColorVertexAttribute(); 40 bool usingVertexColors = a.hasColorVertexAttribute();
40 if (!usingVertexColors && a.fColor != b.fColor) { 41 if (!usingVertexColors && a.fColor != b.fColor) {
41 return kIncompatible_CombinedState; 42 return kIncompatible_CombinedState;
42 } 43 }
43 44
44 if (a.fRenderTarget.get() != b.fRenderTarget.get() || 45 if (a.fRenderTarget.get() != b.fRenderTarget.get() ||
45 !a.fViewMatrix.cheapEqualTo(b.fViewMatrix) || 46 !a.fViewMatrix.cheapEqualTo(b.fViewMatrix) ||
46 a.fBlendConstant != b.fBlendConstant || 47 a.fBlendConstant != b.fBlendConstant ||
47 a.fFlagBits != b.fFlagBits || 48 a.fFlagBits != b.fFlagBits ||
(...skipping 10 matching lines...) Expand all
58 } 59 }
59 60
60 bool explicitLocalCoords = a.hasLocalCoordAttribute(); 61 bool explicitLocalCoords = a.hasLocalCoordAttribute();
61 62
62 SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices, 63 SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices,
63 b.fFixedFunctionVertexAttribIndices, 64 b.fFixedFunctionVertexAttribIndices,
64 sizeof(a.fFixedFunctionVertexAttribIndices))); 65 sizeof(a.fFixedFunctionVertexAttribIndices)));
65 if (!State::HaveCompatibleState(a.fState, b.fState, explicitLocalCoords)) { 66 if (!State::HaveCompatibleState(a.fState, b.fState, explicitLocalCoords)) {
66 return kIncompatible_CombinedState; 67 return kIncompatible_CombinedState;
67 } 68 }
69
70 if (usingVertexColors) {
71 // If one is opaque and the other is not then the combined state is not opaque. Moreover,
72 // if the opaqueness affects the ability to get color/coverage blending correct then we
73 // don't combine the draw states.
74 bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints);
75 bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints);
76 if (aIsOpaque != bIsOpaque) {
77 const GrDrawState* opaque;
78 const GrDrawState* nonOpaque;
79 if (aIsOpaque) {
80 opaque = &a;
81 nonOpaque = &b;
82 } else {
83 opaque = &b;
84 nonOpaque = &a;
85 }
86 if (!opaque->hasSolidCoverage() && opaque->couldApplyCoverage(caps)) {
87 SkASSERT(!nonOpaque->hasSolidCoverage());
88 if (!nonOpaque->couldApplyCoverage(caps)) {
89 return kIncompatible_CombinedState;
90 }
91 }
92 return aIsOpaque ? kB_CombinedState : kA_CombinedState;
93 }
94 }
68 return kAOrB_CombinedState; 95 return kAOrB_CombinedState;
69 } 96 }
70 97
71
72 //////////////////////////////////////////////////////////////////////////////s 98 //////////////////////////////////////////////////////////////////////////////s
73 99
74 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr ix) { 100 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr ix) {
75 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) 101 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
76 *this = state; 102 *this = state;
77 if (!preConcatMatrix.isIdentity()) { 103 if (!preConcatMatrix.isIdentity()) {
78 for (int i = 0; i < this->numColorStages(); ++i) { 104 for (int i = 0; i < this->numColorStages(); ++i) {
79 fState.fColorStages[i].localCoordChange(preConcatMatrix); 105 fState.fColorStages[i].localCoordChange(preConcatMatrix);
80 } 106 }
81 for (int i = 0; i < this->numCoverageStages(); ++i) { 107 for (int i = 0; i < this->numCoverageStages(); ++i) {
(...skipping 13 matching lines...) Expand all
95 fVACount = that.fVACount; 121 fVACount = that.fVACount;
96 fVAPtr = that.fVAPtr; 122 fVAPtr = that.fVAPtr;
97 fStencilSettings = that.fStencilSettings; 123 fStencilSettings = that.fStencilSettings;
98 fCoverage = that.fCoverage; 124 fCoverage = that.fCoverage;
99 fDrawFace = that.fDrawFace; 125 fDrawFace = that.fDrawFace;
100 fOptSrcBlend = that.fOptSrcBlend; 126 fOptSrcBlend = that.fOptSrcBlend;
101 fOptDstBlend = that.fOptDstBlend; 127 fOptDstBlend = that.fOptDstBlend;
102 fBlendOptFlags = that.fBlendOptFlags; 128 fBlendOptFlags = that.fBlendOptFlags;
103 129
104 fState = that.fState; 130 fState = that.fState;
131 fHints = that.fHints;
105 132
106 memcpy(fFixedFunctionVertexAttribIndices, 133 memcpy(fFixedFunctionVertexAttribIndices,
107 that.fFixedFunctionVertexAttribIndices, 134 that.fFixedFunctionVertexAttribIndices,
108 sizeof(fFixedFunctionVertexAttribIndices)); 135 sizeof(fFixedFunctionVertexAttribIndices));
109 return *this; 136 return *this;
110 } 137 }
111 138
112 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { 139 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
113 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); 140 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
114 fState.reset(); 141 fState.reset();
115 142
116 fRenderTarget.reset(NULL); 143 fRenderTarget.reset(NULL);
117 144
118 this->setDefaultVertexAttribs(); 145 this->setDefaultVertexAttribs();
119 146
120 fColor = 0xffffffff; 147 fColor = 0xffffffff;
121 if (NULL == initialViewMatrix) { 148 if (NULL == initialViewMatrix) {
122 fViewMatrix.reset(); 149 fViewMatrix.reset();
123 } else { 150 } else {
124 fViewMatrix = *initialViewMatrix; 151 fViewMatrix = *initialViewMatrix;
125 } 152 }
126 fBlendConstant = 0x0; 153 fBlendConstant = 0x0;
127 fFlagBits = 0x0; 154 fFlagBits = 0x0;
128 fStencilSettings.setDisabled(); 155 fStencilSettings.setDisabled();
129 fCoverage = 0xffffffff; 156 fCoverage = 0xffffffff;
130 fDrawFace = kBoth_DrawFace; 157 fDrawFace = kBoth_DrawFace;
131 158
159 fHints = 0;
160
132 this->invalidateBlendOptFlags(); 161 this->invalidateBlendOptFlags();
133 } 162 }
134 163
135 bool GrDrawState::setIdentityViewMatrix() { 164 bool GrDrawState::setIdentityViewMatrix() {
136 if (this->numTotalStages()) { 165 if (this->numTotalStages()) {
137 SkMatrix invVM; 166 SkMatrix invVM;
138 if (!fViewMatrix.invert(&invVM)) { 167 if (!fViewMatrix.invert(&invVM)) {
139 // sad trombone sound 168 // sad trombone sound
140 return false; 169 return false;
141 } 170 }
(...skipping 23 matching lines...) Expand all
165 194
166 this->setRenderTarget(rt); 195 this->setRenderTarget(rt);
167 196
168 fViewMatrix = vm; 197 fViewMatrix = vm;
169 198
170 // These have no equivalent in GrPaint, set them to defaults 199 // These have no equivalent in GrPaint, set them to defaults
171 fBlendConstant = 0x0; 200 fBlendConstant = 0x0;
172 fDrawFace = kBoth_DrawFace; 201 fDrawFace = kBoth_DrawFace;
173 fStencilSettings.setDisabled(); 202 fStencilSettings.setDisabled();
174 this->resetStateFlags(); 203 this->resetStateFlags();
204 fHints = 0;
175 205
176 // Enable the clip bit 206 // Enable the clip bit
177 this->enableState(GrDrawState::kClip_StateBit); 207 this->enableState(GrDrawState::kClip_StateBit);
178 208
179 this->setColor(paint.getColor()); 209 this->setColor(paint.getColor());
180 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); 210 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
181 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); 211 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
182 212
183 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); 213 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
184 this->setCoverage(paint.getCoverage()); 214 this->setCoverage(paint.getCoverage());
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 for (int s = 0; s < this->numCoverageStages(); ++s) { 349 for (int s = 0; s < this->numCoverageStages(); ++s) {
320 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) { 350 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) {
321 return true; 351 return true;
322 } 352 }
323 } 353 }
324 return false; 354 return false;
325 } 355 }
326 356
327 //////////////////////////////////////////////////////////////////////////////// 357 ////////////////////////////////////////////////////////////////////////////////
328 358
359 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
360 if (caps.dualSourceBlendingSupport()) {
361 return true;
362 }
363 // we can correctly apply coverage if a) we have dual source blending
364 // or b) one of our blend optimizations applies
365 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
366 GrBlendCoeff srcCoeff;
367 GrBlendCoeff dstCoeff;
368 GrDrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCo eff);
369 return GrDrawState::kNone_BlendOpt != flag ||
370 (this->willEffectReadDstColor() &&
371 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
372 }
373
329 bool GrDrawState::srcAlphaWillBeOne() const { 374 bool GrDrawState::srcAlphaWillBeOne() const {
330 uint32_t validComponentFlags; 375 uint32_t validComponentFlags;
331 GrColor color; 376 GrColor color;
332 // Check if per-vertex or constant color may have partial alpha 377 // Check if per-vertex or constant color may have partial alpha
333 if (this->hasColorVertexAttribute()) { 378 if (this->hasColorVertexAttribute()) {
334 validComponentFlags = 0; 379 if (fHints & kVertexColorsAreOpaque_Hint) {
335 color = 0; // not strictly necessary but we get false alarms from tools about uninit. 380 validComponentFlags = kA_GrColorComponentFlag;
381 color = 0xFF << GrColor_SHIFT_A;
382 } else {
383 validComponentFlags = 0;
384 color = 0; // not strictly necessary but we get false alarms from to ols about uninit.
385 }
336 } else { 386 } else {
337 validComponentFlags = kRGBA_GrColorComponentFlags; 387 validComponentFlags = kRGBA_GrColorComponentFlags;
338 color = this->getColor(); 388 color = this->getColor();
339 } 389 }
340 390
341 // Run through the color stages 391 // Run through the color stages
342 for (int s = 0; s < this->numColorStages(); ++s) { 392 for (int s = 0; s < this->numColorStages(); ++s) {
343 const GrEffect* effect = this->getColorStage(s).getEffect(); 393 const GrEffect* effect = this->getColorStage(s).getEffect();
344 effect->getConstantColorComponents(&color, &validComponentFlags); 394 effect->getConstantColorComponents(&color, &validComponentFlags);
345 } 395 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 *srcCoeff = kZero_GrBlendCoeff; 498 *srcCoeff = kZero_GrBlendCoeff;
449 *dstCoeff = kOne_GrBlendCoeff; 499 *dstCoeff = kOne_GrBlendCoeff;
450 } 500 }
451 501
452 bool srcAIsOne = this->srcAlphaWillBeOne(); 502 bool srcAIsOne = this->srcAlphaWillBeOne();
453 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || 503 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
454 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); 504 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
455 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || 505 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
456 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); 506 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
457 507
458 bool covIsZero = !this->isCoverageDrawing() &&
459 !this->hasCoverageVertexAttribute() &&
460 0 == this->getCoverageColor();
461 // When coeffs are (0,1) there is no reason to draw at all, unless 508 // When coeffs are (0,1) there is no reason to draw at all, unless
462 // stenciling is enabled. Having color writes disabled is effectively 509 // stenciling is enabled. Having color writes disabled is effectively
463 // (0,1). The same applies when coverage is known to be 0. 510 // (0,1).
464 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { 511 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) {
465 if (this->getStencil().doesWrite()) { 512 if (this->getStencil().doesWrite()) {
466 return kEmitCoverage_BlendOptFlag; 513 return kEmitCoverage_BlendOptFlag;
467 } else { 514 } else {
468 return kSkipDraw_BlendOptFlag; 515 return kSkipDraw_BlendOptFlag;
469 } 516 }
470 } 517 }
471 518
472 // check for coverage due to constant coverage, per-vertex coverage, or cove rage stage 519 bool hasCoverage = forceCoverage || !this->hasSolidCoverage();
473 bool hasCoverage = forceCoverage ||
474 0xffffffff != this->getCoverageColor() ||
475 this->hasCoverageVertexAttribute() ||
476 this->numCoverageStages() > 0;
477 520
478 // if we don't have coverage we can check whether the dst 521 // if we don't have coverage we can check whether the dst
479 // has to read at all. If not, we'll disable blending. 522 // has to read at all. If not, we'll disable blending.
480 if (!hasCoverage) { 523 if (!hasCoverage) {
481 if (dstCoeffIsZero) { 524 if (dstCoeffIsZero) {
482 if (kOne_GrBlendCoeff == *srcCoeff) { 525 if (kOne_GrBlendCoeff == *srcCoeff) {
483 // if there is no coverage and coeffs are (1,0) then we 526 // if there is no coverage and coeffs are (1,0) then we
484 // won't need to read the dst at all, it gets replaced by src 527 // won't need to read the dst at all, it gets replaced by src
485 *dstCoeff = kZero_GrBlendCoeff; 528 *dstCoeff = kZero_GrBlendCoeff;
486 return kNone_BlendOpt; 529 return kNone_BlendOpt;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]); 692 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
650 fDrawState->fState.fColorStages[s].localCoordChange(coordChangeMatrix); 693 fDrawState->fState.fColorStages[s].localCoordChange(coordChangeMatrix);
651 } 694 }
652 695
653 int numCoverageStages = fDrawState->numCoverageStages(); 696 int numCoverageStages = fDrawState->numCoverageStages();
654 for (int s = 0; s < numCoverageStages; ++s, ++i) { 697 for (int s = 0; s < numCoverageStages; ++s, ++i) {
655 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); 698 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]);
656 fDrawState->fState.fCoverageStages[s].localCoordChange(coordChangeMatrix ); 699 fDrawState->fState.fCoverageStages[s].localCoordChange(coordChangeMatrix );
657 } 700 }
658 } 701 }
OLDNEW
« no previous file with comments | « src/gpu/GrDrawState.h ('k') | src/gpu/GrDrawTarget.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698