blob: c1f9141a716c80a6d9f01127ba2afc3cb8069dd9 [file] [log] [blame]
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkAlphaThresholdFilter.h"
9#include "SkBitmap.h"
senorblanco1d3ff432015-10-20 10:17:34 -070010#include "SkDevice.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000011#include "SkReadBuffer.h"
12#include "SkWriteBuffer.h"
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000013#include "SkRegion.h"
robertphillipsea461502015-05-26 11:38:03 -070014#if SK_SUPPORT_GPU
15#include "GrDrawContext.h"
16#endif
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000017
18class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter {
19public:
senorblanco9ea3d572014-07-08 09:16:22 -070020 SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold,
21 SkScalar outerThreshold, SkImageFilter* input);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000022
robertphillipsf3f5bad2014-12-19 13:49:15 -080023 SK_TO_STRING_OVERRIDE()
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000024 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterImpl)
halcanary07456532015-12-07 10:29:54 -080025 friend void SkAlphaThresholdFilter::InitializeFlattenables();
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000026
27protected:
mtklein36352bf2015-03-25 18:17:31 -070028 void flatten(SkWriteBuffer&) const override;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000029
robertphillips48e78462016-02-17 13:57:16 -080030 bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
31 SkBitmap* result, SkIPoint* offset) const override;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000032#if SK_SUPPORT_GPU
bsalomon4a339522015-10-06 08:40:50 -070033 bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
34 const SkIRect& bounds) const override;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000035#endif
36
37private:
38 SkRegion fRegion;
39 SkScalar fInnerThreshold;
40 SkScalar fOuterThreshold;
41 typedef SkImageFilter INHERITED;
42};
43
halcanary07456532015-12-07 10:29:54 -080044SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkAlphaThresholdFilter)
45 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAlphaThresholdFilterImpl)
46SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
47
48
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000049SkImageFilter* SkAlphaThresholdFilter::Create(const SkRegion& region,
50 SkScalar innerThreshold,
senorblanco9ea3d572014-07-08 09:16:22 -070051 SkScalar outerThreshold,
52 SkImageFilter* input) {
halcanary385fe4d2015-08-26 13:07:48 -070053 return new SkAlphaThresholdFilterImpl(region, innerThreshold, outerThreshold, input);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000054}
55
56#if SK_SUPPORT_GPU
57#include "GrContext.h"
58#include "GrCoordTransform.h"
bsalomon6251d172014-10-15 10:50:36 -070059#include "GrFragmentProcessor.h"
egdaniel605dd0f2014-11-12 08:35:25 -080060#include "GrInvariantOutput.h"
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000061#include "GrTextureAccess.h"
egdaniel95131432014-12-09 11:15:43 -080062#include "effects/GrPorterDuffXferProcessor.h"
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000063
64#include "SkGr.h"
65
egdaniel64c47282015-11-13 06:54:19 -080066#include "glsl/GrGLSLFragmentProcessor.h"
egdaniel2d721d32015-11-11 13:06:05 -080067#include "glsl/GrGLSLFragmentShaderBuilder.h"
egdaniel018fb622015-10-28 07:26:40 -070068#include "glsl/GrGLSLProgramDataManager.h"
egdaniel7ea439b2015-12-03 09:20:44 -080069#include "glsl/GrGLSLUniformHandler.h"
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000070
senorblanco1ea67a32016-01-19 08:50:18 -080071namespace {
72
73SkMatrix make_div_and_translate_matrix(GrTexture* texture, int x, int y) {
74 SkMatrix matrix = GrCoordTransform::MakeDivByTextureWHMatrix(texture);
75 matrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
76 return matrix;
77}
78
79};
80
joshualittb0a8a372014-09-23 09:50:21 -070081class AlphaThresholdEffect : public GrFragmentProcessor {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000082
83public:
bsalomon4a339522015-10-06 08:40:50 -070084 static GrFragmentProcessor* Create(GrTexture* texture,
joshualittb0a8a372014-09-23 09:50:21 -070085 GrTexture* maskTexture,
86 float innerThreshold,
senorblanco1ea67a32016-01-19 08:50:18 -080087 float outerThreshold,
88 const SkIRect& bounds) {
89 return new AlphaThresholdEffect(texture, maskTexture, innerThreshold, outerThreshold,
90 bounds);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000091 }
92
93 virtual ~AlphaThresholdEffect() {};
94
mtklein36352bf2015-03-25 18:17:31 -070095 const char* name() const override { return "Alpha Threshold"; }
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000096
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +000097 float innerThreshold() const { return fInnerThreshold; }
98 float outerThreshold() const { return fOuterThreshold; }
99
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000100private:
bsalomon4a339522015-10-06 08:40:50 -0700101 AlphaThresholdEffect(GrTexture* texture,
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000102 GrTexture* maskTexture,
103 float innerThreshold,
senorblanco1ea67a32016-01-19 08:50:18 -0800104 float outerThreshold,
105 const SkIRect& bounds)
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000106 : fInnerThreshold(innerThreshold)
107 , fOuterThreshold(outerThreshold)
bsalomon6267f812014-08-29 15:05:53 -0700108 , fImageCoordTransform(kLocal_GrCoordSet,
bsalomon9f876a32014-12-09 10:51:07 -0800109 GrCoordTransform::MakeDivByTextureWHMatrix(texture), texture,
110 GrTextureParams::kNone_FilterMode)
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000111 , fImageTextureAccess(texture)
bsalomon6267f812014-08-29 15:05:53 -0700112 , fMaskCoordTransform(kLocal_GrCoordSet,
senorblanco1ea67a32016-01-19 08:50:18 -0800113 make_div_and_translate_matrix(maskTexture, -bounds.x(), -bounds.y()),
114 maskTexture,
bsalomon9f876a32014-12-09 10:51:07 -0800115 GrTextureParams::kNone_FilterMode)
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000116 , fMaskTextureAccess(maskTexture) {
joshualitteb2a6762014-12-04 11:35:33 -0800117 this->initClassID<AlphaThresholdEffect>();
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000118 this->addCoordTransform(&fImageCoordTransform);
119 this->addTextureAccess(&fImageTextureAccess);
120 this->addCoordTransform(&fMaskCoordTransform);
121 this->addTextureAccess(&fMaskTextureAccess);
122 }
123
egdaniel57d3b032015-11-13 11:57:27 -0800124 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
wangyixb1daa862015-08-18 11:29:31 -0700125
egdaniel57d3b032015-11-13 11:57:27 -0800126 void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
wangyix4b3050b2015-08-04 07:59:37 -0700127
mtklein36352bf2015-03-25 18:17:31 -0700128 bool onIsEqual(const GrFragmentProcessor&) const override;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000129
mtklein36352bf2015-03-25 18:17:31 -0700130 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
egdaniel1a8ecdf2014-10-03 06:24:12 -0700131
joshualittb0a8a372014-09-23 09:50:21 -0700132 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000133
134 float fInnerThreshold;
135 float fOuterThreshold;
136 GrCoordTransform fImageCoordTransform;
137 GrTextureAccess fImageTextureAccess;
138 GrCoordTransform fMaskCoordTransform;
139 GrTextureAccess fMaskTextureAccess;
140
joshualittb0a8a372014-09-23 09:50:21 -0700141 typedef GrFragmentProcessor INHERITED;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000142};
143
egdaniel64c47282015-11-13 06:54:19 -0800144class GrGLAlphaThresholdEffect : public GrGLSLFragmentProcessor {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000145public:
robertphillips9cdb9922016-02-03 12:25:40 -0800146 void emitCode(EmitArgs&) override;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000147
wangyixb1daa862015-08-18 11:29:31 -0700148protected:
egdaniel018fb622015-10-28 07:26:40 -0700149 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000150
151private:
egdaniel018fb622015-10-28 07:26:40 -0700152 GrGLSLProgramDataManager::UniformHandle fInnerThresholdVar;
153 GrGLSLProgramDataManager::UniformHandle fOuterThresholdVar;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000154
egdaniel64c47282015-11-13 06:54:19 -0800155 typedef GrGLSLFragmentProcessor INHERITED;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000156};
157
wangyix7c157a92015-07-22 15:08:53 -0700158void GrGLAlphaThresholdEffect::emitCode(EmitArgs& args) {
egdaniel7ea439b2015-12-03 09:20:44 -0800159 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
cdalton5e58cee2016-02-11 12:49:47 -0800160 fInnerThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
egdaniel7ea439b2015-12-03 09:20:44 -0800161 kFloat_GrSLType, kDefault_GrSLPrecision,
162 "inner_threshold");
cdalton5e58cee2016-02-11 12:49:47 -0800163 fOuterThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
egdaniel7ea439b2015-12-03 09:20:44 -0800164 kFloat_GrSLType, kDefault_GrSLPrecision,
165 "outer_threshold");
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000166
egdaniel4ca2e602015-11-18 08:01:26 -0800167 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
168 SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
169 SkString maskCoords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000170
egdaniel4ca2e602015-11-18 08:01:26 -0800171 fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
172 fragBuilder->codeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str());
173 fragBuilder->codeAppend("\t\tvec4 input_color = ");
174 fragBuilder->appendTextureLookup(args.fSamplers[0], "coord");
175 fragBuilder->codeAppend(";\n");
176 fragBuilder->codeAppend("\t\tvec4 mask_color = ");
177 fragBuilder->appendTextureLookup(args.fSamplers[1], "mask_coord");
178 fragBuilder->codeAppend(";\n");
joshualitt30ba4362014-08-21 20:18:45 -0700179
egdaniel4ca2e602015-11-18 08:01:26 -0800180 fragBuilder->codeAppendf("\t\tfloat inner_thresh = %s;\n",
egdaniel7ea439b2015-12-03 09:20:44 -0800181 uniformHandler->getUniformCStr(fInnerThresholdVar));
egdaniel4ca2e602015-11-18 08:01:26 -0800182 fragBuilder->codeAppendf("\t\tfloat outer_thresh = %s;\n",
egdaniel7ea439b2015-12-03 09:20:44 -0800183 uniformHandler->getUniformCStr(fOuterThresholdVar));
egdaniel4ca2e602015-11-18 08:01:26 -0800184 fragBuilder->codeAppend("\t\tfloat mask = mask_color.a;\n");
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000185
egdaniel4ca2e602015-11-18 08:01:26 -0800186 fragBuilder->codeAppend("vec4 color = input_color;\n");
187 fragBuilder->codeAppend("\t\tif (mask < 0.5) {\n"
188 "\t\t\tif (color.a > outer_thresh) {\n"
189 "\t\t\t\tfloat scale = outer_thresh / color.a;\n"
190 "\t\t\t\tcolor.rgb *= scale;\n"
191 "\t\t\t\tcolor.a = outer_thresh;\n"
192 "\t\t\t}\n"
193 "\t\t} else if (color.a < inner_thresh) {\n"
194 "\t\t\tfloat scale = inner_thresh / max(0.001, color.a);\n"
195 "\t\t\tcolor.rgb *= scale;\n"
196 "\t\t\tcolor.a = inner_thresh;\n"
197 "\t\t}\n");
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000198
egdaniel4ca2e602015-11-18 08:01:26 -0800199 fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor,
200 (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str());
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000201}
202
egdaniel018fb622015-10-28 07:26:40 -0700203void GrGLAlphaThresholdEffect::onSetData(const GrGLSLProgramDataManager& pdman,
joshualittb0a8a372014-09-23 09:50:21 -0700204 const GrProcessor& proc) {
205 const AlphaThresholdEffect& alpha_threshold = proc.cast<AlphaThresholdEffect>();
kkinnunen7510b222014-07-30 00:04:16 -0700206 pdman.set1f(fInnerThresholdVar, alpha_threshold.innerThreshold());
207 pdman.set1f(fOuterThresholdVar, alpha_threshold.outerThreshold());
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000208}
209
210/////////////////////////////////////////////////////////////////////
211
joshualittb0a8a372014-09-23 09:50:21 -0700212GR_DEFINE_FRAGMENT_PROCESSOR_TEST(AlphaThresholdEffect);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000213
bsalomonc21b09e2015-08-28 18:46:56 -0700214const GrFragmentProcessor* AlphaThresholdEffect::TestCreate(GrProcessorTestData* d) {
joshualitt0067ff52015-07-08 14:26:19 -0700215 GrTexture* bmpTex = d->fTextures[GrProcessorUnitTest::kSkiaPMTextureIdx];
216 GrTexture* maskTex = d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx];
217 float innerThresh = d->fRandom->nextUScalar1();
218 float outerThresh = d->fRandom->nextUScalar1();
senorblanco1ea67a32016-01-19 08:50:18 -0800219 const int kMaxWidth = 1000;
220 const int kMaxHeight = 1000;
221 uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
222 uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
223 uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width);
224 uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height);
225 SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
226 return AlphaThresholdEffect::Create(bmpTex, maskTex, innerThresh, outerThresh, bounds);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000227}
228
229///////////////////////////////////////////////////////////////////////////////
230
egdaniel57d3b032015-11-13 11:57:27 -0800231void AlphaThresholdEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
232 GrProcessorKeyBuilder* b) const {
joshualitteb2a6762014-12-04 11:35:33 -0800233 GrGLAlphaThresholdEffect::GenKey(*this, caps, b);
234}
235
egdaniel57d3b032015-11-13 11:57:27 -0800236GrGLSLFragmentProcessor* AlphaThresholdEffect::onCreateGLSLInstance() const {
robertphillips9cdb9922016-02-03 12:25:40 -0800237 return new GrGLAlphaThresholdEffect;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000238}
239
bsalomon0e08fc12014-10-15 08:19:04 -0700240bool AlphaThresholdEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
joshualitt49586be2014-09-16 08:21:41 -0700241 const AlphaThresholdEffect& s = sBase.cast<AlphaThresholdEffect>();
bsalomon420d7e92014-10-16 09:18:09 -0700242 return (this->fInnerThreshold == s.fInnerThreshold &&
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000243 this->fOuterThreshold == s.fOuterThreshold);
244}
245
egdaniel605dd0f2014-11-12 08:35:25 -0800246void AlphaThresholdEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
egdanielf8449ba2014-11-25 10:24:56 -0800247 if (GrPixelConfigIsAlphaOnly(this->texture(0)->config())) {
joshualitt56995b52014-12-11 15:44:02 -0800248 inout->mulByUnknownSingleComponent();
egdanielf8449ba2014-11-25 10:24:56 -0800249 } else if (GrPixelConfigIsOpaque(this->texture(0)->config()) && fOuterThreshold >= 1.f) {
joshualitt56995b52014-12-11 15:44:02 -0800250 inout->mulByUnknownOpaqueFourComponents();
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000251 } else {
joshualitt56995b52014-12-11 15:44:02 -0800252 inout->mulByUnknownFourComponents();
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000253 }
254}
255
256#endif
257
reed9fa60da2014-08-21 07:59:51 -0700258SkFlattenable* SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer) {
259 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
260 SkScalar inner = buffer.readScalar();
261 SkScalar outer = buffer.readScalar();
262 SkRegion rgn;
263 buffer.readRegion(&rgn);
264 return SkAlphaThresholdFilter::Create(rgn, inner, outer, common.getInput(0));
265}
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000266
267SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region,
268 SkScalar innerThreshold,
senorblanco9ea3d572014-07-08 09:16:22 -0700269 SkScalar outerThreshold,
270 SkImageFilter* input)
271 : INHERITED(1, &input)
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000272 , fRegion(region)
273 , fInnerThreshold(innerThreshold)
274 , fOuterThreshold(outerThreshold) {
275}
276
277#if SK_SUPPORT_GPU
joshualittb0a8a372014-09-23 09:50:21 -0700278bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
279 GrTexture* texture,
robertphillips2e1e51f2015-10-15 08:01:48 -0700280 const SkMatrix& inMatrix,
senorblanco1ea67a32016-01-19 08:50:18 -0800281 const SkIRect& bounds) const {
joshualittb0a8a372014-09-23 09:50:21 -0700282 if (fp) {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000283 GrContext* context = texture->getContext();
bsalomonf2703d82014-10-28 14:33:06 -0700284 GrSurfaceDesc maskDesc;
bsalomon76228632015-05-29 08:02:10 -0700285 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000286 maskDesc.fConfig = kAlpha_8_GrPixelConfig;
287 } else {
288 maskDesc.fConfig = kRGBA_8888_GrPixelConfig;
289 }
bsalomon6bc1b5f2015-02-23 09:06:38 -0800290 maskDesc.fFlags = kRenderTarget_GrSurfaceFlag;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000291 // Add one pixel of border to ensure that clamp mode will be all zeros
292 // the outside.
senorblanco1ea67a32016-01-19 08:50:18 -0800293 maskDesc.fWidth = bounds.width();
294 maskDesc.fHeight = bounds.height();
bsalomoneae62002015-07-31 13:59:30 -0700295 SkAutoTUnref<GrTexture> maskTexture(
296 context->textureProvider()->createApproxTexture(maskDesc));
bsalomone3059732014-10-14 11:47:22 -0700297 if (!maskTexture) {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000298 return false;
299 }
300
robertphillips2e1e51f2015-10-15 08:01:48 -0700301 SkAutoTUnref<GrDrawContext> drawContext(
302 context->drawContext(maskTexture->asRenderTarget()));
robertphillipsea461502015-05-26 11:38:03 -0700303 if (drawContext) {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000304 GrPaint grPaint;
egdaniel95131432014-12-09 11:15:43 -0800305 grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000306 SkRegion::Iterator iter(fRegion);
robertphillips2e1e51f2015-10-15 08:01:48 -0700307 drawContext->clear(nullptr, 0x0, true);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000308
senorblanco1ea67a32016-01-19 08:50:18 -0800309 GrClip clip(SkRect::Make(SkIRect::MakeWH(bounds.width(), bounds.height())));
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000310 while (!iter.done()) {
311 SkRect rect = SkRect::Make(iter.rect());
senorblanco1ea67a32016-01-19 08:50:18 -0800312 drawContext->drawRect(clip, grPaint, inMatrix, rect);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000313 iter.next();
314 }
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000315 }
316
bsalomon4a339522015-10-06 08:40:50 -0700317 *fp = AlphaThresholdEffect::Create(texture,
joshualittb0a8a372014-09-23 09:50:21 -0700318 maskTexture,
319 fInnerThreshold,
senorblanco1ea67a32016-01-19 08:50:18 -0800320 fOuterThreshold,
321 bounds);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000322 }
323 return true;
324}
325#endif
326
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000327void SkAlphaThresholdFilterImpl::flatten(SkWriteBuffer& buffer) const {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000328 this->INHERITED::flatten(buffer);
329 buffer.writeScalar(fInnerThreshold);
330 buffer.writeScalar(fOuterThreshold);
331 buffer.writeRegion(fRegion);
332}
333
robertphillips48e78462016-02-17 13:57:16 -0800334bool SkAlphaThresholdFilterImpl::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src,
335 const Context& ctx, SkBitmap* dst,
336 SkIPoint* offset) const {
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000337 SkASSERT(src.colorType() == kN32_SkColorType);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000338
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000339 if (src.colorType() != kN32_SkColorType) {
commit-bot@chromium.org9109e182014-01-07 16:04:01 +0000340 return false;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000341 }
342
343 SkMatrix localInverse;
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +0000344 if (!ctx.ctm().invert(&localInverse)) {
commit-bot@chromium.org9109e182014-01-07 16:04:01 +0000345 return false;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000346 }
347
348 SkAutoLockPixels alp(src);
349 SkASSERT(src.getPixels());
350 if (!src.getPixels() || src.width() <= 0 || src.height() <= 0) {
commit-bot@chromium.org9109e182014-01-07 16:04:01 +0000351 return false;
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000352 }
353
senorblanco1d3ff432015-10-20 10:17:34 -0700354 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(src.width(), src.height()));
355 if (!device) {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000356 return false;
357 }
senorblanco1d3ff432015-10-20 10:17:34 -0700358 *dst = device->accessBitmap(false);
359 SkAutoLockPixels alp_dst(*dst);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000360
commit-bot@chromium.org9109e182014-01-07 16:04:01 +0000361 U8CPU innerThreshold = (U8CPU)(fInnerThreshold * 0xFF);
362 U8CPU outerThreshold = (U8CPU)(fOuterThreshold * 0xFF);
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000363 SkColor* sptr = src.getAddr32(0, 0);
364 SkColor* dptr = dst->getAddr32(0, 0);
365 int width = src.width(), height = src.height();
366 for (int y = 0; y < height; ++y) {
367 for (int x = 0; x < width; ++x) {
368 const SkColor& source = sptr[y * width + x];
369 SkColor output_color(source);
370 SkPoint position;
commit-bot@chromium.org9109e182014-01-07 16:04:01 +0000371 localInverse.mapXY((SkScalar)x, (SkScalar)y, &position);
372 if (fRegion.contains((int32_t)position.x(), (int32_t)position.y())) {
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000373 if (SkColorGetA(source) < innerThreshold) {
374 U8CPU alpha = SkColorGetA(source);
375 if (alpha == 0)
376 alpha = 1;
377 float scale = (float)innerThreshold / alpha;
378 output_color = SkColorSetARGB(innerThreshold,
commit-bot@chromium.org9109e182014-01-07 16:04:01 +0000379 (U8CPU)(SkColorGetR(source) * scale),
380 (U8CPU)(SkColorGetG(source) * scale),
381 (U8CPU)(SkColorGetB(source) * scale));
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000382 }
383 } else {
384 if (SkColorGetA(source) > outerThreshold) {
385 float scale = (float)outerThreshold / SkColorGetA(source);
386 output_color = SkColorSetARGB(outerThreshold,
commit-bot@chromium.org9109e182014-01-07 16:04:01 +0000387 (U8CPU)(SkColorGetR(source) * scale),
388 (U8CPU)(SkColorGetG(source) * scale),
389 (U8CPU)(SkColorGetB(source) * scale));
commit-bot@chromium.org40eb3c12014-01-06 23:41:14 +0000390 }
391 }
392 dptr[y * dst->width() + x] = output_color;
393 }
394 }
395
396 return true;
397}
robertphillipsf3f5bad2014-12-19 13:49:15 -0800398
399#ifndef SK_IGNORE_TO_STRING
400void SkAlphaThresholdFilterImpl::toString(SkString* str) const {
401 str->appendf("SkAlphaThresholdImageFilter: (");
402 str->appendf("inner: %f outer: %f", fInnerThreshold, fOuterThreshold);
403 str->append(")");
404}
405#endif
406