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