Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2013 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 "GrCustomCoordsTextureEffect.h"
      9 #include "gl/builders/GrGLFullProgramBuilder.h"
     10 #include "gl/GrGLProcessor.h"
     11 #include "gl/GrGLSL.h"
     12 #include "gl/GrGLTexture.h"
     13 #include "gl/GrGLGeometryProcessor.h"
     14 #include "GrTBackendProcessorFactory.h"
     15 #include "GrTexture.h"
     16 
     17 class GrGLCustomCoordsTextureEffect : public GrGLGeometryProcessor {
     18 public:
     19     GrGLCustomCoordsTextureEffect(const GrBackendProcessorFactory& factory, const GrProcessor&)
     20         : INHERITED (factory) {}
     21 
     22     virtual void emitCode(GrGLFullProgramBuilder* builder,
     23                           const GrGeometryProcessor& geometryProcessor,
     24                           const GrProcessorKey& key,
     25                           const char* outputColor,
     26                           const char* inputColor,
     27                           const TransformedCoordsArray&,
     28                           const TextureSamplerArray& samplers) SK_OVERRIDE {
     29         const GrCustomCoordsTextureEffect& customCoordsTextureEffect =
     30                 geometryProcessor.cast<GrCustomCoordsTextureEffect>();
     31         SkASSERT(1 == customCoordsTextureEffect.getVertexAttribs().count());
     32 
     33         SkString fsCoordName;
     34         const char* vsVaryingName;
     35         const char* fsVaryingNamePtr;
     36         builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr);
     37         fsCoordName = fsVaryingNamePtr;
     38 
     39         GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
     40         const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
     41         vsBuilder->codeAppendf("\t%s = %s;\n", vsVaryingName, inTextureCoords.c_str());
     42 
     43         GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
     44         fsBuilder->codeAppendf("\t%s = ", outputColor);
     45         fsBuilder->appendTextureLookupAndModulate(inputColor,
     46                                                   samplers[0],
     47                                                   fsCoordName.c_str(),
     48                                                   kVec2f_GrSLType);
     49         fsBuilder->codeAppend(";\n");
     50     }
     51 
     52     virtual void setData(const GrGLProgramDataManager&,
     53                          const GrProcessor&) SK_OVERRIDE {}
     54 
     55 private:
     56     typedef GrGLGeometryProcessor INHERITED;
     57 };
     58 
     59 ///////////////////////////////////////////////////////////////////////////////
     60 
     61 GrCustomCoordsTextureEffect::GrCustomCoordsTextureEffect(GrTexture* texture,
     62                                                          const GrTextureParams& params)
     63     : fTextureAccess(texture, params)
     64     , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords",
     65                                                          kVec2f_GrSLType,
     66                                                          GrShaderVar::kAttribute_TypeModifier))) {
     67     this->addTextureAccess(&fTextureAccess);
     68 }
     69 
     70 bool GrCustomCoordsTextureEffect::onIsEqual(const GrProcessor& other) const {
     71     const GrCustomCoordsTextureEffect& cte = other.cast<GrCustomCoordsTextureEffect>();
     72     return fTextureAccess == cte.fTextureAccess;
     73 }
     74 
     75 void GrCustomCoordsTextureEffect::getConstantColorComponents(GrColor* color,
     76                                                              uint32_t* validFlags) const {
     77     if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) &&
     78         GrPixelConfigIsOpaque(this->texture(0)->config())) {
     79         *validFlags = kA_GrColorComponentFlag;
     80     } else {
     81         *validFlags = 0;
     82     }
     83 }
     84 
     85 const GrBackendGeometryProcessorFactory& GrCustomCoordsTextureEffect::getFactory() const {
     86     return GrTBackendGeometryProcessorFactory<GrCustomCoordsTextureEffect>::getInstance();
     87 }
     88 
     89 ///////////////////////////////////////////////////////////////////////////////
     90 
     91 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCustomCoordsTextureEffect);
     92 
     93 GrGeometryProcessor* GrCustomCoordsTextureEffect::TestCreate(SkRandom* random,
     94                                                              GrContext*,
     95                                                              const GrDrawTargetCaps&,
     96                                                              GrTexture* textures[]) {
     97     int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
     98                                       GrProcessorUnitTest::kAlphaTextureIdx;
     99     static const SkShader::TileMode kTileModes[] = {
    100         SkShader::kClamp_TileMode,
    101         SkShader::kRepeat_TileMode,
    102         SkShader::kMirror_TileMode,
    103     };
    104     SkShader::TileMode tileModes[] = {
    105         kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
    106         kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
    107     };
    108     GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
    109                                                            GrTextureParams::kNone_FilterMode);
    110 
    111     return GrCustomCoordsTextureEffect::Create(textures[texIdx], params);
    112 }
    113