| 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..5f286946348c7ba2e771833722b775ff78692a09
|
| --- /dev/null
|
| +++ b/src/gpu/effects/GrConstColorProcessor.cpp
|
| @@ -0,0 +1,133 @@
|
| +/*
|
| + * 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 (kModulateRGBA_InputMode == fMode) {
|
| + 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);
|
| +}
|
| +
|
| +bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const {
|
| + const GrConstColorProcessor& that = other.cast<GrConstColorProcessor>();
|
| + return fMode == that.fMode && fColor == that.fColor;
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor);
|
| +
|
| +GrFragmentProcessor* GrConstColorProcessor::TestCreate(SkRandom* random,
|
| + GrContext*,
|
| + const GrDrawTargetCaps&,
|
| + GrTexture*[]) {
|
| + GrColor color;
|
| + int colorPicker = random->nextULessThan(3);
|
| + switch (colorPicker) {
|
| + case 0: {
|
| + uint32_t a = random->nextULessThan(0x100);
|
| + uint32_t r = random->nextULessThan(a+1);
|
| + uint32_t g = random->nextULessThan(a+1);
|
| + uint32_t b = random->nextULessThan(a+1);
|
| + color = GrColorPackRGBA(r, g, b, a);
|
| + break;
|
| + }
|
| + case 1:
|
| + color = 0;
|
| + break;
|
| + case 2:
|
| + color = random->nextULessThan(0x100);
|
| + color = color | (color << 8) | (color << 16) | (color << 24);
|
| + break;
|
| + }
|
| + InputMode mode = static_cast<InputMode>(random->nextULessThan(kInputModeCnt));
|
| + return GrConstColorProcessor::Create(color, mode);
|
| +}
|
|
|