aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects/GrColorTableEffect.cpp
blob: 0edc00de95a0a62115f0be2d6f938643e8151a9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

 #include "GrColorTableEffect.h"
 #include "gl/GrGLProgramStage.h"
 #include "GrProgramStageFactory.h"
 #include "SkString.h"

///////////////////////////////////////////////////////////////////////////////

class GrGLColorTableEffect : public GrGLProgramStage {
public:
    GrGLColorTableEffect(const GrProgramStageFactory& factory,
                         const GrCustomStage& stage);

    virtual void setupVariables(GrGLShaderBuilder* state) SK_OVERRIDE {}
    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE {}
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const TextureSamplerArray&) SK_OVERRIDE;

    virtual void setData(const GrGLUniformManager&,
                         const GrCustomStage&,
                         const GrRenderTarget*,
                         int stageNum) SK_OVERRIDE {}

    static StageKey GenKey(const GrCustomStage&, const GrGLCaps&);

private:

    typedef GrGLProgramStage INHERITED;
};

GrGLColorTableEffect::GrGLColorTableEffect(
    const GrProgramStageFactory& factory, const GrCustomStage& stage)
    : INHERITED(factory) {
 }

void GrGLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TextureSamplerArray& samplers) {
    static const float kColorScaleFactor = 255.0f / 256.0f;
    static const float kColorOffsetFactor = 1.0f / 512.0f;
    SkString* code = &builder->fFSCode;
    if (NULL == inputColor) {
        // the input color is solid white (all ones).
        static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
        code->appendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
                      kMaxValue, kMaxValue, kMaxValue, kMaxValue);

    } else {
        code->appendf("\t\tvec4 coord = vec4(%s.rgb / %s.a, %s.a);\n",
                      inputColor, inputColor, inputColor);
        code->appendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
                      kColorScaleFactor,
                      kColorOffsetFactor, kColorOffsetFactor,
                      kColorOffsetFactor, kColorOffsetFactor);
    }

    code->appendf("\t\t%s.a = ", outputColor);
    builder->appendTextureLookup(code, samplers[0], "vec2(coord.a, 0.125)");
    code->append(";\n");

    code->appendf("\t\t%s.r = ", outputColor);
    builder->appendTextureLookup(code, samplers[0], "vec2(coord.r, 0.375)");
    code->append(";\n");

    code->appendf("\t\t%s.g = ", outputColor);
    builder->appendTextureLookup(code, samplers[0], "vec2(coord.g, 0.625)");
    code->append(";\n");

    code->appendf("\t\t%s.b = ", outputColor);
    builder->appendTextureLookup(code, samplers[0], "vec2(coord.b, 0.875)");
    code->append(";\n");

    code->appendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
}

GrGLProgramStage::StageKey GrGLColorTableEffect::GenKey(const GrCustomStage& s,
                                                        const GrGLCaps& caps) {
    return 0;
}

///////////////////////////////////////////////////////////////////////////////

GrColorTableEffect::GrColorTableEffect(GrTexture* texture)
    : fTextureAccess(texture, "a") {
}

GrColorTableEffect::~GrColorTableEffect() {
}

const GrProgramStageFactory&  GrColorTableEffect::getFactory() const {
    return GrTProgramStageFactory<GrColorTableEffect>::getInstance();
}

bool GrColorTableEffect::isEqual(const GrCustomStage& sBase) const {
    return INHERITED::isEqual(sBase);
}

const GrTextureAccess& GrColorTableEffect::textureAccess(int index) const {
    GrAssert(0 == index);
    return fTextureAccess;
}

///////////////////////////////////////////////////////////////////////////////

GR_DEFINE_CUSTOM_STAGE_TEST(GrColorTableEffect);

GrCustomStage* GrColorTableEffect::TestCreate(SkRandom* random,
                                              GrContext* context,
                                              GrTexture* textures[]) {
    return SkNEW_ARGS(GrColorTableEffect, (textures[GrCustomStageUnitTest::kAlphaTextureIdx]));
}