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/GrGLSLProgramDataManager.h"
12 #include "glsl/GrGLSLUniformHandler.h"
13
14 class GLConstColorProcessor : public GrGLSLFragmentProcessor {
15 public:
GLConstColorProcessor()16 GLConstColorProcessor() : fPrevColor(GrColor4f::kIllegalConstructor) {}
17
emitCode(EmitArgs & args)18 void emitCode(EmitArgs& args) override {
19 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
20 const char* colorUni;
21 fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
22 kVec4f_GrSLType, kMedium_GrSLPrecision,
23 "constantColor",
24 &colorUni);
25 GrConstColorProcessor::InputMode mode = args.fFp.cast<GrConstColorProcessor>().inputMode();
26 if (!args.fInputColor) {
27 mode = GrConstColorProcessor::kIgnore_InputMode;
28 }
29 switch (mode) {
30 case GrConstColorProcessor::kIgnore_InputMode:
31 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUni);
32 break;
33 case GrConstColorProcessor::kModulateRGBA_InputMode:
34 fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, args.fInputColor,
35 colorUni);
36 break;
37 case GrConstColorProcessor::kModulateA_InputMode:
38 fragBuilder->codeAppendf("%s = %s.a * %s;", args.fOutputColor, args.fInputColor,
39 colorUni);
40 break;
41 }
42 }
43
44 protected:
onSetData(const GrGLSLProgramDataManager & pdm,const GrProcessor & processor)45 void onSetData(const GrGLSLProgramDataManager& pdm, const GrProcessor& processor) override {
46 GrColor4f color = processor.cast<GrConstColorProcessor>().color();
47 // We use the "illegal" color value as an uninit sentinel. With GrColor4f, the "illegal"
48 // color is *really* illegal (not just unpremultiplied), so this check is simple.
49 if (fPrevColor != color) {
50 pdm.set4fv(fColorUniform, 1, color.fRGBA);
51 fPrevColor = color;
52 }
53 }
54
55 private:
56 GrGLSLProgramDataManager::UniformHandle fColorUniform;
57 GrColor4f fPrevColor;
58
59 typedef GrGLSLFragmentProcessor INHERITED;
60 };
61
62 ///////////////////////////////////////////////////////////////////////////////
63
constantOutputForConstantInput(GrColor4f input) const64 GrColor4f GrConstColorProcessor::constantOutputForConstantInput(GrColor4f input) const {
65 switch (fMode) {
66 case kIgnore_InputMode:
67 return fColor;
68 case kModulateA_InputMode:
69 return fColor.mulByScalar(input.fRGBA[3]);
70 case kModulateRGBA_InputMode:
71 return fColor.modulate(input);
72 }
73 SkFAIL("Unexpected mode");
74 return GrColor4f::TransparentBlack();
75 }
76
onGetGLSLProcessorKey(const GrShaderCaps &,GrProcessorKeyBuilder * b) const77 void GrConstColorProcessor::onGetGLSLProcessorKey(const GrShaderCaps&,
78 GrProcessorKeyBuilder* b) const {
79 b->add32(fMode);
80 }
81
onCreateGLSLInstance() const82 GrGLSLFragmentProcessor* GrConstColorProcessor::onCreateGLSLInstance() const {
83 return new GLConstColorProcessor;
84 }
85
onIsEqual(const GrFragmentProcessor & other) const86 bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const {
87 const GrConstColorProcessor& that = other.cast<GrConstColorProcessor>();
88 return fMode == that.fMode && fColor == that.fColor;
89 }
90
91 ///////////////////////////////////////////////////////////////////////////////
92
93 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor);
94
95 #if GR_TEST_UTILS
TestCreate(GrProcessorTestData * d)96 sk_sp<GrFragmentProcessor> GrConstColorProcessor::TestCreate(GrProcessorTestData* d) {
97 GrColor4f color;
98 int colorPicker = d->fRandom->nextULessThan(3);
99 switch (colorPicker) {
100 case 0: {
101 uint32_t a = d->fRandom->nextULessThan(0x100);
102 uint32_t r = d->fRandom->nextULessThan(a+1);
103 uint32_t g = d->fRandom->nextULessThan(a+1);
104 uint32_t b = d->fRandom->nextULessThan(a+1);
105 color = GrColor4f::FromGrColor(GrColorPackRGBA(r, g, b, a));
106 break;
107 }
108 case 1:
109 color = GrColor4f::TransparentBlack();
110 break;
111 case 2:
112 uint32_t c = d->fRandom->nextULessThan(0x100);
113 color = GrColor4f::FromGrColor(c | (c << 8) | (c << 16) | (c << 24));
114 break;
115 }
116 InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
117 return GrConstColorProcessor::Make(color, mode);
118 }
119 #endif
120