aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp39
-rwxr-xr-xsrc/gpu/effects/GrDistanceFieldTextureEffect.cpp127
-rw-r--r--src/gpu/effects/GrDistanceFieldTextureEffect.h34
3 files changed, 137 insertions, 63 deletions
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 1fe43200c2..66c97c7dc0 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -271,6 +271,12 @@ inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrClip& c
fSkPaint.setAutohinted(false);
fSkPaint.setHinting(SkPaint::kNormal_Hinting);
fSkPaint.setSubpixelText(true);
+
+ // fix for skia:3528
+ // if we're scaling up, include any scaling to match text size in the view matrix
+ if (fTextRatio > 1.0f) {
+ fViewMatrix.preScale(fTextRatio, fTextRatio);
+ }
}
void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
@@ -483,13 +489,24 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
kRectToRect_DistanceFieldEffectFlag : 0;
bool useBGR = SkPixelGeometryIsBGR(fDeviceProperties.pixelGeometry());
flags |= fUseLCDText && useBGR ? kBGR_DistanceFieldEffectFlag : 0;
-
+
+ // fix for skia:3528
+ // set the local matrix to correct any text size scaling for gradients et al.
+ SkMatrix localMatrix;
+ if (fTextRatio > 1.0f) {
+ localMatrix.setScale(fTextRatio, fTextRatio);
+ } else {
+ localMatrix.reset();
+ }
+
// see if we need to create a new effect
if (textureUniqueID != fEffectTextureUniqueID ||
filteredColor != fEffectColor ||
flags != fEffectFlags ||
- !fCachedGeometryProcessor->viewMatrix().cheapEqualTo(fViewMatrix)) {
+ !fCachedGeometryProcessor->viewMatrix().cheapEqualTo(fViewMatrix) ||
+ !fCachedGeometryProcessor->localMatrix().cheapEqualTo(localMatrix)) {
GrColor color = fPaint.getColor();
+
if (fUseLCDText) {
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
@@ -505,6 +522,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
blueCorrection);
fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(color,
fViewMatrix,
+ localMatrix,
fCurrTexture,
params,
widthAdjust,
@@ -518,6 +536,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
float correction = fDistanceAdjustTable[lum >> kDistanceAdjustLumShift];
fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(color,
fViewMatrix,
+ localMatrix,
fCurrTexture,
params,
correction,
@@ -526,6 +545,7 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
#else
fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(color,
fViewMatrix,
+ localMatrix,
fCurrTexture,
params,
flags,
@@ -604,12 +624,18 @@ bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceFieldInset);
SkScalar scale = fTextRatio;
- dx *= scale;
- dy *= scale;
+ // if we're scaling up, using fix for skia:3528
+ if (scale > 1.0f) {
+ sx /= scale;
+ sy /= scale;
+ } else {
+ dx *= scale;
+ dy *= scale;
+ width *= scale;
+ height *= scale;
+ }
sx += dx;
sy += dy;
- width *= scale;
- height *= scale;
SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height);
// check if we clipped out
@@ -643,7 +669,6 @@ bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
this->flush();
SkMatrix ctm;
- ctm.setScale(fTextRatio, fTextRatio);
ctm.postTranslate(sx - dx, sy - dy);
SkPath tmpPath(*glyph->fPath);
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index d44c193260..b6cc463bac 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -51,16 +51,6 @@ public:
// emit attributes
vsBuilder->emitAttributes(dfTexEffect);
- GrGLVertToFrag st(kVec2f_GrSLType);
- args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
-
- GrGLVertToFrag uv(kVec2f_GrSLType);
- args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
- // this is only used with text, so our texture bounds always match the glyph atlas
- vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
- GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
- dfTexEffect.inTextureCoords()->fName);
#ifdef SK_GAMMA_APPLY_TO_A8
// adjust based on gamma
const char* distanceAdjustUniName = NULL;
@@ -78,9 +68,35 @@ public:
this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
// emit transforms
+ const SkMatrix& localMatrix = dfTexEffect.localMatrix();
this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
- dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
+ localMatrix, args.fTransformsIn, args.fTransformsOut);
+ // add varyings
+ GrGLVertToFrag recipScale(kFloat_GrSLType);
+ GrGLVertToFrag st(kVec2f_GrSLType);
+ bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
+ const char* viewMatrixName = this->uViewM();
+ // view matrix name is NULL if identity matrix
+ bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName;
+ if (isSimilarity && useInverseScale) {
+ args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision);
+ vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);",
+ viewMatrixName, viewMatrixName);
+ vsBuilder->codeAppend("float tx2 = dot(tx, tx);");
+ vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut());
+ } else {
+ args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
+ vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
+ }
+
+ GrGLVertToFrag uv(kVec2f_GrSLType);
+ args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
+ // this is only used with text, so our texture bounds always match the glyph atlas
+ vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
+ GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
+ dfTexEffect.inTextureCoords()->fName);
+
// Use highp to work around aliasing issues
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
pb->ctxInfo().standard()));
@@ -98,17 +114,21 @@ public:
fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
#endif
- fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
- pb->ctxInfo().standard()));
- fsBuilder->codeAppendf("vec2 st = %s;", st.fsIn());
fsBuilder->codeAppend("float afwidth;");
- if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
+ if (isSimilarity) {
// For uniform scale, we adjust for the effect of the transformation on the distance
+ // either by using the inverse scale in the view matrix, or (if there is no view matrix)
// by using the length of the gradient of the texture coordinates. We use st coordinates
- // to ensure we're mapping 1:1 from texel space to pixel space.
+ // with the latter to ensure we're mapping 1:1 from texel space to pixel space.
// this gives us a smooth step across approximately one fragment
- fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));");
+ if (useInverseScale) {
+ fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*%s);",
+ recipScale.fsIn());
+ } else {
+ fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));",
+ st.fsIn());
+ }
} else {
// For general transforms, to determine the amount of correction we multiply a unit
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
@@ -123,8 +143,8 @@ public:
fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
fsBuilder->codeAppend("}");
- fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
- fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
+ fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
+ fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
@@ -170,6 +190,7 @@ public:
key |= local.fInputColorType << 16;
key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
key |= ComputePosKey(gp.viewMatrix()) << 25;
+ key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity()) ? 0x1 << 27 : 0x0;
b->add32(key);
}
@@ -188,13 +209,14 @@ private:
GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
GrTexture* texture,
const GrTextureParams& params,
#ifdef SK_GAMMA_APPLY_TO_A8
float distanceAdjust,
#endif
uint32_t flags, bool opaqueVertexColors)
- : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
+ : INHERITED(color, viewMatrix, localMatrix, opaqueVertexColors)
, fTextureAccess(texture, params)
#ifdef SK_GAMMA_APPLY_TO_A8
, fDistanceAdjust(distanceAdjust)
@@ -281,6 +303,7 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
return GrDistanceFieldTextureEffect::Create(GrRandomColor(random),
GrProcessorUnitTest::TestMatrix(random),
+ GrProcessorUnitTest::TestMatrix(random),
textures[texIdx], params,
#ifdef SK_GAMMA_APPLY_TO_A8
random->nextF(),
@@ -564,17 +587,6 @@ public:
// emit attributes
vsBuilder->emitAttributes(dfTexEffect);
- GrGLVertToFrag st(kVec2f_GrSLType);
- args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
- vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
-
- GrGLVertToFrag uv(kVec2f_GrSLType);
- args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
- // this is only used with text, so our texture bounds always match the glyph atlas
- vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
- GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
- dfTexEffect.inTextureCoords()->fName);
-
// setup pass through color
this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
&fColorUniform);
@@ -583,9 +595,36 @@ public:
this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
// emit transforms
+ const SkMatrix& localMatrix = dfTexEffect.localMatrix();
this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
- dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
+ localMatrix, args.fTransformsIn, args.fTransformsOut);
+ // set up varyings
+ bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
+ GrGLVertToFrag recipScale(kFloat_GrSLType);
+ GrGLVertToFrag st(kVec2f_GrSLType);
+ const char* viewMatrixName = this->uViewM();
+ // view matrix name is NULL if identity matrix
+ bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName;
+ if (isUniformScale && useInverseScale) {
+ args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision);
+ vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);",
+ viewMatrixName, viewMatrixName);
+ vsBuilder->codeAppend("float tx2 = dot(tx, tx);");
+ vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut());
+ } else {
+ args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
+ vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
+ }
+
+ GrGLVertToFrag uv(kVec2f_GrSLType);
+ args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
+ // this is only used with text, so our texture bounds always match the glyph atlas
+ vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
+ GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
+ dfTexEffect.inTextureCoords()->fName);
+
+ // add frag shader code
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
@@ -598,21 +637,24 @@ public:
fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
pb->ctxInfo().standard()));
- fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
- bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
-
if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n");
} else {
fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n");
}
if (isUniformScale) {
- fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n");
- fsBuilder->codeAppend("\tvec2 offset = vec2(dx*delta, 0.0);\n");
+ if (useInverseScale) {
+ fsBuilder->codeAppendf("float dx = %s;", recipScale.fsIn());
+ } else {
+ fsBuilder->codeAppendf("float dx = dFdx(%s.x);", st.fsIn());
+ }
+ fsBuilder->codeAppend("vec2 offset = vec2(dx*delta, 0.0);");
} else {
- fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n");
- fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n");
- fsBuilder->codeAppend("\tvec2 offset = delta*Jdx;\n");
+ fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
+
+ fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
+ fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
+ fsBuilder->codeAppend("vec2 offset = delta*Jdx;");
}
// green is distance to uv center
@@ -721,6 +763,7 @@ public:
key |= local.fInputColorType << 16;
key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
key |= ComputePosKey(gp.viewMatrix()) << 25;
+ key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity()) ? 0x1 << 27 : 0x0;
b->add32(key);
}
@@ -737,10 +780,11 @@ private:
GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
GrColor color, const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
GrTexture* texture, const GrTextureParams& params,
DistanceAdjust distanceAdjust,
uint32_t flags)
- : INHERITED(color, viewMatrix, SkMatrix::I())
+ : INHERITED(color, viewMatrix, localMatrix)
, fTextureAccess(texture, params)
, fDistanceAdjust(distanceAdjust)
, fFlags(flags & kLCD_DistanceFieldEffectMask){
@@ -821,6 +865,7 @@ GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando
flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random),
GrProcessorUnitTest::TestMatrix(random),
+ GrProcessorUnitTest::TestMatrix(random),
textures[texIdx], params,
wa,
flags);
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h
index 6be7f9eef3..58d1b77a59 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -47,18 +47,20 @@ enum GrDistanceFieldEffectFlags {
class GrDistanceFieldTextureEffect : public GrGeometryProcessor {
public:
#ifdef SK_GAMMA_APPLY_TO_A8
- static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
- const GrTextureParams& params,
+ static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrTexture* tex, const GrTextureParams& params,
float lum, uint32_t flags, bool opaqueVertexColors) {
- return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, tex, params, lum,
- flags, opaqueVertexColors));
+ return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, localMatrix, tex,
+ params, lum, flags, opaqueVertexColors));
}
#else
- static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
- const GrTextureParams& params,
+ static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrTexture* tex, const GrTextureParams& params,
uint32_t flags, bool opaqueVertexColors) {
- return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, tex, params, flags,
- opaqueVertexColors));
+ return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, localMatrix, tex,
+ params, flags, opaqueVertexColors));
}
#endif
@@ -88,8 +90,8 @@ public:
const GrBatchTracker&) const override;
private:
- GrDistanceFieldTextureEffect(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
- const GrTextureParams& params,
+ GrDistanceFieldTextureEffect(GrColor, const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
+ GrTexture* texture, const GrTextureParams& params,
#ifdef SK_GAMMA_APPLY_TO_A8
float distanceAdjust,
#endif
@@ -194,11 +196,12 @@ public:
}
};
- static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
- const GrTextureParams& params,
+ static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrTexture* tex, const GrTextureParams& params,
DistanceAdjust distanceAdjust, uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldLCDTextureEffect,
- (color, viewMatrix, tex, params, distanceAdjust, flags));
+ (color, viewMatrix, localMatrix, tex, params, distanceAdjust, flags));
}
virtual ~GrDistanceFieldLCDTextureEffect() {}
@@ -224,8 +227,9 @@ public:
const GrBatchTracker&) const override;
private:
- GrDistanceFieldLCDTextureEffect(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
- const GrTextureParams& params,
+ GrDistanceFieldLCDTextureEffect(GrColor, const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix,
+ GrTexture* texture, const GrTextureParams& params,
DistanceAdjust wa, uint32_t flags);
bool onIsEqual(const GrGeometryProcessor& other) const override;