Home | History | Annotate | Download | only in effects
      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 
     16 class GrGLSimpleTextureEffect : public GrGLEffect {
     17 public:
     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             GrAssert(ste.getMatrix().isIdentity());
     38             GrAssert(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             GrAssert(ste.getMatrix().isIdentity());
     74         } else {
     75             fEffectMatrix.get()->setData(uman, ste.getMatrix(), drawEffect, ste.texture(0));
     76         }
     77     }
     78 
     79 private:
     80     SkTLazy<GrGLEffectMatrix> fEffectMatrix;
     81     typedef GrGLEffect INHERITED;
     82 };
     83 
     84 ///////////////////////////////////////////////////////////////////////////////
     85 
     86 void GrSimpleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
     87     this->updateConstantColorComponentsForModulation(color, validFlags);
     88 }
     89 
     90 const GrBackendEffectFactory& GrSimpleTextureEffect::getFactory() const {
     91     return GrTBackendEffectFactory<GrSimpleTextureEffect>::getInstance();
     92 }
     93 
     94 ///////////////////////////////////////////////////////////////////////////////
     95 
     96 GR_DEFINE_EFFECT_TEST(GrSimpleTextureEffect);
     97 
     98 GrEffectRef* 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