Revert "Fix SDF generation for pixel-aligned paths"
authorJim Van Verth <jvanverth@google.com>
Wed, 7 Dec 2016 20:51:11 +0000 (20:51 +0000)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 7 Dec 2016 21:24:59 +0000 (21:24 +0000)
This reverts commit 92964124c5ff61729357a51dc212ca5938093e89.

Reason for revert: Causing roll failure. Need to find images to rebaseline

Change-Id: I09cad4c3a48fefcfc669fb1045613336c88cb33a
Reviewed-on: https://skia-review.googlesource.com/5686
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
gm/pathfill.cpp
src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
src/gpu/batches/GrAADistanceFieldPathRenderer.h

index ae49a9d..3496cfd 100644 (file)
@@ -50,15 +50,15 @@ static SkScalar make_oval(SkPath* path) {
     return SkIntToScalar(30);
 }
 
-static SkScalar make_sawtooth(SkPath* path, int teeth) {
+static SkScalar make_sawtooth(SkPath* path) {
     SkScalar x = SkIntToScalar(20);
     SkScalar y = SkIntToScalar(20);
     const SkScalar x0 = x;
-    const SkScalar dx = SkIntToScalar(5);
-    const SkScalar dy = SkIntToScalar(10);
+    const SkScalar dx = SK_Scalar1 * 5;
+    const SkScalar dy = SK_Scalar1 * 10;
 
     path->moveTo(x, y);
-    for (int i = 0; i < teeth; i++) {
+    for (int i = 0; i < 32; i++) {
         x += dx;
         path->lineTo(x, y - dy);
         x += dx;
@@ -70,33 +70,6 @@ static SkScalar make_sawtooth(SkPath* path, int teeth) {
     return SkIntToScalar(30);
 }
 
-static SkScalar make_sawtooth_3(SkPath* path) { return make_sawtooth(path, 3); }
-static SkScalar make_sawtooth_32(SkPath* path) { return make_sawtooth(path, 32); }
-
-static SkScalar make_house(SkPath* path) {
-    path->moveTo(21, 23);
-    path->lineTo(21, 11.534f);
-    path->lineTo(22.327f, 12.741f);
-    path->lineTo(23.673f, 11.261f);
-    path->lineTo(12, 0.648f);
-    path->lineTo(8, 4.285f);
-    path->lineTo(8, 2);
-    path->lineTo(4, 2);
-    path->lineTo(4, 7.921f);
-    path->lineTo(0.327f, 11.26f);
-    path->lineTo(1.673f, 12.74f);
-    path->lineTo(3, 11.534f);
-    path->lineTo(3, 23);
-    path->lineTo(11, 23);
-    path->lineTo(11, 18);
-    path->lineTo(13, 18);
-    path->lineTo(13, 23);
-    path->lineTo(21, 23);
-    path->close();
-    path->offset(20, 0);
-    return SkIntToScalar(30);
-}
-
 static SkScalar make_star(SkPath* path, int n) {
     const SkScalar c = SkIntToScalar(45);
     const SkScalar r = SkIntToScalar(20);
@@ -134,12 +107,10 @@ constexpr MakePathProc gProcs[] = {
     make_triangle,
     make_rect,
     make_oval,
-    make_sawtooth_32,
+    make_sawtooth,
     make_star_5,
     make_star_13,
     make_line,
-    make_house,
-    make_sawtooth_3,
 };
 
 #define N   SK_ARRAY_COUNT(gProcs)
index e61b1cb..b06c503 100644 (file)
@@ -248,16 +248,9 @@ private:
             const SkRect& bounds = args.fShape.bounds();
             SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
             SkScalar size = maxScale * maxDim;
-            SkScalar desiredDimension;
-            // For minimizing (or the common case of identity) transforms, we try to
-            // create the DF at the appropriately sized native src-space path resolution.
-            // In the majority of cases this will yield a crisper rendering.
-            if (size <= maxDim && maxDim < kSmallMIP) {
-                desiredDimension = maxDim;
-            } else if (size <= kSmallMIP) {
+            uint32_t desiredDimension;
+            if (size <= kSmallMIP) {
                 desiredDimension = kSmallMIP;
-            } else if (size <= maxDim) {
-                desiredDimension = maxDim;
             } else if (size <= kMediumMIP) {
                 desiredDimension = kMediumMIP;
             } else {
@@ -265,7 +258,7 @@ private:
             }
 
             // check to see if path is cached
-            ShapeData::Key key(args.fShape, SkScalarCeilToInt(desiredDimension));
+            ShapeData::Key key(args.fShape, desiredDimension);
             ShapeData* shapeData = fShapeCache->find(key);
             if (nullptr == shapeData || !atlas->hasID(shapeData->fID)) {
                 // Remove the stale cache entry
@@ -275,7 +268,6 @@ private:
                     delete shapeData;
                 }
                 SkScalar scale = desiredDimension/maxDim;
-
                 shapeData = new ShapeData;
                 if (!this->addPathToAtlas(target,
                                           &flushInfo,
@@ -283,7 +275,7 @@ private:
                                           shapeData,
                                           args.fShape,
                                           args.fAntiAlias,
-                                          SkScalarCeilToInt(desiredDimension),
+                                          desiredDimension,
                                           scale)) {
                     delete shapeData;
                     SkDebugf("Can't rasterize path\n");
@@ -319,25 +311,29 @@ private:
         scaledBounds.fTop *= scale;
         scaledBounds.fRight *= scale;
         scaledBounds.fBottom *= scale;
-        // subtract out integer portion of origin
-        // (SDF created will be placed with fractional offset burnt in)
-        SkScalar dx = SkScalarFloorToInt(scaledBounds.fLeft);
-        SkScalar dy = SkScalarFloorToInt(scaledBounds.fTop);
+        // move the origin to an integer boundary (gives better results)
+        SkScalar dx = SkScalarFraction(scaledBounds.fLeft);
+        SkScalar dy = SkScalarFraction(scaledBounds.fTop);
         scaledBounds.offset(-dx, -dy);
         // get integer boundary
         SkIRect devPathBounds;
         scaledBounds.roundOut(&devPathBounds);
         // pad to allow room for antialiasing
         const int intPad = SkScalarCeilToInt(kAntiAliasPad);
-        // place devBounds at origin
-        int width = devPathBounds.width() + 2*intPad;
-        int height = devPathBounds.height() + 2*intPad;
-        devPathBounds = SkIRect::MakeWH(width, height);
+        // pre-move origin (after outset, will be 0,0)
+        int width = devPathBounds.width();
+        int height = devPathBounds.height();
+        devPathBounds.fLeft = intPad;
+        devPathBounds.fTop = intPad;
+        devPathBounds.fRight = intPad + width;
+        devPathBounds.fBottom = intPad + height;
+        devPathBounds.outset(intPad, intPad);
 
         // draw path to bitmap
         SkMatrix drawMatrix;
-        drawMatrix.setScale(scale, scale);
-        drawMatrix.postTranslate(intPad - dx, intPad - dy);
+        drawMatrix.setTranslate(-bounds.left(), -bounds.top());
+        drawMatrix.postScale(scale, scale);
+        drawMatrix.postTranslate(kAntiAliasPad, kAntiAliasPad);
 
         // setup bitmap backing
         SkASSERT(devPathBounds.fLeft == 0);
@@ -382,7 +378,7 @@ private:
         // add to atlas
         SkIPoint16 atlasLocation;
         GrBatchAtlas::AtlasID id;
-        if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atlasLocation)) {
+       if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atlasLocation)) {
             this->flush(target, flushInfo);
             if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atlasLocation)) {
                 return false;
@@ -391,20 +387,22 @@ private:
 
         // add to cache
         shapeData->fKey.set(shape, dimension);
+        shapeData->fScale = scale;
         shapeData->fID = id;
-
-        // set the bounds rect to match the size and placement of the distance field in the atlas
-        shapeData->fBounds.setXYWH(atlasLocation.fX + SK_DistanceFieldPad,
-                                   atlasLocation.fY + SK_DistanceFieldPad,
-                                   width - 2*SK_DistanceFieldPad,
-                                   height - 2*SK_DistanceFieldPad);
-        // we also need to store the transformation from texture space to the original path's space
-        // which is a simple uniform scale and translate
-        shapeData->fScaleToDev = SkScalarInvert(scale);
-        dx -= SK_DistanceFieldPad + kAntiAliasPad;
-        dy -= SK_DistanceFieldPad + kAntiAliasPad;
-        shapeData->fTranslateToDev = SkPoint::Make((-atlasLocation.fX + dx)*shapeData->fScaleToDev,
-                                                   (-atlasLocation.fY + dy)*shapeData->fScaleToDev);
+        // change the scaled rect to match the size of the inset distance field
+        scaledBounds.fRight = scaledBounds.fLeft +
+            SkIntToScalar(devPathBounds.width() - 2*SK_DistanceFieldInset);
+        scaledBounds.fBottom = scaledBounds.fTop +
+            SkIntToScalar(devPathBounds.height() - 2*SK_DistanceFieldInset);
+        // shift the origin to the correct place relative to the distance field
+        // need to also restore the fractional translation
+        scaledBounds.offset(-SkIntToScalar(SK_DistanceFieldInset) - kAntiAliasPad + dx,
+                            -SkIntToScalar(SK_DistanceFieldInset) - kAntiAliasPad + dy);
+        shapeData->fBounds = scaledBounds;
+        // origin we render from is inset from distance field edge
+        atlasLocation.fX += SK_DistanceFieldInset;
+        atlasLocation.fY += SK_DistanceFieldInset;
+        shapeData->fAtlasLocation = atlasLocation;
 
         fShapeCache->add(shapeData);
         fShapeList->addToTail(shapeData);
@@ -428,14 +426,11 @@ private:
         SkScalar width = shapeData->fBounds.width();
         SkScalar height = shapeData->fBounds.height();
 
-        // transform texture bounds to the original path's space
-        SkScalar invScale = shapeData->fScaleToDev;
+        SkScalar invScale = 1.0f / shapeData->fScale;
         dx *= invScale;
         dy *= invScale;
         width *= invScale;
         height *= invScale;
-        dx += shapeData->fTranslateToDev.fX;
-        dy += shapeData->fTranslateToDev.fY;
 
         SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
 
@@ -450,12 +445,15 @@ private:
             *colorPtr = color;
         }
 
+        const SkScalar tx = SkIntToScalar(shapeData->fAtlasLocation.fX);
+        const SkScalar ty = SkIntToScalar(shapeData->fAtlasLocation.fY);
+
         // vertex texture coords
         SkPoint* textureCoords = (SkPoint*)(offset + sizeof(SkPoint) + sizeof(GrColor));
-        textureCoords->setRectFan((shapeData->fBounds.fLeft) / texture->width(),
-                                  (shapeData->fBounds.fTop) / texture->height(),
-                                  (shapeData->fBounds.fRight)/texture->width(),
-                                  (shapeData->fBounds.fBottom)/texture->height(),
+        textureCoords->setRectFan(tx / texture->width(),
+                                  ty / texture->height(),
+                                  (tx + shapeData->fBounds.width()) / texture->width(),
+                                  (ty + shapeData->fBounds.height())  / texture->height(),
                                   vertexStride);
     }
 
index 7bb9022..171108a 100644 (file)
@@ -70,10 +70,10 @@ private:
             SkAutoSTArray<24, uint32_t> fKey;
         };
         Key                   fKey;
+        SkScalar              fScale;
         GrBatchAtlas::AtlasID fID;
         SkRect                fBounds;
-        SkScalar              fScaleToDev;
-        SkPoint               fTranslateToDev;
+        SkIPoint16            fAtlasLocation;
         SK_DECLARE_INTERNAL_LLIST_INTERFACE(ShapeData);
 
         static inline const Key& GetKey(const ShapeData& data) {