blob: a7010a712aadce2fa4058559ea9327804284a1f6 [file] [log] [blame]
Ethan Nicholas9fb036f2017-07-05 16:19:09 -04001in uniform sampler2D image;
2in uniform colorSpaceXform colorXform;
3in uniform sampler2D mask;
4in uniform float innerThreshold;
5in uniform float outerThreshold;
6
7@class {
8 inline OptimizationFlags optFlags(float outerThreshold);
9}
10
11@constructorParams {
12 const SkIRect& bounds
13}
14
15@make {
16 static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> image,
17 sk_sp<GrColorSpaceXform> colorXform,
18 sk_sp<GrTextureProxy> mask,
19 float innerThreshold,
20 float outerThreshold,
21 const SkIRect& bounds) {
22 return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(image,
23 colorXform,
24 mask,
25 innerThreshold,
26 outerThreshold,
27 bounds));
28 }
29}
30
31@fields {
32 GrCoordTransform fImageCoordTransform;
33 GrCoordTransform fMaskCoordTransform;
34}
35
36@initializers {
37 fImageCoordTransform(SkMatrix::I(), image.get()),
38 fMaskCoordTransform(SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
39 mask.get())
40}
41
42@constructorCode {
43 this->addCoordTransform(&fImageCoordTransform);
44 this->addCoordTransform(&fMaskCoordTransform);
45}
46
47@header {
48 #include "SkTypes.h"
49 #if SK_SUPPORT_GPU
50}
51
52@headerEnd {
53 #endif
54}
55
56@cpp {
57 #if SK_SUPPORT_GPU
58 inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags(
59 float outerThreshold) {
60 if (outerThreshold >= 1.0) {
61 return kPreservesOpaqueInput_OptimizationFlag |
62 kCompatibleWithCoverageAsAlpha_OptimizationFlag;
63 } else {
64 return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
65 }
66 }
67}
68
69@cppEnd {
70 #endif
71}
72
73void main() {
74 vec4 color = texture(image, sk_TransformedCoords2D[0], colorXform);
75 vec4 mask_color = texture(mask, sk_TransformedCoords2D[1]);
76 if (mask_color.a < 0.5) {
77 if (color.a > outerThreshold) {
78 float scale = outerThreshold / color.a;
79 color.rgb *= scale;
80 color.a = outerThreshold;
81 }
82 } else if (color.a < innerThreshold) {
83 float scale = innerThreshold / max(0.001, color.a);
84 color.rgb *= scale;
85 color.a = innerThreshold;
86 }
87 sk_OutColor = color;
88}
89
90@test(testData) {
91 sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
92 sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
93 // Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly.
94 float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
95 float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
96 const int kMaxWidth = 1000;
97 const int kMaxHeight = 1000;
98 uint32_t width = testData->fRandom->nextULessThan(kMaxWidth);
99 uint32_t height = testData->fRandom->nextULessThan(kMaxHeight);
100 uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width);
101 uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height);
102 SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
103 sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
104 return GrAlphaThresholdFragmentProcessor::Make(
105 std::move(bmpProxy),
106 colorSpaceXform,
107 std::move(maskProxy),
108 innerThresh, outerThresh,
109 bounds);
110}