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