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