in uniform sampler2D image; in uniform colorSpaceXform colorXform; in uniform sampler2D mask; in uniform half innerThreshold; in uniform half outerThreshold; @class { inline OptimizationFlags optFlags(float outerThreshold); } @constructorParams { const SkIRect& bounds } @make { static std::unique_ptr Make(sk_sp image, sk_sp colorXform, sk_sp mask, float innerThreshold, float outerThreshold, const SkIRect& bounds) { return std::unique_ptr(new GrAlphaThresholdFragmentProcessor( image, colorXform, mask, innerThreshold, outerThreshold, bounds)); } } @coordTransform(image) { SkMatrix::I() } @coordTransform(mask) { SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())) } @header { #include "GrColorSpaceXform.h" } @cpp { inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags( float outerThreshold) { if (outerThreshold >= 1.0) { return kPreservesOpaqueInput_OptimizationFlag | kCompatibleWithCoverageAsAlpha_OptimizationFlag; } else { return kCompatibleWithCoverageAsAlpha_OptimizationFlag; } } } void main() { half4 color = texture(image, sk_TransformedCoords2D[0], colorXform); half4 mask_color = texture(mask, sk_TransformedCoords2D[1]); if (mask_color.a < 0.5) { if (color.a > outerThreshold) { half scale = outerThreshold / color.a; color.rgb *= scale; color.a = outerThreshold; } } else if (color.a < innerThreshold) { half scale = innerThreshold / max(0.001, color.a); color.rgb *= scale; color.a = innerThreshold; } sk_OutColor = color; } @test(testData) { sk_sp bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx); sk_sp 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 colorSpaceXform = GrTest::TestColorXform(testData->fRandom); return GrAlphaThresholdFragmentProcessor::Make( std::move(bmpProxy), colorSpaceXform, std::move(maskProxy), innerThresh, outerThresh, bounds); }