Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: src/effects/GrCircleBlurFragmentProcessor.cpp

Issue 1504333003: Address precision issue in circle blur effect (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix overlength line Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gm/blurredclippedcircle.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « gm/blurredclippedcircle.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698