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 |