OLD | NEW |
| (Empty) |
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 "gl/GrGLProcessor.h" | |
10 #include "gl/GrGLSL.h" | |
11 #include "gl/builders/GrGLProgramBuilder.h" | |
12 | |
13 class GLConstColorProcessor : public GrGLFragmentProcessor { | |
14 public: | |
15 GLConstColorProcessor() : fPrevColor(GrColor_ILLEGAL) {} | |
16 | |
17 void emitCode(GrGLFPBuilder* builder, | |
18 const GrFragmentProcessor& fp, | |
19 const char* outputColor, | |
20 const char* inputColor, | |
21 const TransformedCoordsArray& coords, | |
22 const TextureSamplerArray& samplers) override { | |
23 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | |
24 const char* colorUni; | |
25 fColorUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, | |
26 kVec4f_GrSLType, kMedium_GrSLPrecisi
on, "constantColor", | |
27 &colorUni); | |
28 switch (fp.cast<GrConstColorProcessor>().inputMode()) { | |
29 case GrConstColorProcessor::kIgnore_InputMode: | |
30 fsBuilder->codeAppendf("%s = %s;", outputColor, colorUni); | |
31 break; | |
32 case GrConstColorProcessor::kModulateRGBA_InputMode: | |
33 fsBuilder->codeAppendf("%s = %s * %s;", outputColor, inputColor,
colorUni); | |
34 break; | |
35 case GrConstColorProcessor::kModulateA_InputMode: | |
36 fsBuilder->codeAppendf("%s = %s.a * %s;", outputColor, inputColo
r, colorUni); | |
37 break; | |
38 } | |
39 } | |
40 | |
41 void setData(const GrGLProgramDataManager& pdm, const GrProcessor& processor
) override { | |
42 GrColor color = processor.cast<GrConstColorProcessor>().color(); | |
43 // We use the "illegal" color value as an uninit sentinel. However, ut i
sn't inherently | |
44 // illegal to use this processor with unpremul colors. So we correctly h
andle the case | |
45 // when the "illegal" color is used but we will always upload it. | |
46 if (GrColor_ILLEGAL == color || fPrevColor != color) { | |
47 static const GrGLfloat scale = 1.f / 255.f; | |
48 GrGLfloat floatColor[4] = { | |
49 GrColorUnpackR(color) * scale, | |
50 GrColorUnpackG(color) * scale, | |
51 GrColorUnpackB(color) * scale, | |
52 GrColorUnpackA(color) * scale, | |
53 }; | |
54 pdm.set4fv(fColorUniform, 1, floatColor); | |
55 fPrevColor = color; | |
56 } | |
57 } | |
58 | |
59 private: | |
60 GrGLProgramDataManager::UniformHandle fColorUniform; | |
61 GrColor fPrevColor; | |
62 | |
63 typedef GrGLFragmentProcessor INHERITED; | |
64 }; | |
65 | |
66 /////////////////////////////////////////////////////////////////////////////// | |
67 | |
68 void GrConstColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) c
onst { | |
69 if (kIgnore_InputMode == fMode) { | |
70 inout->setToOther(kRGBA_GrColorComponentFlags, fColor, GrInvariantOutput
::kWill_ReadInput); | |
71 } else { | |
72 GrColor r = GrColorUnpackR(fColor); | |
73 bool colorIsSingleChannel = r == GrColorUnpackG(fColor) && r == GrColorU
npackB(fColor) && | |
74 r == GrColorUnpackA(fColor); | |
75 if (kModulateRGBA_InputMode == fMode) { | |
76 if (colorIsSingleChannel) { | |
77 inout->mulByKnownSingleComponent(r); | |
78 } else { | |
79 inout->mulByKnownFourComponents(fColor); | |
80 } | |
81 } else { | |
82 if (colorIsSingleChannel) { | |
83 inout->mulAlphaByKnownSingleComponent(r); | |
84 } else { | |
85 inout->mulAlphaByKnownFourComponents(fColor); | |
86 } | |
87 } | |
88 } | |
89 } | |
90 | |
91 void GrConstColorProcessor::getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBui
lder* b) const { | |
92 b->add32(fMode); | |
93 } | |
94 | |
95 GrGLFragmentProcessor* GrConstColorProcessor::createGLInstance() const { | |
96 return SkNEW(GLConstColorProcessor); | |
97 } | |
98 | |
99 bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const { | |
100 const GrConstColorProcessor& that = other.cast<GrConstColorProcessor>(); | |
101 return fMode == that.fMode && fColor == that.fColor; | |
102 } | |
103 | |
104 /////////////////////////////////////////////////////////////////////////////// | |
105 | |
106 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor); | |
107 | |
108 GrFragmentProcessor* GrConstColorProcessor::TestCreate(SkRandom* random, | |
109 GrContext*, | |
110 const GrDrawTargetCaps&, | |
111 GrTexture*[]) { | |
112 GrColor color; | |
113 int colorPicker = random->nextULessThan(3); | |
114 switch (colorPicker) { | |
115 case 0: { | |
116 uint32_t a = random->nextULessThan(0x100); | |
117 uint32_t r = random->nextULessThan(a+1); | |
118 uint32_t g = random->nextULessThan(a+1); | |
119 uint32_t b = random->nextULessThan(a+1); | |
120 color = GrColorPackRGBA(r, g, b, a); | |
121 break; | |
122 } | |
123 case 1: | |
124 color = 0; | |
125 break; | |
126 case 2: | |
127 color = random->nextULessThan(0x100); | |
128 color = color | (color << 8) | (color << 16) | (color << 24); | |
129 break; | |
130 } | |
131 InputMode mode = static_cast<InputMode>(random->nextULessThan(kInputModeCnt)
); | |
132 return GrConstColorProcessor::Create(color, mode); | |
133 } | |
OLD | NEW |