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

Side by Side Diff: src/gpu/effects/GrPorterDuffXferProcessor.cpp

Issue 764643004: Create xfer processor backend. (Closed) Base URL: https://skia.googlesource.com/skia.git@xferBlendSolo
Patch Set: Blend off ODS and only on XP 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
« no previous file with comments | « src/gpu/GrProgramDesc.h ('k') | src/gpu/gl/GrGLProcessor.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 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 "effects/GrPorterDuffXferProcessor.h" 8 #include "effects/GrPorterDuffXferProcessor.h"
9 9
10 #include "GrBlend.h" 10 #include "GrBlend.h"
11 #include "GrDrawState.h" 11 #include "GrDrawState.h"
12 #include "GrDrawTargetCaps.h"
12 #include "GrInvariantOutput.h" 13 #include "GrInvariantOutput.h"
13 #include "GrProcessor.h" 14 #include "GrProcessor.h"
14 #include "GrTypes.h" 15 #include "GrTypes.h"
15 #include "GrXferProcessor.h" 16 #include "GrXferProcessor.h"
16 #include "gl/GrGLProcessor.h" 17 #include "gl/GrGLXferProcessor.h"
17 #include "gl/builders/GrGLFragmentShaderBuilder.h" 18 #include "gl/builders/GrGLFragmentShaderBuilder.h"
18 #include "gl/builders/GrGLProgramBuilder.h" 19 #include "gl/builders/GrGLProgramBuilder.h"
19 20
20 static bool can_tweak_alpha_for_coverage(GrBlendCoeff dstCoeff, bool isCoverageD rawing) { 21 static bool can_tweak_alpha_for_coverage(GrBlendCoeff dstCoeff, bool isCoverageD rawing) {
21 /* 22 /*
22 The fractional coverage is f. 23 The fractional coverage is f.
23 The src and dst coeffs are Cs and Cd. 24 The src and dst coeffs are Cs and Cd.
24 The dst and src colors are S and D. 25 The dst and src colors are S and D.
25 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou rce color's alpha 26 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou rce color's alpha
26 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second 27 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
27 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss ibilities for Cd we 28 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss ibilities for Cd we
28 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D. 29 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
29 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag e is treated as 30 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag e is treated as
30 color by definition. 31 color by definition.
31 */ 32 */
32 // TODO: Once we have a CoverageDrawing XP, we don't need to check is Covera geDrawing here 33 // TODO: Once we have a CoverageDrawing XP, we don't need to check is Covera geDrawing here
33 return kOne_GrBlendCoeff == dstCoeff || 34 return kOne_GrBlendCoeff == dstCoeff ||
34 kISA_GrBlendCoeff == dstCoeff || 35 kISA_GrBlendCoeff == dstCoeff ||
35 kISC_GrBlendCoeff == dstCoeff || 36 kISC_GrBlendCoeff == dstCoeff ||
36 isCoverageDrawing; 37 isCoverageDrawing;
37 } 38 }
38 39
39 class GrGLPorterDuffXferProcessor : public GrGLXferProcessor { 40 class GrGLPorterDuffXferProcessor : public GrGLXferProcessor {
40 public: 41 public:
41 GrGLPorterDuffXferProcessor(const GrProcessor&) {} 42 GrGLPorterDuffXferProcessor(const GrProcessor&) {}
42 43
43 virtual ~GrGLPorterDuffXferProcessor() {} 44 virtual ~GrGLPorterDuffXferProcessor() {}
44 45
45 virtual void emitCode(GrGLFPBuilder* builder, 46 virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
46 const GrFragmentProcessor& fp, 47 const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProc essor>();
47 const char* outputColor, 48 GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
48 const char* inputColor, 49 if (xp.hasSecondaryOutput()) {
49 const TransformedCoordsArray& coords, 50 switch(xp.secondaryOutputType()) {
50 const TextureSamplerArray& samplers) SK_OVERRIDE { 51 case GrPorterDuffXferProcessor::kCoverage_SecondaryOutputType:
51 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 52 fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, ar gs.fInputCoverage);
52 fsBuilder->codeAppendf("%s = %s;", outputColor, inputColor); 53 break;
54 case GrPorterDuffXferProcessor::kCoverageISA_SecondaryOutputType :
55 fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
56 args.fOutputSecondary, args.fInputCol or,
57 args.fInputCoverage);
58 break;
59 case GrPorterDuffXferProcessor::kCoverageISC_SecondaryOutputType :
60 fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
61 args.fOutputSecondary, args.fInputCol or,
62 args.fInputCoverage);
63 break;
64 default:
65 SkFAIL("Unexpected Secondary Output");
66 }
67 }
68
69 fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInput Color,
70 args.fInputCoverage);
71 if (GrPorterDuffXferProcessor::kCombineWithDst_PrimaryOutputType == xp.p rimaryOutputType()){
72 fsBuilder->codeAppendf("%s += (vec4(1.0) - %s) * %s;", args.fOutputP rimary,
73 args.fInputCoverage, fsBuilder->dstColor());
74 }
53 } 75 }
54 76
55 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O VERRIDE {}; 77 virtual void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
56 78
57 static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyB uilder* b) {}; 79 static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
80 GrProcessorKeyBuilder* b) {
81 const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferPro cessor>();
82 b->add32(xp.primaryOutputType());
83 b->add32(xp.secondaryOutputType());
84 };
58 85
59 private: 86 private:
60 typedef GrGLXferProcessor INHERITED; 87 typedef GrGLXferProcessor INHERITED;
61 }; 88 };
62 89
63 /////////////////////////////////////////////////////////////////////////////// 90 ///////////////////////////////////////////////////////////////////////////////
64 91
65 GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBl endCoeff dstBlend, 92 GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBl endCoeff dstBlend,
66 GrColor constant) 93 GrColor constant)
67 : fSrcBlend(srcBlend), fDstBlend(dstBlend), fBlendConstant(constant) { 94 : fSrcBlend(srcBlend)
95 , fDstBlend(dstBlend)
96 , fBlendConstant(constant)
97 , fPrimaryOutputType(kModulate_PrimaryOutputType)
98 , fSecondaryOutputType(kNone_SecondaryOutputType) {
68 this->initClassID<GrPorterDuffXferProcessor>(); 99 this->initClassID<GrPorterDuffXferProcessor>();
69 } 100 }
70 101
71 GrPorterDuffXferProcessor::~GrPorterDuffXferProcessor() { 102 GrPorterDuffXferProcessor::~GrPorterDuffXferProcessor() {
72 } 103 }
73 104
74 void GrPorterDuffXferProcessor::getGLProcessorKey(const GrGLCaps& caps, 105 void GrPorterDuffXferProcessor::getGLProcessorKey(const GrGLCaps& caps,
75 GrProcessorKeyBuilder* b) cons t { 106 GrProcessorKeyBuilder* b) cons t {
76 GrGLPorterDuffXferProcessor::GenKey(*this, caps, b); 107 GrGLPorterDuffXferProcessor::GenKey(*this, caps, b);
77 } 108 }
78 109
79 GrGLFragmentProcessor* GrPorterDuffXferProcessor::createGLInstance() const { 110 GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const {
80 return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this)); 111 return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this));
81 } 112 }
82 113
83 void GrPorterDuffXferProcessor::onComputeInvariantOutput(GrInvariantOutput* inou t) const { 114 void GrPorterDuffXferProcessor::onComputeInvariantOutput(GrInvariantOutput* inou t) const {
84 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); 115 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
85 } 116 }
86 117
87 GrXferProcessor::OptFlags 118 GrXferProcessor::OptFlags
88 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, 119 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
89 const GrProcOptInfo& coveragePOI, 120 const GrProcOptInfo& coveragePOI,
90 bool isCoverageDrawing, 121 bool isCoverageDrawing,
91 bool colorWriteDisabled, 122 bool colorWriteDisabled,
92 bool doesStencilWrite, 123 bool doesStencilWrite,
93 GrColor* color, uint8_t* coverage) { 124 GrColor* color, uint8_t* coverage,
125 const GrDrawTargetCaps& caps) {
126 GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI ,
127 coverage POI,
128 isCovera geDrawing,
129 colorWri teDisabled,
130 doesSten cilWrite,
131 color,
132 coverage );
133
134 this->calcOutputTypes(optFlags, caps, isCoverageDrawing || coveragePOI.isSol idWhite(),
135 colorPOI.readsDst() || coveragePOI.readsDst());
136 return optFlags;
137 }
138
139 void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla gs,
140 const GrDrawTargetCaps& caps,
141 bool hasSolidCoverage, bool read sDst) {
142 // If we do have coverage determine whether it matters. Dual source blendin g is expensive so
143 // we don't do it if we are doing coverage drawing. If we aren't then We al ways do dual source
144 // blending if we have any effective coverage stages OR the geometry process or doesn't emits
145 // solid coverage.
146 if (!(optFlags & kSetCoverageDrawing_OptFlag) && !hasSolidCoverage) {
147 if (caps.dualSourceBlendingSupport()) {
148 if (kZero_GrBlendCoeff == fDstBlend) {
149 // write the coverage value to second color
150 fSecondaryOutputType = kCoverage_SecondaryOutputType;
151 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
152 } else if (kSA_GrBlendCoeff == fDstBlend) {
153 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
154 fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
155 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
156 } else if (kSC_GrBlendCoeff == fDstBlend) {
157 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
158 fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
159 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
160 }
161 } else if (readsDst &&
162 kOne_GrBlendCoeff == fSrcBlend &&
163 kZero_GrBlendCoeff == fDstBlend) {
164 fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
165 }
166 }
167 }
168
169 GrXferProcessor::OptFlags
170 GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO I,
171 const GrProcOptInfo& coverag ePOI,
172 bool isCoverageDrawing,
173 bool colorWriteDisabled,
174 bool doesStencilWrite,
175 GrColor* color, uint8_t* cov erage) {
94 if (colorWriteDisabled) { 176 if (colorWriteDisabled) {
95 fSrcBlend = kZero_GrBlendCoeff; 177 fSrcBlend = kZero_GrBlendCoeff;
96 fDstBlend = kOne_GrBlendCoeff; 178 fDstBlend = kOne_GrBlendCoeff;
97 } 179 }
98 180
99 bool srcAIsOne; 181 bool srcAIsOne;
100 bool hasCoverage; 182 bool hasCoverage;
101 if (isCoverageDrawing) { 183 if (isCoverageDrawing) {
102 srcAIsOne = colorPOI.isOpaque() && coveragePOI.isOpaque(); 184 srcAIsOne = colorPOI.isOpaque() && coveragePOI.isOpaque();
103 hasCoverage = false; 185 hasCoverage = false;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 } else if (dstCoeffIsOne) { 267 } else if (dstCoeffIsOne) {
186 // the dst coeff is effectively one so blend works out to: 268 // the dst coeff is effectively one so blend works out to:
187 // cS + (c)(1)D + (1-c)D = cS + D. 269 // cS + (c)(1)D + (1-c)D = cS + D.
188 fDstBlend = kOne_GrBlendCoeff; 270 fDstBlend = kOne_GrBlendCoeff;
189 return GrXferProcessor::kSetCoverageDrawing_OptFlag; 271 return GrXferProcessor::kSetCoverageDrawing_OptFlag;
190 } 272 }
191 } 273 }
192 274
193 return GrXferProcessor::kNone_Opt; 275 return GrXferProcessor::kNone_Opt;
194 } 276 }
277
278 bool GrPorterDuffXferProcessor::hasSecondaryOutput() const {
279 return kNone_SecondaryOutputType != fSecondaryOutputType;
280 }
281
195 /////////////////////////////////////////////////////////////////////////////// 282 ///////////////////////////////////////////////////////////////////////////////
196 283
197 GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst) 284 GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst)
198 : fSrcCoeff(src), fDstCoeff(dst) { 285 : fSrcCoeff(src), fDstCoeff(dst) {
199 this->initClassID<GrPorterDuffXPFactory>(); 286 this->initClassID<GrPorterDuffXPFactory>();
200 } 287 }
201 288
202 GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) { 289 GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) {
203 switch (mode) { 290 switch (mode) {
204 case SkXfermode::kClear_Mode: { 291 case SkXfermode::kClear_Mode: {
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 *solidColorKnownComponents = 0; 530 *solidColorKnownComponents = 0;
444 break; 531 break;
445 } 532 }
446 } else { 533 } else {
447 solidColorKnownComponents = 0; 534 solidColorKnownComponents = 0;
448 } 535 }
449 } 536 }
450 return opaque; 537 return opaque;
451 } 538 }
452 539
540 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
453 541
542 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
543 GrContext*,
544 const GrDrawTargetCaps&,
545 GrTexture*[]) {
546 GrBlendCoeff src;
547 do {
548 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
549 } while (GrBlendCoeffRefsSrc(src));
550
551 GrBlendCoeff dst;
552 do {
553 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
554 } while (GrBlendCoeffRefsDst(dst));
555
556 return GrPorterDuffXPFactory::Create(src, dst);
557 }
558
OLDNEW
« no previous file with comments | « src/gpu/GrProgramDesc.h ('k') | src/gpu/gl/GrGLProcessor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698