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 8in uniform sampler2D mask; 9in uniform half innerThreshold; 10in 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 46void 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