Home | History | Annotate | Download | only in effects
      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 "glsl/GrGLSLFragmentProcessor.h"
     10 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     11 #include "glsl/GrGLSLProgramDataManager.h"
     12 #include "glsl/GrGLSLUniformHandler.h"
     13 
     14 class GLConstColorProcessor : public GrGLSLFragmentProcessor {
     15 public:
     16     GLConstColorProcessor() : fPrevColor(GrColor4f::kIllegalConstructor) {}
     17 
     18     void emitCode(EmitArgs& args) override {
     19         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
     20         const char* colorUni;
     21         fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
     22                                                          kVec4f_GrSLType, kMedium_GrSLPrecision,
     23                                                          "constantColor",
     24                                                          &colorUni);
     25         GrConstColorProcessor::InputMode mode = args.fFp.cast<GrConstColorProcessor>().inputMode();
     26         if (!args.fInputColor) {
     27             mode = GrConstColorProcessor::kIgnore_InputMode;
     28         }
     29         switch (mode) {
     30             case GrConstColorProcessor::kIgnore_InputMode:
     31                 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUni);
     32                 break;
     33             case GrConstColorProcessor::kModulateRGBA_InputMode:
     34                 fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, args.fInputColor,
     35                                        colorUni);
     36                 break;
     37             case GrConstColorProcessor::kModulateA_InputMode:
     38                 fragBuilder->codeAppendf("%s = %s.a * %s;", args.fOutputColor, args.fInputColor,
     39                                        colorUni);
     40                 break;
     41         }
     42     }
     43 
     44 protected:
     45     void onSetData(const GrGLSLProgramDataManager& pdm,
     46                    const GrFragmentProcessor& processor) override {
     47         GrColor4f color = processor.cast<GrConstColorProcessor>().color();
     48         // We use the "illegal" color value as an uninit sentinel. With GrColor4f, the "illegal"
     49         // color is *really* illegal (not just unpremultiplied), so this check is simple.
     50         if (fPrevColor != color) {
     51             pdm.set4fv(fColorUniform, 1, color.fRGBA);
     52             fPrevColor = color;
     53         }
     54     }
     55 
     56 private:
     57     GrGLSLProgramDataManager::UniformHandle fColorUniform;
     58     GrColor4f                               fPrevColor;
     59 
     60     typedef GrGLSLFragmentProcessor INHERITED;
     61 };
     62 
     63 ///////////////////////////////////////////////////////////////////////////////
     64 
     65 GrColor4f GrConstColorProcessor::constantOutputForConstantInput(GrColor4f input) const {
     66     switch (fMode) {
     67         case kIgnore_InputMode:
     68             return fColor;
     69         case kModulateA_InputMode:
     70             return fColor.mulByScalar(input.fRGBA[3]);
     71         case kModulateRGBA_InputMode:
     72             return fColor.modulate(input);
     73     }
     74     SkFAIL("Unexpected mode");
     75     return GrColor4f::TransparentBlack();
     76 }
     77 
     78 void GrConstColorProcessor::onGetGLSLProcessorKey(const GrShaderCaps&,
     79                                                   GrProcessorKeyBuilder* b) const {
     80     b->add32(fMode);
     81 }
     82 
     83 GrGLSLFragmentProcessor* GrConstColorProcessor::onCreateGLSLInstance() const  {
     84     return new GLConstColorProcessor;
     85 }
     86 
     87 bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const {
     88     const GrConstColorProcessor& that = other.cast<GrConstColorProcessor>();
     89     return fMode == that.fMode && fColor == that.fColor;
     90 }
     91 
     92 ///////////////////////////////////////////////////////////////////////////////
     93 
     94 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor);
     95 
     96 #if GR_TEST_UTILS
     97 sk_sp<GrFragmentProcessor> GrConstColorProcessor::TestCreate(GrProcessorTestData* d) {
     98     GrColor4f color;
     99     int colorPicker = d->fRandom->nextULessThan(3);
    100     switch (colorPicker) {
    101         case 0: {
    102             uint32_t a = d->fRandom->nextULessThan(0x100);
    103             uint32_t r = d->fRandom->nextULessThan(a+1);
    104             uint32_t g = d->fRandom->nextULessThan(a+1);
    105             uint32_t b = d->fRandom->nextULessThan(a+1);
    106             color = GrColor4f::FromGrColor(GrColorPackRGBA(r, g, b, a));
    107             break;
    108         }
    109         case 1:
    110             color = GrColor4f::TransparentBlack();
    111             break;
    112         case 2:
    113             uint32_t c = d->fRandom->nextULessThan(0x100);
    114             color = GrColor4f::FromGrColor(c | (c << 8) | (c << 16) | (c << 24));
    115             break;
    116     }
    117     InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
    118     return GrConstColorProcessor::Make(color, mode);
    119 }
    120 #endif
    121