GrSimpleTextureEffect.cpp revision b86add1ad37776818e1f730359ec587c9fdbff5f
168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com/*
268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com * Copyright 2012 Google Inc.
368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com *
468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com * found in the LICENSE file.
668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com */
768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "GrSimpleTextureEffect.h"
968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "gl/GrGLEffect.h"
1068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "gl/GrGLEffectMatrix.h"
1168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "gl/GrGLSL.h"
1268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "gl/GrGLTexture.h"
1368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "GrTBackendEffectFactory.h"
1468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "GrTexture.h"
1568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
1668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comclass GrGLSimpleTextureEffect : public GrGLEffect {
1768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.compublic:
18c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect)
19c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    : INHERITED (factory) {
20c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        GrEffect::CoordsType coordsType =
21c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            drawEffect.castEffect<GrSimpleTextureEffect>().coordsType();
22c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        if (GrEffect::kCustom_CoordsType != coordsType) {
23c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            SkNEW_IN_TLAZY(&fEffectMatrix, GrGLEffectMatrix, (coordsType));
24c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        }
25c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    }
2668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
2768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    virtual void emitCode(GrGLShaderBuilder* builder,
28c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                          const GrDrawEffect& drawEffect,
2968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                          EffectKey key,
3068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                          const char* outputColor,
3168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                          const char* inputColor,
3268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                          const TextureSamplerArray& samplers) SK_OVERRIDE {
33c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
34c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        const char* fsCoordName;
35c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        GrSLType fsCoordSLType;
36c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
37c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            GrAssert(ste.getMatrix().isIdentity());
38c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            GrAssert(1 == ste.numVertexAttribs());
39c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            fsCoordSLType = kVec2f_GrSLType;
40c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            const char* vsVaryingName;
41c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsCoordName);
42c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            const char* attrName =
43c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str();
44018f179efb2413431bdb1a9e6701eb44ef36b792bsalomon@google.com            builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName);
45c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        } else {
46c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            fsCoordSLType = fEffectMatrix.get()->emitCode(builder, key, &fsCoordName);
47c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        }
48f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        builder->fsCodeAppendf("\t%s = ", outputColor);
49f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        builder->appendTextureLookupAndModulate(GrGLShaderBuilder::kFragment_ShaderType,
5068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                                                inputColor,
5168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                                                samplers[0],
52c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                                fsCoordName,
53c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                                fsCoordSLType);
54f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com        builder->fsCodeAppend(";\n");
5568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    }
5668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
57c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
58c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
59c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
60c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            return 1 << GrGLEffectMatrix::kKeyBits;
61c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        } else {
62c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            return GrGLEffectMatrix::GenKey(ste.getMatrix(),
63c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                            drawEffect,
64c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                            ste.coordsType(),
65c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                            ste.texture(0));
66c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        }
6768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    }
6868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
69c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    virtual void setData(const GrGLUniformManager& uman,
70c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                         const GrDrawEffect& drawEffect) SK_OVERRIDE {
71c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        const GrSimpleTextureEffect& ste = drawEffect.castEffect<GrSimpleTextureEffect>();
72c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        if (GrEffect::kCustom_CoordsType == ste.coordsType()) {
73c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            GrAssert(ste.getMatrix().isIdentity());
74c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        } else {
75c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            fEffectMatrix.get()->setData(uman, ste.getMatrix(), drawEffect, ste.texture(0));
76c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        }
7768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    }
7868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
7968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comprivate:
80c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    SkTLazy<GrGLEffectMatrix> fEffectMatrix;
8168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    typedef GrGLEffect INHERITED;
8268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com};
8368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
8468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
8568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
8668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comvoid GrSimpleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
8768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    this->updateConstantColorComponentsForModulation(color, validFlags);
8868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com}
8968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
9068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comconst GrBackendEffectFactory& GrSimpleTextureEffect::getFactory() const {
9168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    return GrTBackendEffectFactory<GrSimpleTextureEffect>::getInstance();
9268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com}
9368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
9468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
9568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
9668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comGR_DEFINE_EFFECT_TEST(GrSimpleTextureEffect);
9768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
9873a9694b4ceb67547e5863db5315488e7d5294f7bsalomon@google.comGrEffectRef* GrSimpleTextureEffect::TestCreate(SkMWCRandom* random,
99e0e385c1d4171e065348ba17c546b3463a0bd651sugoi@google.com                                               GrContext*,
100c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com                                               const GrDrawTargetCaps&,
10168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                                               GrTexture* textures[]) {
10268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com    int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
10368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com                                      GrEffectUnitTest::kAlphaTextureIdx;
104c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    static const SkShader::TileMode kTileModes[] = {
105c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        SkShader::kClamp_TileMode,
106c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        SkShader::kRepeat_TileMode,
107c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        SkShader::kMirror_TileMode,
108c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    };
109c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    SkShader::TileMode tileModes[] = {
110c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
111c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
112c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    };
113b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
114b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                                                           GrTextureParams::kNone_FilterMode);
115c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
116c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    static const CoordsType kCoordsTypes[] = {
117c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kLocal_CoordsType,
118c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kPosition_CoordsType,
119c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kCustom_CoordsType
120c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    };
121c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    CoordsType coordsType = kCoordsTypes[random->nextULessThan(GR_ARRAY_COUNT(kCoordsTypes))];
122c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
123c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    if (kCustom_CoordsType == coordsType) {
124c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        return GrSimpleTextureEffect::CreateWithCustomCoords(textures[texIdx], params);
125c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    } else {
126c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
127c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        return GrSimpleTextureEffect::Create(textures[texIdx], matrix);
128c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    }
12968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com}
130