Index: src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
index e94cd591f3e30925c6b077c58976c4c0af19a828..3313eb1b5bdd5fda206671e491407055e27344bb 100644 |
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
@@ -1,6 +1,7 @@ |
/* |
* Copyright 2014 Google Inc. |
+ * Copyright 2016 ARM Ltd. |
* |
* Use of this source code is governed by a BSD-style license that can be |
* found in the LICENSE file. |
@@ -21,7 +22,9 @@ |
#include "effects/GrDistanceFieldGeoProc.h" |
#include "SkDistanceFieldGen.h" |
+#include "GrDistanceFieldGenFromVector.h" |
#include "SkRTConf.h" |
+#include "SkPathOps.h" |
#define ATLAS_TEXTURE_WIDTH 2048 |
#define ATLAS_TEXTURE_HEIGHT 2048 |
@@ -94,7 +97,7 @@ bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c |
if (args.fViewMatrix->hasPerspective()) { |
return false; |
} |
- |
+ |
// only support paths with bounds within kMediumMIP by kMediumMIP, |
// scaled to have bounds within 2.0f*kLargeMIP by 2.0f*kLargeMIP |
// the goal is to accelerate rendering of lots of small paths that may be scaling |
@@ -109,7 +112,7 @@ bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c |
} |
maxDim += extraWidth; |
} |
- |
+ |
return maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP; |
} |
@@ -153,7 +156,7 @@ public: |
const char* name() const override { return "AADistanceFieldPathBatch"; } |
- void computePipelineOptimizations(GrInitInvariantOutput* color, |
+ void computePipelineOptimizations(GrInitInvariantOutput* color, |
GrInitInvariantOutput* coverage, |
GrBatchToXPOverrides* overrides) const override { |
color->setKnownFourComponents(fGeoData[0].fColor); |
@@ -358,49 +361,66 @@ private: |
drawMatrix.postScale(scale, scale); |
drawMatrix.postTranslate(kAntiAliasPad, kAntiAliasPad); |
- // setup bitmap backing |
SkASSERT(devPathBounds.fLeft == 0); |
SkASSERT(devPathBounds.fTop == 0); |
- SkAutoPixmapStorage dst; |
- if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(), |
- devPathBounds.height()))) { |
- return false; |
- } |
- sk_bzero(dst.writable_addr(), dst.getSafeSize()); |
- // rasterize path |
- SkPaint paint; |
- paint.setStyle(SkPaint::kFill_Style); |
- paint.setAntiAlias(antiAlias); |
+ // setup signed distance field storage |
+ SkIRect sdfPathBounds = devPathBounds.makeOutset(SK_DistanceFieldPad, SK_DistanceFieldPad); |
+ width = sdfPathBounds.width(); |
+ height = sdfPathBounds.height(); |
+ // TODO We should really generate this directly into the plot somehow |
+ SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); |
+ |
+ bool success = false; |
+ SkPath simplifiedPath; |
+ |
+ Simplify(path, &simplifiedPath); |
bsalomon
2016/02/06 13:22:06
Should this go into GrGenerateDistanceFieldFromPat
Joel.Liang
2016/02/17 10:42:42
Done.
|
- SkDraw draw; |
- sk_bzero(&draw, sizeof(draw)); |
+ if (SkPath::kEvenOdd_FillType == simplifiedPath.getFillType()) { |
bsalomon
2016/02/06 13:22:06
Can this be an assert rather than a branch?
Joel.Liang
2016/02/17 10:42:42
Done and moved the assertion into GrGenerateDistan
|
+ // Generate signed distance field directly from SkPath |
+ success = GrGenerateDistanceFieldFromPath((unsigned char*)dfStorage.get(), |
+ simplifiedPath, drawMatrix, |
+ width, height, width * sizeof(unsigned char)); |
+ } |
+ if (!success) { |
+ SkASSERT(false && |
bsalomon
2016/02/06 13:22:06
This seems like a lot of code for a fallback we ne
Joel.Liang
2016/02/15 08:36:48
We will need this fallback if "get_direction" may
Joel.Liang
2016/02/17 10:42:42
I have removed the fallback code as now we can han
|
+ "We should use GrGenerateDistanceFieldFromPath to generate SDF for all paths."); |
+ |
+ // setup bitmap backing |
+ SkAutoPixmapStorage dst; |
+ if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(), |
+ devPathBounds.height()))) { |
+ return false; |
+ } |
+ sk_bzero(dst.writable_addr(), dst.getSafeSize()); |
- SkRasterClip rasterClip; |
- rasterClip.setRect(devPathBounds); |
- draw.fRC = &rasterClip; |
- draw.fClip = &rasterClip.bwRgn(); |
- draw.fMatrix = &drawMatrix; |
- draw.fDst = dst; |
+ // rasterize path |
+ SkPaint paint; |
+ paint.setStyle(SkPaint::kFill_Style); |
+ paint.setAntiAlias(antiAlias); |
- draw.drawPathCoverage(path, paint); |
+ SkDraw draw; |
+ sk_bzero(&draw, sizeof(draw)); |
- // generate signed distance field |
- devPathBounds.outset(SK_DistanceFieldPad, SK_DistanceFieldPad); |
- width = devPathBounds.width(); |
- height = devPathBounds.height(); |
- // TODO We should really generate this directly into the plot somehow |
- SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); |
+ SkRasterClip rasterClip; |
+ rasterClip.setRect(devPathBounds); |
+ draw.fRC = &rasterClip; |
+ draw.fClip = &rasterClip.bwRgn(); |
+ draw.fMatrix = &drawMatrix; |
+ draw.fDst = dst; |
+ |
+ draw.drawPathCoverage(simplifiedPath, paint); |
- // Generate signed distance field |
- SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(), |
- (const unsigned char*)dst.addr(), |
- dst.width(), dst.height(), dst.rowBytes()); |
+ // Generate signed distance field |
+ SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(), |
+ (const unsigned char*)dst.addr(), |
+ dst.width(), dst.height(), dst.rowBytes()); |
+ } |
// add to atlas |
SkIPoint16 atlasLocation; |
GrBatchAtlas::AtlasID id; |
- bool success = atlas->addToAtlas(&id, target, width, height, dfStorage.get(), |
+ success = atlas->addToAtlas(&id, target, width, height, dfStorage.get(), |
&atlasLocation); |
if (!success) { |
this->flush(target, flushInfo); |
@@ -568,7 +588,7 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) { |
// generated due to stroking it is important that the original path's id is used |
// for caching. |
geometry.fGenID = args.fPath->getGenerationID(); |
- |
+ |
SkAutoTUnref<GrDrawBatch> batch(AADistanceFieldPathBatch::Create(geometry, |
*args.fViewMatrix, fAtlas, |
&fPathCache, &fPathList)); |