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

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

Issue 759713002: Make all blending up to GrOptDrawState be handled by the xp/xp factory. (Closed) Base URL: https://skia.googlesource.com/skia.git@xferFactorySolo
Patch Set: Clean up Created 6 years 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
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 9
10 #include "GrBlend.h" 10 #include "GrBlend.h"
11 #include "GrOptDrawState.h" 11 #include "GrOptDrawState.h"
12 #include "GrPaint.h" 12 #include "GrPaint.h"
13 #include "GrProcOptInfo.h" 13 #include "GrProcOptInfo.h"
14 #include "GrXferProcessor.h" 14 #include "GrXferProcessor.h"
15 #include "effects/GrPorterDuffXferProcessor.h" 15 #include "effects/GrPorterDuffXferProcessor.h"
16 16
17 ///////////////////////////////////////////////////////////////////////////////
18
19 bool GrDrawState::isEqual(const GrDrawState& that) const { 17 bool GrDrawState::isEqual(const GrDrawState& that) const {
20 bool usingVertexColors = this->hasColorVertexAttribute(); 18 bool usingVertexColors = this->hasColorVertexAttribute();
21 if (!usingVertexColors && this->fColor != that.fColor) { 19 if (!usingVertexColors && this->fColor != that.fColor) {
22 return false; 20 return false;
23 } 21 }
24 22
25 if (this->getRenderTarget() != that.getRenderTarget() || 23 if (this->getRenderTarget() != that.getRenderTarget() ||
26 this->fColorStages.count() != that.fColorStages.count() || 24 this->fColorStages.count() != that.fColorStages.count() ||
27 this->fCoverageStages.count() != that.fCoverageStages.count() || 25 this->fCoverageStages.count() != that.fCoverageStages.count() ||
28 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || 26 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
29 this->fSrcBlend != that.fSrcBlend ||
30 this->fDstBlend != that.fDstBlend ||
31 this->fBlendConstant != that.fBlendConstant ||
32 this->fFlagBits != that.fFlagBits || 27 this->fFlagBits != that.fFlagBits ||
33 this->fStencilSettings != that.fStencilSettings || 28 this->fStencilSettings != that.fStencilSettings ||
34 this->fDrawFace != that.fDrawFace) { 29 this->fDrawFace != that.fDrawFace) {
35 return false; 30 return false;
36 } 31 }
37 32
38 bool usingVertexCoverage = this->hasCoverageVertexAttribute(); 33 bool usingVertexCoverage = this->hasCoverageVertexAttribute();
39 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) { 34 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
40 return false; 35 return false;
41 } 36 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 for (int i = 0; i < this->numCoverageStages(); ++i) { 74 for (int i = 0; i < this->numCoverageStages(); ++i) {
80 fCoverageStages[i].localCoordChange(preConcatMatrix); 75 fCoverageStages[i].localCoordChange(preConcatMatrix);
81 } 76 }
82 } 77 }
83 } 78 }
84 79
85 GrDrawState& GrDrawState::operator=(const GrDrawState& that) { 80 GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
86 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get())); 81 fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
87 fColor = that.fColor; 82 fColor = that.fColor;
88 fViewMatrix = that.fViewMatrix; 83 fViewMatrix = that.fViewMatrix;
89 fSrcBlend = that.fSrcBlend;
90 fDstBlend = that.fDstBlend;
91 fBlendConstant = that.fBlendConstant;
92 fFlagBits = that.fFlagBits; 84 fFlagBits = that.fFlagBits;
93 fStencilSettings = that.fStencilSettings; 85 fStencilSettings = that.fStencilSettings;
94 fCoverage = that.fCoverage; 86 fCoverage = that.fCoverage;
95 fDrawFace = that.fDrawFace; 87 fDrawFace = that.fDrawFace;
96 fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get())); 88 fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get()));
97 fXPFactory.reset(SkRef(that.getXPFactory())); 89 fXPFactory.reset(SkRef(that.getXPFactory()));
98 fColorStages = that.fColorStages; 90 fColorStages = that.fColorStages;
99 fCoverageStages = that.fCoverageStages; 91 fCoverageStages = that.fCoverageStages;
100 92
101 fHints = that.fHints; 93 fHints = that.fHints;
(...skipping 17 matching lines...) Expand all
119 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode)); 111 fXPFactory.reset(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode));
120 fColorStages.reset(); 112 fColorStages.reset();
121 fCoverageStages.reset(); 113 fCoverageStages.reset();
122 114
123 fColor = 0xffffffff; 115 fColor = 0xffffffff;
124 if (NULL == initialViewMatrix) { 116 if (NULL == initialViewMatrix) {
125 fViewMatrix.reset(); 117 fViewMatrix.reset();
126 } else { 118 } else {
127 fViewMatrix = *initialViewMatrix; 119 fViewMatrix = *initialViewMatrix;
128 } 120 }
129 fSrcBlend = kOne_GrBlendCoeff;
130 fDstBlend = kZero_GrBlendCoeff;
131 fBlendConstant = 0x0;
132 fFlagBits = 0x0; 121 fFlagBits = 0x0;
133 fStencilSettings.setDisabled(); 122 fStencilSettings.setDisabled();
134 fCoverage = 0xff; 123 fCoverage = 0xff;
135 fDrawFace = kBoth_DrawFace; 124 fDrawFace = kBoth_DrawFace;
136 125
137 fHints = 0; 126 fHints = 0;
138 127
139 fColorProcInfoValid = false; 128 fColorProcInfoValid = false;
140 fCoverageProcInfoValid = false; 129 fCoverageProcInfoValid = false;
141 } 130 }
(...skipping 26 matching lines...) Expand all
168 for (int i = 0; i < paint.numColorStages(); ++i) { 157 for (int i = 0; i < paint.numColorStages(); ++i) {
169 fColorStages.push_back(paint.getColorStage(i)); 158 fColorStages.push_back(paint.getColorStage(i));
170 } 159 }
171 160
172 for (int i = 0; i < paint.numCoverageStages(); ++i) { 161 for (int i = 0; i < paint.numCoverageStages(); ++i) {
173 fCoverageStages.push_back(paint.getCoverageStage(i)); 162 fCoverageStages.push_back(paint.getCoverageStage(i));
174 } 163 }
175 164
176 fXPFactory.reset(SkRef(paint.getXPFactory())); 165 fXPFactory.reset(SkRef(paint.getXPFactory()));
177 166
178 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
179 this->setRenderTarget(rt); 167 this->setRenderTarget(rt);
180 168
181 fViewMatrix = vm; 169 fViewMatrix = vm;
182 170
183 // These have no equivalent in GrPaint, set them to defaults 171 // These have no equivalent in GrPaint, set them to defaults
184 fBlendConstant = 0x0;
185 fDrawFace = kBoth_DrawFace; 172 fDrawFace = kBoth_DrawFace;
186 fStencilSettings.setDisabled(); 173 fStencilSettings.setDisabled();
187 fFlagBits = 0; 174 fFlagBits = 0;
188 fHints = 0; 175 fHints = 0;
189 176
190 // Enable the clip bit 177 // Enable the clip bit
191 this->enableState(GrDrawState::kClip_StateBit); 178 this->enableState(GrDrawState::kClip_StateBit);
192 179
193 this->setColor(paint.getColor()); 180 this->setColor(paint.getColor());
194 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); 181 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
195 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); 182 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
196 183
197 this->setCoverage(0xFF); 184 this->setCoverage(0xFF);
198 fColorProcInfoValid = false; 185 fColorProcInfoValid = false;
199 fCoverageProcInfoValid = false; 186 fCoverageProcInfoValid = false;
200 } 187 }
201 188
202 //////////////////////////////////////////////////////////////////////////////// 189 ////////////////////////////////////////////////////////////////////////////////
203 190
204 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { 191 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
205 if (caps.dualSourceBlendingSupport()) { 192 if (caps.dualSourceBlendingSupport()) {
206 return true; 193 return true;
207 } 194 }
208 // we can correctly apply coverage if a) we have dual source blending 195
209 // or b) one of our blend optimizations applies 196 this->calcColorInvariantOutput();
210 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color 197 this->calcCoverageInvariantOutput();
211 GrBlendCoeff srcCoeff; 198 return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo,
212 GrBlendCoeff dstCoeff; 199 this->isCoverageDrawing(), this->isColor WriteDisabled());
213 BlendOpt opt = this->getBlendOpt(true, &srcCoeff, &dstCoeff);
214 return GrDrawState::kNone_BlendOpt != opt ||
215 (this->willEffectReadDstColor() &&
216 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
217 } 200 }
218 201
219 bool GrDrawState::hasSolidCoverage() const { 202 bool GrDrawState::hasSolidCoverage() const {
220 // If we're drawing coverage directly then coverage is effectively treated a s color. 203 // If we're drawing coverage directly then coverage is effectively treated a s color.
221 if (this->isCoverageDrawing()) { 204 if (this->isCoverageDrawing()) {
222 return true; 205 return true;
223 } 206 }
224 207
225 if (this->numCoverageStages() > 0) { 208 if (this->numCoverageStages() > 0) {
226 return false; 209 return false;
227 } 210 }
228 211
229 this->calcCoverageInvariantOutput(); 212 this->calcCoverageInvariantOutput();
230 return fCoverageProcInfo.isSolidWhite(); 213 return fCoverageProcInfo.isSolidWhite();
231 } 214 }
232 215
233 //////////////////////////////////////////////////////////////////////////////s 216 //////////////////////////////////////////////////////////////////////////////s
234 217
235 bool GrDrawState::willEffectReadDstColor() const { 218 bool GrDrawState::willEffectReadDstColor() const {
219 this->calcColorInvariantOutput();
220 this->calcCoverageInvariantOutput();
221 // TODO: Remove need to create the XP here.
222 // Also once all custom blends are turned into XPs we can remove the n eed
223 // to check other stages since only xp's will be able to read dst
224 const GrXferProcessor* xferProcessor = fXPFactory->createXferProcessor(fColo rProcInfo,
225 fCove rageProcInfo);
226 if (xferProcessor && xferProcessor->willReadDstColor()) {
227 return true;
228 }
229 SkSafeUnref(xferProcessor);
230
236 if (!this->isColorWriteDisabled()) { 231 if (!this->isColorWriteDisabled()) {
237 this->calcColorInvariantOutput();
238 if (fColorProcInfo.readsDst()) { 232 if (fColorProcInfo.readsDst()) {
239 return true; 233 return true;
240 } 234 }
241 } 235 }
242 this->calcCoverageInvariantOutput();
243 return fCoverageProcInfo.readsDst(); 236 return fCoverageProcInfo.readsDst();
244 } 237 }
245 238
246 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { 239 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
247 if (fDrawState) { 240 if (fDrawState) {
248 // See the big comment on the class definition about GPs. 241 // See the big comment on the class definition about GPs.
249 if (SK_InvalidUniqueID == fOriginalGPID) { 242 if (SK_InvalidUniqueID == fOriginalGPID) {
250 fDrawState->fGeometryProcessor.reset(NULL); 243 fDrawState->fGeometryProcessor.reset(NULL);
251 } else { 244 } else {
252 SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() == 245 SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
(...skipping 24 matching lines...) Expand all
277 fCoverageEffectCnt = ds->numCoverageStages(); 270 fCoverageEffectCnt = ds->numCoverageStages();
278 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) 271 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
279 } 272 }
280 } 273 }
281 274
282 //////////////////////////////////////////////////////////////////////////////// 275 ////////////////////////////////////////////////////////////////////////////////
283 276
284 // Some blend modes allow folding a fractional coverage value into the color's a lpha channel, while 277 // Some blend modes allow folding a fractional coverage value into the color's a lpha channel, while
285 // others will blend incorrectly. 278 // others will blend incorrectly.
286 bool GrDrawState::canTweakAlphaForCoverage() const { 279 bool GrDrawState::canTweakAlphaForCoverage() const {
287 /* 280 return fXPFactory->canTweakAlphaForCoverage(this->isCoverageDrawing());
288 The fractional coverage is f.
289 The src and dst coeffs are Cs and Cd.
290 The dst and src colors are S and D.
291 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou rce color's alpha
292 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
293 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss ibilities for Cd we
294 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
295 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag e is treated as
296 color by definition.
297 */
298 return kOne_GrBlendCoeff == fDstBlend ||
299 kISA_GrBlendCoeff == fDstBlend ||
300 kISC_GrBlendCoeff == fDstBlend ||
301 this->isCoverageDrawing();
302 } 281 }
303 282
304 //////////////////////////////////////////////////////////////////////////////// 283 ////////////////////////////////////////////////////////////////////////////////
305 284
306 void GrDrawState::AutoViewMatrixRestore::restore() { 285 void GrDrawState::AutoViewMatrixRestore::restore() {
307 if (fDrawState) { 286 if (fDrawState) {
308 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) 287 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
309 fDrawState->fViewMatrix = fViewMatrix; 288 fDrawState->fViewMatrix = fViewMatrix;
310 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); 289 SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
311 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; 290 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 368 }
390 369
391 //////////////////////////////////////////////////////////////////////////////// 370 ////////////////////////////////////////////////////////////////////////////////
392 371
393 GrDrawState::~GrDrawState() { 372 GrDrawState::~GrDrawState() {
394 SkASSERT(0 == fBlockEffectRemovalCnt); 373 SkASSERT(0 == fBlockEffectRemovalCnt);
395 } 374 }
396 375
397 //////////////////////////////////////////////////////////////////////////////// 376 ////////////////////////////////////////////////////////////////////////////////
398 377
399 GrDrawState::BlendOpt GrDrawState::getBlendOpt(bool forceCoverage,
400 GrBlendCoeff* srcCoeff,
401 GrBlendCoeff* dstCoeff) const {
402 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
403 if (NULL == srcCoeff) {
404 srcCoeff = &bogusSrcCoeff;
405 }
406 if (NULL == dstCoeff) {
407 dstCoeff = &bogusDstCoeff;
408 }
409
410 *srcCoeff = this->getSrcBlendCoeff();
411 *dstCoeff = this->getDstBlendCoeff();
412
413 if (this->isColorWriteDisabled()) {
414 *srcCoeff = kZero_GrBlendCoeff;
415 *dstCoeff = kOne_GrBlendCoeff;
416 }
417
418 bool srcAIsOne = this->srcAlphaWillBeOne();
419 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
420 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
421 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
422 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
423
424 // When coeffs are (0,1) there is no reason to draw at all, unless
425 // stenciling is enabled. Having color writes disabled is effectively
426 // (0,1).
427 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) {
428 if (this->getStencil().doesWrite()) {
429 return kEmitCoverage_BlendOpt;
430 } else {
431 *dstCoeff = kOne_GrBlendCoeff;
432 return kSkipDraw_BlendOpt;
433 }
434 }
435
436 bool hasCoverage = forceCoverage || !this->hasSolidCoverage();
437
438 // if we don't have coverage we can check whether the dst
439 // has to read at all. If not, we'll disable blending.
440 if (!hasCoverage) {
441 if (dstCoeffIsZero) {
442 if (kOne_GrBlendCoeff == *srcCoeff) {
443 // if there is no coverage and coeffs are (1,0) then we
444 // won't need to read the dst at all, it gets replaced by src
445 *dstCoeff = kZero_GrBlendCoeff;
446 return kNone_BlendOpt;
447 } else if (kZero_GrBlendCoeff == *srcCoeff) {
448 // if the op is "clear" then we don't need to emit a color
449 // or blend, just write transparent black into the dst.
450 *srcCoeff = kOne_GrBlendCoeff;
451 *dstCoeff = kZero_GrBlendCoeff;
452 return kEmitTransBlack_BlendOpt;
453 }
454 }
455 } else if (this->isCoverageDrawing()) {
456 // we have coverage but we aren't distinguishing it from alpha by reques t.
457 return kCoverageAsAlpha_BlendOpt;
458 } else {
459 // check whether coverage can be safely rolled into alpha
460 // of if we can skip color computation and just emit coverage
461 if (this->canTweakAlphaForCoverage()) {
462 return kCoverageAsAlpha_BlendOpt;
463 }
464 if (dstCoeffIsZero) {
465 if (kZero_GrBlendCoeff == *srcCoeff) {
466 // the source color is not included in the blend
467 // the dst coeff is effectively zero so blend works out to:
468 // (c)(0)D + (1-c)D = (1-c)D.
469 *dstCoeff = kISA_GrBlendCoeff;
470 return kEmitCoverage_BlendOpt;
471 } else if (srcAIsOne) {
472 // the dst coeff is effectively zero so blend works out to:
473 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
474 // If Sa is 1 then we can replace Sa with c
475 // and set dst coeff to 1-Sa.
476 *dstCoeff = kISA_GrBlendCoeff;
477 return kCoverageAsAlpha_BlendOpt;
478 }
479 } else if (dstCoeffIsOne) {
480 // the dst coeff is effectively one so blend works out to:
481 // cS + (c)(1)D + (1-c)D = cS + D.
482 *dstCoeff = kOne_GrBlendCoeff;
483 return kCoverageAsAlpha_BlendOpt;
484 }
485 }
486
487 return kNone_BlendOpt;
488 }
489
490 bool GrDrawState::srcAlphaWillBeOne() const { 378 bool GrDrawState::srcAlphaWillBeOne() const {
491 this->calcColorInvariantOutput(); 379 this->calcColorInvariantOutput();
492 if (this->isCoverageDrawing()) { 380 if (this->isCoverageDrawing()) {
493 this->calcCoverageInvariantOutput(); 381 this->calcCoverageInvariantOutput();
494 return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque()); 382 return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque());
495 } 383 }
496 return fColorProcInfo.isOpaque(); 384 return fColorProcInfo.isOpaque();
497 } 385 }
498 386
499 bool GrDrawState::willBlendWithDst() const { 387 bool GrDrawState::willBlendWithDst() const {
500 if (!this->hasSolidCoverage()) { 388 this->calcColorInvariantOutput();
501 return true; 389 this->calcCoverageInvariantOutput();
502 } 390 return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo,
503 391 this->isCoverageDrawing(), this->isColor WriteDisabled());
504 if (this->willEffectReadDstColor()) {
505 return true;
506 }
507
508 if (GrBlendCoeffRefsDst(this->getSrcBlendCoeff())) {
509 return true;
510 }
511
512 GrBlendCoeff dstCoeff = this->getDstBlendCoeff();
513 if (!(kZero_GrBlendCoeff == dstCoeff ||
514 (kISA_GrBlendCoeff == dstCoeff && this->srcAlphaWillBeOne()))) {
515 return true;
516 }
517
518 return false;
519 } 392 }
520 393
521 void GrDrawState::calcColorInvariantOutput() const { 394 void GrDrawState::calcColorInvariantOutput() const {
522 if (!fColorProcInfoValid) { 395 if (!fColorProcInfoValid) {
523 GrColor color; 396 GrColor color;
524 GrColorComponentFlags flags; 397 GrColorComponentFlags flags;
525 if (this->hasColorVertexAttribute()) { 398 if (this->hasColorVertexAttribute()) {
526 if (fHints & kVertexColorsAreOpaque_Hint) { 399 if (fHints & kVertexColorsAreOpaque_Hint) {
527 flags = kA_GrColorComponentFlag; 400 flags = kA_GrColorComponentFlag;
528 color = 0xFF << GrColor_SHIFT_A; 401 color = 0xFF << GrColor_SHIFT_A;
(...skipping 21 matching lines...) Expand all
550 color = 0; 423 color = 0;
551 } else { 424 } else {
552 flags = kRGBA_GrColorComponentFlags; 425 flags = kRGBA_GrColorComponentFlags;
553 color = this->getCoverageColor(); 426 color = this->getCoverageColor();
554 } 427 }
555 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->n umCoverageStages(), 428 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->n umCoverageStages(),
556 color, flags, true, fGeometryPro cessor.get()); 429 color, flags, true, fGeometryPro cessor.get());
557 fCoverageProcInfoValid = true; 430 fCoverageProcInfoValid = true;
558 } 431 }
559 } 432 }
560
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698