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 |