Chromium Code Reviews| Index: src/gpu/effects/GrConstColorProcessor.cpp |
| diff --git a/src/gpu/effects/GrConstColorProcessor.cpp b/src/gpu/effects/GrConstColorProcessor.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..dbc145a94d4026760fa3d05088ca407ec575332f |
| --- /dev/null |
| +++ b/src/gpu/effects/GrConstColorProcessor.cpp |
| @@ -0,0 +1,129 @@ |
| +/* |
| + * Copyright 2015 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "effects/GrConstColorProcessor.h" |
| +#include "gl/GrGLProcessor.h" |
| +#include "gl/GrGLSL.h" |
| +#include "gl/builders/GrGLProgramBuilder.h" |
| + |
| +class GLConstColorProcessor : public GrGLFragmentProcessor { |
| +public: |
| + GLConstColorProcessor() : fPrevColor(GrColor_ILLEGAL) {} |
| + |
| + void emitCode(GrGLFPBuilder* builder, |
| + const GrFragmentProcessor& fp, |
| + const char* outputColor, |
| + const char* inputColor, |
| + const TransformedCoordsArray& coords, |
| + const TextureSamplerArray& samplers) override { |
| + GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
| + const char* colorUni; |
| + fColorUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| + kVec4f_GrSLType, kMedium_GrSLPrecision, "constantColor", |
| + &colorUni); |
| + switch (fp.cast<GrConstColorProcessor>().inputMode()) { |
| + case GrConstColorProcessor::kIgnore_InputMode: |
| + fsBuilder->codeAppendf("%s = %s;", outputColor, colorUni); |
| + break; |
| + case GrConstColorProcessor::kModulateRGBA_InputMode: |
| + fsBuilder->codeAppendf("%s = %s * %s;", outputColor, inputColor, colorUni); |
| + break; |
| + case GrConstColorProcessor::kModulateA_InputMode: |
| + fsBuilder->codeAppendf("%s = %s.a * %s;", outputColor, inputColor, colorUni); |
| + break; |
| + } |
| + } |
| + |
| + void setData(const GrGLProgramDataManager& pdm, const GrProcessor& processor) override { |
| + GrColor color = processor.cast<GrConstColorProcessor>().color(); |
| + // We use the "illegal" color value as an uninit sentinel. However, ut isn't inherently |
| + // illegal to use this processor with unpremul colors. So we correctly handle the case |
| + // when the "illegal" color is used but we will always upload it. |
| + if (GrColor_ILLEGAL == color || fPrevColor != color) { |
| + static const GrGLfloat scale = 1.f / 255.f; |
| + GrGLfloat floatColor[4] = { |
| + GrColorUnpackR(color) * scale, |
| + GrColorUnpackG(color) * scale, |
| + GrColorUnpackB(color) * scale, |
| + GrColorUnpackA(color) * scale, |
| + }; |
| + pdm.set4fv(fColorUniform, 1, floatColor); |
| + fPrevColor = color; |
| + } |
| + } |
| + |
| +private: |
| + GrGLProgramDataManager::UniformHandle fColorUniform; |
| + GrColor fPrevColor; |
| + |
| + typedef GrGLFragmentProcessor INHERITED; |
| +}; |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| +void GrConstColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const { |
| + if (kIgnore_InputMode == fMode) { |
| + inout->setToOther(kRGBA_GrColorComponentFlags, fColor, GrInvariantOutput::kWill_ReadInput); |
| + } else { |
| + GrColor r = GrColorUnpackR(fColor); |
| + bool colorIsSingleChannel = r == GrColorUnpackG(fColor) && r == GrColorUnpackB(fColor) && |
| + r == GrColorUnpackA(fColor); |
| + if (kIgnore_InputMode == fMode) { |
|
egdaniel
2015/03/31 21:02:54
did you mean kRGB_InputMode?
bsalomon
2015/04/01 19:54:27
Done.
|
| + if (colorIsSingleChannel) { |
| + inout->mulByKnownSingleComponent(r); |
| + } else { |
| + inout->mulByKnownFourComponents(fColor); |
| + } |
| + } else { |
| + if (colorIsSingleChannel) { |
| + inout->mulAlphaByKnownSingleComponent(r); |
| + } else { |
| + inout->mulAlphaByKnownFourComponents(fColor); |
| + } |
| + } |
| + } |
| +} |
| + |
| +void GrConstColorProcessor::getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBuilder* b) const { |
| + b->add32(fMode); |
| +} |
| + |
| +GrGLFragmentProcessor* GrConstColorProcessor::createGLInstance() const { |
| + return SkNEW(GLConstColorProcessor); |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor); |
| + |
| +GrFragmentProcessor* GrConstColorProcessor::TestCreate(SkRandom* random, |
| + GrContext*, |
| + const GrDrawTargetCaps&, |
| + GrTexture*[]) { |
| + GrColor color; |
| + int colorPicker = random->nextULessThan(5); |
| + switch (colorPicker) { |
| + case 0: |
| + color = random->nextU(); |
| + break; |
| + case 1: |
| + color = random->nextU() & 0x00ffffff; |
| + break; |
| + case 2: |
| + color = 0; |
| + break; |
| + case 3: |
| + color = random->nextULessThan(0x100); |
| + color = color | (color << 8) | (color << 16) | (color << 24); |
| + break; |
| + case 4: |
| + color = GrColor_ILLEGAL; |
| + break; |
| + } |
| + InputMode mode = static_cast<InputMode>(random->nextULessThan(kInputModeCnt)); |
| + return GrConstColorProcessor::Create(color, mode); |
| +} |