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