Index: src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
index cdf998ed6aa620de83179ee97eeef3aa15c9ca9a..1a8a07e3a26bda4986be8809bf1077d50be3ea7b 100755 |
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
@@ -6,7 +6,6 @@ |
*/ |
#include "GrDistanceFieldTextureEffect.h" |
-#include "GrFontAtlasSizes.h" |
#include "GrInvariantOutput.h" |
#include "GrTexture.h" |
#include "SkDistanceFieldGen.h" |
@@ -30,6 +29,7 @@ |
GrGLDistanceFieldTextureEffect(const GrGeometryProcessor&, |
const GrBatchTracker&) |
: fColor(GrColor_ILLEGAL) |
+ , fTextureSize(SkISize::Make(-1,-1)) |
#ifdef SK_GAMMA_APPLY_TO_A8 |
, fLuminance(-1.0f) |
#endif |
@@ -49,16 +49,9 @@ |
// emit attributes |
vsBuilder->emitAttributes(dfTexEffect); |
- GrGLVertToFrag st(kVec2f_GrSLType); |
- args.fPB->addVarying("IntTextureCoords", &st); |
- vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); |
- |
- GrGLVertToFrag uv(kVec2f_GrSLType); |
- args.fPB->addVarying("TextureCoords", &uv); |
- // this is only used with text, so our texture bounds always match the glyph atlas |
- vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", " |
- GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
- dfTexEffect.inTextureCoords()->fName); |
+ GrGLVertToFrag v(kVec2f_GrSLType); |
+ args.fPB->addVarying("TextureCoords", &v); |
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); |
// Setup pass through color |
this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, |
@@ -71,10 +64,15 @@ |
this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, |
dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); |
+ const char* textureSizeUniName = NULL; |
+ fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
+ kVec2f_GrSLType, kDefault_GrSLPrecision, |
+ "TextureSize", &textureSizeUniName); |
+ |
// Use highp to work around aliasing issues |
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
pb->ctxInfo().standard())); |
- fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
+ fsBuilder->codeAppendf("vec2 uv = %s;\n", v.fsIn()); |
fsBuilder->codeAppend("\tfloat texColor = "); |
fsBuilder->appendTextureLookup(args.fSamplers[0], |
@@ -89,7 +87,7 @@ |
// to ensure we're mapping 1:1 from texel space to pixel space. |
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
pb->ctxInfo().standard())); |
- fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); |
+ fsBuilder->codeAppendf("vec2 st = uv*%s;\n", textureSizeUniName); |
fsBuilder->codeAppend("\tfloat afwidth;\n"); |
if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
// this gives us a smooth step across approximately one fragment |
@@ -139,6 +137,16 @@ |
virtual void setData(const GrGLProgramDataManager& pdman, |
const GrPrimitiveProcessor& proc, |
const GrBatchTracker& bt) SK_OVERRIDE { |
+ SkASSERT(fTextureSizeUni.isValid()); |
+ |
+ GrTexture* texture = proc.texture(0); |
+ if (texture->width() != fTextureSize.width() || |
+ texture->height() != fTextureSize.height()) { |
+ fTextureSize = SkISize::Make(texture->width(), texture->height()); |
+ pdman.set2f(fTextureSizeUni, |
+ SkIntToScalar(fTextureSize.width()), |
+ SkIntToScalar(fTextureSize.height())); |
+ } |
#ifdef SK_GAMMA_APPLY_TO_A8 |
const GrDistanceFieldTextureEffect& dfTexEffect = |
proc.cast<GrDistanceFieldTextureEffect>(); |
@@ -176,6 +184,8 @@ |
private: |
GrColor fColor; |
UniformHandle fColorUniform; |
+ UniformHandle fTextureSizeUni; |
+ SkISize fTextureSize; |
UniformHandle fLuminanceUni; |
#ifdef SK_GAMMA_APPLY_TO_A8 |
float fLuminance; |
@@ -212,7 +222,7 @@ |
this->setHasVertexColor(); |
} |
fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", |
- kVec2s_GrVertexAttribType)); |
+ kVec2f_GrVertexAttribType)); |
this->addTextureAccess(&fTextureAccess); |
#ifdef SK_GAMMA_APPLY_TO_A8 |
this->addTextureAccess(&fGammaTextureAccess); |
@@ -316,7 +326,7 @@ |
public: |
GrGLDistanceFieldNoGammaTextureEffect(const GrGeometryProcessor&, |
const GrBatchTracker&) |
- : fColor(GrColor_ILLEGAL) {} |
+ : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {} |
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{ |
const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
@@ -334,25 +344,15 @@ |
// emit attributes |
vsBuilder->emitAttributes(dfTexEffect); |
- GrGLVertToFrag st(kVec2f_GrSLType); |
- args.fPB->addVarying("IntTextureCoords", &st); |
- vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); |
- |
- const char* recipTextureSizeUniName = NULL; |
- fRecipTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kVertex_Visibility, |
- kVec2f_GrSLType, kDefault_GrSLPrecision, |
- "RecipTextureSize", &recipTextureSizeUniName); |
- GrGLVertToFrag uv(kVec2f_GrSLType); |
- args.fPB->addVarying("TextureCoords", &uv); |
- // this GP can be used with either text or paths, so texture bound params need to |
- // be set by a uniform |
- vsBuilder->codeAppendf("%s = %s*%s;", uv.vsOut(), recipTextureSizeUniName, |
- dfTexEffect.inTextureCoords()->fName); |
+ GrGLVertToFrag v(kVec2f_GrSLType); |
+ args.fPB->addVarying("TextureCoords", &v); |
// setup pass through color |
this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, |
dfTexEffect.inColor(), &fColorUniform); |
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); |
+ |
// Setup position |
this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix()); |
@@ -360,10 +360,15 @@ |
this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, |
dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); |
+ const char* textureSizeUniName = NULL; |
+ fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
+ kVec2f_GrSLType, kDefault_GrSLPrecision, |
+ "TextureSize", &textureSizeUniName); |
+ |
// Use highp to work around aliasing issues |
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
pb->ctxInfo().standard())); |
- fsBuilder->codeAppendf("vec2 uv = %s;", uv.fsIn()); |
+ fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); |
fsBuilder->codeAppend("float texColor = "); |
fsBuilder->appendTextureLookup(args.fSamplers[0], |
@@ -378,7 +383,7 @@ |
// to ensure we're mapping 1:1 from texel space to pixel space. |
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
pb->ctxInfo().standard())); |
- fsBuilder->codeAppendf("vec2 st = %s;", st.fsIn()); |
+ fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); |
fsBuilder->codeAppend("float afwidth;"); |
if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
// this gives us a smooth step across approximately one fragment |
@@ -413,15 +418,15 @@ |
virtual void setData(const GrGLProgramDataManager& pdman, |
const GrPrimitiveProcessor& proc, |
const GrBatchTracker& bt) SK_OVERRIDE { |
- SkASSERT(fRecipTextureSizeUni.isValid()); |
+ SkASSERT(fTextureSizeUni.isValid()); |
GrTexture* texture = proc.texture(0); |
if (texture->width() != fTextureSize.width() || |
texture->height() != fTextureSize.height()) { |
fTextureSize = SkISize::Make(texture->width(), texture->height()); |
- pdman.set2f(fRecipTextureSizeUni, |
- 1.0f/SkIntToScalar(fTextureSize.width()), |
- 1.0f/SkIntToScalar(fTextureSize.height())); |
+ pdman.set2f(fTextureSizeUni, |
+ SkIntToScalar(fTextureSize.width()), |
+ SkIntToScalar(fTextureSize.height())); |
} |
this->setUniformViewMatrix(pdman, proc.viewMatrix()); |
@@ -452,7 +457,7 @@ |
private: |
UniformHandle fColorUniform; |
- UniformHandle fRecipTextureSizeUni; |
+ UniformHandle fTextureSizeUni; |
GrColor fColor; |
SkISize fTextureSize; |
@@ -480,7 +485,7 @@ |
this->setHasVertexColor(); |
} |
fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", |
- kVec2s_GrVertexAttribType)); |
+ kVec2f_GrVertexAttribType)); |
this->addTextureAccess(&fTextureAccess); |
} |
@@ -567,6 +572,7 @@ |
GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&, |
const GrBatchTracker&) |
: fColor(GrColor_ILLEGAL) |
+ , fTextureSize(SkISize::Make(-1,-1)) |
, fTextColor(GrColor_ILLEGAL) {} |
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) SK_OVERRIDE{ |
@@ -580,17 +586,10 @@ |
// emit attributes |
vsBuilder->emitAttributes(dfTexEffect); |
- GrGLVertToFrag st(kVec2f_GrSLType); |
- args.fPB->addVarying("IntTextureCoords", &st); |
- vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); |
- |
- GrGLVertToFrag uv(kVec2f_GrSLType); |
- args.fPB->addVarying("TextureCoords", &uv); |
- // this is only used with text, so our texture bounds always match the glyph atlas |
- vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", " |
- GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
- dfTexEffect.inTextureCoords()->fName); |
- |
+ GrGLVertToFrag v(kVec2f_GrSLType); |
+ args.fPB->addVarying("TextureCoords", &v); |
+ vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); |
+ |
// setup pass through color |
this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, |
&fColorUniform); |
@@ -601,6 +600,12 @@ |
// emit transforms |
this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, |
dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); |
+ |
+ const char* textureSizeUniName = NULL; |
+ // width, height, 1/(3*width) |
+ fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
+ kVec3f_GrSLType, kDefault_GrSLPrecision, |
+ "TextureSize", &textureSizeUniName); |
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
@@ -611,24 +616,18 @@ |
// Use highp to work around aliasing issues |
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
pb->ctxInfo().standard())); |
- fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
+ fsBuilder->codeAppendf("vec2 uv = %s;\n", v.fsIn()); |
fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
pb->ctxInfo().standard())); |
- fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); |
+ fsBuilder->codeAppendf("vec2 st = uv*%s.xy;\n", textureSizeUniName); |
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"); |
+ fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", textureSizeUniName); |
} else { |
fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
- fsBuilder->codeAppend("\tvec2 offset = delta*Jdx;\n"); |
+ fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUniName); |
} |
// green is distance to uv center |
@@ -689,6 +688,7 @@ |
// adjust based on gamma |
const char* textColorUniName = NULL; |
+ // width, height, 1/(3*width) |
fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
kVec3f_GrSLType, kDefault_GrSLPrecision, |
"TextColor", &textColorUniName); |
@@ -717,10 +717,25 @@ |
virtual void setData(const GrGLProgramDataManager& pdman, |
const GrPrimitiveProcessor& processor, |
const GrBatchTracker& bt) SK_OVERRIDE { |
+ SkASSERT(fTextureSizeUni.isValid()); |
SkASSERT(fTextColorUni.isValid()); |
const GrDistanceFieldLCDTextureEffect& dfTexEffect = |
processor.cast<GrDistanceFieldLCDTextureEffect>(); |
+ GrTexture* texture = processor.texture(0); |
+ if (texture->width() != fTextureSize.width() || |
+ texture->height() != fTextureSize.height()) { |
+ fTextureSize = SkISize::Make(texture->width(), texture->height()); |
+ float delta = 1.0f/(3.0f*texture->width()); |
+ if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { |
+ delta = -delta; |
+ } |
+ pdman.set3f(fTextureSizeUni, |
+ SkIntToScalar(fTextureSize.width()), |
+ SkIntToScalar(fTextureSize.height()), |
+ delta); |
+ } |
+ |
GrColor textColor = dfTexEffect.getTextColor(); |
if (textColor != fTextColor) { |
static const float ONE_OVER_255 = 1.f / 255.f; |
@@ -760,6 +775,8 @@ |
private: |
GrColor fColor; |
UniformHandle fColorUniform; |
+ UniformHandle fTextureSizeUni; |
+ SkISize fTextureSize; |
UniformHandle fTextColorUni; |
SkColor fTextColor; |
@@ -783,7 +800,7 @@ |
this->initClassID<GrDistanceFieldLCDTextureEffect>(); |
fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); |
fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", |
- kVec2s_GrVertexAttribType)); |
+ kVec2f_GrVertexAttribType)); |
this->addTextureAccess(&fTextureAccess); |
this->addTextureAccess(&fGammaTextureAccess); |
} |