Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Unified Diff: src/gpu/GrAADistanceFieldPathRenderer.cpp

Issue 687283002: Support multiple scales for dfpaths. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update based on comments Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrAADistanceFieldPathRenderer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrAADistanceFieldPathRenderer.cpp
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index 95675e4fce6b35bc3489ce7af9db66dfec54b06d..fdd0f68afeda7b58a2f9c59d1ccc289aa054ff64 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -20,7 +20,7 @@
#include "SkRTConf.h"
#define ATLAS_TEXTURE_WIDTH 1024
-#define ATLAS_TEXTURE_HEIGHT 1024
+#define ATLAS_TEXTURE_HEIGHT 2048
#define PLOT_WIDTH 256
#define PLOT_HEIGHT 256
@@ -35,6 +35,11 @@ static int g_NumCachedPaths = 0;
static int g_NumFreedPaths = 0;
#endif
+// mip levels
+static const int kSmallMIP = 32;
+static const int kMediumMIP = 64;
+static const int kLargeMIP = 128;
+
////////////////////////////////////////////////////////////////////////////////
GrAADistanceFieldPathRenderer::GrAADistanceFieldPathRenderer(GrContext* context)
: fContext(context)
@@ -72,16 +77,19 @@ bool GrAADistanceFieldPathRenderer::canDrawPath(const SkPath& path,
return false;
}
- // currently don't support perspective or scaling more than 3x
+ // currently don't support perspective
const GrDrawState& drawState = target->getDrawState();
const SkMatrix& vm = drawState.getViewMatrix();
- if (vm.hasPerspective() || vm.getMaxScale() > 3.0f) {
+ if (vm.hasPerspective()) {
return false;
}
- // only support paths smaller than 64 x 64
+ // only support paths smaller than 64x64, scaled to less than 256x256
+ // the goal is to accelerate rendering of lots of small paths that may be scaling
+ SkScalar maxScale = vm.getMaxScale();
const SkRect& bounds = path.getBounds();
- return bounds.width() < 64.f && bounds.height() < 64.f;
+ SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
+ return maxDim < 64.f && maxDim*maxScale < 256.f;
}
@@ -112,11 +120,29 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const SkPath& path,
SkASSERT(fContext);
+ // get mip level
+ const GrDrawState& drawState = target->getDrawState();
+ const SkMatrix& vm = drawState.getViewMatrix();
+ SkScalar maxScale = vm.getMaxScale();
+ const SkRect& bounds = path.getBounds();
+ SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
+ SkScalar size = maxScale*maxDim;
+ uint32_t desiredDimension;
+ if (size <= kSmallMIP) {
+ desiredDimension = kSmallMIP;
+ } else if (size <= kMediumMIP) {
+ desiredDimension = kMediumMIP;
+ } else {
+ desiredDimension = kLargeMIP;
+ }
+
// check to see if path is cached
// TODO: handle stroked vs. filled version of same path
- PathData* pathData = fPathCache.find(path.getGenerationID());
+ PathData::Key key = { path.getGenerationID(), desiredDimension };
+ PathData* pathData = fPathCache.find(key);
if (NULL == pathData) {
- pathData = this->addPathToAtlas(path, stroke, antiAlias);
+ SkScalar scale = desiredDimension/maxDim;
+ pathData = this->addPathToAtlas(path, stroke, antiAlias, desiredDimension, scale);
if (NULL == pathData) {
return false;
}
@@ -126,15 +152,15 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const SkPath& path,
return this->internalDrawPath(path, pathData, target);
}
-// factor used to scale the path prior to building distance field
-const SkScalar kScaleFactor = 2.0f;
// padding around path bounds to allow for antialiased pixels
const SkScalar kAntiAliasPad = 1.0f;
GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathToAtlas(
const SkPath& path,
const SkStrokeRec& stroke,
- bool antiAlias) {
+ bool antiAlias,
+ uint32_t dimension,
+ SkScalar scale) {
// generate distance field and add to atlas
if (NULL == fAtlas) {
@@ -151,11 +177,11 @@ GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathT
// generate bounding rect for bitmap draw
SkRect scaledBounds = bounds;
- // scale up to improve maxification range
- scaledBounds.fLeft *= kScaleFactor;
- scaledBounds.fTop *= kScaleFactor;
- scaledBounds.fRight *= kScaleFactor;
- scaledBounds.fBottom *= kScaleFactor;
+ // scale to mip level size
+ scaledBounds.fLeft *= scale;
+ scaledBounds.fTop *= scale;
+ scaledBounds.fRight *= scale;
+ scaledBounds.fBottom *= scale;
// move the origin to an integer boundary (gives better results)
SkScalar dx = SkScalarFraction(scaledBounds.fLeft);
SkScalar dy = SkScalarFraction(scaledBounds.fTop);
@@ -171,7 +197,7 @@ GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathT
// draw path to bitmap
SkMatrix drawMatrix;
drawMatrix.setTranslate(-bounds.left(), -bounds.top());
- drawMatrix.postScale(kScaleFactor, kScaleFactor);
+ drawMatrix.postScale(scale, scale);
drawMatrix.postTranslate(kAntiAliasPad, kAntiAliasPad);
GrSWMaskHelper helper(fContext);
@@ -226,7 +252,9 @@ GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathT
HAS_ATLAS:
// add to cache
PathData* pathData = SkNEW(PathData);
- pathData->fGenID = path.getGenerationID();
+ pathData->fKey.fGenID = path.getGenerationID();
+ pathData->fKey.fDimension = dimension;
+ pathData->fScale = scale;
pathData->fPlot = plot;
// change the scaled rect to match the size of the inset distance field
scaledBounds.fRight = scaledBounds.fLeft +
@@ -267,7 +295,7 @@ bool GrAADistanceFieldPathRenderer::freeUnusedPlot() {
while ((pathData = iter.get())) {
iter.next();
if (plot == pathData->fPlot) {
- fPathCache.remove(pathData->fGenID);
+ fPathCache.remove(pathData->fKey);
fPathList.remove(pathData);
SkDELETE(pathData);
#ifdef DF_PATH_TRACKING
@@ -305,7 +333,7 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(const SkPath& path,
SkScalar width = pathData->fBounds.width();
SkScalar height = pathData->fBounds.height();
- SkScalar invScale = 1.0f/kScaleFactor;
+ SkScalar invScale = 1.0f/pathData->fScale;
dx *= invScale;
dy *= invScale;
width *= invScale;
« no previous file with comments | « src/gpu/GrAADistanceFieldPathRenderer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698