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 "gl/builders/GrGLProgramBuilder.h" | |
9 #include "GrConvolutionEffect.h" | 8 #include "GrConvolutionEffect.h" |
10 #include "gl/GrGLProcessor.h" | 9 #include "gl/GrGLProcessor.h" |
11 #include "gl/GrGLSL.h" | 10 #include "gl/GrGLSL.h" |
12 #include "gl/GrGLTexture.h" | 11 #include "gl/GrGLTexture.h" |
13 #include "GrTBackendProcessorFactory.h" | 12 #include "gl/builders/GrGLProgramBuilder.h" |
14 | 13 |
15 // For brevity | 14 // For brevity |
16 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 15 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
17 | 16 |
18 class GrGLConvolutionEffect : public GrGLFragmentProcessor { | 17 class GrGLConvolutionEffect : public GrGLFragmentProcessor { |
19 public: | 18 public: |
20 GrGLConvolutionEffect(const GrBackendProcessorFactory&, const GrProcessor&); | 19 GrGLConvolutionEffect(const GrProcessor&); |
21 | 20 |
22 virtual void emitCode(GrGLFPBuilder*, | 21 virtual void emitCode(GrGLFPBuilder*, |
23 const GrFragmentProcessor&, | 22 const GrFragmentProcessor&, |
24 const char* outputColor, | 23 const char* outputColor, |
25 const char* inputColor, | 24 const char* inputColor, |
26 const TransformedCoordsArray&, | 25 const TransformedCoordsArray&, |
27 const TextureSamplerArray&) SK_OVERRIDE; | 26 const TextureSamplerArray&) SK_OVERRIDE; |
28 | 27 |
29 virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&
) SK_OVERRIDE; | 28 virtual void setData(const GrGLProgramDataManager& pdman, const GrProcessor&
) SK_OVERRIDE; |
30 | 29 |
31 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe
yBuilder*); | 30 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe
yBuilder*); |
32 | 31 |
33 private: | 32 private: |
34 int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); } | 33 int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); } |
35 bool useBounds() const { return fUseBounds; } | 34 bool useBounds() const { return fUseBounds; } |
36 Gr1DKernelEffect::Direction direction() const { return fDirection; } | 35 Gr1DKernelEffect::Direction direction() const { return fDirection; } |
37 | 36 |
38 int fRadius; | 37 int fRadius; |
39 bool fUseBounds; | 38 bool fUseBounds; |
40 Gr1DKernelEffect::Direction fDirection; | 39 Gr1DKernelEffect::Direction fDirection; |
41 UniformHandle fKernelUni; | 40 UniformHandle fKernelUni; |
42 UniformHandle fImageIncrementUni; | 41 UniformHandle fImageIncrementUni; |
43 UniformHandle fBoundsUni; | 42 UniformHandle fBoundsUni; |
44 | 43 |
45 typedef GrGLFragmentProcessor INHERITED; | 44 typedef GrGLFragmentProcessor INHERITED; |
46 }; | 45 }; |
47 | 46 |
48 GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendProcessorFactory& fa
ctory, | 47 GrGLConvolutionEffect::GrGLConvolutionEffect(const GrProcessor& processor) { |
49 const GrProcessor& processor) | |
50 : INHERITED(factory) { | |
51 const GrConvolutionEffect& c = processor.cast<GrConvolutionEffect>(); | 48 const GrConvolutionEffect& c = processor.cast<GrConvolutionEffect>(); |
52 fRadius = c.radius(); | 49 fRadius = c.radius(); |
53 fUseBounds = c.useBounds(); | 50 fUseBounds = c.useBounds(); |
54 fDirection = c.direction(); | 51 fDirection = c.direction(); |
55 } | 52 } |
56 | 53 |
57 void GrGLConvolutionEffect::emitCode(GrGLFPBuilder* builder, | 54 void GrGLConvolutionEffect::emitCode(GrGLFPBuilder* builder, |
58 const GrFragmentProcessor&, | 55 const GrFragmentProcessor&, |
59 const char* outputColor, | 56 const char* outputColor, |
60 const char* inputColor, | 57 const char* inputColor, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 145 |
149 /////////////////////////////////////////////////////////////////////////////// | 146 /////////////////////////////////////////////////////////////////////////////// |
150 | 147 |
151 GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture, | 148 GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture, |
152 Direction direction, | 149 Direction direction, |
153 int radius, | 150 int radius, |
154 const float* kernel, | 151 const float* kernel, |
155 bool useBounds, | 152 bool useBounds, |
156 float bounds[2]) | 153 float bounds[2]) |
157 : Gr1DKernelEffect(texture, direction, radius), fUseBounds(useBounds) { | 154 : Gr1DKernelEffect(texture, direction, radius), fUseBounds(useBounds) { |
| 155 this->initClassID<GrConvolutionEffect>(); |
158 SkASSERT(radius <= kMaxKernelRadius); | 156 SkASSERT(radius <= kMaxKernelRadius); |
159 SkASSERT(kernel); | 157 SkASSERT(kernel); |
160 int width = this->width(); | 158 int width = this->width(); |
161 for (int i = 0; i < width; i++) { | 159 for (int i = 0; i < width; i++) { |
162 fKernel[i] = kernel[i]; | 160 fKernel[i] = kernel[i]; |
163 } | 161 } |
164 memcpy(fBounds, bounds, sizeof(fBounds)); | 162 memcpy(fBounds, bounds, sizeof(fBounds)); |
165 } | 163 } |
166 | 164 |
167 GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture, | 165 GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture, |
168 Direction direction, | 166 Direction direction, |
169 int radius, | 167 int radius, |
170 float gaussianSigma, | 168 float gaussianSigma, |
171 bool useBounds, | 169 bool useBounds, |
172 float bounds[2]) | 170 float bounds[2]) |
173 : Gr1DKernelEffect(texture, direction, radius), fUseBounds(useBounds) { | 171 : Gr1DKernelEffect(texture, direction, radius), fUseBounds(useBounds) { |
| 172 this->initClassID<GrConvolutionEffect>(); |
174 SkASSERT(radius <= kMaxKernelRadius); | 173 SkASSERT(radius <= kMaxKernelRadius); |
175 int width = this->width(); | 174 int width = this->width(); |
176 | 175 |
177 float sum = 0.0f; | 176 float sum = 0.0f; |
178 float denom = 1.0f / (2.0f * gaussianSigma * gaussianSigma); | 177 float denom = 1.0f / (2.0f * gaussianSigma * gaussianSigma); |
179 for (int i = 0; i < width; ++i) { | 178 for (int i = 0; i < width; ++i) { |
180 float x = static_cast<float>(i - this->radius()); | 179 float x = static_cast<float>(i - this->radius()); |
181 // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian | 180 // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian |
182 // is dropped here, since we renormalize the kernel below. | 181 // is dropped here, since we renormalize the kernel below. |
183 fKernel[i] = sk_float_exp(- x * x * denom); | 182 fKernel[i] = sk_float_exp(- x * x * denom); |
184 sum += fKernel[i]; | 183 sum += fKernel[i]; |
185 } | 184 } |
186 // Normalize the kernel | 185 // Normalize the kernel |
187 float scale = 1.0f / sum; | 186 float scale = 1.0f / sum; |
188 for (int i = 0; i < width; ++i) { | 187 for (int i = 0; i < width; ++i) { |
189 fKernel[i] *= scale; | 188 fKernel[i] *= scale; |
190 } | 189 } |
191 memcpy(fBounds, bounds, sizeof(fBounds)); | 190 memcpy(fBounds, bounds, sizeof(fBounds)); |
192 } | 191 } |
193 | 192 |
194 GrConvolutionEffect::~GrConvolutionEffect() { | 193 GrConvolutionEffect::~GrConvolutionEffect() { |
195 } | 194 } |
196 | 195 |
197 const GrBackendFragmentProcessorFactory& GrConvolutionEffect::getFactory() const
{ | 196 void GrConvolutionEffect::getGLProcessorKey(const GrGLCaps& caps, |
198 return GrTBackendFragmentProcessorFactory<GrConvolutionEffect>::getInstance(
); | 197 GrProcessorKeyBuilder* b) const { |
| 198 GrGLConvolutionEffect::GenKey(*this, caps, b); |
| 199 } |
| 200 |
| 201 GrGLFragmentProcessor* GrConvolutionEffect::createGLInstance() const { |
| 202 return SkNEW_ARGS(GrGLConvolutionEffect, (*this)); |
199 } | 203 } |
200 | 204 |
201 bool GrConvolutionEffect::onIsEqual(const GrFragmentProcessor& sBase) const { | 205 bool GrConvolutionEffect::onIsEqual(const GrFragmentProcessor& sBase) const { |
202 const GrConvolutionEffect& s = sBase.cast<GrConvolutionEffect>(); | 206 const GrConvolutionEffect& s = sBase.cast<GrConvolutionEffect>(); |
203 return (this->radius() == s.radius() && | 207 return (this->radius() == s.radius() && |
204 this->direction() == s.direction() && | 208 this->direction() == s.direction() && |
205 this->useBounds() == s.useBounds() && | 209 this->useBounds() == s.useBounds() && |
206 0 == memcmp(fBounds, s.fBounds, sizeof(fBounds)) && | 210 0 == memcmp(fBounds, s.fBounds, sizeof(fBounds)) && |
207 0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float))); | 211 0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float))); |
208 } | 212 } |
(...skipping 20 matching lines...) Expand all Loading... |
229 } | 233 } |
230 | 234 |
231 bool useBounds = random->nextBool(); | 235 bool useBounds = random->nextBool(); |
232 return GrConvolutionEffect::Create(textures[texIdx], | 236 return GrConvolutionEffect::Create(textures[texIdx], |
233 dir, | 237 dir, |
234 radius, | 238 radius, |
235 kernel, | 239 kernel, |
236 useBounds, | 240 useBounds, |
237 bounds); | 241 bounds); |
238 } | 242 } |
OLD | NEW |