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

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

Issue 508663002: Create an optimized draw state but not hooked in yet to gpu pipeline (Closed) Base URL: https://skia.googlesource.com/skia.git@drawBase
Patch Set: Updates Created 6 years, 3 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
« src/gpu/GrRODrawState.h ('K') | « src/gpu/GrRODrawState.h ('k') | no next file » | 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 2014 Google Inc. 2 * Copyright 2014 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 "GrRODrawState.h" 8 #include "GrRODrawState.h"
9 #include "GrDrawTargetCaps.h" 9 #include "GrDrawTargetCaps.h"
10 10
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 for (int s = 0; s < this->numCoverageStages(); ++s) { 138 for (int s = 0; s < this->numCoverageStages(); ++s) {
139 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) { 139 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) {
140 return true; 140 return true;
141 } 141 }
142 } 142 }
143 return false; 143 return false;
144 } 144 }
145 145
146 //////////////////////////////////////////////////////////////////////////////// 146 ////////////////////////////////////////////////////////////////////////////////
147 147
148 GrRODrawState::BlendOptFlags GrRODrawState::getBlendOpts(bool forceCoverage,
149 GrBlendCoeff* srcCoeff,
150 GrBlendCoeff* dstCoeff) const {
151 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
152 if (NULL == srcCoeff) {
153 srcCoeff = &bogusSrcCoeff;
154 }
155 if (NULL == dstCoeff) {
156 dstCoeff = &bogusDstCoeff;
157 }
158
159 if (forceCoverage) {
160 return this->calcBlendOpts(true, srcCoeff, dstCoeff);
161 }
162
163 if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) {
164 *srcCoeff = fOptSrcBlend;
165 *dstCoeff = fOptDstBlend;
166 return fBlendOptFlags;
167 }
168
169 fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff);
170 fOptSrcBlend = *srcCoeff;
171 fOptDstBlend = *dstCoeff;
172
173 return fBlendOptFlags;
174 }
175
176 GrRODrawState::BlendOptFlags GrRODrawState::calcBlendOpts(bool forceCoverage,
177 GrBlendCoeff* srcCoeff ,
178 GrBlendCoeff* dstCoeff ) const {
179 *srcCoeff = this->getSrcBlendCoeff();
180 *dstCoeff = this->getDstBlendCoeff();
181
182 if (this->isColorWriteDisabled()) {
183 *srcCoeff = kZero_GrBlendCoeff;
184 *dstCoeff = kOne_GrBlendCoeff;
185 }
186
187 bool srcAIsOne = this->srcAlphaWillBeOne();
188 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
189 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
190 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
191 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
192
193 // When coeffs are (0,1) there is no reason to draw at all, unless
194 // stenciling is enabled. Having color writes disabled is effectively
195 // (0,1).
196 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) {
197 if (this->getStencil().doesWrite()) {
198 return kEmitCoverage_BlendOptFlag;
199 } else {
200 return kSkipDraw_BlendOptFlag;
201 }
202 }
203
204 bool hasCoverage = forceCoverage || !this->hasSolidCoverage();
205
206 // if we don't have coverage we can check whether the dst
207 // has to read at all. If not, we'll disable blending.
208 if (!hasCoverage) {
209 if (dstCoeffIsZero) {
210 if (kOne_GrBlendCoeff == *srcCoeff) {
211 // if there is no coverage and coeffs are (1,0) then we
212 // won't need to read the dst at all, it gets replaced by src
213 *dstCoeff = kZero_GrBlendCoeff;
214 return kNone_BlendOpt;
215 } else if (kZero_GrBlendCoeff == *srcCoeff) {
216 // if the op is "clear" then we don't need to emit a color
217 // or blend, just write transparent black into the dst.
218 *srcCoeff = kOne_GrBlendCoeff;
219 *dstCoeff = kZero_GrBlendCoeff;
220 return kEmitTransBlack_BlendOptFlag;
221 }
222 }
223 } else if (this->isCoverageDrawing()) {
224 // we have coverage but we aren't distinguishing it from alpha by reques t.
225 return kCoverageAsAlpha_BlendOptFlag;
226 } else {
227 // check whether coverage can be safely rolled into alpha
228 // of if we can skip color computation and just emit coverage
229 if (this->canTweakAlphaForCoverage()) {
230 return kCoverageAsAlpha_BlendOptFlag;
231 }
232 if (dstCoeffIsZero) {
233 if (kZero_GrBlendCoeff == *srcCoeff) {
234 // the source color is not included in the blend
235 // the dst coeff is effectively zero so blend works out to:
236 // (c)(0)D + (1-c)D = (1-c)D.
237 *dstCoeff = kISA_GrBlendCoeff;
238 return kEmitCoverage_BlendOptFlag;
239 } else if (srcAIsOne) {
240 // the dst coeff is effectively zero so blend works out to:
241 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
242 // If Sa is 1 then we can replace Sa with c
243 // and set dst coeff to 1-Sa.
244 *dstCoeff = kISA_GrBlendCoeff;
245 return kCoverageAsAlpha_BlendOptFlag;
246 }
247 } else if (dstCoeffIsOne) {
248 // the dst coeff is effectively one so blend works out to:
249 // cS + (c)(1)D + (1-c)D = cS + D.
250 *dstCoeff = kOne_GrBlendCoeff;
251 return kCoverageAsAlpha_BlendOptFlag;
252 }
253 }
254
255 return kNone_BlendOpt;
256 }
257
258 ////////////////////////////////////////////////////////////////////////////////
259
148 // Some blend modes allow folding a fractional coverage value into the color's a lpha channel, while 260 // Some blend modes allow folding a fractional coverage value into the color's a lpha channel, while
149 // others will blend incorrectly. 261 // others will blend incorrectly.
150 bool GrRODrawState::canTweakAlphaForCoverage() const { 262 bool GrRODrawState::canTweakAlphaForCoverage() const {
151 /* 263 /*
152 The fractional coverage is f. 264 The fractional coverage is f.
153 The src and dst coeffs are Cs and Cd. 265 The src and dst coeffs are Cs and Cd.
154 The dst and src colors are S and D. 266 The dst and src colors are S and D.
155 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou rce color's alpha 267 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou rce color's alpha
156 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second 268 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
157 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss ibilities for Cd we 269 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss ibilities for Cd we
158 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D. 270 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
159 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag e is treated as 271 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag e is treated as
160 color by definition. 272 color by definition.
161 */ 273 */
162 return kOne_GrBlendCoeff == fDstBlend || 274 return kOne_GrBlendCoeff == fDstBlend ||
163 kISA_GrBlendCoeff == fDstBlend || 275 kISA_GrBlendCoeff == fDstBlend ||
164 kISC_GrBlendCoeff == fDstBlend || 276 kISC_GrBlendCoeff == fDstBlend ||
165 this->isCoverageDrawing(); 277 this->isCoverageDrawing();
166 } 278 }
167 279
280 bool GrRODrawState::srcAlphaWillBeOne() const {
281 uint32_t validComponentFlags;
282 GrColor color;
283 // Check if per-vertex or constant color may have partial alpha
284 if (this->hasColorVertexAttribute()) {
285 if (fHints & kVertexColorsAreOpaque_Hint) {
286 validComponentFlags = kA_GrColorComponentFlag;
287 color = 0xFF << GrColor_SHIFT_A;
288 } else {
289 validComponentFlags = 0;
290 color = 0; // not strictly necessary but we get false alarms from to ols about uninit.
291 }
292 } else {
293 validComponentFlags = kRGBA_GrColorComponentFlags;
294 color = this->getColor();
295 }
296
297 // Run through the color stages
298 for (int s = 0; s < this->numColorStages(); ++s) {
299 const GrEffect* effect = this->getColorStage(s).getEffect();
300 effect->getConstantColorComponents(&color, &validComponentFlags);
301 }
302
303 // Check whether coverage is treated as color. If so we run through the cove rage computation.
304 if (this->isCoverageDrawing()) {
305 // The shader generated for coverage drawing runs the full coverage comp utation and then
306 // makes the shader output be the multiplication of color and coverage. We mirror that here.
307 GrColor coverage;
308 uint32_t coverageComponentFlags;
309 if (this->hasCoverageVertexAttribute()) {
310 coverageComponentFlags = 0;
311 coverage = 0; // suppresses any warnings.
312 } else {
313 coverageComponentFlags = kRGBA_GrColorComponentFlags;
314 coverage = this->getCoverageColor();
315 }
316
317 // Run through the coverage stages
318 for (int s = 0; s < this->numCoverageStages(); ++s) {
319 const GrEffect* effect = this->getCoverageStage(s).getEffect();
320 effect->getConstantColorComponents(&coverage, &coverageComponentFlag s);
321 }
322
323 // Since the shader will multiply coverage and color, the only way the f inal A==1 is if
324 // coverage and color both have A==1.
325 return (kA_GrColorComponentFlag & validComponentFlags & coverageComponen tFlags) &&
326 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage );
327
328 }
329
330 return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnp ackA(color);
331 }
332
333 ////////////////////////////////////////////////////////////////////////////////
334
335 bool GrRODrawState::canIgnoreColorAttribute() const {
336 if (fBlendOptFlags & kInvalid_BlendOptFlag) {
337 this->getBlendOpts();
338 }
339 return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFla g |
340 GrRODrawState::kEmitCoverage_BlendOptFlag) );
341 }
342
OLDNEW
« src/gpu/GrRODrawState.h ('K') | « src/gpu/GrRODrawState.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698