diff options
author | 2016-12-07 20:51:11 +0000 | |
---|---|---|
committer | 2016-12-07 21:24:59 +0000 | |
commit | e1f29c7b3c301ba8aa649ca8fb74237b4960fd4f (patch) | |
tree | 10395698cfd64bf1403fbdefe3bf57b964e7e349 | |
parent | 02e65df343d7b6d2116d6ed2a17cea3f222978e0 (diff) |
Revert "Fix SDF generation for pixel-aligned paths"
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>
-rw-r--r-- | gm/pathfill.cpp | 39 | ||||
-rw-r--r-- | src/gpu/batches/GrAADistanceFieldPathRenderer.cpp | 86 | ||||
-rw-r--r-- | src/gpu/batches/GrAADistanceFieldPathRenderer.h | 4 |
3 files changed, 49 insertions, 80 deletions
diff --git a/gm/pathfill.cpp b/gm/pathfill.cpp index ae49a9dbd6..3496cfd04d 100644 --- a/gm/pathfill.cpp +++ b/gm/pathfill.cpp @@ -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) diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp index e61b1cbd33..b06c503041 100644 --- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp @@ -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); } diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.h b/src/gpu/batches/GrAADistanceFieldPathRenderer.h index 7bb90229c4..171108af91 100644 --- a/src/gpu/batches/GrAADistanceFieldPathRenderer.h +++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.h @@ -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) { |