diff options
author | Yuqian Li <liyuqian@google.com> | 2017-07-25 11:26:31 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-25 21:55:19 +0000 |
commit | df60e369a8fb83c5dafded3f2453defa423f174a (patch) | |
tree | dc5383b60c1efa6430756670e8b0618465bea857 /src/core/SkEdgeBuilder.h | |
parent | 3f475d948251e00a1525914469ee72e891bf436c (diff) |
New analytic AA scan converter using delta (I call it DAA for now)
DAA is:
1. Much simpler than AAA.
SkScan_AAAPath.cpp is about 1700 lines.
SkScan_DAAPath.cpp is about 300 lines.
The whole DAA CL is only about 800 lines.
2. Much faster than AAA for complicated paths.
The speedup applies to GL backend (including ccpr)!
Here's the frame time of 'SampleApp --slide Chart' on macbook pro:
AAA-raster: 33ms
DAA-raster: 21ms
AAA-gl: 30ms
DAA-gl: 20ms
AAA-ccpr: 18ms
DAA-ccpr: 12ms
My linux desktop doesn't have SSE3 so the speedup is smaller
(~25% for Chart). I believe that DAA is so fast that I can enable
it for any paths (AAA is not enabled by default for complicated
paths because it is slow; hence our older supersampling scan
converter is used for stroking on Chart for AAA-xxx config.)
3. The SkCoverageDelta is suitable for threaded backend with
out-of-order concurrent scan conversion as commented in the source
code. Maybe we can also just send deltas to GPU.
4. Similar to most analytic path renderers, the quality is on the best
ground-truth level, unless there are intersections within a pixel.
The intersections look good to my eyes although theoretically that
could be arbitrary far from the ground truth (see my AAA slides).
5. For simple paths, such as circle, triangle, rrect, etc., DAA is
slower than AAA. But DAA is faster than our older supersampling
scan converter in most cases. As those simple paths usually don't
constitute the bottleneck of a picture (skp or svg), I strongly
recommend use DAA.
6. DAA also heavily favors blitMask so it may work quite well with
SkRasterPipeline and SkRasterPipelineBlitter.
Finally, please check https://skia-review.googlesource.com/c/22420/
which accelerate DAA by specializing blitCoverageDeltas for
SkARGB32_Blitter and SkARGB32_Black_Blitter. It brings a little(<5%)
speedup. But I couldn't figure out how to reduce the duplicate code
so I don't intend to land it.
Bug: skia:
Change-Id: I3b7ed6a727447922e645b1acb737a506e7c09a4c
Reviewed-on: https://skia-review.googlesource.com/19666
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
Diffstat (limited to 'src/core/SkEdgeBuilder.h')
-rw-r--r-- | src/core/SkEdgeBuilder.h | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/src/core/SkEdgeBuilder.h b/src/core/SkEdgeBuilder.h index 2f2b35104f..b876fcf5e5 100644 --- a/src/core/SkEdgeBuilder.h +++ b/src/core/SkEdgeBuilder.h @@ -10,6 +10,8 @@ #include "SkArenaAlloc.h" #include "SkRect.h" #include "SkTDArray.h" +#include "SkEdge.h" +#include "SkAnalyticEdge.h" struct SkEdge; struct SkAnalyticEdge; @@ -18,18 +20,27 @@ class SkPath; class SkEdgeBuilder { public: + enum EdgeType { + kEdge, + kAnalyticEdge, + kBezier + }; + + // static constexpr int kEdgeSizes[3] = {sizeof(SkEdge), sizeof(SkAnalyticEdge), sizeof(SkBezier)}; + SkEdgeBuilder(); // returns the number of built edges. The array of those edge pointers // is returned from edgeList(). int build(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight, - bool analyticAA = false); + EdgeType edgeType = kEdge); int build_edges(const SkPath& path, const SkIRect* shiftedClip, - int shiftEdgesUp, bool pathContainedInClip, bool analyticAA = false); + int shiftEdgesUp, bool pathContainedInClip, EdgeType edgeType = kEdge); SkEdge** edgeList() { return (SkEdge**)fEdgeList; } SkAnalyticEdge** analyticEdgeList() { return (SkAnalyticEdge**)fEdgeList; } + SkBezier** bezierList() { return (SkBezier**)fEdgeList; } private: enum Combine { @@ -57,7 +68,7 @@ private: void** fEdgeList; int fShiftUp; - bool fAnalyticAA; + EdgeType fEdgeType; public: void addLine(const SkPoint pts[]); @@ -66,6 +77,32 @@ public: void addClipper(SkEdgeClipper*); int buildPoly(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight); + + inline void addPolyLine(SkPoint pts[], char* &edge, size_t edgeSize, char** &edgePtr, + int shiftUp) { + if (fEdgeType == kBezier) { + if (((SkLine*)edge)->set(pts)) { + *edgePtr++ = edge; + edge += edgeSize; + } + return; + } + bool analyticAA = fEdgeType == kAnalyticEdge; + bool setLineResult = analyticAA ? + ((SkAnalyticEdge*)edge)->setLine(pts[0], pts[1]) : + ((SkEdge*)edge)->setLine(pts[0], pts[1], shiftUp); + if (setLineResult) { + Combine combine = analyticAA ? + checkVertical((SkAnalyticEdge*)edge, (SkAnalyticEdge**)edgePtr) : + checkVertical((SkEdge*)edge, (SkEdge**)edgePtr); + if (kNo_Combine == combine) { + *edgePtr++ = edge; + edge += edgeSize; + } else if (kTotal_Combine == combine) { + --edgePtr; + } + } + } }; #endif |