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