Chromium Code Reviews| Index: src/gpu/effects/GrColorProcessor.cpp |
| diff --git a/src/gpu/effects/GrColorProcessor.cpp b/src/gpu/effects/GrColorProcessor.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d0f896427ba5529215fcc853c2e55e8e874a1320 |
| --- /dev/null |
| +++ b/src/gpu/effects/GrColorProcessor.cpp |
| @@ -0,0 +1,109 @@ |
| +/* |
| + * 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/GrColorProcessor.h" |
| +#include "gl/GrGLProcessor.h" |
| +#include "gl/GrGLSL.h" |
| +#include "gl/builders/GrGLProgramBuilder.h" |
| + |
| +class GrGLColorProcessor : public GrGLFragmentProcessor { |
| +public: |
| + GrGLColorProcessor() : fPrevColor(GrColor_ILLEGAL) {} |
| + |
| + void emitCode(GrGLFPBuilder* builder, |
| + const GrFragmentProcessor& fp, |
| + const char* outputColor, |
| + const char* inputColor, |
| + const TransformedCoordsArray& coords, |
| + const TextureSamplerArray& samplers) SK_OVERRIDE { |
| + GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
| + const char* colorUni; |
| + fColorUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| + kVec4f_GrSLType, kMedium_GrSLPrecision, "constantColor", |
| + &colorUni); |
| + switch (fp.cast<GrColorProcessor>().inputMode()) { |
| + case GrColorProcessor::kIgnore_InputMode: |
| + fsBuilder->codeAppendf("%s = %s;", outputColor, colorUni); |
| + break; |
| + case GrColorProcessor::kModulateRGBA_InputMode: |
| + fsBuilder->codeAppendf("%s = %s * %s;", outputColor, inputColor, colorUni); |
| + break; |
| + case GrColorProcessor::kModulateA_InputMode: |
| + fsBuilder->codeAppendf("%s = %s.a * %s;", outputColor, inputColor, colorUni); |
| + break; |
| + } |
| + } |
| + |
| + void setData(const GrGLProgramDataManager& pdm, const GrProcessor& processor) SK_OVERRIDE { |
| + GrColor color = processor.cast<GrColorProcessor>().color(); |
| + // We use the value 0 as an uninit sentinel, so we will always upload that value even if it |
|
egdaniel
2015/03/04 20:22:34
update comment to say grcolor_illegal
bsalomon
2015/03/31 19:33:42
Done.
|
| + // were to be used repeatedly. |
| + 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 GrColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const { |
| + if (kIgnore_InputMode == fMode) { |
| + inout->setToOther(kRGBA_GrColorComponentFlags, fColor, GrInvariantOutput::kWill_ReadInput); |
|
egdaniel
2015/03/04 20:22:34
do you think we should update setToOther to set fI
bsalomon
2015/03/31 19:33:42
Done.
|
| + } else { |
| + GrColor r = GrColorUnpackR(fColor); |
| + bool colorIsSingleChannel = r == GrColorUnpackG(fColor) && r == GrColorUnpackB(fColor) && |
| + r == GrColorUnpackA(fColor); |
| + if (kIgnore_InputMode == fMode) { |
| + if (colorIsSingleChannel) { |
| + inout->mulByKnownSingleComponent(r); |
| + } else { |
| + inout->mulByKnownFourComponents(fColor); |
| + } |
| + } else { |
| + if (colorIsSingleChannel) { |
| + inout->mulAlphaByKnownSingleComponent(r); |
| + } else { |
| + inout->mulAlphaByKnownFourComponents(fColor); |
| + } |
| + } |
| + } |
| +} |
| + |
| +void GrColorProcessor::getGLProcessorKey(const GrGLCaps&, GrProcessorKeyBuilder* b) const { |
| + b->add32(fMode); |
| +} |
| + |
| +GrGLFragmentProcessor* GrColorProcessor::createGLInstance() const { |
| + return SkNEW(GrGLColorProcessor); |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| +GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrColorProcessor); |
| + |
| +GrFragmentProcessor* GrColorProcessor::TestCreate(SkRandom* random, |
| + GrContext*, |
| + const GrDrawTargetCaps&, |
| + GrTexture*[]) { |
| + GrColor color = random->nextU(); |
| + InputMode mode = static_cast<InputMode>(random->nextULessThan(kInputModeCnt)); |
| + return GrColorProcessor::Create(color, mode); |
| +} |