aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/effects/GrAtlasedShaderHelpers.h60
-rw-r--r--src/gpu/effects/GrBitmapTextGeoProc.cpp31
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.cpp97
-rw-r--r--src/gpu/ops/GrSmallPathRenderer.cpp15
-rw-r--r--src/gpu/text/GrAtlasTextBlob_regenInOp.cpp5
5 files changed, 129 insertions, 79 deletions
diff --git a/src/gpu/effects/GrAtlasedShaderHelpers.h b/src/gpu/effects/GrAtlasedShaderHelpers.h
new file mode 100644
index 0000000000..c7d1a41c10
--- /dev/null
+++ b/src/gpu/effects/GrAtlasedShaderHelpers.h
@@ -0,0 +1,60 @@
+/*
+ * 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 *st,
+ GrGLSLVertToFrag *texIdx) {
+ // 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 intCoords = floor(0.5*float2(%s.x, %s.y));",
+ inTexCoordsName, inTexCoordsName);
+ args.fVertBuilder->codeAppendf("float2 diff = %s - 2.0*intCoords;", inTexCoordsName);
+ 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("IntTextureCoords", st, kHigh_GrSLPrecision);
+ args.fVertBuilder->codeAppendf("%s = intCoords;", st->vsOut());
+
+ args.fVaryingHandler->addVarying("TexIndex", texIdx);
+ args.fVertBuilder->codeAppendf("%s = texIdx;", texIdx->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..fab0904a4f 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,11 @@ 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 st(kVec2f_GrSLType);
+ GrGLSLVertToFrag texIdx(kFloat_GrSLType);
+ append_index_uv_varyings(args, btgp.inTextureCoords()->fName, atlasSizeInvName,
+ &uv, &st, &texIdx);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
@@ -64,18 +64,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 +87,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 +106,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..b8f0386820 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 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);
+ GrGLSLVertToFrag texIdx(kFloat_GrSLType);
+ append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName,
+ &uv, &st, &texIdx);
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 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);
+ GrGLSLVertToFrag texIdx(kFloat_GrSLType);
+ append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName,
+ &uv, &st, &texIdx);
// 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 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);
+ GrGLSLVertToFrag texIdx(kFloat_GrSLType);
+ append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName,
+ &uv, &st, &texIdx);
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:
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 1b0648615d..ec63e9ec7d 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -485,10 +485,12 @@ private:
shapeData->fBounds.fRight /= scale;
shapeData->fBounds.fBottom /= scale;
- shapeData->fTextureCoords.set(atlasLocation.fX+SK_DistanceFieldPad,
- atlasLocation.fY+SK_DistanceFieldPad,
- atlasLocation.fX+SK_DistanceFieldPad+devPathBounds.width(),
- atlasLocation.fY+SK_DistanceFieldPad+devPathBounds.height());
+ shapeData->fTextureCoords.set((atlasLocation.fX+SK_DistanceFieldPad) << 1,
+ (atlasLocation.fY+SK_DistanceFieldPad) << 1,
+ (atlasLocation.fX+SK_DistanceFieldPad+
+ devPathBounds.width()) << 1,
+ (atlasLocation.fY+SK_DistanceFieldPad+
+ devPathBounds.height()) << 1);
fShapeCache->add(shapeData);
fShapeList->addToTail(shapeData);
@@ -576,8 +578,9 @@ private:
shapeData->fBounds = SkRect::Make(devPathBounds);
shapeData->fBounds.offset(-translateX, -translateY);
- shapeData->fTextureCoords.set(atlasLocation.fX, atlasLocation.fY,
- atlasLocation.fX+width, atlasLocation.fY+height);
+ shapeData->fTextureCoords.set(atlasLocation.fX << 1, atlasLocation.fY << 1,
+ (atlasLocation.fX+width) << 1,
+ (atlasLocation.fY+height) << 1);
fShapeCache->add(shapeData);
fShapeList->addToTail(shapeData);
diff --git a/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp b/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp
index 96f0080ec2..b7911c3eae 100644
--- a/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp
+++ b/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp
@@ -39,6 +39,11 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS
u1 = u0 + width;
v1 = v0 + height;
}
+ // shift to make space for index bits
+ u0 <<= 1;
+ v0 <<= 1;
+ u1 <<= 1;
+ v1 <<= 1;
}
// This is a bit wonky, but sometimes we have LCD text, in which case we won't have color