aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-02-17 14:02:13 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-21 15:31:56 +0000
commit25b8ca1ee794867f4d0f08b8d3a4fe6ac4ff7387 (patch)
tree6671b852dca1b62dfc6a3286a553679ee930534b /src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
parent1b5b944f69cf0f59060c19c0cb88029f0528b1ac (diff)
Clean up DFs for extremely small paths
BUG=skia:6255 Change-Id: Ie2b645c4e18fab30c67cd3ee9857f7b003713339 Reviewed-on: https://skia-review.googlesource.com/8665 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src/gpu/ops/GrAADistanceFieldPathRenderer.cpp')
-rw-r--r--src/gpu/ops/GrAADistanceFieldPathRenderer.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
index 0bc356db81..c5842c0913 100644
--- a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
@@ -39,10 +39,11 @@ static int g_NumFreedShapes = 0;
#endif
// mip levels
+static const SkScalar kIdealMinMIP = 12;
static const SkScalar kMaxMIP = 162;
static const SkScalar kMaxDim = 73;
-static const SkScalar kMinSize = 4;
+static const SkScalar kMinSize = SK_ScalarHalf;
static const SkScalar kMaxSize = 2*kMaxMIP;
// Callback to clear out internal path cache when eviction occurs
@@ -252,16 +253,31 @@ private:
// In the majority of cases this will yield a crisper rendering.
SkScalar mipScale = 1.0f;
// Our mipscale is the maxScale clamped to the next highest power of 2
- if (maxScale < SK_ScalarHalf) {
+ if (maxScale <= SK_ScalarHalf) {
SkScalar log = SkScalarFloorToScalar(SkScalarLog2(SkScalarInvert(maxScale)));
mipScale = SkScalarPow(2, -log);
} else if (maxScale > SK_Scalar1) {
SkScalar log = SkScalarCeilToScalar(SkScalarLog2(maxScale));
mipScale = SkScalarPow(2, log);
}
-
- SkScalar mipSize = mipScale*maxDim;
- SkASSERT(maxScale * maxDim <= mipSize);
+ SkASSERT(maxScale <= mipScale);
+
+ SkScalar mipSize = mipScale*SkScalarAbs(maxDim);
+ // For sizes less than kIdealMinMIP we want to use as large a distance field as we can
+ // so we can preserve as much detail as possible. However, we can't scale down more
+ // than a 1/4 of the size without artifacts. So the idea is that we pick the mipsize
+ // just bigger than the ideal, and then scale down until we are no more than 4x the
+ // original mipsize.
+ if (mipSize < kIdealMinMIP) {
+ SkScalar newMipSize = mipSize;
+ do {
+ newMipSize *= 2;
+ } while (newMipSize < kIdealMinMIP);
+ while (newMipSize > 4*mipSize) {
+ newMipSize *= 0.25f;
+ }
+ mipSize = newMipSize;
+ }
SkScalar desiredDimension = SkTMin(mipSize, kMaxMIP);
// check to see if path is cached
@@ -340,6 +356,8 @@ private:
SkASSERT(devPathBounds.fLeft == 0);
SkASSERT(devPathBounds.fTop == 0);
+ SkASSERT(devPathBounds.width() > 0);
+ SkASSERT(devPathBounds.height() > 0);
// setup signed distance field storage
SkIRect dfBounds = devPathBounds.makeOutset(SK_DistanceFieldPad, SK_DistanceFieldPad);