1 /* 2 * Copyright 2018 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 in uniform sampler2D mask; 9 in uniform half innerThreshold; 10 in uniform half outerThreshold; 11 12 @class { 13 inline OptimizationFlags optFlags(float outerThreshold); 14 } 15 16 @constructorParams { 17 const SkIRect& bounds 18 } 19 20 @make { 21 static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> mask, 22 float innerThreshold, 23 float outerThreshold, 24 const SkIRect& bounds) { 25 return std::unique_ptr<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor( 26 mask, innerThreshold, outerThreshold, bounds)); 27 } 28 } 29 30 @coordTransform(mask) { 31 SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())) 32 } 33 34 @cpp { 35 inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags( 36 float outerThreshold) { 37 if (outerThreshold >= 1.0) { 38 return kPreservesOpaqueInput_OptimizationFlag | 39 kCompatibleWithCoverageAsAlpha_OptimizationFlag; 40 } else { 41 return kCompatibleWithCoverageAsAlpha_OptimizationFlag; 42 } 43 } 44 } 45 46 void main() { 47 half4 color = sk_InColor; 48 half4 mask_color = texture(mask, sk_TransformedCoords2D[0]); 49 if (mask_color.a < 0.5) { 50 if (color.a > outerThreshold) { 51 half scale = outerThreshold / color.a; 52 color.rgb *= scale; 53 color.a = outerThreshold; 54 } 55 } else if (color.a < innerThreshold) { 56 half scale = innerThreshold / max(0.001, color.a); 57 color.rgb *= scale; 58 color.a = innerThreshold; 59 } 60 sk_OutColor = color; 61 } 62 63 @test(testData) { 64 sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx); 65 // Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly. 66 float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f; 67 float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f; 68 const int kMaxWidth = 1000; 69 const int kMaxHeight = 1000; 70 uint32_t width = testData->fRandom->nextULessThan(kMaxWidth); 71 uint32_t height = testData->fRandom->nextULessThan(kMaxHeight); 72 uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width); 73 uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height); 74 SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height); 75 return GrAlphaThresholdFragmentProcessor::Make(std::move(maskProxy), innerThresh, outerThresh, 76 bounds); 77 } 78