OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2012 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "GrDrawState.h" | |
9 | |
10 #include "GrBlend.h" | |
11 #include "GrOptDrawState.h" | |
12 #include "GrPaint.h" | |
13 #include "GrProcOptInfo.h" | |
14 #include "GrXferProcessor.h" | |
15 #include "effects/GrPorterDuffXferProcessor.h" | |
16 | |
17 GrDrawState::GrDrawState() | |
18 : fFlagBits(0x0) | |
19 , fDrawFace(kBoth_DrawFace) | |
20 , fColorProcInfoValid(false) | |
21 , fCoverageProcInfoValid(false) | |
22 , fColorCache(GrColor_ILLEGAL) | |
23 , fCoverageCache(GrColor_ILLEGAL) | |
24 , fColorPrimProc(NULL) | |
25 , fCoveragePrimProc(NULL) { | |
26 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) | |
27 } | |
28 | |
29 GrDrawState& GrDrawState::operator=(const GrDrawState& that) { | |
30 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get())); | |
31 fFlagBits = that.fFlagBits; | |
32 fStencilSettings = that.fStencilSettings; | |
33 fDrawFace = that.fDrawFace; | |
34 fXPFactory.reset(SkRef(that.getXPFactory())); | |
35 fColorStages = that.fColorStages; | |
36 fCoverageStages = that.fCoverageStages; | |
37 | |
38 fColorProcInfoValid = that.fColorProcInfoValid; | |
39 fCoverageProcInfoValid = that.fCoverageProcInfoValid; | |
40 fColorCache = that.fColorCache; | |
41 fCoverageCache = that.fCoverageCache; | |
42 fColorPrimProc = that.fColorPrimProc; | |
43 fCoveragePrimProc = that.fCoveragePrimProc; | |
44 if (fColorProcInfoValid) { | |
45 fColorProcInfo = that.fColorProcInfo; | |
46 } | |
47 if (fCoverageProcInfoValid) { | |
48 fCoverageProcInfo = that.fCoverageProcInfo; | |
49 } | |
50 return *this; | |
51 } | |
52 | |
53 void GrDrawState::setFromPaint(const GrPaint& paint, GrRenderTarget* rt) { | |
54 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages()); | |
55 | |
56 fColorStages.reset(); | |
57 fCoverageStages.reset(); | |
58 | |
59 for (int i = 0; i < paint.numColorStages(); ++i) { | |
60 fColorStages.push_back(paint.getColorStage(i)); | |
61 } | |
62 | |
63 for (int i = 0; i < paint.numCoverageStages(); ++i) { | |
64 fCoverageStages.push_back(paint.getCoverageStage(i)); | |
65 } | |
66 | |
67 fXPFactory.reset(SkRef(paint.getXPFactory())); | |
68 | |
69 this->setRenderTarget(rt); | |
70 | |
71 // These have no equivalent in GrPaint, set them to defaults | |
72 fDrawFace = kBoth_DrawFace; | |
73 fStencilSettings.setDisabled(); | |
74 fFlagBits = 0; | |
75 | |
76 // Enable the clip bit | |
77 this->enableState(GrDrawState::kClip_StateBit); | |
78 | |
79 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | |
80 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | |
81 | |
82 fColorProcInfoValid = false; | |
83 fCoverageProcInfoValid = false; | |
84 | |
85 fColorCache = GrColor_ILLEGAL; | |
86 fCoverageCache = GrColor_ILLEGAL; | |
87 | |
88 fColorPrimProc = NULL; | |
89 fCoveragePrimProc = NULL; | |
90 } | |
91 | |
92 //////////////////////////////////////////////////////////////////////////////// | |
93 | |
94 bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCa
ps& caps) const { | |
95 if (caps.dualSourceBlendingSupport()) { | |
96 return true; | |
97 } | |
98 | |
99 this->calcColorInvariantOutput(color); | |
100 | |
101 // The coverage isn't actually white, its unknown, but this will produce the
same effect | |
102 // TODO we want to cache the result of this call, but we can probably clean
up the interface | |
103 // so we don't have to pass in a seemingly known coverage | |
104 this->calcCoverageInvariantOutput(GrColor_WHITE); | |
105 return this->getXPFactory()->canApplyCoverage(fColorProcInfo, fCoverageProcI
nfo); | |
106 } | |
107 | |
108 //////////////////////////////////////////////////////////////////////////////s | |
109 | |
110 bool GrDrawState::willEffectReadDstColor() const { | |
111 return this->getXPFactory()->willReadDst(); | |
112 } | |
113 | |
114 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { | |
115 if (fDrawState) { | |
116 int m = fDrawState->numColorStages() - fColorEffectCnt; | |
117 SkASSERT(m >= 0); | |
118 fDrawState->fColorStages.pop_back_n(m); | |
119 | |
120 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt; | |
121 SkASSERT(n >= 0); | |
122 fDrawState->fCoverageStages.pop_back_n(n); | |
123 if (m + n > 0) { | |
124 fDrawState->fColorProcInfoValid = false; | |
125 fDrawState->fCoverageProcInfoValid = false; | |
126 } | |
127 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | |
128 } | |
129 fDrawState = ds; | |
130 if (NULL != ds) { | |
131 fColorEffectCnt = ds->numColorStages(); | |
132 fCoverageEffectCnt = ds->numCoverageStages(); | |
133 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) | |
134 } | |
135 } | |
136 | |
137 //////////////////////////////////////////////////////////////////////////////// | |
138 | |
139 // Some blend modes allow folding a fractional coverage value into the color's a
lpha channel, while | |
140 // others will blend incorrectly. | |
141 bool GrDrawState::canTweakAlphaForCoverage() const { | |
142 return this->getXPFactory()->canTweakAlphaForCoverage(); | |
143 } | |
144 | |
145 //////////////////////////////////////////////////////////////////////////////// | |
146 | |
147 GrDrawState::~GrDrawState() { | |
148 SkASSERT(0 == fBlockEffectRemovalCnt); | |
149 } | |
150 | |
151 //////////////////////////////////////////////////////////////////////////////// | |
152 | |
153 bool GrDrawState::willBlendWithDst(const GrPrimitiveProcessor* pp) const { | |
154 this->calcColorInvariantOutput(pp); | |
155 this->calcCoverageInvariantOutput(pp); | |
156 | |
157 GrXPFactory::InvariantOutput output; | |
158 fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output); | |
159 return output.fWillBlendWithDst; | |
160 } | |
161 | |
162 void GrDrawState::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const
{ | |
163 if (!fColorProcInfoValid || fColorPrimProc != pp) { | |
164 fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->num
ColorStages()); | |
165 fColorProcInfoValid = true; | |
166 fColorPrimProc = pp; | |
167 } | |
168 } | |
169 | |
170 void GrDrawState::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) co
nst { | |
171 if (!fCoverageProcInfoValid || fCoveragePrimProc != pp) { | |
172 fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(), | |
173 this->numCoverageStages()); | |
174 fCoverageProcInfoValid = true; | |
175 fCoveragePrimProc = pp; | |
176 } | |
177 } | |
178 | |
179 void GrDrawState::calcColorInvariantOutput(GrColor color) const { | |
180 if (!fColorProcInfoValid || color != fColorCache) { | |
181 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags; | |
182 fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColo
rStages(), color, | |
183 flags, false); | |
184 fColorProcInfoValid = true; | |
185 fColorCache = color; | |
186 } | |
187 } | |
188 | |
189 void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const { | |
190 if (!fCoverageProcInfoValid || coverage != fCoverageCache) { | |
191 GrColorComponentFlags flags = kRGBA_GrColorComponentFlags; | |
192 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), | |
193 this->numCoverageStages(), cover
age, flags, | |
194 true); | |
195 fCoverageProcInfoValid = true; | |
196 fCoverageCache = coverage; | |
197 } | |
198 } | |
OLD | NEW |