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