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

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

Issue 1893193002: Split AlphaThresholdEffect out into its own file (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix test Created 4 years, 8 months 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 | « src/effects/GrAlphaThresholdFragmentProcessor.cpp ('k') | tests/FlattenableFactoryToName.cpp » ('j') | 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 * Copyright 2013 Google Inc. 2 * Copyright 2013 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 "SkAlphaThresholdFilter.h" 8 #include "SkAlphaThresholdFilter.h"
9 9
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
12 #include "SkSpecialImage.h" 12 #include "SkSpecialImage.h"
13 #include "SkWriteBuffer.h" 13 #include "SkWriteBuffer.h"
14 #include "SkRegion.h" 14 #include "SkRegion.h"
15
15 #if SK_SUPPORT_GPU 16 #if SK_SUPPORT_GPU
17 #include "GrAlphaThresholdFragmentProcessor.h"
18 #include "GrContext.h"
16 #include "GrDrawContext.h" 19 #include "GrDrawContext.h"
17 #endif 20 #endif
18 21
19 class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter { 22 class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter {
20 public: 23 public:
21 SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold, 24 SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold,
22 SkScalar outerThreshold, sk_sp<SkImageFilter> inp ut, 25 SkScalar outerThreshold, sk_sp<SkImageFilter> inp ut,
23 const CropRect* cropRect = nullptr); 26 const CropRect* cropRect = nullptr);
24 27
25 SK_TO_STRING_OVERRIDE() 28 SK_TO_STRING_OVERRIDE()
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 outerThreshold = pin_0_1(outerThreshold); 63 outerThreshold = pin_0_1(outerThreshold);
61 if (!SkScalarIsFinite(innerThreshold) || !SkScalarIsFinite(outerThreshold)) { 64 if (!SkScalarIsFinite(innerThreshold) || !SkScalarIsFinite(outerThreshold)) {
62 return nullptr; 65 return nullptr;
63 } 66 }
64 return sk_sp<SkImageFilter>(new SkAlphaThresholdFilterImpl(region, innerThre shold, 67 return sk_sp<SkImageFilter>(new SkAlphaThresholdFilterImpl(region, innerThre shold,
65 outerThreshold, 68 outerThreshold,
66 std::move(input), 69 std::move(input),
67 cropRect)); 70 cropRect));
68 } 71 }
69 72
70 #if SK_SUPPORT_GPU
71 #include "GrContext.h"
72 #include "GrCoordTransform.h"
73 #include "GrFragmentProcessor.h"
74 #include "GrInvariantOutput.h"
75 #include "GrTextureAccess.h"
76 #include "effects/GrPorterDuffXferProcessor.h"
77
78 #include "SkGr.h"
79
80 #include "glsl/GrGLSLFragmentProcessor.h"
81 #include "glsl/GrGLSLFragmentShaderBuilder.h"
82 #include "glsl/GrGLSLProgramDataManager.h"
83 #include "glsl/GrGLSLUniformHandler.h"
84
85 namespace {
86
87 SkMatrix make_div_and_translate_matrix(GrTexture* texture, int x, int y) {
88 SkMatrix matrix = GrCoordTransform::MakeDivByTextureWHMatrix(texture);
89 matrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
90 return matrix;
91 }
92
93 };
94
95 class AlphaThresholdEffect : public GrFragmentProcessor {
96
97 public:
98 static GrFragmentProcessor* Create(GrTexture* texture,
99 GrTexture* maskTexture,
100 float innerThreshold,
101 float outerThreshold,
102 const SkIRect& bounds) {
103 return new AlphaThresholdEffect(texture, maskTexture, innerThreshold, ou terThreshold,
104 bounds);
105 }
106
107 virtual ~AlphaThresholdEffect() {};
108
109 const char* name() const override { return "Alpha Threshold"; }
110
111 float innerThreshold() const { return fInnerThreshold; }
112 float outerThreshold() const { return fOuterThreshold; }
113
114 private:
115 AlphaThresholdEffect(GrTexture* texture,
116 GrTexture* maskTexture,
117 float innerThreshold,
118 float outerThreshold,
119 const SkIRect& bounds)
120 : fInnerThreshold(innerThreshold)
121 , fOuterThreshold(outerThreshold)
122 , fImageCoordTransform(kLocal_GrCoordSet,
123 GrCoordTransform::MakeDivByTextureWHMatrix(textur e), texture,
124 GrTextureParams::kNone_FilterMode)
125 , fImageTextureAccess(texture)
126 , fMaskCoordTransform(kLocal_GrCoordSet,
127 make_div_and_translate_matrix(maskTexture, -bounds .x(), -bounds.y()),
128 maskTexture,
129 GrTextureParams::kNone_FilterMode)
130 , fMaskTextureAccess(maskTexture) {
131 this->initClassID<AlphaThresholdEffect>();
132 this->addCoordTransform(&fImageCoordTransform);
133 this->addTextureAccess(&fImageTextureAccess);
134 this->addCoordTransform(&fMaskCoordTransform);
135 this->addTextureAccess(&fMaskTextureAccess);
136 }
137
138 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
139
140 void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
141
142 bool onIsEqual(const GrFragmentProcessor&) const override;
143
144 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
145
146 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
147
148 float fInnerThreshold;
149 float fOuterThreshold;
150 GrCoordTransform fImageCoordTransform;
151 GrTextureAccess fImageTextureAccess;
152 GrCoordTransform fMaskCoordTransform;
153 GrTextureAccess fMaskTextureAccess;
154
155 typedef GrFragmentProcessor INHERITED;
156 };
157
158 class GrGLAlphaThresholdEffect : public GrGLSLFragmentProcessor {
159 public:
160 void emitCode(EmitArgs&) override;
161
162 protected:
163 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override ;
164
165 private:
166 GrGLSLProgramDataManager::UniformHandle fInnerThresholdVar;
167 GrGLSLProgramDataManager::UniformHandle fOuterThresholdVar;
168
169 typedef GrGLSLFragmentProcessor INHERITED;
170 };
171
172 void GrGLAlphaThresholdEffect::emitCode(EmitArgs& args) {
173 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
174 fInnerThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
175 kFloat_GrSLType, kDefault_Gr SLPrecision,
176 "inner_threshold");
177 fOuterThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
178 kFloat_GrSLType, kDefault_Gr SLPrecision,
179 "outer_threshold");
180
181 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
182 SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
183 SkString maskCoords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1);
184
185 fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
186 fragBuilder->codeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str() );
187 fragBuilder->codeAppend("\t\tvec4 input_color = ");
188 fragBuilder->appendTextureLookup(args.fTexSamplers[0], "coord");
189 fragBuilder->codeAppend(";\n");
190 fragBuilder->codeAppend("\t\tvec4 mask_color = ");
191 fragBuilder->appendTextureLookup(args.fTexSamplers[1], "mask_coord");
192 fragBuilder->codeAppend(";\n");
193
194 fragBuilder->codeAppendf("\t\tfloat inner_thresh = %s;\n",
195 uniformHandler->getUniformCStr(fInnerThresholdVar)) ;
196 fragBuilder->codeAppendf("\t\tfloat outer_thresh = %s;\n",
197 uniformHandler->getUniformCStr(fOuterThresholdVar)) ;
198 fragBuilder->codeAppend("\t\tfloat mask = mask_color.a;\n");
199
200 fragBuilder->codeAppend("vec4 color = input_color;\n");
201 fragBuilder->codeAppend("\t\tif (mask < 0.5) {\n"
202 "\t\t\tif (color.a > outer_thresh) {\n"
203 "\t\t\t\tfloat scale = outer_thresh / color.a;\n"
204 "\t\t\t\tcolor.rgb *= scale;\n"
205 "\t\t\t\tcolor.a = outer_thresh;\n"
206 "\t\t\t}\n"
207 "\t\t} else if (color.a < inner_thresh) {\n"
208 "\t\t\tfloat scale = inner_thresh / max(0.001, color .a);\n"
209 "\t\t\tcolor.rgb *= scale;\n"
210 "\t\t\tcolor.a = inner_thresh;\n"
211 "\t\t}\n");
212
213 fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor,
214 (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color ")).c_str());
215 }
216
217 void GrGLAlphaThresholdEffect::onSetData(const GrGLSLProgramDataManager& pdman,
218 const GrProcessor& proc) {
219 const AlphaThresholdEffect& alpha_threshold = proc.cast<AlphaThresholdEffect >();
220 pdman.set1f(fInnerThresholdVar, alpha_threshold.innerThreshold());
221 pdman.set1f(fOuterThresholdVar, alpha_threshold.outerThreshold());
222 }
223
224 /////////////////////////////////////////////////////////////////////
225
226 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AlphaThresholdEffect);
227
228 const GrFragmentProcessor* AlphaThresholdEffect::TestCreate(GrProcessorTestData* d) {
229 GrTexture* bmpTex = d->fTextures[GrProcessorUnitTest::kSkiaPMTextureIdx];
230 GrTexture* maskTex = d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx];
231 float innerThresh = d->fRandom->nextUScalar1();
232 float outerThresh = d->fRandom->nextUScalar1();
233 const int kMaxWidth = 1000;
234 const int kMaxHeight = 1000;
235 uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
236 uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
237 uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width);
238 uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height);
239 SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
240 return AlphaThresholdEffect::Create(bmpTex, maskTex, innerThresh, outerThres h, bounds);
241 }
242
243 ///////////////////////////////////////////////////////////////////////////////
244
245 void AlphaThresholdEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
246 GrProcessorKeyBuilder* b) const {
247 GrGLAlphaThresholdEffect::GenKey(*this, caps, b);
248 }
249
250 GrGLSLFragmentProcessor* AlphaThresholdEffect::onCreateGLSLInstance() const {
251 return new GrGLAlphaThresholdEffect;
252 }
253
254 bool AlphaThresholdEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
255 const AlphaThresholdEffect& s = sBase.cast<AlphaThresholdEffect>();
256 return (this->fInnerThreshold == s.fInnerThreshold &&
257 this->fOuterThreshold == s.fOuterThreshold);
258 }
259
260 void AlphaThresholdEffect::onComputeInvariantOutput(GrInvariantOutput* inout) co nst {
261 if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
262 inout->mulByUnknownSingleComponent();
263 } else if (GrPixelConfigIsOpaque(this->texture(0)->config()) && fOuterThresh old >= 1.f) {
264 inout->mulByUnknownOpaqueFourComponents();
265 } else {
266 inout->mulByUnknownFourComponents();
267 }
268 }
269
270 #endif
271
272 sk_sp<SkFlattenable> SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer ) { 73 sk_sp<SkFlattenable> SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer ) {
273 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 74 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
274 SkScalar inner = buffer.readScalar(); 75 SkScalar inner = buffer.readScalar();
275 SkScalar outer = buffer.readScalar(); 76 SkScalar outer = buffer.readScalar();
276 SkRegion rgn; 77 SkRegion rgn;
277 buffer.readRegion(&rgn); 78 buffer.readRegion(&rgn);
278 return SkAlphaThresholdFilter::Make(rgn, inner, outer, common.getInput(0), 79 return SkAlphaThresholdFilter::Make(rgn, inner, outer, common.getInput(0),
279 &common.cropRect()); 80 &common.cropRect());
280 } 81 }
281 82
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 170
370 SkMatrix matrix(ctx.ctm()); 171 SkMatrix matrix(ctx.ctm());
371 matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bound s.top())); 172 matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bound s.top()));
372 173
373 sk_sp<GrTexture> maskTexture(this->createMaskTexture(context, matrix, bo unds)); 174 sk_sp<GrTexture> maskTexture(this->createMaskTexture(context, matrix, bo unds));
374 if (!maskTexture) { 175 if (!maskTexture) {
375 return nullptr; 176 return nullptr;
376 } 177 }
377 178
378 // SRGBTODO: handle sRGB here 179 // SRGBTODO: handle sRGB here
379 sk_sp<GrFragmentProcessor> fp(AlphaThresholdEffect::Create(inputTexture. get(), 180 sk_sp<GrFragmentProcessor> fp(GrAlphaThresholdFragmentProcessor::Make(
181 inputTexture. get(),
380 maskTexture.g et(), 182 maskTexture.g et(),
381 fInnerThresho ld, 183 fInnerThresho ld,
382 fOuterThresho ld, 184 fOuterThresho ld,
383 bounds)); 185 bounds));
384 if (!fp) { 186 if (!fp) {
385 return nullptr; 187 return nullptr;
386 } 188 }
387 189
388 return DrawWithFP(context, std::move(fp), bounds, source->internal_getPr oxy()); 190 return DrawWithFP(context, std::move(fp), bounds, source->internal_getPr oxy());
389 } 191 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 dst); 267 dst);
466 } 268 }
467 269
468 #ifndef SK_IGNORE_TO_STRING 270 #ifndef SK_IGNORE_TO_STRING
469 void SkAlphaThresholdFilterImpl::toString(SkString* str) const { 271 void SkAlphaThresholdFilterImpl::toString(SkString* str) const {
470 str->appendf("SkAlphaThresholdImageFilter: ("); 272 str->appendf("SkAlphaThresholdImageFilter: (");
471 str->appendf("inner: %f outer: %f", fInnerThreshold, fOuterThreshold); 273 str->appendf("inner: %f outer: %f", fInnerThreshold, fOuterThreshold);
472 str->append(")"); 274 str->append(")");
473 } 275 }
474 #endif 276 #endif
OLDNEW
« no previous file with comments | « src/effects/GrAlphaThresholdFragmentProcessor.cpp ('k') | tests/FlattenableFactoryToName.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698