Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2017 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 #ifndef GrAtlasedShaderHelpers_DEFINED
      9 #define GrAtlasedShaderHelpers_DEFINED
     10 
     11 #include "GrShaderCaps.h"
     12 #include "glsl/GrGLSLPrimitiveProcessor.h"
     13 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     14 #include "glsl/GrGLSLVarying.h"
     15 #include "glsl/GrGLSLVertexGeoBuilder.h"
     16 
     17 static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args,
     18                                      const char* inTexCoordsName,
     19                                      const char* atlasSizeInvName,
     20                                      GrGLSLVarying *uv,
     21                                      GrGLSLVarying *texIdx,
     22                                      GrGLSLVarying *st) {
     23     using Interpolation = GrGLSLVaryingHandler::Interpolation;
     24 
     25     // This extracts the texture index and texel coordinates from the same variable
     26     // Packing structure: texel coordinates are multiplied by 2 (or shifted left 1)
     27     //                    texture index is stored as lower bits of both x and y
     28     if (args.fShaderCaps->integerSupport()) {
     29         args.fVertBuilder->codeAppendf("int2 signedCoords = int2(%s.x, %s.y);",
     30                                        inTexCoordsName, inTexCoordsName);
     31         args.fVertBuilder->codeAppend("int texIdx = 2*(signedCoords.x & 0x1) + (signedCoords.y & 0x1);");
     32         args.fVertBuilder->codeAppend("float2 unormTexCoords = float2(signedCoords.x/2, signedCoords.y/2);");
     33     } else {
     34         args.fVertBuilder->codeAppendf("float2 indexTexCoords = float2(%s.x, %s.y);",
     35                                        inTexCoordsName, inTexCoordsName);
     36         args.fVertBuilder->codeAppend("float2 unormTexCoords = floor(0.5*indexTexCoords);");
     37         args.fVertBuilder->codeAppend("float2 diff = indexTexCoords - 2.0*unormTexCoords;");
     38         args.fVertBuilder->codeAppend("float texIdx = 2.0*diff.x + diff.y;");
     39     }
     40 
     41     // Multiply by 1/atlasSize to get normalized texture coordinates
     42     args.fVaryingHandler->addVarying("TextureCoords", uv);
     43     args.fVertBuilder->codeAppendf("%s = unormTexCoords * %s;", uv->vsOut(), atlasSizeInvName);
     44 
     45     args.fVaryingHandler->addVarying("TexIndex", texIdx, args.fShaderCaps->integerSupport()
     46                                                                  ? Interpolation::kMustBeFlat
     47                                                                  : Interpolation::kCanBeFlat);
     48     args.fVertBuilder->codeAppendf("%s = texIdx;", texIdx->vsOut());
     49 
     50     if (st) {
     51         args.fVaryingHandler->addVarying("IntTextureCoords", st);
     52         args.fVertBuilder->codeAppendf("%s = unormTexCoords;", st->vsOut());
     53     }
     54 }
     55 
     56 static void append_multitexture_lookup(GrGLSLPrimitiveProcessor::EmitArgs& args,
     57                                        int numTextureSamplers,
     58                                        const GrGLSLVarying &texIdx,
     59                                        const char* coordName,
     60                                        const char* colorName) {
     61     // conditionally load from the indexed texture sampler
     62     for (int i = 0; i < numTextureSamplers-1; ++i) {
     63         args.fFragBuilder->codeAppendf("if (%s == %d) { %s = ", texIdx.fsIn(), i, colorName);
     64         args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName,
     65                                                kFloat2_GrSLType);
     66         args.fFragBuilder->codeAppend("; } else ");
     67     }
     68     args.fFragBuilder->codeAppendf("{ %s = ", colorName);
     69     args.fFragBuilder->appendTextureLookup(args.fTexSamplers[numTextureSamplers-1], coordName,
     70                                            kFloat2_GrSLType);
     71     args.fFragBuilder->codeAppend("; }");
     72 }
     73 
     74 #endif
     75