aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-10-19 12:54:28 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-19 20:07:44 +0000
commita4aa1332a4c6a70d6c54a3bbc6172d26fc2dce15 (patch)
treee6ab58d4ba8a3f636acb357ed75fe12cb31f6f53 /src
parent5f379a8b117f68b2087ab4b400b7d2f110f5600c (diff)
Remove color space xform from alpha threshold FP
This does math on the sampled color. In order to do that math in the destination color space, I split the behavior up - the threshold FP now operates on the input color, and we construct a series with a simple texture effect (possibly wrapped in a color xform), then the threshold. I also added a GM that verifies this behavior. All other GMs using this effect were operating on a layer source, which is always created in the destination color space. The new GM explicitly makes a DAG with an image source, so the alpha threshold filter needs to handle any color space mismatch. Bug: skia: Change-Id: I1ed08c99f4eed17f68176bf751677a3ae1614fe3 Reviewed-on: https://skia-review.googlesource.com/61942 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.cpp47
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.fp26
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.h21
-rw-r--r--src/effects/SkAlphaThresholdFilter.cpp27
4 files changed, 34 insertions, 87 deletions
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
index 5ef0221be7..871d6084d1 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
@@ -34,39 +34,25 @@ public:
const GrAlphaThresholdFragmentProcessor& _outer =
args.fFp.cast<GrAlphaThresholdFragmentProcessor>();
(void)_outer;
- auto colorXform = _outer.colorXform();
- (void)colorXform;
auto innerThreshold = _outer.innerThreshold();
(void)innerThreshold;
auto outerThreshold = _outer.outerThreshold();
(void)outerThreshold;
- fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get());
fInnerThresholdVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kHalf_GrSLType, kDefault_GrSLPrecision, "innerThreshold");
fOuterThresholdVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kHalf_GrSLType, kDefault_GrSLPrecision, "outerThreshold");
SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
- SkString sk_TransformedCoords2D_1 = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]);
fragBuilder->codeAppendf(
- "half4 _tmpVar1;half4 color = %stexture(%s, %s).%s%s;\nhalf4 mask_color = "
- "texture(%s, %s).%s;\nif (float(mask_color.w) < 0.5) {\n if (color.w > %s) {\n "
- " half scale = %s / color.w;\n color.xyz *= scale;\n color.w = "
- "%s;\n }\n} else if (color.w < %s) {\n half scale = float(%s) / max(0.001, "
- "float(color.w));\n color.xyz *= scale;\n color.w = %s;\n}\n%s = color;\n",
- fColorSpaceHelper.isValid() ? "(_tmpVar1 = " : "",
+ "half4 color = %s;\nhalf4 mask_color = texture(%s, %s).%s;\nif "
+ "(float(mask_color.w) < 0.5) {\n if (color.w > %s) {\n half scale = %s / "
+ "color.w;\n color.xyz *= scale;\n color.w = %s;\n }\n} else if "
+ "(color.w < %s) {\n half scale = float(%s) / max(0.001, float(color.w));\n "
+ "color.xyz *= scale;\n color.w = %s;\n}\n%s = color;\n",
+ args.fInputColor ? args.fInputColor : "half4(1)",
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
sk_TransformedCoords2D_0.c_str(),
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
- fColorSpaceHelper.isValid()
- ? SkStringPrintf(", half4(clamp((%s * half4(_tmpVar1.rgb, 1.0)).rgb, 0.0, "
- "_tmpVar1.a), _tmpVar1.a))",
- args.fUniformHandler->getUniformCStr(
- fColorSpaceHelper.gamutXformUniform()))
- .c_str()
- : "",
- fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(),
- sk_TransformedCoords2D_1.c_str(),
- fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(),
args.fUniformHandler->getUniformCStr(fOuterThresholdVar),
args.fUniformHandler->getUniformCStr(fOuterThresholdVar),
args.fUniformHandler->getUniformCStr(fOuterThresholdVar),
@@ -81,31 +67,22 @@ private:
const GrAlphaThresholdFragmentProcessor& _outer =
_proc.cast<GrAlphaThresholdFragmentProcessor>();
{
- if (fColorSpaceHelper.isValid()) {
- fColorSpaceHelper.setData(pdman, _outer.colorXform().get());
- }
pdman.set1f(fInnerThresholdVar, _outer.innerThreshold());
pdman.set1f(fOuterThresholdVar, _outer.outerThreshold());
}
}
- UniformHandle fImageVar;
UniformHandle fMaskVar;
UniformHandle fInnerThresholdVar;
UniformHandle fOuterThresholdVar;
- GrGLSLColorSpaceXformHelper fColorSpaceHelper;
};
GrGLSLFragmentProcessor* GrAlphaThresholdFragmentProcessor::onCreateGLSLInstance() const {
return new GrGLSLAlphaThresholdFragmentProcessor();
}
void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const {
- b->add32(GrColorSpaceXform::XformKey(fColorXform.get()));
-}
+ GrProcessorKeyBuilder* b) const {}
bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
const GrAlphaThresholdFragmentProcessor& that = other.cast<GrAlphaThresholdFragmentProcessor>();
(void)that;
- if (fImage != that.fImage) return false;
- if (fColorXform != that.fColorXform) return false;
if (fMask != that.fMask) return false;
if (fInnerThreshold != that.fInnerThreshold) return false;
if (fOuterThreshold != that.fOuterThreshold) return false;
@@ -114,16 +91,11 @@ bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& oth
GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(
const GrAlphaThresholdFragmentProcessor& src)
: INHERITED(kGrAlphaThresholdFragmentProcessor_ClassID, src.optimizationFlags())
- , fImage(src.fImage)
- , fColorXform(src.fColorXform)
, fMask(src.fMask)
, fInnerThreshold(src.fInnerThreshold)
, fOuterThreshold(src.fOuterThreshold)
- , fImageCoordTransform(src.fImageCoordTransform)
, fMaskCoordTransform(src.fMaskCoordTransform) {
- this->addTextureSampler(&fImage);
this->addTextureSampler(&fMask);
- this->addCoordTransform(&fImageCoordTransform);
this->addCoordTransform(&fMaskCoordTransform);
}
std::unique_ptr<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::clone() const {
@@ -133,7 +105,6 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAlphaThresholdFragmentProcessor);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate(
GrProcessorTestData* testData) {
- sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
// Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly.
float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
@@ -145,9 +116,7 @@ std::unique_ptr<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCrea
uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width);
uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height);
SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
- sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
- return GrAlphaThresholdFragmentProcessor::Make(std::move(bmpProxy), colorSpaceXform,
- std::move(maskProxy), innerThresh, outerThresh,
+ return GrAlphaThresholdFragmentProcessor::Make(std::move(maskProxy), innerThresh, outerThresh,
bounds);
}
#endif
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.fp b/src/effects/GrAlphaThresholdFragmentProcessor.fp
index 51e15b4f59..f4470cab42 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.fp
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.fp
@@ -1,5 +1,3 @@
-in uniform sampler2D image;
-in uniform colorSpaceXform colorXform;
in uniform sampler2D mask;
in uniform half innerThreshold;
in uniform half outerThreshold;
@@ -13,21 +11,15 @@ in uniform half outerThreshold;
}
@make {
- static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> image,
- sk_sp<GrColorSpaceXform> colorXform,
- sk_sp<GrTextureProxy> mask,
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> mask,
float innerThreshold,
float outerThreshold,
const SkIRect& bounds) {
return std::unique_ptr<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(
- image, colorXform, mask, innerThreshold, outerThreshold, bounds));
+ mask, innerThreshold, outerThreshold, bounds));
}
}
-@coordTransform(image) {
- SkMatrix::I()
-}
-
@coordTransform(mask) {
SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y()))
}
@@ -45,8 +37,8 @@ in uniform half outerThreshold;
}
void main() {
- half4 color = texture(image, sk_TransformedCoords2D[0], colorXform);
- half4 mask_color = texture(mask, sk_TransformedCoords2D[1]);
+ half4 color = sk_InColor;
+ half4 mask_color = texture(mask, sk_TransformedCoords2D[0]);
if (mask_color.a < 0.5) {
if (color.a > outerThreshold) {
half scale = outerThreshold / color.a;
@@ -62,7 +54,6 @@ void main() {
}
@test(testData) {
- sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
// Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly.
float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
@@ -74,11 +65,6 @@ void main() {
uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width);
uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height);
SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
- sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
- return GrAlphaThresholdFragmentProcessor::Make(
- std::move(bmpProxy),
- colorSpaceXform,
- std::move(maskProxy),
- innerThresh, outerThresh,
- bounds);
+ return GrAlphaThresholdFragmentProcessor::Make(std::move(maskProxy), innerThresh, outerThresh,
+ bounds);
}
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.h b/src/effects/GrAlphaThresholdFragmentProcessor.h
index 0d8a8e68ad..c376bb1a80 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.h
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.h
@@ -18,55 +18,40 @@
class GrAlphaThresholdFragmentProcessor : public GrFragmentProcessor {
public:
inline OptimizationFlags optFlags(float outerThreshold);
- sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }
float innerThreshold() const { return fInnerThreshold; }
float outerThreshold() const { return fOuterThreshold; }
- static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> image,
- sk_sp<GrColorSpaceXform>
- colorXform,
- sk_sp<GrTextureProxy>
- mask,
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> mask,
float innerThreshold,
float outerThreshold,
const SkIRect& bounds) {
return std::unique_ptr<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(
- image, colorXform, mask, innerThreshold, outerThreshold, bounds));
+ mask, innerThreshold, outerThreshold, bounds));
}
GrAlphaThresholdFragmentProcessor(const GrAlphaThresholdFragmentProcessor& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "AlphaThresholdFragmentProcessor"; }
private:
- GrAlphaThresholdFragmentProcessor(sk_sp<GrTextureProxy> image,
- sk_sp<GrColorSpaceXform> colorXform,
- sk_sp<GrTextureProxy> mask, float innerThreshold,
+ GrAlphaThresholdFragmentProcessor(sk_sp<GrTextureProxy> mask, float innerThreshold,
float outerThreshold, const SkIRect& bounds)
: INHERITED(kGrAlphaThresholdFragmentProcessor_ClassID, kNone_OptimizationFlags)
- , fImage(std::move(image))
- , fColorXform(colorXform)
, fMask(std::move(mask))
, fInnerThreshold(innerThreshold)
, fOuterThreshold(outerThreshold)
- , fImageCoordTransform(SkMatrix::I(), fImage.proxy())
, fMaskCoordTransform(
SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
fMask.proxy()) {
- this->addTextureSampler(&fImage);
this->addTextureSampler(&fMask);
- this->addCoordTransform(&fImageCoordTransform);
this->addCoordTransform(&fMaskCoordTransform);
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
- TextureSampler fImage;
- sk_sp<GrColorSpaceXform> fColorXform;
TextureSampler fMask;
float fInnerThreshold;
float fOuterThreshold;
- GrCoordTransform fImageCoordTransform;
GrCoordTransform fMaskCoordTransform;
typedef GrFragmentProcessor INHERITED;
};
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 634e6ae08b..f5e4a689e0 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -20,6 +20,7 @@
#include "GrFixedClip.h"
#include "GrRenderTargetContext.h"
#include "GrTextureProxy.h"
+#include "effects/GrSimpleTextureEffect.h"
#endif
class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter {
@@ -170,19 +171,25 @@ sk_sp<SkSpecialImage> SkAlphaThresholdFilterImpl::onFilterImage(SkSpecialImage*
}
const OutputProperties& outProps = ctx.outputProperties();
- sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(input->getColorSpace(),
- outProps.colorSpace());
-
- auto fp = GrAlphaThresholdFragmentProcessor::Make(std::move(inputProxy),
- std::move(colorSpaceXform),
- std::move(maskProxy),
- fInnerThreshold,
- fOuterThreshold,
- bounds);
- if (!fp) {
+ auto textureFP = GrSimpleTextureEffect::Make(std::move(inputProxy), SkMatrix::I());
+ textureFP = GrColorSpaceXformEffect::Make(std::move(textureFP), input->getColorSpace(),
+ outProps.colorSpace());
+ if (!textureFP) {
return nullptr;
}
+ auto thresholdFP = GrAlphaThresholdFragmentProcessor::Make(std::move(maskProxy),
+ fInnerThreshold,
+ fOuterThreshold,
+ bounds);
+ if (!thresholdFP) {
+ return nullptr;
+ }
+
+ std::unique_ptr<GrFragmentProcessor> fpSeries[] = { std::move(textureFP),
+ std::move(thresholdFP) };
+ auto fp = GrFragmentProcessor::RunInSeries(fpSeries, 2);
+
return DrawWithFP(context, std::move(fp), bounds, outProps);
}
#endif