| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 #include "GrMatrixConvolutionEffect.h" | 7 #include "GrMatrixConvolutionEffect.h" |
| 8 #include "glsl/GrGLSLFragmentProcessor.h" | 8 #include "glsl/GrGLSLFragmentProcessor.h" |
| 9 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 9 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
| 10 #include "glsl/GrGLSLProgramDataManager.h" | 10 #include "glsl/GrGLSLProgramDataManager.h" |
| 11 #include "glsl/GrGLSLUniformHandler.h" | 11 #include "glsl/GrGLSLUniformHandler.h" |
| 12 | 12 |
| 13 class GrGLMatrixConvolutionEffect : public GrGLSLFragmentProcessor { | 13 class GrGLMatrixConvolutionEffect : public GrGLSLFragmentProcessor { |
| 14 public: | 14 public: |
| 15 GrGLMatrixConvolutionEffect(const GrProcessor&); | |
| 16 void emitCode(EmitArgs&) override; | 15 void emitCode(EmitArgs&) override; |
| 17 | 16 |
| 18 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); | 17 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder*); |
| 19 | 18 |
| 20 protected: | 19 protected: |
| 21 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; | 20 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; |
| 22 | 21 |
| 23 private: | 22 private: |
| 24 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; | 23 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; |
| 25 SkISize fKernelSize; | |
| 26 bool fConvolveAlpha; | |
| 27 | 24 |
| 28 UniformHandle fKernelUni; | 25 UniformHandle fKernelUni; |
| 29 UniformHandle fImageIncrementUni; | 26 UniformHandle fImageIncrementUni; |
| 30 UniformHandle fKernelOffsetUni; | 27 UniformHandle fKernelOffsetUni; |
| 31 UniformHandle fGainUni; | 28 UniformHandle fGainUni; |
| 32 UniformHandle fBiasUni; | 29 UniformHandle fBiasUni; |
| 33 GrTextureDomain::GLDomain fDomain; | 30 GrTextureDomain::GLDomain fDomain; |
| 34 | 31 |
| 35 typedef GrGLSLFragmentProcessor INHERITED; | 32 typedef GrGLSLFragmentProcessor INHERITED; |
| 36 }; | 33 }; |
| 37 | 34 |
| 38 GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrProcessor& proc
essor) { | 35 void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) { |
| 39 const GrMatrixConvolutionEffect& m = processor.cast<GrMatrixConvolutionEffec
t>(); | 36 const GrMatrixConvolutionEffect& mce = args.fFp.cast<GrMatrixConvolutionEffe
ct>(); |
| 40 fKernelSize = m.kernelSize(); | 37 const GrTextureDomain& domain = mce.domain(); |
| 41 fConvolveAlpha = m.convolveAlpha(); | |
| 42 } | |
| 43 | 38 |
| 44 void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) { | 39 int kWidth = mce.kernelSize().width(); |
| 45 const GrTextureDomain& domain = args.fFp.cast<GrMatrixConvolutionEffect>().d
omain(); | 40 int kHeight = mce.kernelSize().height(); |
| 41 |
| 46 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; | 42 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
| 47 fImageIncrementUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragm
ent_Visibility, | 43 fImageIncrementUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragm
ent_Visibility, |
| 48 kVec2f_GrSLType, kDefault_Gr
SLPrecision, | 44 kVec2f_GrSLType, kDefault_Gr
SLPrecision, |
| 49 "ImageIncrement"); | 45 "ImageIncrement"); |
| 50 fKernelUni = uniformHandler->addUniformArray(GrGLSLUniformHandler::kFragment
_Visibility, | 46 fKernelUni = uniformHandler->addUniformArray(GrGLSLUniformHandler::kFragment
_Visibility, |
| 51 kFloat_GrSLType, kDefault_GrSLP
recision, | 47 kFloat_GrSLType, kDefault_GrSLP
recision, |
| 52 "Kernel", | 48 "Kernel", |
| 53 fKernelSize.width() * fKernelSi
ze.height()); | 49 kWidth * kHeight); |
| 54 fKernelOffsetUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragmen
t_Visibility, | 50 fKernelOffsetUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragmen
t_Visibility, |
| 55 kVec2f_GrSLType, kDefault_GrSL
Precision, | 51 kVec2f_GrSLType, kDefault_GrSL
Precision, |
| 56 "KernelOffset"); | 52 "KernelOffset"); |
| 57 fGainUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibi
lity, | 53 fGainUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibi
lity, |
| 58 kFloat_GrSLType, kDefault_GrSLPrecisio
n, "Gain"); | 54 kFloat_GrSLType, kDefault_GrSLPrecisio
n, "Gain"); |
| 59 fBiasUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibi
lity, | 55 fBiasUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibi
lity, |
| 60 kFloat_GrSLType, kDefault_GrSLPrecisio
n, "Bias"); | 56 kFloat_GrSLType, kDefault_GrSLPrecisio
n, "Bias"); |
| 61 | 57 |
| 62 const char* kernelOffset = uniformHandler->getUniformCStr(fKernelOffsetUni); | 58 const char* kernelOffset = uniformHandler->getUniformCStr(fKernelOffsetUni); |
| 63 const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); | 59 const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); |
| 64 const char* kernel = uniformHandler->getUniformCStr(fKernelUni); | 60 const char* kernel = uniformHandler->getUniformCStr(fKernelUni); |
| 65 const char* gain = uniformHandler->getUniformCStr(fGainUni); | 61 const char* gain = uniformHandler->getUniformCStr(fGainUni); |
| 66 const char* bias = uniformHandler->getUniformCStr(fBiasUni); | 62 const char* bias = uniformHandler->getUniformCStr(fBiasUni); |
| 67 int kWidth = fKernelSize.width(); | |
| 68 int kHeight = fKernelSize.height(); | |
| 69 | 63 |
| 70 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 64 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 71 SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0); | 65 SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0); |
| 72 fragBuilder->codeAppend("vec4 sum = vec4(0, 0, 0, 0);"); | 66 fragBuilder->codeAppend("vec4 sum = vec4(0, 0, 0, 0);"); |
| 73 fragBuilder->codeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), ker
nelOffset, imgInc); | 67 fragBuilder->codeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), ker
nelOffset, imgInc); |
| 74 fragBuilder->codeAppend("vec4 c;"); | 68 fragBuilder->codeAppend("vec4 c;"); |
| 75 | 69 |
| 76 for (int y = 0; y < kHeight; y++) { | 70 for (int y = 0; y < kHeight; y++) { |
| 77 for (int x = 0; x < kWidth; x++) { | 71 for (int x = 0; x < kWidth; x++) { |
| 78 GrGLSLShaderBuilder::ShaderBlock block(fragBuilder); | 72 GrGLSLShaderBuilder::ShaderBlock block(fragBuilder); |
| 79 fragBuilder->codeAppendf("float k = %s[%d * %d + %d];", kernel, y, k
Width, x); | 73 fragBuilder->codeAppendf("float k = %s[%d * %d + %d];", kernel, y, k
Width, x); |
| 80 SkString coord; | 74 SkString coord; |
| 81 coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc); | 75 coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc); |
| 82 fDomain.sampleTexture(fragBuilder, | 76 fDomain.sampleTexture(fragBuilder, |
| 83 uniformHandler, | 77 uniformHandler, |
| 84 args.fGLSLCaps, | 78 args.fGLSLCaps, |
| 85 domain, | 79 domain, |
| 86 "c", | 80 "c", |
| 87 coord, | 81 coord, |
| 88 args.fSamplers[0]); | 82 args.fSamplers[0]); |
| 89 if (!fConvolveAlpha) { | 83 if (!mce.convolveAlpha()) { |
| 90 fragBuilder->codeAppend("c.rgb /= c.a;"); | 84 fragBuilder->codeAppend("c.rgb /= c.a;"); |
| 91 fragBuilder->codeAppend("c.rgb = clamp(c.rgb, 0.0, 1.0);"); | 85 fragBuilder->codeAppend("c.rgb = clamp(c.rgb, 0.0, 1.0);"); |
| 92 } | 86 } |
| 93 fragBuilder->codeAppend("sum += c * k;"); | 87 fragBuilder->codeAppend("sum += c * k;"); |
| 94 } | 88 } |
| 95 } | 89 } |
| 96 if (fConvolveAlpha) { | 90 if (mce.convolveAlpha()) { |
| 97 fragBuilder->codeAppendf("%s = sum * %s + %s;", args.fOutputColor, gain,
bias); | 91 fragBuilder->codeAppendf("%s = sum * %s + %s;", args.fOutputColor, gain,
bias); |
| 98 fragBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);", | 92 fragBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);", |
| 99 args.fOutputColor, args.fOutputColor, args.fOut
putColor); | 93 args.fOutputColor, args.fOutputColor, args.fOut
putColor); |
| 100 } else { | 94 } else { |
| 101 fDomain.sampleTexture(fragBuilder, | 95 fDomain.sampleTexture(fragBuilder, |
| 102 uniformHandler, | 96 uniformHandler, |
| 103 args.fGLSLCaps, | 97 args.fGLSLCaps, |
| 104 domain, | 98 domain, |
| 105 "c", | 99 "c", |
| 106 coords2D, | 100 coords2D, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 122 uint32_t key = m.kernelSize().width() << 16 | m.kernelSize().height(); | 116 uint32_t key = m.kernelSize().width() << 16 | m.kernelSize().height(); |
| 123 key |= m.convolveAlpha() ? 1 << 31 : 0; | 117 key |= m.convolveAlpha() ? 1 << 31 : 0; |
| 124 b->add32(key); | 118 b->add32(key); |
| 125 b->add32(GrTextureDomain::GLDomain::DomainKey(m.domain())); | 119 b->add32(GrTextureDomain::GLDomain::DomainKey(m.domain())); |
| 126 } | 120 } |
| 127 | 121 |
| 128 void GrGLMatrixConvolutionEffect::onSetData(const GrGLSLProgramDataManager& pdma
n, | 122 void GrGLMatrixConvolutionEffect::onSetData(const GrGLSLProgramDataManager& pdma
n, |
| 129 const GrProcessor& processor) { | 123 const GrProcessor& processor) { |
| 130 const GrMatrixConvolutionEffect& conv = processor.cast<GrMatrixConvolutionEf
fect>(); | 124 const GrMatrixConvolutionEffect& conv = processor.cast<GrMatrixConvolutionEf
fect>(); |
| 131 GrTexture& texture = *conv.texture(0); | 125 GrTexture& texture = *conv.texture(0); |
| 132 // the code we generated was for a specific kernel size | 126 |
| 133 SkASSERT(conv.kernelSize() == fKernelSize); | |
| 134 float imageIncrement[2]; | 127 float imageIncrement[2]; |
| 135 float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f; | 128 float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f; |
| 136 imageIncrement[0] = 1.0f / texture.width(); | 129 imageIncrement[0] = 1.0f / texture.width(); |
| 137 imageIncrement[1] = ySign / texture.height(); | 130 imageIncrement[1] = ySign / texture.height(); |
| 138 pdman.set2fv(fImageIncrementUni, 1, imageIncrement); | 131 pdman.set2fv(fImageIncrementUni, 1, imageIncrement); |
| 139 pdman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset()); | 132 pdman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset()); |
| 140 pdman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.ke
rnel()); | 133 pdman.set1fv(fKernelUni, conv.kernelSize().width() * conv.kernelSize().heigh
t(), conv.kernel()); |
| 141 pdman.set1f(fGainUni, conv.gain()); | 134 pdman.set1f(fGainUni, conv.gain()); |
| 142 pdman.set1f(fBiasUni, conv.bias()); | 135 pdman.set1f(fBiasUni, conv.bias()); |
| 143 fDomain.setData(pdman, conv.domain(), texture.origin()); | 136 fDomain.setData(pdman, conv.domain(), texture.origin()); |
| 144 } | 137 } |
| 145 | 138 |
| 146 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, | 139 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, |
| 147 const SkIRect& bounds, | 140 const SkIRect& bounds, |
| 148 const SkISize& kernelSize, | 141 const SkISize& kernelSize, |
| 149 const SkScalar* kernel, | 142 const SkScalar* kernel, |
| 150 SkScalar gain, | 143 SkScalar gain, |
| 151 SkScalar bias, | 144 SkScalar bias, |
| 152 const SkIPoint& kernelOffse
t, | 145 const SkIPoint& kernelOffse
t, |
| 153 GrTextureDomain::Mode tileM
ode, | 146 GrTextureDomain::Mode tileM
ode, |
| 154 bool convolveAlpha) | 147 bool convolveAlpha) |
| 155 : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)), | 148 : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)), |
| 156 fKernelSize(kernelSize), | 149 fKernelSize(kernelSize), |
| 157 fGain(SkScalarToFloat(gain)), | 150 fGain(SkScalarToFloat(gain)), |
| 158 fBias(SkScalarToFloat(bias) / 255.0f), | 151 fBias(SkScalarToFloat(bias) / 255.0f), |
| 159 fConvolveAlpha(convolveAlpha), | 152 fConvolveAlpha(convolveAlpha), |
| 160 fDomain(GrTextureDomain::MakeTexelDomainForMode(texture, bounds, tileMode),
tileMode) { | 153 fDomain(GrTextureDomain::MakeTexelDomainForMode(texture, bounds, tileMode),
tileMode) { |
| 161 this->initClassID<GrMatrixConvolutionEffect>(); | 154 this->initClassID<GrMatrixConvolutionEffect>(); |
| 162 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { | 155 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { |
| 163 fKernel[i] = SkScalarToFloat(kernel[i]); | 156 fKernel[i] = SkScalarToFloat(kernel[i]); |
| 164 } | 157 } |
| 165 fKernelOffset[0] = static_cast<float>(kernelOffset.x()); | 158 fKernelOffset[0] = static_cast<float>(kernelOffset.x()); |
| 166 fKernelOffset[1] = static_cast<float>(kernelOffset.y()); | 159 fKernelOffset[1] = static_cast<float>(kernelOffset.y()); |
| 167 } | 160 } |
| 168 | 161 |
| 169 GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() { | |
| 170 } | |
| 171 | |
| 172 void GrMatrixConvolutionEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 162 void GrMatrixConvolutionEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
| 173 GrProcessorKeyBuilder* b)
const { | 163 GrProcessorKeyBuilder* b)
const { |
| 174 GrGLMatrixConvolutionEffect::GenKey(*this, caps, b); | 164 GrGLMatrixConvolutionEffect::GenKey(*this, caps, b); |
| 175 } | 165 } |
| 176 | 166 |
| 177 GrGLSLFragmentProcessor* GrMatrixConvolutionEffect::onCreateGLSLInstance() const
{ | 167 GrGLSLFragmentProcessor* GrMatrixConvolutionEffect::onCreateGLSLInstance() const
{ |
| 178 return new GrGLMatrixConvolutionEffect(*this); | 168 return new GrGLMatrixConvolutionEffect; |
| 179 } | 169 } |
| 180 | 170 |
| 181 bool GrMatrixConvolutionEffect::onIsEqual(const GrFragmentProcessor& sBase) cons
t { | 171 bool GrMatrixConvolutionEffect::onIsEqual(const GrFragmentProcessor& sBase) cons
t { |
| 182 const GrMatrixConvolutionEffect& s = sBase.cast<GrMatrixConvolutionEffect>()
; | 172 const GrMatrixConvolutionEffect& s = sBase.cast<GrMatrixConvolutionEffect>()
; |
| 183 return fKernelSize == s.kernelSize() && | 173 return fKernelSize == s.kernelSize() && |
| 184 !memcmp(fKernel, s.kernel(), | 174 !memcmp(fKernel, s.kernel(), |
| 185 fKernelSize.width() * fKernelSize.height() * sizeof(float)) &
& | 175 fKernelSize.width() * fKernelSize.height() * sizeof(float)) &
& |
| 186 fGain == s.gain() && | 176 fGain == s.gain() && |
| 187 fBias == s.bias() && | 177 fBias == s.bias() && |
| 188 fKernelOffset == s.kernelOffset() && | 178 fKernelOffset == s.kernelOffset() && |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 return GrMatrixConvolutionEffect::Create(d->fTextures[texIdx], | 248 return GrMatrixConvolutionEffect::Create(d->fTextures[texIdx], |
| 259 bounds, | 249 bounds, |
| 260 kernelSize, | 250 kernelSize, |
| 261 kernel.get(), | 251 kernel.get(), |
| 262 gain, | 252 gain, |
| 263 bias, | 253 bias, |
| 264 kernelOffset, | 254 kernelOffset, |
| 265 tileMode, | 255 tileMode, |
| 266 convolveAlpha); | 256 convolveAlpha); |
| 267 } | 257 } |
| OLD | NEW |