Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |