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:
GLConstColorProcessor()17 GLConstColorProcessor() : fPrevColor(GrColor_ILLEGAL) {}
18
emitCode(EmitArgs & args)19 void emitCode(EmitArgs& args) override {
20 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
21 const char* colorUni;
22 fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
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:
onSetData(const GrGLSLProgramDataManager & pdm,const GrProcessor & processor)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
onComputeInvariantOutput(GrInvariantOutput * inout) const73 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
onGetGLSLProcessorKey(const GrGLSLCaps &,GrProcessorKeyBuilder * b) const97 void GrConstColorProcessor::onGetGLSLProcessorKey(const GrGLSLCaps&,
98 GrProcessorKeyBuilder* b) const {
99 b->add32(fMode);
100 }
101
onCreateGLSLInstance() const102 GrGLSLFragmentProcessor* GrConstColorProcessor::onCreateGLSLInstance() const {
103 return new GLConstColorProcessor;
104 }
105
onIsEqual(const GrFragmentProcessor & other) const106 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
TestCreate(GrProcessorTestData * d)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 }
138