Chromium Code Reviews| 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)); |