aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/GrAlphaThresholdFragmentProcessor.fp
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects/GrAlphaThresholdFragmentProcessor.fp')
-rw-r--r--src/effects/GrAlphaThresholdFragmentProcessor.fp110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.fp b/src/effects/GrAlphaThresholdFragmentProcessor.fp
new file mode 100644
index 0000000000..a7010a712a
--- /dev/null
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.fp
@@ -0,0 +1,110 @@
+in uniform sampler2D image;
+in uniform colorSpaceXform colorXform;
+in uniform sampler2D mask;
+in uniform float innerThreshold;
+in uniform float outerThreshold;
+
+@class {
+ inline OptimizationFlags optFlags(float outerThreshold);
+}
+
+@constructorParams {
+ const SkIRect& bounds
+}
+
+@make {
+ static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> image,
+ sk_sp<GrColorSpaceXform> colorXform,
+ sk_sp<GrTextureProxy> mask,
+ float innerThreshold,
+ float outerThreshold,
+ const SkIRect& bounds) {
+ return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(image,
+ colorXform,
+ mask,
+ innerThreshold,
+ outerThreshold,
+ bounds));
+ }
+}
+
+@fields {
+ GrCoordTransform fImageCoordTransform;
+ GrCoordTransform fMaskCoordTransform;
+}
+
+@initializers {
+ fImageCoordTransform(SkMatrix::I(), image.get()),
+ fMaskCoordTransform(SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
+ mask.get())
+}
+
+@constructorCode {
+ this->addCoordTransform(&fImageCoordTransform);
+ this->addCoordTransform(&fMaskCoordTransform);
+}
+
+@header {
+ #include "SkTypes.h"
+ #if SK_SUPPORT_GPU
+}
+
+@headerEnd {
+ #endif
+}
+
+@cpp {
+ #if SK_SUPPORT_GPU
+ inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags(
+ float outerThreshold) {
+ if (outerThreshold >= 1.0) {
+ return kPreservesOpaqueInput_OptimizationFlag |
+ kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ } else {
+ return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ }
+ }
+}
+
+@cppEnd {
+ #endif
+}
+
+void main() {
+ vec4 color = texture(image, sk_TransformedCoords2D[0], colorXform);
+ vec4 mask_color = texture(mask, sk_TransformedCoords2D[1]);
+ if (mask_color.a < 0.5) {
+ if (color.a > outerThreshold) {
+ float scale = outerThreshold / color.a;
+ color.rgb *= scale;
+ color.a = outerThreshold;
+ }
+ } else if (color.a < innerThreshold) {
+ float scale = innerThreshold / max(0.001, color.a);
+ color.rgb *= scale;
+ color.a = innerThreshold;
+ }
+ sk_OutColor = color;
+}
+
+@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;
+ float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
+ const int kMaxWidth = 1000;
+ const int kMaxHeight = 1000;
+ uint32_t width = testData->fRandom->nextULessThan(kMaxWidth);
+ uint32_t height = testData->fRandom->nextULessThan(kMaxHeight);
+ 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);
+} \ No newline at end of file