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

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

Issue 1251173002: Added GrGLFragmentProcessor::EmitArgs struct for use with emitCode() (Closed) Base URL: https://skia.googlesource.com/skia@composeshader_gpu
Patch Set: Created 5 years, 5 months 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 "GrConvolutionEffect.h" 8 #include "GrConvolutionEffect.h"
9 #include "gl/GrGLFragmentProcessor.h" 9 #include "gl/GrGLFragmentProcessor.h"
10 #include "gl/GrGLTexture.h" 10 #include "gl/GrGLTexture.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 /////////////////////////////////////////////////////////////////////////////// 74 ///////////////////////////////////////////////////////////////////////////////
75 75
76 /** 76 /**
77 * Applies a convolution effect which restricts samples to the provided bounds 77 * Applies a convolution effect which restricts samples to the provided bounds
78 * using shader logic. 78 * using shader logic.
79 */ 79 */
80 class GrGLBoundedConvolutionEffect : public GrGLConvolutionEffect { 80 class GrGLBoundedConvolutionEffect : public GrGLConvolutionEffect {
81 public: 81 public:
82 GrGLBoundedConvolutionEffect(const GrProcessor& processor) : INHERITED(proce ssor) {} 82 GrGLBoundedConvolutionEffect(const GrProcessor& processor) : INHERITED(proce ssor) {}
83 83
84 virtual void emitCode(GrGLFPBuilder*, 84 virtual void emitCode(EmitArgs&) override;
85 const GrFragmentProcessor&,
86 const char* outputColor,
87 const char* inputColor,
88 const TransformedCoordsArray&,
89 const TextureSamplerArray&) override;
90 85
91 void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) overri de; 86 void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) overri de;
92 87
93 private: 88 private:
94 UniformHandle fKernelUni; 89 UniformHandle fKernelUni;
95 UniformHandle fImageIncrementUni; 90 UniformHandle fImageIncrementUni;
96 UniformHandle fBoundsUni; 91 UniformHandle fBoundsUni;
97 92
98 typedef GrGLConvolutionEffect INHERITED; 93 typedef GrGLConvolutionEffect INHERITED;
99 }; 94 };
100 95
101 void GrGLBoundedConvolutionEffect::emitCode(GrGLFPBuilder* builder, 96 void GrGLBoundedConvolutionEffect::emitCode(EmitArgs& args) {
102 const GrFragmentProcessor& processor ,
103 const char* outputColor,
104 const char* inputColor,
105 const TransformedCoordsArray& coords ,
106 const TextureSamplerArray& samplers) {
107 fImageIncrementUni = 97 fImageIncrementUni =
108 builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec2f_GrS LType, 98 args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, kVec2f_GrSLType,
109 kDefault_GrSLPrecision, "ImageIncrement"); 99 kDefault_GrSLPrecision, "ImageIncrement");
110 100
111 fBoundsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, k Vec2f_GrSLType, 101 fBoundsUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibil ity, kVec2f_GrSLType,
joshualitt 2015/07/22 19:34:05 line wrap @100
112 kDefault_GrSLPrecision, "Bounds"); 102 kDefault_GrSLPrecision, "Bounds");
113 103
114 fKernelUni = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibili ty, kFloat_GrSLType, 104 fKernelUni = args.fBuilder->addUniformArray(GrGLProgramBuilder::kFragment_Vi sibility, kFloat_GrSLType,
joshualitt 2015/07/22 19:34:05 line wrap @100
115 kDefault_GrSLPrecision, "Kernel", this ->width()); 105 kDefault_GrSLPrecision, "Kernel", this ->width());
116 106
117 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 107 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
118 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); 108 SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
119 109
120 fsBuilder->codeAppendf("%s = vec4(0, 0, 0, 0);\n", outputColor); 110 fsBuilder->codeAppendf("%s = vec4(0, 0, 0, 0);\n", args.fOutputColor);
121 111
122 int width = this->width(); 112 int width = this->width();
123 const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni); 113 const GrGLShaderVar& kernel = args.fBuilder->getUniformVariable(fKernelUni);
124 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); 114 const char* imgInc = args.fBuilder->getUniformCStr(fImageIncrementUni);
125 115
126 fsBuilder->codeAppendf("vec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), t his->radius(), 116 fsBuilder->codeAppendf("vec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), t his->radius(),
127 imgInc); 117 imgInc);
128 118
129 // Manually unroll loop because some drivers don't; yields 20-30% speedup. 119 // Manually unroll loop because some drivers don't; yields 20-30% speedup.
130 for (int i = 0; i < width; i++) { 120 for (int i = 0; i < width; i++) {
131 SkString index; 121 SkString index;
132 SkString kernelIndex; 122 SkString kernelIndex;
133 index.appendS32(i); 123 index.appendS32(i);
134 kernel.appendArrayAccess(index.c_str(), &kernelIndex); 124 kernel.appendArrayAccess(index.c_str(), &kernelIndex);
135 // We used to compute a bool indicating whether we're in bounds or not, cast it to a 125 // We used to compute a bool indicating whether we're in bounds or not, cast it to a
136 // float, and then mul weight*texture_sample by the float. However, the Adreno 430 seems 126 // float, and then mul weight*texture_sample by the float. However, the Adreno 430 seems
137 // to have a bug that caused corruption. 127 // to have a bug that caused corruption.
138 const char* bounds = builder->getUniformCStr(fBoundsUni); 128 const char* bounds = args.fBuilder->getUniformCStr(fBoundsUni);
139 const char* component = this->direction() == Gr1DKernelEffect::kY_Direct ion ? "y" : "x"; 129 const char* component = this->direction() == Gr1DKernelEffect::kY_Direct ion ? "y" : "x";
140 fsBuilder->codeAppendf("if (coord.%s >= %s.x && coord.%s <= %s.y) {", 130 fsBuilder->codeAppendf("if (coord.%s >= %s.x && coord.%s <= %s.y) {",
141 component, bounds, component, bounds); 131 component, bounds, component, bounds);
142 fsBuilder->codeAppendf("%s += ", outputColor); 132 fsBuilder->codeAppendf("%s += ", args.fOutputColor);
143 fsBuilder->appendTextureLookup(samplers[0], "coord"); 133 fsBuilder->appendTextureLookup(args.fSamplers[0], "coord");
144 fsBuilder->codeAppendf(" * %s;\n", kernelIndex.c_str()); 134 fsBuilder->codeAppendf(" * %s;\n", kernelIndex.c_str());
145 fsBuilder->codeAppend("}"); 135 fsBuilder->codeAppend("}");
146 fsBuilder->codeAppendf("coord += %s;\n", imgInc); 136 fsBuilder->codeAppendf("coord += %s;\n", imgInc);
147 } 137 }
148 138
149 SkString modulate; 139 SkString modulate;
150 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); 140 GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
151 fsBuilder->codeAppend(modulate.c_str()); 141 fsBuilder->codeAppend(modulate.c_str());
152 } 142 }
153 143
154 void GrGLBoundedConvolutionEffect::setData(const GrGLProgramDataManager& pdman, 144 void GrGLBoundedConvolutionEffect::setData(const GrGLProgramDataManager& pdman,
155 const GrProcessor& processor) { 145 const GrProcessor& processor) {
156 const GrConvolutionEffect& conv = processor.cast<GrConvolutionEffect>(); 146 const GrConvolutionEffect& conv = processor.cast<GrConvolutionEffect>();
157 147
158 // the code we generated was for a specific kernel radius 148 // the code we generated was for a specific kernel radius
159 SkASSERT(conv.radius() == this->radius()); 149 SkASSERT(conv.radius() == this->radius());
160 150
(...skipping 17 matching lines...) Expand all
178 /////////////////////////////////////////////////////////////////////////////// 168 ///////////////////////////////////////////////////////////////////////////////
179 169
180 /** 170 /**
181 * Applies a convolution effect which applies the convolution using a linear 171 * Applies a convolution effect which applies the convolution using a linear
182 * interpolation optimization to use half as many samples. 172 * interpolation optimization to use half as many samples.
183 */ 173 */
184 class GrGLLerpConvolutionEffect : public GrGLConvolutionEffect { 174 class GrGLLerpConvolutionEffect : public GrGLConvolutionEffect {
185 public: 175 public:
186 GrGLLerpConvolutionEffect(const GrProcessor& processor) : INHERITED(processo r) {} 176 GrGLLerpConvolutionEffect(const GrProcessor& processor) : INHERITED(processo r) {}
187 177
188 virtual void emitCode(GrGLFPBuilder*, 178 virtual void emitCode(EmitArgs&) override;
189 const GrFragmentProcessor&,
190 const char* outputColor,
191 const char* inputColor,
192 const TransformedCoordsArray&,
193 const TextureSamplerArray&) override;
194 179
195 void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) overri de; 180 void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) overri de;
196 181
197 private: 182 private:
198 int bilerpSampleCount() const; 183 int bilerpSampleCount() const;
199 184
200 // Bounded uniforms 185 // Bounded uniforms
201 UniformHandle fSampleWeightUni; 186 UniformHandle fSampleWeightUni;
202 UniformHandle fSampleOffsetUni; 187 UniformHandle fSampleOffsetUni;
203 188
204 typedef GrGLConvolutionEffect INHERITED; 189 typedef GrGLConvolutionEffect INHERITED;
205 }; 190 };
206 191
207 void GrGLLerpConvolutionEffect::emitCode(GrGLFPBuilder* builder, 192 void GrGLLerpConvolutionEffect::emitCode(EmitArgs& args) {
208 const GrFragmentProcessor& processor,
209 const char* outputColor,
210 const char* inputColor,
211 const TransformedCoordsArray& coords,
212 const TextureSamplerArray& samplers) {
213 int sampleCount = bilerpSampleCount(); 193 int sampleCount = bilerpSampleCount();
214 194
215 // We use 2 * sampleCount uniforms. The maximum allowed by PS2.0 is 32, so 195 // We use 2 * sampleCount uniforms. The maximum allowed by PS2.0 is 32, so
216 // ensure we don't exceed this. Note that it is currently impossible to 196 // ensure we don't exceed this. Note that it is currently impossible to
217 // exceed this as bilerpSampleCount = (kernelWidth + 1) / 2, and kernelWidth 197 // exceed this as bilerpSampleCount = (kernelWidth + 1) / 2, and kernelWidth
218 // maxes out at 25, resulting in a max sampleCount of 26. 198 // maxes out at 25, resulting in a max sampleCount of 26.
219 SkASSERT(sampleCount < 16); 199 SkASSERT(sampleCount < 16);
220 200
221 fSampleOffsetUni = 201 fSampleOffsetUni =
222 builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, kVec2 f_GrSLType, 202 args.fBuilder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, kVec2f_GrSLType,
223 kDefault_GrSLPrecision, "SampleOffset", sampleC ount); 203 kDefault_GrSLPrecision, "SampleOffset", sampleC ount);
224 fSampleWeightUni = 204 fSampleWeightUni =
225 builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, kFloa t_GrSLType, 205 args.fBuilder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, kFloat_GrSLType,
226 kDefault_GrSLPrecision, "SampleWeight", sampleC ount); 206 kDefault_GrSLPrecision, "SampleWeight", sampleC ount);
227 207
228 GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 208 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
229 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); 209 SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
230 210
231 fsBuilder->codeAppendf("%s = vec4(0, 0, 0, 0);\n", outputColor); 211 fsBuilder->codeAppendf("%s = vec4(0, 0, 0, 0);\n", args.fOutputColor);
232 212
233 const GrGLShaderVar& kernel = builder->getUniformVariable(fSampleWeightUni); 213 const GrGLShaderVar& kernel = args.fBuilder->getUniformVariable(fSampleWeigh tUni);
234 const GrGLShaderVar& imgInc = builder->getUniformVariable(fSampleOffsetUni); 214 const GrGLShaderVar& imgInc = args.fBuilder->getUniformVariable(fSampleOffse tUni);
235 215
236 fsBuilder->codeAppendf("vec2 coord; \n"); 216 fsBuilder->codeAppendf("vec2 coord; \n");
237 217
238 // Manually unroll loop because some drivers don't; yields 20-30% speedup. 218 // Manually unroll loop because some drivers don't; yields 20-30% speedup.
239 for (int i = 0; i < sampleCount; i++) { 219 for (int i = 0; i < sampleCount; i++) {
240 SkString index; 220 SkString index;
241 SkString weightIndex; 221 SkString weightIndex;
242 SkString offsetIndex; 222 SkString offsetIndex;
243 index.appendS32(i); 223 index.appendS32(i);
244 kernel.appendArrayAccess(index.c_str(), &weightIndex); 224 kernel.appendArrayAccess(index.c_str(), &weightIndex);
245 imgInc.appendArrayAccess(index.c_str(), &offsetIndex); 225 imgInc.appendArrayAccess(index.c_str(), &offsetIndex);
246 fsBuilder->codeAppendf("coord = %s + %s;\n", coords2D.c_str(), offsetInd ex.c_str()); 226 fsBuilder->codeAppendf("coord = %s + %s;\n", coords2D.c_str(), offsetInd ex.c_str());
247 fsBuilder->codeAppendf("%s += ", outputColor); 227 fsBuilder->codeAppendf("%s += ", args.fOutputColor);
248 fsBuilder->appendTextureLookup(samplers[0], "coord"); 228 fsBuilder->appendTextureLookup(args.fSamplers[0], "coord");
249 fsBuilder->codeAppendf(" * %s;\n", weightIndex.c_str()); 229 fsBuilder->codeAppendf(" * %s;\n", weightIndex.c_str());
250 } 230 }
251 231
252 SkString modulate; 232 SkString modulate;
253 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); 233 GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
254 fsBuilder->codeAppend(modulate.c_str()); 234 fsBuilder->codeAppend(modulate.c_str());
255 } 235 }
256 236
257 void GrGLLerpConvolutionEffect::setData(const GrGLProgramDataManager& pdman, 237 void GrGLLerpConvolutionEffect::setData(const GrGLProgramDataManager& pdman,
258 const GrProcessor& processor) { 238 const GrProcessor& processor) {
259 const GrConvolutionEffect& conv = processor.cast<GrConvolutionEffect>(); 239 const GrConvolutionEffect& conv = processor.cast<GrConvolutionEffect>();
260 240
261 // the code we generated was for a specific kernel radius 241 // the code we generated was for a specific kernel radius
262 SkASSERT(conv.radius() == this->radius()); 242 SkASSERT(conv.radius() == this->radius());
263 243
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 399
420 bool useBounds = d->fRandom->nextBool(); 400 bool useBounds = d->fRandom->nextBool();
421 return GrConvolutionEffect::Create(d->fProcDataManager, 401 return GrConvolutionEffect::Create(d->fProcDataManager,
422 d->fTextures[texIdx], 402 d->fTextures[texIdx],
423 dir, 403 dir,
424 radius, 404 radius,
425 kernel, 405 kernel,
426 useBounds, 406 useBounds,
427 bounds); 407 bounds);
428 } 408 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698