Revert of Distance field fixes for Android (https://codereview.chromium.org/205343008/)
Reason for revert:
compile error at line 110 in GrDistanceFieldTextureEffect.cpp
Original issue's description:
> Distance field fixes for Android
> - Expand glyph size by 2 on each side to compensate for bilerp lookup
> - Correct for Adreno tendency to drop entire tile if any pixel has divide-by-0
> - Fix blurriness on Adreno by using uv coords to compute gradient instead
> of st coords
> - Add faster version for uniform scale
>
> BUG=skia:2173
>
> Committed: http://code.google.com/p/skia/source/detail?r=13955
R=bsalomon@google.com
TBR=bsalomon@google.com
NOTREECHECKS=true
NOTRY=true
BUG=skia:2173
Author: jvanverth@google.com
Review URL: https://codereview.chromium.org/212953008
git-svn-id: http://skia.googlecode.com/svn/trunk@13956 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkDistanceFieldGen.cpp b/src/core/SkDistanceFieldGen.cpp
index 8ec7f32..2093a2b 100755
--- a/src/core/SkDistanceFieldGen.cpp
+++ b/src/core/SkDistanceFieldGen.cpp
@@ -336,10 +336,10 @@
SkASSERT(NULL != image);
// the final distance field will have additional texels on each side to handle
- // the maximum distance + 1 for bilerp
+ // the maximum distance
// we expand our temp data by one more on each side to simplify
// the scanning code -- will always be treated as infinitely far away
- int pad = distanceMagnitude+2;
+ int pad = distanceMagnitude+1;
// set params for distance field data
int dataWidth = width + 2*pad;
diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp
index e17171f..349b47f 100644
--- a/src/gpu/GrAtlas.cpp
+++ b/src/gpu/GrAtlas.cpp
@@ -209,3 +209,7 @@
return NULL;
}
+
+SkISize GrAtlas::getSize() const {
+ return SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, GR_ATLAS_TEXTURE_HEIGHT);
+}
diff --git a/src/gpu/GrAtlas.h b/src/gpu/GrAtlas.h
index c7536e3..7219ab2 100644
--- a/src/gpu/GrAtlas.h
+++ b/src/gpu/GrAtlas.h
@@ -103,6 +103,8 @@
bool isEmpty() { return 0 == fPlots.count(); }
+ SkISize getSize() const;
+
private:
SkTDArray<GrPlot*> fPlots;
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 4ce336b..1a422c6 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -81,10 +81,10 @@
GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
// This effect could be stored with one of the cache objects (atlas?)
+ SkISize size = fStrike->getAtlasSize();
drawState->addCoverageEffect(
- GrDistanceFieldTextureEffect::Create(fCurrTexture, params,
- fContext->getMatrix().isSimilarity()),
- kGlyphCoordsAttributeIndex)->unref();
+ GrDistanceFieldTextureEffect::Create(fCurrTexture, params, size),
+ kGlyphCoordsAttributeIndex)->unref();
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 23ce230..ac33a5c 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -232,9 +232,8 @@
builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
// we need to clamp the length^2 of the gradiant vector to a non-zero value, because
// on the Nexus 4 the undefined result of inversesqrt(0) drops out an entire tile
- if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
- builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
- }
+ // TODO: restrict this to Adreno-only
+ builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
@@ -381,9 +380,8 @@
builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
// we need to clamp the length^2 of the gradiant vector to a non-zero value, because
// on the Nexus 4 the undefined result of inversesqrt(0) drops out an entire tile
- if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
- builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
- }
+ // TODO: restrict this to Adreno-only
+ builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
if (kHairline == ellipseEffect.getMode()) {
// can probably do this with one step
diff --git a/src/gpu/GrTextStrike.cpp b/src/gpu/GrTextStrike.cpp
index 7084b93..0a1fd1e 100644
--- a/src/gpu/GrTextStrike.cpp
+++ b/src/gpu/GrTextStrike.cpp
@@ -181,11 +181,7 @@
GrTexture* texture = fAtlasMgr[i]->getTexture();
if (NULL != texture) {
SkString filename;
-#ifdef SK_BUILD_FOR_ANDROID
- filename.printf("/sdcard/fontcache_%d%d.png", gDumpCount, i);
-#else
filename.printf("fontcache_%d%d.png", gDumpCount, i);
-#endif
texture->savePixels(filename.c_str());
}
}
@@ -252,13 +248,11 @@
GrGlyph* glyph = fPool.alloc();
// expand bounds to hold full distance field data
- // + room for bilerp
- int pad = DISTANCE_FIELD_RANGE+1;
if (fUseDistanceField) {
- bounds.fLeft -= pad;
- bounds.fRight += pad;
- bounds.fTop -= pad;
- bounds.fBottom += pad;
+ bounds.fLeft -= DISTANCE_FIELD_RANGE;
+ bounds.fRight += DISTANCE_FIELD_RANGE;
+ bounds.fTop -= DISTANCE_FIELD_RANGE;
+ bounds.fBottom += DISTANCE_FIELD_RANGE;
}
glyph->init(packed, bounds);
fCache.insert(packed, glyph);
@@ -298,9 +292,8 @@
// but must shrink back down to get the packed glyph data
int dfWidth = glyph->width();
int dfHeight = glyph->height();
- int pad = DISTANCE_FIELD_RANGE+1;
- int width = dfWidth - 2*pad;
- int height = dfHeight - 2*pad;
+ int width = dfWidth - 2*DISTANCE_FIELD_RANGE;
+ int height = dfHeight - 2*DISTANCE_FIELD_RANGE;
int stride = width*bytesPerPixel;
size_t size = width * height * bytesPerPixel;
diff --git a/src/gpu/GrTextStrike.h b/src/gpu/GrTextStrike.h
index 2f2b720..8036ec3 100644
--- a/src/gpu/GrTextStrike.h
+++ b/src/gpu/GrTextStrike.h
@@ -39,6 +39,8 @@
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
bool addGlyphToAtlas(GrGlyph*, GrFontScaler*);
+ SkISize getAtlasSize() const { return fAtlas.getSize(); }
+
// testing
int countGlyphs() const { return fCache.getArray().count(); }
const GrGlyph* glyphAt(int index) const {
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index cd80e06..9159a70 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -35,8 +35,6 @@
SkASSERT(1 == drawEffect.castEffect<GrDistanceFieldTextureEffect>().numVertexAttribs());
SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
- const GrDistanceFieldTextureEffect& dfTexEffect =
- drawEffect.castEffect<GrDistanceFieldTextureEffect>();
SkString fsCoordName;
const char* vsCoordName;
@@ -63,37 +61,16 @@
// we adjust for the effect of the transformation on the distance 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.
- builder->fsCodeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
- builder->fsCodeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
- builder->fsCodeAppend("\tfloat afwidth;\n");
- if (dfTexEffect.isUniformScale()) {
- // this gives us a smooth step across approximately one fragment
- // (assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2)
- builder->fsCodeAppend("\tafwidth = 0.7071*dFdx(st.x);\n");
- } else {
- builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
- builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
+ builder->fsCodeAppendf("\tvec2 st = %s*%s;\n", fsCoordName.c_str(), textureSizeUniName);
+ builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n");
+ builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n");
+ builder->fsCodeAppend("\tvec2 st_grad = normalize(st);\n");
+ builder->fsCodeAppend("\tvec2 grad = vec2(st_grad.x*Jdx.x + st_grad.y*Jdy.x,\n");
+ builder->fsCodeAppend("\t st_grad.x*Jdx.y + st_grad.y*Jdy.y);\n");
- builder->fsCodeAppend("\tvec2 uv_grad;\n");
- if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) {
- // this is to compensate for the Adreno, which likes to drop tiles on division by 0
- builder->fsCodeAppend("\tfloat uv_len2 = dot(uv, uv);\n");
- builder->fsCodeAppend("\tif (uv_len2 < 0.0001) {\n");
- builder->fsCodeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n");
- builder->fsCodeAppend("\t} else {\n");
- builder->fsCodeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n");
- builder->fsCodeAppend("\t}\n");
- } else {
- builder->fsCodeAppend("\tuv_grad = normalize(uv);\n");
- }
- builder->fsCodeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n");
- builder->fsCodeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n");
-
- // this gives us a smooth step across approximately one fragment
- // (assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2)
- builder->fsCodeAppend("\tafwidth = 0.7071*length(grad);\n");
- }
-
+ // this gives us a smooth step across approximately one fragment
+ // (assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2)
+ builder->fsCodeAppend("\tfloat afwidth = 0.7071*length(grad);\n");
builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n");
builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
@@ -103,22 +80,15 @@
virtual void setData(const GrGLUniformManager& uman,
const GrDrawEffect& drawEffect) SK_OVERRIDE {
SkASSERT(fTextureSizeUni.isValid());
-
- GrTexture* texture = drawEffect.effect()->get()->texture(0);
- if (texture->width() != fTextureSize.width() ||
- texture->height() != fTextureSize.height()) {
- fTextureSize = SkSize::Make(texture->width(), texture->height());
- uman.set2f(fTextureSizeUni,
- fTextureSize.width(),
- fTextureSize.height());
- }
- }
-
- static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
- const GrDistanceFieldTextureEffect& dfTexEffect =
+ const GrDistanceFieldTextureEffect& distanceFieldEffect =
drawEffect.castEffect<GrDistanceFieldTextureEffect>();
-
- return dfTexEffect.isUniformScale() ? 0x1 : 0x0;
+ if (distanceFieldEffect.getSize().width() != fTextureSize.width() ||
+ distanceFieldEffect.getSize().height() != fTextureSize.height()) {
+ fTextureSize = distanceFieldEffect.getSize();
+ uman.set2f(fTextureSizeUni,
+ distanceFieldEffect.getSize().width(),
+ distanceFieldEffect.getSize().height());
+ }
}
private:
@@ -132,9 +102,9 @@
GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture,
const GrTextureParams& params,
- bool uniformScale)
+ const SkISize& size)
: fTextureAccess(texture, params)
- , fUniformScale(uniformScale) {
+ , fSize(SkSize::Make(SkIntToScalar(size.width()), SkIntToScalar(size.height()))) {
this->addTextureAccess(&fTextureAccess);
this->addVertexAttrib(kVec2f_GrSLType);
}
@@ -179,6 +149,7 @@
};
GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
+ SkISize size = SkISize::Make(1024, 2048);
- return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, random->nextBool());
+ return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, size);
}
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h
index 212532e..1292c03 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -21,8 +21,8 @@
*/
class GrDistanceFieldTextureEffect : public GrVertexEffect {
public:
- static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& para, bool uniformScale) {
- AutoEffectUnref effect(SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, para, uniformScale)));
+ static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& p, const SkISize& s) {
+ AutoEffectUnref effect(SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, p, s)));
return CreateEffectRef(effect);
}
@@ -31,7 +31,7 @@
static const char* Name() { return "DistanceFieldTexture"; }
virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
- bool isUniformScale() const { return fUniformScale; }
+ const SkSize& getSize() const { return fSize; }
typedef GrGLDistanceFieldTextureEffect GLEffect;
@@ -39,12 +39,12 @@
private:
GrDistanceFieldTextureEffect(GrTexture* texture, const GrTextureParams& params,
- bool uniformScale);
+ const SkISize& textureSize);
virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
GrTextureAccess fTextureAccess;
- bool fUniformScale;
+ SkSize fSize;
GR_DECLARE_EFFECT_TEST;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 47f3f0f..a60230a 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -47,7 +47,6 @@
fFixedFunctionSupport = false;
fDiscardFBSupport = false;
fFullClearIsFree = false;
- fDropsTileOnZeroDivide = false;
}
GrGLCaps::GrGLCaps(const GrGLCaps& caps) : GrDrawTargetCaps() {
@@ -85,7 +84,6 @@
fFixedFunctionSupport = caps.fFixedFunctionSupport;
fDiscardFBSupport = caps.fDiscardFBSupport;
fFullClearIsFree = caps.fFullClearIsFree;
- fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide;
return *this;
}
@@ -246,9 +244,6 @@
}
}
- // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero in a shader
- fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor();
-
this->initFSAASupport(ctxInfo, gli);
this->initStencilFormats(ctxInfo);
@@ -666,6 +661,5 @@
(fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
r.appendf("Discard FrameBuffer support: %s\n", (fDiscardFBSupport ? "YES" : "NO"));
r.appendf("Full screen clear is free: %s\n", (fFullClearIsFree ? "YES" : "NO"));
- r.appendf("Drops tile on zero divide: %s\n", (fDropsTileOnZeroDivide ? "YES" : "NO"));
return r;
}
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 0939f80..7f0c887 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -250,8 +250,6 @@
bool fullClearIsFree() const { return fFullClearIsFree; }
- bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
-
private:
/**
* Maintains a bit per GrPixelConfig. It is used to avoid redundantly
@@ -334,7 +332,6 @@
bool fFixedFunctionSupport : 1;
bool fDiscardFBSupport : 1;
bool fFullClearIsFree : 1;
- bool fDropsTileOnZeroDivide : 1;
typedef GrDrawTargetCaps INHERITED;
};