Revert of Distance field fixes for Android (https://codereview.chromium.org/205343008/)
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 26 Mar 2014 18:21:55 +0000 (18:21 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 26 Mar 2014 18:21:55 +0000 (18:21 +0000)
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

src/core/SkDistanceFieldGen.cpp
src/gpu/GrAtlas.cpp
src/gpu/GrAtlas.h
src/gpu/GrDistanceFieldTextContext.cpp
src/gpu/GrOvalRenderer.cpp
src/gpu/GrTextStrike.cpp
src/gpu/GrTextStrike.h
src/gpu/effects/GrDistanceFieldTextureEffect.cpp
src/gpu/effects/GrDistanceFieldTextureEffect.h
src/gpu/gl/GrGLCaps.cpp
src/gpu/gl/GrGLCaps.h

index 8ec7f32..2093a2b 100755 (executable)
@@ -336,10 +336,10 @@ bool SkGenerateDistanceFieldFromImage(unsigned char* distanceField,
     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;
index e17171f..349b47f 100644 (file)
@@ -209,3 +209,7 @@ GrPlot* GrAtlasMgr::getUnusedPlot() {
 
     return NULL;
 }
+
+SkISize GrAtlas::getSize() const {
+    return SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, GR_ATLAS_TEXTURE_HEIGHT);
+}
index c7536e3..7219ab2 100644 (file)
@@ -103,6 +103,8 @@ public:
 
     bool isEmpty() { return 0 == fPlots.count(); }
 
+    SkISize getSize() const;
+
 private:
     SkTDArray<GrPlot*> fPlots;
 
index 4ce336b..1a422c6 100755 (executable)
@@ -81,10 +81,10 @@ void GrDistanceFieldTextContext::flushGlyphs() {
         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() ||
index 23ce230..ac33a5c 100644 (file)
@@ -232,9 +232,8 @@ public:
             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 @@ public:
             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
index 7084b93..0a1fd1e 100644 (file)
@@ -181,11 +181,7 @@ void GrFontCache::dump() const {
             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* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
 
     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 @@ bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
         // 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;
index 2f2b720..8036ec3 100644 (file)
@@ -39,6 +39,8 @@ public:
     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 {
index cd80e06..9159a70 100755 (executable)
@@ -35,8 +35,6 @@ public:
         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 @@ public:
         // 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->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");
-        }
-
+        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");
+
+        // 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,24 +80,17 @@ public:
     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());
+        const GrDistanceFieldTextureEffect& distanceFieldEffect =
+                                              drawEffect.castEffect<GrDistanceFieldTextureEffect>();
+        if (distanceFieldEffect.getSize().width() != fTextureSize.width() ||
+            distanceFieldEffect.getSize().height() != fTextureSize.height()) {
+            fTextureSize = distanceFieldEffect.getSize();
             uman.set2f(fTextureSizeUni,
-                       fTextureSize.width(),
-                       fTextureSize.height());
+                       distanceFieldEffect.getSize().width(),
+                       distanceFieldEffect.getSize().height());
         }
     }
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        const GrDistanceFieldTextureEffect& dfTexEffect =
-                                              drawEffect.castEffect<GrDistanceFieldTextureEffect>();
-
-        return dfTexEffect.isUniformScale() ? 0x1 : 0x0;
-    }
-
 private:
     GrGLUniformManager::UniformHandle fTextureSizeUni;
     SkSize                            fTextureSize;
@@ -132,9 +102,9 @@ private:
 
 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 @@ GrEffectRef* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
     };
     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);
 }
index 212532e..1292c03 100644 (file)
@@ -21,8 +21,8 @@ class GrGLDistanceFieldTextureEffect;
  */
 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 @@ public:
     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 @@ public:
 
 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;
 
index 47f3f0f..a60230a 100644 (file)
@@ -47,7 +47,6 @@ void GrGLCaps::reset() {
     fFixedFunctionSupport = false;
     fDiscardFBSupport = false;
     fFullClearIsFree = false;
-    fDropsTileOnZeroDivide = false;
 }
 
 GrGLCaps::GrGLCaps(const GrGLCaps& caps) : GrDrawTargetCaps() {
@@ -85,7 +84,6 @@ GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) {
     fFixedFunctionSupport = caps.fFixedFunctionSupport;
     fDiscardFBSupport = caps.fDiscardFBSupport;
     fFullClearIsFree = caps.fFullClearIsFree;
-    fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide;
 
     return *this;
 }
@@ -246,9 +244,6 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
         }
     }
 
-    // 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 @@ SkString GrGLCaps::dump() const {
              (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;
 }
index 0939f80..7f0c887 100644 (file)
@@ -250,8 +250,6 @@ public:
 
     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 @@ private:
     bool fFixedFunctionSupport : 1;
     bool fDiscardFBSupport : 1;
     bool fFullClearIsFree : 1;
-    bool fDropsTileOnZeroDivide : 1;
 
     typedef GrDrawTargetCaps INHERITED;
 };