GrSimpleTextureEffect.cpp revision f6de475e5cbd143f348ff7738919e397b7fe7f57
1/*
2 * Copyright 2012 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 "GrSimpleTextureEffect.h"
9#include "gl/GrGLEffect.h"
10#include "gl/GrGLEffectMatrix.h"
11#include "gl/GrGLSL.h"
12#include "gl/GrGLTexture.h"
13#include "GrTBackendEffectFactory.h"
14#include "GrTexture.h"
15
16class GrGLSimpleTextureEffect : public GrGLEffect {
17public:
18    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
19    : INHERITED (factory) {
20        GrEffect::CoordsType coordsType =
21            drawEffect.castEffect<GrSimpleTextureEffect>().coordsType();
22        if (GrEffect::kCustom_CoordsType != coordsType) {
23            SkNEW_IN_TLAZY(&fEffectMatrix, GrGLEffectMatrix, (coordsType));
24        }
25    }
26
27    virtual void emitCode(GrGLShaderBuilder* builder,
28                          const GrDrawEffect& drawEffect,
29                          EffectKey key,
30                          const char* outputColor,
31                          const char* inputColor,
32                          const TextureSamplerArray& samplers) SK_OVERRIDE {
33        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
34        const char* fsCoordName;
35        GrSLType fsCoordSLType;
36        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
37            SkASSERT(ste.getMatrix().isIdentity());
38            SkASSERT(1 == ste.numVertexAttribs());
39            fsCoordSLType = kVec2f_GrSLType;
40            const char* vsVaryingName;
41            builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsCoordName);
42            const char* attrName =
43                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
44            builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName);
45        } else {
46            fsCoordSLType = fEffectMatrix.get()->emitCode(builder, key, &fsCoordName);
47        }
48        builder->fsCodeAppendf("\t%s = ", outputColor);
49        builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderType,
50                                                inputColor,
51                                                samplers[0],
52                                                fsCoordName,
53                                                fsCoordSLType);
54        builder->fsCodeAppend(";\n");
55    }
56
57    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
58        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
59        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
60            return 1 << GrGLEffectMatrix::kKeyBits;
61        } else {
62            return GrGLEffectMatrix::GenKey(ste.getMatrix(),
63                                            drawEffect,
64                                            ste.coordsType(),
65                                            ste.texture(0));
66        }
67    }
68
69    virtual void setData(const GrGLUniformManager& uman,
70                         const GrDrawEffect& drawEffect) SK_OVERRIDE {
71        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
72        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
73            SkASSERT(ste.getMatrix().isIdentity());
74        } else {
75            fEffectMatrix.get()->setData(uman, ste.getMatrix(), drawEffect, ste.texture(0));
76        }
77    }
78
79private:
80    SkTLazy<GrGLEffectMatrix> fEffectMatrix;
81    typedef GrGLEffect INHERITED;
82};
83
84///////////////////////////////////////////////////////////////////////////////
85
86void GrSimpleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
87    this->updateConstantColorComponentsForModulation(color, validFlags);
88}
89
90const GrBackendEffectFactory& GrSimpleTextureEffect::getFactory() const {
91    return GrTBackendEffectFactory<GrSimpleTextureEffect>::getInstance();
92}
93
94///////////////////////////////////////////////////////////////////////////////
95
96GR_DEFINE_EFFECT_TEST(GrSimpleTextureEffect);
97
98GrEffectRef* GrSimpleTextureEffect::TestCreate(SkMWCRandom* random,
99                                               GrContext*,
100                                               const GrDrawTargetCaps&,
101                                               GrTexture* textures[]) {
102    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
103                                      GrEffectUnitTest::kAlphaTextureIdx;
104    static const SkShader::TileMode kTileModes[] = {
105        SkShader::kClamp_TileMode,
106        SkShader::kRepeat_TileMode,
107        SkShader::kMirror_TileMode,
108    };
109    SkShader::TileMode tileModes[] = {
110        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
111        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
112    };
113    GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
114                                                           GrTextureParams::kNone_FilterMode);
115
116    static const CoordsType kCoordsTypes[] = {
117        kLocal_CoordsType,
118        kPosition_CoordsType,
119        kCustom_CoordsType
120    };
121    CoordsType coordsType = kCoordsTypes[random->nextULessThan(GR_ARRAY_COUNT(kCoordsTypes))];
122
123    if (kCustom_CoordsType == coordsType) {
124        return GrSimpleTextureEffect::CreateWithCustomCoords(textures[texIdx], params);
125    } else {
126        const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
127        return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
128    }
129}
130