diff options
Diffstat (limited to 'src/gpu/effects')
-rw-r--r-- | src/gpu/effects/GrAtlasedShaderHelpers.h | 63 | ||||
-rw-r--r-- | src/gpu/effects/GrBitmapTextGeoProc.cpp | 30 | ||||
-rw-r--r-- | src/gpu/effects/GrDistanceFieldGeoProc.cpp | 97 |
3 files changed, 117 insertions, 73 deletions
diff --git a/src/gpu/effects/GrAtlasedShaderHelpers.h b/src/gpu/effects/GrAtlasedShaderHelpers.h new file mode 100644 index 0000000000..67f2c242c2 --- /dev/null +++ b/src/gpu/effects/GrAtlasedShaderHelpers.h @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrAtlasedShaderHelpers_DEFINED +#define GrAtlasedShaderHelpers_DEFINED + +#include "glsl/GrGLSLPrimitiveProcessor.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLVarying.h" +#include "glsl/GrGLSLVertexShaderBuilder.h" + +static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args, + const char* inTexCoordsName, + const char* atlasSizeInvName, + GrGLSLVertToFrag *uv, + GrGLSLVertToFrag *texIdx, + GrGLSLVertToFrag *st) { + // This extracts the texture index and texel coordinates from the same variable + // Packing structure: texel coordinates are multiplied by 2 (or shifted left 1) + // texture index is stored as lower bits of both x and y + args.fVertBuilder->codeAppendf("float2 indexTexCoords = float2(%s.x, %s.y);", + inTexCoordsName, inTexCoordsName); + args.fVertBuilder->codeAppend("float2 intCoords = floor(0.5*indexTexCoords);"); + args.fVertBuilder->codeAppend("float2 diff = indexTexCoords - 2.0*intCoords;"); + args.fVertBuilder->codeAppend("float texIdx = 2.0*diff.x + diff.y;"); + + // Multiply by 1/atlasSize to get normalized texture coordinates + args.fVaryingHandler->addVarying("TextureCoords", uv, kHigh_GrSLPrecision); + args.fVertBuilder->codeAppendf("%s = intCoords * %s;", uv->vsOut(), atlasSizeInvName); + + args.fVaryingHandler->addVarying("TexIndex", texIdx); + args.fVertBuilder->codeAppendf("%s = texIdx;", texIdx->vsOut()); + + if (st) { + args.fVaryingHandler->addVarying("IntTextureCoords", st, kHigh_GrSLPrecision); + args.fVertBuilder->codeAppendf("%s = intCoords;", st->vsOut()); + } +} + +static void append_multitexture_lookup(GrGLSLPrimitiveProcessor::EmitArgs& args, + int numTextureSamplers, + const GrGLSLVertToFrag &texIdx, + const char* coordName, + const char* colorName) { + // conditionally load from the indexed texture sampler + if (numTextureSamplers > 1) { + args.fFragBuilder->codeAppendf("if (%s == 0) ", texIdx.fsIn()); + } + args.fFragBuilder->codeAppendf("{ %s = ", colorName); + args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], coordName, kVec2f_GrSLType); + args.fFragBuilder->codeAppend("; }"); + for (int i = 1; i < numTextureSamplers; ++i) { + args.fFragBuilder->codeAppendf("else if (%s == %d) { %s =", texIdx.fsIn(), i, colorName); + args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName, kVec2f_GrSLType); + args.fFragBuilder->codeAppend("; }"); + } +} + +#endif diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index c2cf8ebc22..8013d2e4b8 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -7,6 +7,7 @@ #include "GrBitmapTextGeoProc.h" +#include "GrAtlasedShaderHelpers.h" #include "GrTexture.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLGeometryProcessor.h" @@ -36,12 +37,10 @@ public: "AtlasSizeInv", &atlasSizeInvName); - GrGLSLVertToFrag v(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%s.x, %s.y) * %s;", v.vsOut(), - btgp.inTextureCoords()->fName, - btgp.inTextureCoords()->fName, - atlasSizeInvName); + GrGLSLVertToFrag uv(kVec2f_GrSLType); + GrGLSLVertToFrag texIdx(kFloat_GrSLType); + append_index_uv_varyings(args, btgp.inTextureCoords()->fName, atlasSizeInvName, + &uv, &texIdx, nullptr); GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; // Setup pass through color @@ -64,18 +63,16 @@ public: btgp.localMatrix(), args.fFPCoordTransformHandler); + fragBuilder->codeAppend("float4 texColor;"); + append_multitexture_lookup(args, btgp.numTextureSamplers(), + texIdx, uv.fsIn(), "texColor"); + if (btgp.maskFormat() == kARGB_GrMaskFormat) { - fragBuilder->codeAppendf("%s = ", args.fOutputColor); - fragBuilder->appendTextureLookupAndModulate(args.fOutputColor, - args.fTexSamplers[0], - v.fsIn(), - kVec2f_GrSLType); - fragBuilder->codeAppend(";"); + // modulate by color + fragBuilder->codeAppendf("%s = %s * texColor;", args.fOutputColor, args.fOutputColor); fragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage); } else { - fragBuilder->codeAppendf("%s = ", args.fOutputCoverage); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], v.fsIn(), kVec2f_GrSLType); - fragBuilder->codeAppend(";"); + fragBuilder->codeAppendf("%s = texColor;", args.fOutputCoverage); } } @@ -89,7 +86,7 @@ public: fColor = btgp.color(); } - SkASSERT(btgp.numTextureSamplers() == 1); + SkASSERT(btgp.numTextureSamplers() >= 1); GrTexture* atlas = btgp.textureSampler(0).peekTexture(); SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); @@ -108,6 +105,7 @@ public: key |= (btgp.usesLocalCoords() && btgp.localMatrix().hasPerspective()) ? 0x1 : 0x0; key |= btgp.maskFormat() << 1; b->add32(key); + b->add32(btgp.numTextureSamplers()); } private: diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 81b33262da..953d4cc2bc 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -7,6 +7,7 @@ #include "GrDistanceFieldGeoProc.h" +#include "GrAtlasedShaderHelpers.h" #include "GrTexture.h" #include "SkDistanceFieldGen.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" @@ -78,17 +79,10 @@ public: // add varyings GrGLSLVertToFrag uv(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%s.x, %s.y) * %s;", uv.vsOut(), - dfTexEffect.inTextureCoords()->fName, - dfTexEffect.inTextureCoords()->fName, - atlasSizeInvName); - + GrGLSLVertToFrag texIdx(kFloat_GrSLType); GrGLSLVertToFrag st(kVec2f_GrSLType); - varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%s.x, %s.y);", st.vsOut(), - dfTexEffect.inTextureCoords()->fName, - dfTexEffect.inTextureCoords()->fName); + append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, + &uv, &texIdx, &st); bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == kUniformScale_DistanceFieldEffectMask; @@ -100,12 +94,12 @@ public: // Use highp to work around aliasing issues fragBuilder->codeAppendf("highp float2 uv = %s;\n", uv.fsIn()); + fragBuilder->codeAppend("float4 texColor;"); + append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), + texIdx, "uv", "texColor"); - fragBuilder->codeAppend("float texColor = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv", kVec2f_GrSLType); - fragBuilder->codeAppend(".r;"); fragBuilder->codeAppend("float distance = " - SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); + SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");"); #ifdef SK_GAMMA_APPLY_TO_A8 // adjust width based on gamma fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); @@ -197,7 +191,7 @@ public: pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } - SkASSERT(dfa8gp.numTextureSamplers() == 1); + SkASSERT(dfa8gp.numTextureSamplers() >= 1); GrTexture* atlas = dfa8gp.textureSampler(0).peekTexture(); SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); @@ -216,6 +210,7 @@ public: uint32_t key = dfTexEffect.getFlags(); key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16; b->add32(key); + b->add32(dfTexEffect.numTextureSamplers()); } private: @@ -332,17 +327,10 @@ public: &atlasSizeInvName); GrGLSLVertToFrag uv(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%s.x, %s.y) * %s;", uv.vsOut(), - dfTexEffect.inTextureCoords()->fName, - dfTexEffect.inTextureCoords()->fName, - atlasSizeInvName); - + GrGLSLVertToFrag texIdx(kFloat_GrSLType); GrGLSLVertToFrag st(kVec2f_GrSLType); - varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%s.x, %s.y);", st.vsOut(), - dfTexEffect.inTextureCoords()->fName, - dfTexEffect.inTextureCoords()->fName); + append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, + &uv, &texIdx, &st); // setup pass through color varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); @@ -365,12 +353,12 @@ public: // Use highp to work around aliasing issues fragBuilder->codeAppendf("highp float2 uv = %s;", uv.fsIn()); + fragBuilder->codeAppend("float4 texColor;"); + append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), + texIdx, "uv", "texColor"); - fragBuilder->codeAppend("float texColor = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv", kVec2f_GrSLType); - fragBuilder->codeAppend(".r;"); fragBuilder->codeAppend("float distance = " - SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); + SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");"); fragBuilder->codeAppend("float afwidth;"); bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == @@ -452,7 +440,7 @@ public: pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } - SkASSERT(dfpgp.numTextureSamplers() == 1); + SkASSERT(dfpgp.numTextureSamplers() >= 1); GrTexture* atlas = dfpgp.textureSampler(0).peekTexture(); SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); @@ -472,6 +460,7 @@ public: uint32_t key = dfTexEffect.getFlags(); key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16; b->add32(key); + b->add32(dfTexEffect.numTextureSamplers()); } private: @@ -599,17 +588,10 @@ public: // set up varyings GrGLSLVertToFrag uv(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%s.x, %s.y) * %s;", uv.vsOut(), - dfTexEffect.inTextureCoords()->fName, - dfTexEffect.inTextureCoords()->fName, - atlasSizeInvName); - + GrGLSLVertToFrag texIdx(kFloat_GrSLType); GrGLSLVertToFrag st(kVec2f_GrSLType); - varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%s.x, %s.y);", st.vsOut(), - dfTexEffect.inTextureCoords()->fName, - dfTexEffect.inTextureCoords()->fName); + append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, + &uv, &texIdx, &st); GrGLSLVertToFrag delta(kFloat_GrSLType); varyingHandler->addVarying("Delta", &delta, kHigh_GrSLPrecision); @@ -660,26 +642,26 @@ public: fragBuilder->codeAppendf("float2 offset = %s*Jdx;", delta.fsIn()); } + // sample the texture by index + fragBuilder->codeAppend("float4 texColor;"); + append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), + texIdx, "uv", "texColor"); + // green is distance to uv center - fragBuilder->codeAppend("\tfloat4 texColor = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv", kVec2f_GrSLType); - fragBuilder->codeAppend(";\n"); - fragBuilder->codeAppend("\tfloat3 distance;\n"); - fragBuilder->codeAppend("\tdistance.y = texColor.r;\n"); + fragBuilder->codeAppend("float3 distance;"); + fragBuilder->codeAppend("distance.y = texColor.r;"); // red is distance to left offset - fragBuilder->codeAppend("\tfloat2 uv_adjusted = uv - offset;\n"); - fragBuilder->codeAppend("\ttexColor = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv_adjusted", kVec2f_GrSLType); - fragBuilder->codeAppend(";\n"); - fragBuilder->codeAppend("\tdistance.x = texColor.r;\n"); + fragBuilder->codeAppend("float2 uv_adjusted = uv - offset;"); + append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), + texIdx, "uv_adjusted", "texColor"); + fragBuilder->codeAppend("distance.x = texColor.r;"); // blue is distance to right offset - fragBuilder->codeAppend("\tuv_adjusted = uv + offset;\n"); - fragBuilder->codeAppend("\ttexColor = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv_adjusted", kVec2f_GrSLType); - fragBuilder->codeAppend(";\n"); - fragBuilder->codeAppend("\tdistance.z = texColor.r;\n"); + fragBuilder->codeAppend("uv_adjusted = uv + offset;"); + append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), + texIdx, "uv_adjusted", "texColor"); + fragBuilder->codeAppend("distance.z = texColor.r;"); - fragBuilder->codeAppend("\tdistance = " + fragBuilder->codeAppend("distance = " "float3(" SK_DistanceFieldMultiplier ")*(distance - float3(" SK_DistanceFieldThreshold"));"); // adjust width based on gamma @@ -757,7 +739,7 @@ public: pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } - SkASSERT(dflcd.numTextureSamplers() == 1); + SkASSERT(dflcd.numTextureSamplers() >= 1); GrTexture* atlas = dflcd.textureSampler(0).peekTexture(); SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); @@ -777,6 +759,7 @@ public: uint32_t key = dfTexEffect.getFlags(); key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16; b->add32(key); + b->add32(dfTexEffect.numTextureSamplers()); } private: |