1 /*
2 * Copyright 2015 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 "GrXferProcessor.h"
9
10 #include "GrCaps.h"
11 #include "GrPipeline.h"
12
GrXferProcessor(ClassID classID)13 GrXferProcessor::GrXferProcessor(ClassID classID)
14 : INHERITED(classID)
15 , fWillReadDstColor(false)
16 , fDstReadUsesMixedSamples(false)
17 , fIsLCD(false) {}
18
GrXferProcessor(ClassID classID,bool willReadDstColor,bool hasMixedSamples,GrProcessorAnalysisCoverage coverage)19 GrXferProcessor::GrXferProcessor(ClassID classID, bool willReadDstColor, bool hasMixedSamples,
20 GrProcessorAnalysisCoverage coverage)
21 : INHERITED(classID)
22 , fWillReadDstColor(willReadDstColor)
23 , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples)
24 , fIsLCD(GrProcessorAnalysisCoverage::kLCD == coverage) {}
25
hasSecondaryOutput() const26 bool GrXferProcessor::hasSecondaryOutput() const {
27 if (!this->willReadDstColor()) {
28 return this->onHasSecondaryOutput();
29 }
30 return this->dstReadUsesMixedSamples();
31 }
32
getBlendInfo(BlendInfo * blendInfo) const33 void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const {
34 blendInfo->reset();
35 if (!this->willReadDstColor()) {
36 this->onGetBlendInfo(blendInfo);
37 } else if (this->dstReadUsesMixedSamples()) {
38 blendInfo->fDstBlend = kIS2A_GrBlendCoeff;
39 }
40 }
41
getGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b,const GrSurfaceOrigin * originIfDstTexture) const42 void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b,
43 const GrSurfaceOrigin* originIfDstTexture) const {
44 uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
45 if (key) {
46 if (originIfDstTexture) {
47 key |= 0x2;
48 if (kTopLeft_GrSurfaceOrigin == *originIfDstTexture) {
49 key |= 0x4;
50 }
51 }
52 if (this->dstReadUsesMixedSamples()) {
53 key |= 0x8;
54 }
55 }
56 if (fIsLCD) {
57 key |= 0x10;
58 }
59 b->add32(key);
60 this->onGetGLSLProcessorKey(caps, b);
61 }
62
63 #ifdef SK_DEBUG
equation_string(GrBlendEquation eq)64 static const char* equation_string(GrBlendEquation eq) {
65 switch (eq) {
66 case kAdd_GrBlendEquation:
67 return "add";
68 case kSubtract_GrBlendEquation:
69 return "subtract";
70 case kReverseSubtract_GrBlendEquation:
71 return "reverse_subtract";
72 case kScreen_GrBlendEquation:
73 return "screen";
74 case kOverlay_GrBlendEquation:
75 return "overlay";
76 case kDarken_GrBlendEquation:
77 return "darken";
78 case kLighten_GrBlendEquation:
79 return "lighten";
80 case kColorDodge_GrBlendEquation:
81 return "color_dodge";
82 case kColorBurn_GrBlendEquation:
83 return "color_burn";
84 case kHardLight_GrBlendEquation:
85 return "hard_light";
86 case kSoftLight_GrBlendEquation:
87 return "soft_light";
88 case kDifference_GrBlendEquation:
89 return "difference";
90 case kExclusion_GrBlendEquation:
91 return "exclusion";
92 case kMultiply_GrBlendEquation:
93 return "multiply";
94 case kHSLHue_GrBlendEquation:
95 return "hsl_hue";
96 case kHSLSaturation_GrBlendEquation:
97 return "hsl_saturation";
98 case kHSLColor_GrBlendEquation:
99 return "hsl_color";
100 case kHSLLuminosity_GrBlendEquation:
101 return "hsl_luminosity";
102 case kIllegal_GrBlendEquation:
103 SkASSERT(false);
104 return "<illegal>";
105 }
106 return "";
107 }
108
coeff_string(GrBlendCoeff coeff)109 static const char* coeff_string(GrBlendCoeff coeff) {
110 switch (coeff) {
111 case kZero_GrBlendCoeff:
112 return "zero";
113 case kOne_GrBlendCoeff:
114 return "one";
115 case kSC_GrBlendCoeff:
116 return "src_color";
117 case kISC_GrBlendCoeff:
118 return "inv_src_color";
119 case kDC_GrBlendCoeff:
120 return "dst_color";
121 case kIDC_GrBlendCoeff:
122 return "inv_dst_color";
123 case kSA_GrBlendCoeff:
124 return "src_alpha";
125 case kISA_GrBlendCoeff:
126 return "inv_src_alpha";
127 case kDA_GrBlendCoeff:
128 return "dst_alpha";
129 case kIDA_GrBlendCoeff:
130 return "inv_dst_alpha";
131 case kConstC_GrBlendCoeff:
132 return "const_color";
133 case kIConstC_GrBlendCoeff:
134 return "inv_const_color";
135 case kConstA_GrBlendCoeff:
136 return "const_alpha";
137 case kIConstA_GrBlendCoeff:
138 return "inv_const_alpha";
139 case kS2C_GrBlendCoeff:
140 return "src2_color";
141 case kIS2C_GrBlendCoeff:
142 return "inv_src2_color";
143 case kS2A_GrBlendCoeff:
144 return "src2_alpha";
145 case kIS2A_GrBlendCoeff:
146 return "inv_src2_alpha";
147 case kIllegal_GrBlendCoeff:
148 SkASSERT(false);
149 return "<illegal>";
150 }
151 return "";
152 }
153
dump() const154 SkString GrXferProcessor::BlendInfo::dump() const {
155 SkString out;
156 out.printf("write_color(%d) equation(%s) src_coeff(%s) dst_coeff:(%s) const(0x%08x)",
157 fWriteColor, equation_string(fEquation), coeff_string(fSrcBlend),
158 coeff_string(fDstBlend), fBlendConstant.toBytes_RGBA());
159 return out;
160 }
161 #endif
162
163 ///////////////////////////////////////////////////////////////////////////////
164
GetAnalysisProperties(const GrXPFactory * factory,const GrProcessorAnalysisColor & color,const GrProcessorAnalysisCoverage & coverage,const GrCaps & caps)165 GrXPFactory::AnalysisProperties GrXPFactory::GetAnalysisProperties(
166 const GrXPFactory* factory,
167 const GrProcessorAnalysisColor& color,
168 const GrProcessorAnalysisCoverage& coverage,
169 const GrCaps& caps) {
170 AnalysisProperties result;
171 if (factory) {
172 result = factory->analysisProperties(color, coverage, caps);
173 } else {
174 result = GrPorterDuffXPFactory::SrcOverAnalysisProperties(color, coverage, caps);
175 }
176 SkASSERT(!(result & AnalysisProperties::kRequiresDstTexture));
177 if ((result & AnalysisProperties::kReadsDstInShader) &&
178 !caps.shaderCaps()->dstReadInShaderSupport()) {
179 result |= AnalysisProperties::kRequiresDstTexture |
180 AnalysisProperties::kRequiresNonOverlappingDraws;
181 }
182 return result;
183 }
184
MakeXferProcessor(const GrXPFactory * factory,const GrProcessorAnalysisColor & color,GrProcessorAnalysisCoverage coverage,bool hasMixedSamples,const GrCaps & caps)185 sk_sp<const GrXferProcessor> GrXPFactory::MakeXferProcessor(const GrXPFactory* factory,
186 const GrProcessorAnalysisColor& color,
187 GrProcessorAnalysisCoverage coverage,
188 bool hasMixedSamples,
189 const GrCaps& caps) {
190 SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
191 if (factory) {
192 return factory->makeXferProcessor(color, coverage, hasMixedSamples, caps);
193 } else {
194 return GrPorterDuffXPFactory::MakeSrcOverXferProcessor(color, coverage, hasMixedSamples,
195 caps);
196 }
197 }
198