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
8enum class InputMode {
9    kIgnore,
10    kModulateRGBA,
11    kModulateA,
12
13    kLast = kModulateA
14};
15
16layout(ctype=SkPMColor4f, tracked) in uniform half4 color;
17layout(key) in InputMode mode;
18
19@optimizationFlags {
20    OptFlags(color, mode)
21}
22
23void main() {
24    @switch (mode) {
25        case InputMode::kIgnore:
26            sk_OutColor = color;
27            break;
28        case InputMode::kModulateRGBA:
29            sk_OutColor = sk_InColor * color;
30            break;
31        case InputMode::kModulateA:
32            sk_OutColor = sk_InColor.a * color;
33            break;
34    }
35}
36
37@class {
38    static const int kInputModeCnt = (int) InputMode::kLast + 1;
39
40    static OptimizationFlags OptFlags(const SkPMColor4f& color, InputMode mode) {
41        OptimizationFlags flags = kConstantOutputForConstantInput_OptimizationFlag;
42        if (mode != InputMode::kIgnore) {
43            flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
44        }
45        if (color.isOpaque()) {
46            flags |= kPreservesOpaqueInput_OptimizationFlag;
47        }
48        return flags;
49    }
50
51    SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
52        switch (fMode) {
53            case InputMode::kIgnore:
54                return fColor;
55            case InputMode::kModulateA:
56                return fColor * input.fA;
57            case InputMode::kModulateRGBA:
58                return fColor * input;
59        }
60        SK_ABORT("Unexpected mode");
61        return SK_PMColor4fTRANSPARENT;
62    }
63}
64
65@test(d) {
66    SkPMColor4f color;
67    int colorPicker = d->fRandom->nextULessThan(3);
68    switch (colorPicker) {
69        case 0: {
70            uint32_t a = d->fRandom->nextULessThan(0x100);
71            uint32_t r = d->fRandom->nextULessThan(a+1);
72            uint32_t g = d->fRandom->nextULessThan(a+1);
73            uint32_t b = d->fRandom->nextULessThan(a+1);
74            color = SkPMColor4f::FromBytes_RGBA(GrColorPackRGBA(r, g, b, a));
75            break;
76        }
77        case 1:
78            color = SK_PMColor4fTRANSPARENT;
79            break;
80        case 2:
81            uint32_t c = d->fRandom->nextULessThan(0x100);
82            color = SkPMColor4f::FromBytes_RGBA(c | (c << 8) | (c << 16) | (c << 24));
83            break;
84    }
85    InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
86    return GrConstColorProcessor::Make(color, mode);
87}
88