| 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 "src/gpu/GrShaderCaps.h" |
| 12 | #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" |
| 13 | #include "src/gpu/glsl/GrGLSLPrimitiveProcessor.h" |
| 14 | #include "src/gpu/glsl/GrGLSLVarying.h" |
| 15 | #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" |
| 16 | |
| 17 | static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args, |
| 18 | int numTextureSamplers, |
| 19 | const char* inTexCoordsName, |
| 20 | const char* atlasDimensionsInvName, |
| 21 | GrGLSLVarying* uv, |
| 22 | GrGLSLVarying* texIdx, |
| 23 | GrGLSLVarying* st) { |
| 24 | using Interpolation = GrGLSLVaryingHandler::Interpolation; |
| 25 | |
| 26 | // This extracts the texture index and texel coordinates from the same variable |
| 27 | // Packing structure: texel coordinates are multiplied by 2 (or shifted left 1) |
| 28 | // texture index is stored as lower bits of both x and y |
| 29 | if (args.fShaderCaps->integerSupport()) { |
| 30 | args.fVertBuilder->codeAppendf("int2 signedCoords = int2(%s.x, %s.y);" , |
| 31 | inTexCoordsName, inTexCoordsName); |
| 32 | args.fVertBuilder->codeAppend("float2 unormTexCoords = float2(signedCoords.x/2, signedCoords.y/2);" ); |
| 33 | if (numTextureSamplers <= 1) { |
| 34 | args.fVertBuilder->codeAppend("int texIdx = 0;" ); |
| 35 | } else { |
| 36 | args.fVertBuilder->codeAppend("int texIdx = 2*(signedCoords.x & 0x1) + (signedCoords.y & 0x1);" ); |
| 37 | } |
| 38 | } else { |
| 39 | args.fVertBuilder->codeAppendf("float2 indexTexCoords = float2(%s.x, %s.y);" , |
| 40 | inTexCoordsName, inTexCoordsName); |
| 41 | args.fVertBuilder->codeAppend("float2 unormTexCoords = floor(0.5*indexTexCoords);" ); |
| 42 | if (numTextureSamplers <= 1) { |
| 43 | args.fVertBuilder->codeAppend("float texIdx = 0;" ); |
| 44 | } else { |
| 45 | args.fVertBuilder->codeAppend("float2 diff = indexTexCoords - 2.0*unormTexCoords;" ); |
| 46 | args.fVertBuilder->codeAppend("float texIdx = 2.0*diff.x + diff.y;" ); |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | // Multiply by 1/atlasDimensions to get normalized texture coordinates |
| 51 | args.fVaryingHandler->addVarying("TextureCoords" , uv); |
| 52 | args.fVertBuilder->codeAppendf("%s = unormTexCoords * %s;" , uv->vsOut(), |
| 53 | atlasDimensionsInvName); |
| 54 | |
| 55 | args.fVaryingHandler->addVarying("TexIndex" , texIdx, args.fShaderCaps->integerSupport() |
| 56 | ? Interpolation::kMustBeFlat |
| 57 | : Interpolation::kCanBeFlat); |
| 58 | args.fVertBuilder->codeAppendf("%s = texIdx;" , texIdx->vsOut()); |
| 59 | |
| 60 | if (st) { |
| 61 | args.fVaryingHandler->addVarying("IntTextureCoords" , st); |
| 62 | args.fVertBuilder->codeAppendf("%s = unormTexCoords;" , st->vsOut()); |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | static void append_multitexture_lookup(GrGLSLPrimitiveProcessor::EmitArgs& args, |
| 67 | int numTextureSamplers, |
| 68 | const GrGLSLVarying &texIdx, |
| 69 | const char* coordName, |
| 70 | const char* colorName) { |
| 71 | SkASSERT(numTextureSamplers > 0); |
| 72 | // This shouldn't happen, but will avoid a crash if it does |
| 73 | if (numTextureSamplers <= 0) { |
| 74 | args.fFragBuilder->codeAppendf("%s = float4(1, 1, 1, 1);" , colorName); |
| 75 | return; |
| 76 | } |
| 77 | |
| 78 | // conditionally load from the indexed texture sampler |
| 79 | for (int i = 0; i < numTextureSamplers-1; ++i) { |
| 80 | args.fFragBuilder->codeAppendf("if (%s == %d) { %s = " , texIdx.fsIn(), i, colorName); |
| 81 | args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName); |
| 82 | args.fFragBuilder->codeAppend("; } else " ); |
| 83 | } |
| 84 | args.fFragBuilder->codeAppendf("{ %s = " , colorName); |
| 85 | args.fFragBuilder->appendTextureLookup(args.fTexSamplers[numTextureSamplers - 1], coordName); |
| 86 | args.fFragBuilder->codeAppend("; }" ); |
| 87 | } |
| 88 | |
| 89 | #endif |
| 90 | |