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 "GrBitmapTextGeoProc.h"
      9 
     10 #include "GrTexture.h"
     11 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     12 #include "glsl/GrGLSLGeometryProcessor.h"
     13 #include "glsl/GrGLSLProgramDataManager.h"
     14 #include "glsl/GrGLSLUniformHandler.h"
     15 #include "glsl/GrGLSLVarying.h"
     16 #include "glsl/GrGLSLVertexShaderBuilder.h"
     17 
     18 class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor {
     19 public:
     20     GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL) {}
     21 
     22     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
     23         const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>();
     24 
     25         GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
     26         GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
     27         GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
     28 
     29         // emit attributes
     30         varyingHandler->emitAttributes(cte);
     31 
     32         // compute numbers to be hardcoded to convert texture coordinates from int to float
     33         SkASSERT(cte.numTextureSamplers() == 1);
     34         SkDEBUGCODE(GrTexture* atlas = cte.textureSampler(0).peekTexture());
     35         SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
     36 
     37         GrGLSLVertToFrag v(kVec2f_GrSLType);
     38         varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
     39         vertBuilder->codeAppendf("%s = %s;", v.vsOut(),
     40                                  cte.inTextureCoords()->fName);
     41 
     42         GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
     43         // Setup pass through color
     44         if (cte.hasVertexColor()) {
     45             varyingHandler->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
     46         } else {
     47             this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
     48                                     &fColorUniform);
     49         }
     50 
     51         // Setup position
     52         this->setupPosition(vertBuilder, gpArgs, cte.inPosition()->fName);
     53 
     54         // emit transforms
     55         this->emitTransforms(vertBuilder,
     56                              varyingHandler,
     57                              uniformHandler,
     58                              gpArgs->fPositionVar,
     59                              cte.inPosition()->fName,
     60                              cte.localMatrix(),
     61                              args.fFPCoordTransformHandler);
     62 
     63         if (cte.maskFormat() == kARGB_GrMaskFormat) {
     64             fragBuilder->codeAppendf("%s = ", args.fOutputColor);
     65             fragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
     66                                                         args.fTexSamplers[0],
     67                                                         v.fsIn(),
     68                                                         kVec2f_GrSLType);
     69             fragBuilder->codeAppend(";");
     70             fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
     71         } else {
     72             fragBuilder->codeAppendf("%s = ", args.fOutputCoverage);
     73             fragBuilder->appendTextureLookup(args.fTexSamplers[0], v.fsIn(), kVec2f_GrSLType);
     74             fragBuilder->codeAppend(";");
     75         }
     76     }
     77 
     78     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp,
     79                  FPCoordTransformIter&& transformIter) override {
     80         const GrBitmapTextGeoProc& btgp = gp.cast<GrBitmapTextGeoProc>();
     81         if (btgp.color() != fColor && !btgp.hasVertexColor()) {
     82             float c[4];
     83             GrColorToRGBAFloat(btgp.color(), c);
     84             pdman.set4fv(fColorUniform, 1, c);
     85             fColor = btgp.color();
     86         }
     87         this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter);
     88     }
     89 
     90     static inline void GenKey(const GrGeometryProcessor& proc,
     91                               const GrShaderCaps&,
     92                               GrProcessorKeyBuilder* b) {
     93         const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>();
     94         uint32_t key = 0;
     95         key |= (gp.usesLocalCoords() && gp.localMatrix().hasPerspective()) ? 0x1 : 0x0;
     96         key |= gp.maskFormat() << 1;
     97         b->add32(key);
     98 
     99         // Currently we hardcode numbers to convert atlas coordinates to normalized floating point
    100         SkASSERT(gp.numTextureSamplers() == 1);
    101         GrTextureProxy* atlas = gp.textureSampler(0).proxy();
    102         if (atlas) {
    103             b->add32(atlas->width());
    104             b->add32(atlas->height());
    105         }
    106     }
    107 
    108 private:
    109     GrColor fColor;
    110     UniformHandle fColorUniform;
    111 
    112     typedef GrGLSLGeometryProcessor INHERITED;
    113 };
    114 
    115 ///////////////////////////////////////////////////////////////////////////////
    116 
    117 GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color,
    118                                          sk_sp<GrTextureProxy> proxy,
    119                                          const GrSamplerParams& params, GrMaskFormat format,
    120                                          const SkMatrix& localMatrix, bool usesLocalCoords)
    121     : fColor(color)
    122     , fLocalMatrix(localMatrix)
    123     , fUsesLocalCoords(usesLocalCoords)
    124     , fTextureSampler(std::move(proxy), params)
    125     , fInColor(nullptr)
    126     , fMaskFormat(format) {
    127     this->initClassID<GrBitmapTextGeoProc>();
    128     fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType);
    129 
    130     bool hasVertexColor = kA8_GrMaskFormat == fMaskFormat ||
    131                           kA565_GrMaskFormat == fMaskFormat;
    132     if (hasVertexColor) {
    133         fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
    134     }
    135     fInTextureCoords = &this->addVertexAttrib("inTextureCoords",  kVec2us_GrVertexAttribType,
    136                                               kHigh_GrSLPrecision);
    137     this->addTextureSampler(&fTextureSampler);
    138 }
    139 
    140 void GrBitmapTextGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
    141                                               GrProcessorKeyBuilder* b) const {
    142     GrGLBitmapTextGeoProc::GenKey(*this, caps, b);
    143 }
    144 
    145 GrGLSLPrimitiveProcessor* GrBitmapTextGeoProc::createGLSLInstance(const GrShaderCaps& caps) const {
    146     return new GrGLBitmapTextGeoProc();
    147 }
    148 
    149 ///////////////////////////////////////////////////////////////////////////////
    150 
    151 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrBitmapTextGeoProc);
    152 
    153 #if GR_TEST_UTILS
    154 sk_sp<GrGeometryProcessor> GrBitmapTextGeoProc::TestCreate(GrProcessorTestData* d) {
    155     int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
    156                                         : GrProcessorUnitTest::kAlphaTextureIdx;
    157     sk_sp<GrTextureProxy> proxy = d->textureProxy(texIdx);
    158 
    159     static const SkShader::TileMode kTileModes[] = {
    160         SkShader::kClamp_TileMode,
    161         SkShader::kRepeat_TileMode,
    162         SkShader::kMirror_TileMode,
    163     };
    164     SkShader::TileMode tileModes[] = {
    165         kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
    166         kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
    167     };
    168     GrSamplerParams params(tileModes, d->fRandom->nextBool() ? GrSamplerParams::kBilerp_FilterMode
    169                                                              : GrSamplerParams::kNone_FilterMode);
    170 
    171     GrMaskFormat format = kARGB_GrMaskFormat; // init to avoid warning
    172     switch (d->fRandom->nextULessThan(3)) {
    173         case 0:
    174             format = kA8_GrMaskFormat;
    175             break;
    176         case 1:
    177             format = kA565_GrMaskFormat;
    178             break;
    179         case 2:
    180             format = kARGB_GrMaskFormat;
    181             break;
    182     }
    183 
    184     return GrBitmapTextGeoProc::Make(GrRandomColor(d->fRandom), std::move(proxy),
    185                                      params, format, GrTest::TestMatrix(d->fRandom),
    186                                      d->fRandom->nextBool());
    187 }
    188 #endif
    189