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

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: Nits 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
« no previous file with comments | « 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
9 #include "GrDrawTargetCaps.h" 10 #include "GrDrawTargetCaps.h"
11 #include "GrRenderTarget.h"
10 12
11 //////////////////////////////////////////////////////////////////////////////// 13 ////////////////////////////////////////////////////////////////////////////////
12 14
15 GrRODrawState::GrRODrawState(const GrRODrawState& drawState) : INHERITED() {
16 fRenderTarget.setResource(SkSafeRef(drawState.fRenderTarget.getResource()),
17 GrProgramResource::kWrite_IOType);
18 }
19
13 bool GrRODrawState::isEqual(const GrRODrawState& that) const { 20 bool GrRODrawState::isEqual(const GrRODrawState& that) const {
14 bool usingVertexColors = this->hasColorVertexAttribute(); 21 bool usingVertexColors = this->hasColorVertexAttribute();
15 if (!usingVertexColors && this->fColor != that.fColor) { 22 if (!usingVertexColors && this->fColor != that.fColor) {
16 return false; 23 return false;
17 } 24 }
18 25
19 if (this->getRenderTarget() != that.getRenderTarget() || 26 if (this->getRenderTarget() != that.getRenderTarget() ||
20 this->fColorStages.count() != that.fColorStages.count() || 27 this->fColorStages.count() != that.fColorStages.count() ||
21 this->fCoverageStages.count() != that.fCoverageStages.count() || 28 this->fCoverageStages.count() != that.fCoverageStages.count() ||
22 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || 29 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 if (this->hasGeometryProcessor()) { 164 if (this->hasGeometryProcessor()) {
158 if (fGeometryProcessor->getEffect()->willReadDstColor()) { 165 if (fGeometryProcessor->getEffect()->willReadDstColor()) {
159 return true; 166 return true;
160 } 167 }
161 } 168 }
162 return false; 169 return false;
163 } 170 }
164 171
165 //////////////////////////////////////////////////////////////////////////////// 172 ////////////////////////////////////////////////////////////////////////////////
166 173
174 GrRODrawState::BlendOptFlags GrRODrawState::getBlendOpts(bool forceCoverage,
175 GrBlendCoeff* srcCoeff,
176 GrBlendCoeff* dstCoeff) const {
177 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
178 if (NULL == srcCoeff) {
179 srcCoeff = &bogusSrcCoeff;
180 }
181 if (NULL == dstCoeff) {
182 dstCoeff = &bogusDstCoeff;
183 }
184
185 if (forceCoverage) {
186 return this->calcBlendOpts(true, srcCoeff, dstCoeff);
187 }
188
189 if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) {
190 *srcCoeff = fOptSrcBlend;
191 *dstCoeff = fOptDstBlend;
192 return fBlendOptFlags;
193 }
194
195 fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff);
196 fOptSrcBlend = *srcCoeff;
197 fOptDstBlend = *dstCoeff;
198
199 return fBlendOptFlags;
200 }
201
202 GrRODrawState::BlendOptFlags GrRODrawState::calcBlendOpts(bool forceCoverage,
203 GrBlendCoeff* srcCoeff ,
204 GrBlendCoeff* dstCoeff ) const {
205 *srcCoeff = this->getSrcBlendCoeff();
206 *dstCoeff = this->getDstBlendCoeff();
207
208 if (this->isColorWriteDisabled()) {
209 *srcCoeff = kZero_GrBlendCoeff;
210 *dstCoeff = kOne_GrBlendCoeff;
211 }
212
213 bool srcAIsOne = this->srcAlphaWillBeOne();
214 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
215 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
216 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
217 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
218
219 // When coeffs are (0,1) there is no reason to draw at all, unless
220 // stenciling is enabled. Having color writes disabled is effectively
221 // (0,1).
222 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) {
223 if (this->getStencil().doesWrite()) {
224 return kEmitCoverage_BlendOptFlag;
225 } else {
226 return kSkipDraw_BlendOptFlag;
227 }
228 }
229
230 bool hasCoverage = forceCoverage || !this->hasSolidCoverage();
231
232 // if we don't have coverage we can check whether the dst
233 // has to read at all. If not, we'll disable blending.
234 if (!hasCoverage) {
235 if (dstCoeffIsZero) {
236 if (kOne_GrBlendCoeff == *srcCoeff) {
237 // if there is no coverage and coeffs are (1,0) then we
238 // won't need to read the dst at all, it gets replaced by src
239 *dstCoeff = kZero_GrBlendCoeff;
240 return kNone_BlendOpt;
241 } else if (kZero_GrBlendCoeff == *srcCoeff) {
242 // if the op is "clear" then we don't need to emit a color
243 // or blend, just write transparent black into the dst.
244 *srcCoeff = kOne_GrBlendCoeff;
245 *dstCoeff = kZero_GrBlendCoeff;
246 return kEmitTransBlack_BlendOptFlag;
247 }
248 }
249 } else if (this->isCoverageDrawing()) {
250 // we have coverage but we aren't distinguishing it from alpha by reques t.
251 return kCoverageAsAlpha_BlendOptFlag;
252 } else {
253 // check whether coverage can be safely rolled into alpha
254 // of if we can skip color computation and just emit coverage
255 if (this->canTweakAlphaForCoverage()) {
256 return kCoverageAsAlpha_BlendOptFlag;
257 }
258 if (dstCoeffIsZero) {
259 if (kZero_GrBlendCoeff == *srcCoeff) {
260 // the source color is not included in the blend
261 // the dst coeff is effectively zero so blend works out to:
262 // (c)(0)D + (1-c)D = (1-c)D.
263 *dstCoeff = kISA_GrBlendCoeff;
264 return kEmitCoverage_BlendOptFlag;
265 } else if (srcAIsOne) {
266 // the dst coeff is effectively zero so blend works out to:
267 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
268 // If Sa is 1 then we can replace Sa with c
269 // and set dst coeff to 1-Sa.
270 *dstCoeff = kISA_GrBlendCoeff;
271 return kCoverageAsAlpha_BlendOptFlag;
272 }
273 } else if (dstCoeffIsOne) {
274 // the dst coeff is effectively one so blend works out to:
275 // cS + (c)(1)D + (1-c)D = cS + D.
276 *dstCoeff = kOne_GrBlendCoeff;
277 return kCoverageAsAlpha_BlendOptFlag;
278 }
279 }
280
281 return kNone_BlendOpt;
282 }
283
284 ////////////////////////////////////////////////////////////////////////////////
285
167 // Some blend modes allow folding a fractional coverage value into the color's a lpha channel, while 286 // Some blend modes allow folding a fractional coverage value into the color's a lpha channel, while
168 // others will blend incorrectly. 287 // others will blend incorrectly.
169 bool GrRODrawState::canTweakAlphaForCoverage() const { 288 bool GrRODrawState::canTweakAlphaForCoverage() const {
170 /* 289 /*
171 The fractional coverage is f. 290 The fractional coverage is f.
172 The src and dst coeffs are Cs and Cd. 291 The src and dst coeffs are Cs and Cd.
173 The dst and src colors are S and D. 292 The dst and src colors are S and D.
174 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou rce color's alpha 293 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou rce color's alpha
175 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second 294 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
176 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss ibilities for Cd we 295 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss ibilities for Cd we
(...skipping 13 matching lines...) Expand all
190 for (int i = 0; i < fColorStages.count(); ++i) { 309 for (int i = 0; i < fColorStages.count(); ++i) {
191 fColorStages[i].convertToPendingExec(); 310 fColorStages[i].convertToPendingExec();
192 } 311 }
193 if (fGeometryProcessor) { 312 if (fGeometryProcessor) {
194 fGeometryProcessor->convertToPendingExec(); 313 fGeometryProcessor->convertToPendingExec();
195 } 314 }
196 for (int i = 0; i < fCoverageStages.count(); ++i) { 315 for (int i = 0; i < fCoverageStages.count(); ++i) {
197 fCoverageStages[i].convertToPendingExec(); 316 fCoverageStages[i].convertToPendingExec();
198 } 317 }
199 } 318 }
319
320 bool GrRODrawState::srcAlphaWillBeOne() const {
321 uint32_t validComponentFlags;
322 GrColor color;
323 // Check if per-vertex or constant color may have partial alpha
324 if (this->hasColorVertexAttribute()) {
325 if (fHints & kVertexColorsAreOpaque_Hint) {
326 validComponentFlags = kA_GrColorComponentFlag;
327 color = 0xFF << GrColor_SHIFT_A;
328 } else {
329 validComponentFlags = 0;
330 color = 0; // not strictly necessary but we get false alarms from to ols about uninit.
331 }
332 } else {
333 validComponentFlags = kRGBA_GrColorComponentFlags;
334 color = this->getColor();
335 }
336
337 // Run through the color stages
338 for (int s = 0; s < this->numColorStages(); ++s) {
339 const GrEffect* effect = this->getColorStage(s).getEffect();
340 effect->getConstantColorComponents(&color, &validComponentFlags);
341 }
342
343 // Check whether coverage is treated as color. If so we run through the cove rage computation.
344 if (this->isCoverageDrawing()) {
345 // The shader generated for coverage drawing runs the full coverage comp utation and then
346 // makes the shader output be the multiplication of color and coverage. We mirror that here.
347 GrColor coverage;
348 uint32_t coverageComponentFlags;
349 if (this->hasCoverageVertexAttribute()) {
350 coverageComponentFlags = 0;
351 coverage = 0; // suppresses any warnings.
352 } else {
353 coverageComponentFlags = kRGBA_GrColorComponentFlags;
354 coverage = this->getCoverageColor();
355 }
356
357 // Run through the coverage stages
358 for (int s = 0; s < this->numCoverageStages(); ++s) {
359 const GrEffect* effect = this->getCoverageStage(s).getEffect();
360 effect->getConstantColorComponents(&coverage, &coverageComponentFlag s);
361 }
362
363 // Since the shader will multiply coverage and color, the only way the f inal A==1 is if
364 // coverage and color both have A==1.
365 return (kA_GrColorComponentFlag & validComponentFlags & coverageComponen tFlags) &&
366 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage );
367
368 }
369
370 return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnp ackA(color);
371 }
372
373 ////////////////////////////////////////////////////////////////////////////////
374
375 bool GrRODrawState::canIgnoreColorAttribute() const {
376 if (fBlendOptFlags & kInvalid_BlendOptFlag) {
377 this->getBlendOpts();
378 }
379 return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFla g |
380 GrRODrawState::kEmitCoverage_BlendOptFlag) );
381 }
382
OLDNEW
« no previous file with comments | « src/gpu/GrRODrawState.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698