aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-02-15 15:46:52 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-16 13:35:20 +0000
commitf9e678d6964bc5a6c2b38edbc36d9f23cf96c37f (patch)
tree990878ccfa1b0102f48d7108b9bc0000dd95cee8 /src/gpu
parentfa64774820cb42594d3f5bc2059953510f038636 (diff)
Use SDF path miplevels based on the original path's size
Should produce sharper results than arbitrary fixed sizes. Adds a new test to pathfill GM. Was: https://skia-review.googlesource.com/c/8328/ BUG=chromium:682918, skia:6238 Change-Id: Ia62ea5ce6b4a5ac2b8b51d06d57dc951d6c340b8 Reviewed-on: https://skia-review.googlesource.com/8384 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/ops/GrAADistanceFieldPathRenderer.cpp53
1 files changed, 30 insertions, 23 deletions
diff --git a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
index a72f7dc40f..7131e18a46 100644
--- a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
@@ -10,6 +10,7 @@
#include "GrBuffer.h"
#include "GrContext.h"
+#include "GrDistanceFieldGenFromVector.h"
#include "GrDrawOpTest.h"
#include "GrOpFlushState.h"
#include "GrPipelineBuilder.h"
@@ -20,10 +21,9 @@
#include "effects/GrDistanceFieldGeoProc.h"
#include "ops/GrMeshDrawOp.h"
-#include "SkPathOps.h"
#include "SkAutoMalloc.h"
#include "SkDistanceFieldGen.h"
-#include "GrDistanceFieldGenFromVector.h"
+#include "SkPathOps.h"
#define ATLAS_TEXTURE_WIDTH 2048
#define ATLAS_TEXTURE_HEIGHT 2048
@@ -39,9 +39,11 @@ static int g_NumFreedShapes = 0;
#endif
// mip levels
-static const int kSmallMIP = 32;
-static const int kMediumMIP = 73;
-static const int kLargeMIP = 162;
+static const SkScalar kMaxMIP = 162;
+
+static const SkScalar kMaxDim = 73;
+static const SkScalar kMinSize = 8;
+static const SkScalar kMaxSize = 2*kMaxMIP;
// Callback to clear out internal path cache when eviction occurs
void GrAADistanceFieldPathRenderer::HandleEviction(GrDrawOpAtlas::AtlasID id, void* pr) {
@@ -107,14 +109,20 @@ bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c
return false;
}
- // Only support paths with bounds within kMediumMIP by kMediumMIP,
- // scaled to have bounds within 2.0f*kLargeMIP by 2.0f*kLargeMIP.
+ // Only support paths with bounds within kMaxDim by kMaxDim,
+ // scaled to have bounds within kMaxSize by kMaxSize.
// The goal is to accelerate rendering of lots of small paths that may be scaling.
- SkScalar maxScale = args.fViewMatrix->getMaxScale();
+ SkScalar scaleFactors[2];
+ if (!args.fViewMatrix->getMinMaxScales(scaleFactors)) {
+ return false;
+ }
SkRect bounds = args.fShape->styledBounds();
+ SkScalar minDim = SkMinScalar(bounds.width(), bounds.height());
SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
+ SkScalar minSize = minDim * scaleFactors[0];
+ SkScalar maxSize = maxDim * scaleFactors[1];
- return maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP;
+ return maxDim <= kMaxDim && kMinSize <= minSize && maxSize <= kMaxSize;
}
////////////////////////////////////////////////////////////////////////////////
@@ -240,23 +248,22 @@ private:
SkScalar maxScale = this->viewMatrix().getMaxScale();
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.
+ // We try to create the DF at a power of two scaled path resolution (1/2, 1, 2, 4, etc)
// In the majority of cases this will yield a crisper rendering.
- if (size <= maxDim && maxDim < kSmallMIP) {
- desiredDimension = maxDim;
- } else if (size <= kSmallMIP) {
- desiredDimension = kSmallMIP;
- } else if (size <= maxDim) {
- desiredDimension = maxDim;
- } else if (size <= kMediumMIP) {
- desiredDimension = kMediumMIP;
- } else {
- desiredDimension = kLargeMIP;
+ SkScalar mipScale = 1.0f;
+ // Our mipscale is the maxScale clamped to the next highest power of 2
+ 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);
+ SkScalar desiredDimension = SkTMin(mipSize, kMaxMIP);
+
// check to see if path is cached
ShapeData::Key key(args.fShape, SkScalarCeilToInt(desiredDimension));
ShapeData* shapeData = fShapeCache->find(key);