cf567aac5c4f08d91b07131e297a61913a4d3705
[platform/upstream/libSkiaSharp.git] / src / gpu / effects / GrConstColorProcessor.cpp
1 /*
2  * Copyright 2015 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 #include "effects/GrConstColorProcessor.h"
9 #include "glsl/GrGLSLFragmentProcessor.h"
10 #include "glsl/GrGLSLFragmentShaderBuilder.h"
11 #include "glsl/GrGLSLProgramBuilder.h"
12 #include "glsl/GrGLSLProgramDataManager.h"
13
14 class GLConstColorProcessor : public GrGLSLFragmentProcessor {
15 public:
16     GLConstColorProcessor() : fPrevColor(GrColor_ILLEGAL) {}
17
18     void emitCode(EmitArgs& args) override {
19         GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
20         const char* colorUni;
21         fColorUniform = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
22                                             kVec4f_GrSLType, kMedium_GrSLPrecision, "constantColor",
23                                             &colorUni);
24         GrConstColorProcessor::InputMode mode = args.fFp.cast<GrConstColorProcessor>().inputMode();
25         if (!args.fInputColor) {
26             mode = GrConstColorProcessor::kIgnore_InputMode;
27         }
28         switch (mode) {
29             case GrConstColorProcessor::kIgnore_InputMode:
30                 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUni);
31                 break;
32             case GrConstColorProcessor::kModulateRGBA_InputMode:
33                 fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, args.fInputColor,
34                                        colorUni);
35                 break;
36             case GrConstColorProcessor::kModulateA_InputMode:
37                 fragBuilder->codeAppendf("%s = %s.a * %s;", args.fOutputColor, args.fInputColor,
38                                        colorUni);
39                 break;
40         }
41     }
42
43 protected:
44     void onSetData(const GrGLSLProgramDataManager& pdm, const GrProcessor& processor) override {
45         GrColor color = processor.cast<GrConstColorProcessor>().color();
46         // We use the "illegal" color value as an uninit sentinel. However, ut isn't inherently
47         // illegal to use this processor with unpremul colors. So we correctly handle the case
48         // when the "illegal" color is used but we will always upload it.
49         if (GrColor_ILLEGAL == color || fPrevColor != color) {
50             static const float scale = 1.f / 255.f;
51             float floatColor[4] = {
52                 GrColorUnpackR(color) * scale,
53                 GrColorUnpackG(color) * scale,
54                 GrColorUnpackB(color) * scale,
55                 GrColorUnpackA(color) * scale,
56             };
57             pdm.set4fv(fColorUniform, 1, floatColor);
58             fPrevColor = color;
59         }
60     }
61
62 private:
63     GrGLSLProgramDataManager::UniformHandle fColorUniform;
64     GrColor                               fPrevColor;
65
66     typedef GrGLSLFragmentProcessor INHERITED;
67 };
68
69 ///////////////////////////////////////////////////////////////////////////////
70
71 void GrConstColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const {
72     if (kIgnore_InputMode == fMode) {
73         inout->setToOther(kRGBA_GrColorComponentFlags, fColor,
74                           GrInvariantOutput::kWillNot_ReadInput);
75     } else {
76         GrColor r = GrColorUnpackR(fColor);
77         bool colorIsSingleChannel = r == GrColorUnpackG(fColor) && r == GrColorUnpackB(fColor) &&
78                                     r == GrColorUnpackA(fColor);
79         if (kModulateRGBA_InputMode == fMode) {
80             if (colorIsSingleChannel) {
81                 inout->mulByKnownSingleComponent(r);
82             } else {
83                 inout->mulByKnownFourComponents(fColor);
84             }
85         } else {
86             if (colorIsSingleChannel) {
87                 inout->mulAlphaByKnownSingleComponent(r);
88             } else {
89                 inout->mulAlphaByKnownFourComponents(fColor);
90             }
91         }
92     }
93 }
94
95 void GrConstColorProcessor::onGetGLSLProcessorKey(const GrGLSLCaps&,
96                                                   GrProcessorKeyBuilder* b) const {
97     b->add32(fMode);
98 }
99
100 GrGLSLFragmentProcessor* GrConstColorProcessor::onCreateGLSLInstance() const  {
101     return new GLConstColorProcessor;
102 }
103
104 bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const {
105     const GrConstColorProcessor& that = other.cast<GrConstColorProcessor>();
106     return fMode == that.fMode && fColor == that.fColor;
107 }
108
109 ///////////////////////////////////////////////////////////////////////////////
110
111 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor);
112
113 const GrFragmentProcessor* GrConstColorProcessor::TestCreate(GrProcessorTestData* d) {
114     GrColor color;
115     int colorPicker = d->fRandom->nextULessThan(3);
116     switch (colorPicker) {
117         case 0: {
118             uint32_t a = d->fRandom->nextULessThan(0x100);
119             uint32_t r = d->fRandom->nextULessThan(a+1);
120             uint32_t g = d->fRandom->nextULessThan(a+1);
121             uint32_t b = d->fRandom->nextULessThan(a+1);
122             color = GrColorPackRGBA(r, g, b, a);
123             break;
124         }
125         case 1:
126             color = 0;
127             break;
128         case 2:
129             color = d->fRandom->nextULessThan(0x100);
130             color = color | (color << 8) | (color << 16) | (color << 24);
131             break;
132     }
133     InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
134     return GrConstColorProcessor::Create(color, mode);
135 }