OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrCircleBlurFragmentProcessor.h" | 9 #include "GrCircleBlurFragmentProcessor.h" |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... | |
33 typedef GrGLSLFragmentProcessor INHERITED; | 33 typedef GrGLSLFragmentProcessor INHERITED; |
34 }; | 34 }; |
35 | 35 |
36 void GrGLCircleBlurFragmentProcessor::emitCode(EmitArgs& args) { | 36 void GrGLCircleBlurFragmentProcessor::emitCode(EmitArgs& args) { |
37 | 37 |
38 const char *dataName; | 38 const char *dataName; |
39 | 39 |
40 // The data is formatted as: | 40 // The data is formatted as: |
41 // x,y - the center of the circle | 41 // x,y - the center of the circle |
42 // z - the distance at which the intensity starts falling off (e.g., the start of the table) | 42 // z - the distance at which the intensity starts falling off (e.g., the start of the table) |
43 // w - the size of the profile texture | 43 // w - the inverse of the profile texture size |
44 fDataUniform = args.fUniformHandler->addUniform(GrGLSLUniformHandler::kFragm ent_Visibility, | 44 fDataUniform = args.fUniformHandler->addUniform(GrGLSLUniformHandler::kFragm ent_Visibility, |
45 kVec4f_GrSLType, | 45 kVec4f_GrSLType, |
46 kDefault_GrSLPrecision, | 46 kDefault_GrSLPrecision, |
47 "data", | 47 "data", |
48 &dataName); | 48 &dataName); |
49 | 49 |
50 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 50 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
51 const char *fragmentPos = fragBuilder->fragmentPosition(); | 51 const char *fragmentPos = fragBuilder->fragmentPosition(); |
52 | 52 |
53 if (args.fInputColor) { | 53 if (args.fInputColor) { |
54 fragBuilder->codeAppendf("vec4 src=%s;", args.fInputColor); | 54 fragBuilder->codeAppendf("vec4 src=%s;", args.fInputColor); |
55 } else { | 55 } else { |
56 fragBuilder->codeAppendf("vec4 src=vec4(1);"); | 56 fragBuilder->codeAppendf("vec4 src=vec4(1);"); |
57 } | 57 } |
58 | 58 |
59 fragBuilder->codeAppendf("vec2 vec = %s.xy - %s.xy;", fragmentPos, dataName) ; | 59 // We just want to compute "length(vec) - %s.z + 0.5) * %s.w" but need to re arrange |
60 fragBuilder->codeAppendf("float dist = (length(vec) - %s.z + 0.5) / %s.w;", dataName, dataName); | 60 // for precision |
bsalomon
2015/12/10 20:46:05
Should we guard this by if (args.fGLSLCaps->floatP
robertphillips
2015/12/10 20:51:04
If we can get away with it perf-wise I think we sh
| |
61 fragBuilder->codeAppendf("vec2 vec = vec2( (%s.x - %s.x) * %s.w , (%s.y - %s .y) * %s.w );", | |
62 fragmentPos, dataName, dataName, | |
63 fragmentPos, dataName, dataName); | |
64 fragBuilder->codeAppendf("float dist = length(vec) + ( 0.5 - %s.z ) * %s.w;" , | |
65 dataName, dataName); | |
61 | 66 |
62 fragBuilder->codeAppendf("float intensity = "); | 67 fragBuilder->codeAppendf("float intensity = "); |
63 fragBuilder->appendTextureLookup(args.fSamplers[0], "vec2(dist, 0.5)"); | 68 fragBuilder->appendTextureLookup(args.fSamplers[0], "vec2(dist, 0.5)"); |
64 fragBuilder->codeAppend(".a;"); | 69 fragBuilder->codeAppend(".a;"); |
65 | 70 |
66 fragBuilder->codeAppendf("%s = src * intensity;\n", args.fOutputColor ); | 71 fragBuilder->codeAppendf("%s = src * intensity;\n", args.fOutputColor ); |
67 } | 72 } |
68 | 73 |
69 void GrGLCircleBlurFragmentProcessor::onSetData(const GrGLSLProgramDataManager& pdman, | 74 void GrGLCircleBlurFragmentProcessor::onSetData(const GrGLSLProgramDataManager& pdman, |
70 const GrProcessor& proc) { | 75 const GrProcessor& proc) { |
71 const GrCircleBlurFragmentProcessor& cbfp = proc.cast<GrCircleBlurFragmentPr ocessor>(); | 76 const GrCircleBlurFragmentProcessor& cbfp = proc.cast<GrCircleBlurFragmentPr ocessor>(); |
72 const SkRect& circle = cbfp.circle(); | 77 const SkRect& circle = cbfp.circle(); |
73 | 78 |
74 // The data is formatted as: | 79 // The data is formatted as: |
75 // x,y - the center of the circle | 80 // x,y - the center of the circle |
76 // z - the distance at which the intensity starts falling off (e.g., the start of the table) | 81 // z - the distance at which the intensity starts falling off (e.g., the start of the table) |
77 // w - the size of the profile texture | 82 // w - the inverse of the profile texture size |
78 pdman.set4f(fDataUniform, circle.centerX(), circle.centerY(), cbfp.offset(), | 83 pdman.set4f(fDataUniform, circle.centerX(), circle.centerY(), cbfp.offset(), |
79 SkIntToScalar(cbfp.profileSize())); | 84 1.0f / cbfp.profileSize()); |
80 } | 85 } |
81 | 86 |
82 /////////////////////////////////////////////////////////////////////////////// | 87 /////////////////////////////////////////////////////////////////////////////// |
83 | 88 |
84 GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circl e, | 89 GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(const SkRect& circl e, |
85 float sigma, | 90 float sigma, |
86 float offset, | 91 float offset, |
87 GrTexture* blurProf ile) | 92 GrTexture* blurProf ile) |
88 : fCircle(circle) | 93 : fCircle(circle) |
89 , fSigma(sigma) | 94 , fSigma(sigma) |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 return SkUnitScalarClampToByte(acc); | 179 return SkUnitScalarClampToByte(acc); |
175 } | 180 } |
176 | 181 |
177 static inline void compute_profile_offset_and_size(float halfWH, float sigma, | 182 static inline void compute_profile_offset_and_size(float halfWH, float sigma, |
178 float* offset, int* size) { | 183 float* offset, int* size) { |
179 | 184 |
180 if (3*sigma <= halfWH) { | 185 if (3*sigma <= halfWH) { |
181 // The circle is bigger than the Gaussian. In this case we know the inte rior of the | 186 // The circle is bigger than the Gaussian. In this case we know the inte rior of the |
182 // blurred circle is solid. | 187 // blurred circle is solid. |
183 *offset = halfWH - 3 * sigma; // This location maps to 0.5f in the weigh ts texture. | 188 *offset = halfWH - 3 * sigma; // This location maps to 0.5f in the weigh ts texture. |
184 // It should always be 255. | 189 // It should always be 255. |
185 *size = SkScalarCeilToInt(6*sigma); | 190 *size = SkScalarCeilToInt(6*sigma); |
186 } else { | 191 } else { |
187 // The Gaussian is bigger than the circle. | 192 // The Gaussian is bigger than the circle. |
188 *offset = 0.0f; | 193 *offset = 0.0f; |
189 *size = SkScalarCeilToInt(halfWH + 3*sigma); | 194 *size = SkScalarCeilToInt(halfWH + 3*sigma); |
190 } | 195 } |
191 } | 196 } |
192 | 197 |
193 static uint8_t* create_profile(float halfWH, float sigma) { | 198 static uint8_t* create_profile(float halfWH, float sigma) { |
194 | 199 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleBlurFragmentProcessor); | 258 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleBlurFragmentProcessor); |
254 | 259 |
255 const GrFragmentProcessor* GrCircleBlurFragmentProcessor::TestCreate(GrProcessor TestData* d) { | 260 const GrFragmentProcessor* GrCircleBlurFragmentProcessor::TestCreate(GrProcessor TestData* d) { |
256 SkScalar wh = d->fRandom->nextRangeScalar(100.f, 1000.f); | 261 SkScalar wh = d->fRandom->nextRangeScalar(100.f, 1000.f); |
257 SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f); | 262 SkScalar sigma = d->fRandom->nextRangeF(1.f,10.f); |
258 SkRect circle = SkRect::MakeWH(wh, wh); | 263 SkRect circle = SkRect::MakeWH(wh, wh); |
259 return GrCircleBlurFragmentProcessor::Create(d->fContext->textureProvider(), circle, sigma); | 264 return GrCircleBlurFragmentProcessor::Create(d->fContext->textureProvider(), circle, sigma); |
260 } | 265 } |
261 | 266 |
262 #endif | 267 #endif |
OLD | NEW |