Improve quad edges' smoothness in non-AA cases
Previously, non-AA quad edges only have an accuracy about 1/2 pixel (while the AA quad edges have an accuracy about 1/8 pixel). Now, we increase non-AA quad edges' accuracy to 1/8 pixel as well. The difference is very significant for rotating non-AA filled circles. For example, run `./out/Debug/SampleApp --slide GM:fillcircle` with AA turned off (by pressing b). The benchmark added reveals that increasing quad accuracy from 1/2 to 1/8 doesn't affect the performance significantly. The following is the 1/2-accuracy performance versus 1/8-accuracy performance: curr/maxrss loops min median mean max stddev samples config bench 7/17 MB 19 2.43µs 2.57µs 2.81µs 10.5µs 22% 16119 8888 path_fill_big_nonaacircle 7/17 MB 17 1.38µs 1.42µs 1.52µs 13µs 20% 21409 8888 path_fill_small_nonaacircle curr/maxrss loops min median mean max stddev samples config bench 7/17 MB 71 2.52µs 2.59µs 2.79µs 7.67µs 19% 7557 8888 path_fill_big_nonaacircle 7/17 MB 64 1.45µs 1.49µs 1.51µs 2.39µs 5% 12704 8888 path_fill_small_nonaacircle BUG=skia: Change-Id: I3482098aeafcc6f2ec9aa3382977c0dc1b650964 Reviewed-on: https://skia-review.googlesource.com/6699 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Yuqian Li <liyuqian@google.com>
This commit is contained in:
parent
2e2cb9bc76
commit
d4ed326d6f
@ -173,6 +173,23 @@ private:
|
|||||||
typedef PathBench INHERITED;
|
typedef PathBench INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NonAACirclePathBench: public CirclePathBench {
|
||||||
|
public:
|
||||||
|
NonAACirclePathBench(Flags flags) : INHERITED(flags) {}
|
||||||
|
|
||||||
|
void appendName(SkString* name) override {
|
||||||
|
name->append("nonaacircle");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupPaint(SkPaint* paint) override {
|
||||||
|
CirclePathBench::setupPaint(paint);
|
||||||
|
paint->setAntiAlias(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef CirclePathBench INHERITED;
|
||||||
|
};
|
||||||
|
|
||||||
// Test max speedup of Analytic AA for concave paths
|
// Test max speedup of Analytic AA for concave paths
|
||||||
class AAAConcavePathBench : public PathBench {
|
class AAAConcavePathBench : public PathBench {
|
||||||
public:
|
public:
|
||||||
@ -1090,6 +1107,9 @@ DEF_BENCH( return new CirclePathBench(FLAGS01); )
|
|||||||
DEF_BENCH( return new CirclePathBench(FLAGS10); )
|
DEF_BENCH( return new CirclePathBench(FLAGS10); )
|
||||||
DEF_BENCH( return new CirclePathBench(FLAGS11); )
|
DEF_BENCH( return new CirclePathBench(FLAGS11); )
|
||||||
|
|
||||||
|
DEF_BENCH( return new NonAACirclePathBench(FLAGS00); )
|
||||||
|
DEF_BENCH( return new NonAACirclePathBench(FLAGS10); )
|
||||||
|
|
||||||
DEF_BENCH( return new AAAConcavePathBench(FLAGS00); )
|
DEF_BENCH( return new AAAConcavePathBench(FLAGS00); )
|
||||||
DEF_BENCH( return new AAAConcavePathBench(FLAGS10); )
|
DEF_BENCH( return new AAAConcavePathBench(FLAGS10); )
|
||||||
DEF_BENCH( return new AAAConvexPathBench(FLAGS00); )
|
DEF_BENCH( return new AAAConvexPathBench(FLAGS00); )
|
||||||
|
@ -157,16 +157,22 @@ static inline SkFDot6 cheap_distance(SkFDot6 dx, SkFDot6 dy)
|
|||||||
return dx;
|
return dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int diff_to_shift(SkFDot6 dx, SkFDot6 dy)
|
static inline int diff_to_shift(SkFDot6 dx, SkFDot6 dy, int shiftAA = 2)
|
||||||
{
|
{
|
||||||
// cheap calc of distance from center of p0-p2 to the center of the curve
|
// cheap calc of distance from center of p0-p2 to the center of the curve
|
||||||
SkFDot6 dist = cheap_distance(dx, dy);
|
SkFDot6 dist = cheap_distance(dx, dy);
|
||||||
|
|
||||||
// shift down dist (it is currently in dot6)
|
// shift down dist (it is currently in dot6)
|
||||||
// down by 5 should give us 1/2 pixel accuracy (assuming our dist is accurate...)
|
// down by 3 should give us 1/8 pixel accuracy (assuming our dist is accurate...)
|
||||||
// this is chosen by heuristic: make it as big as possible (to minimize segments)
|
// this is chosen by heuristic: make it as big as possible (to minimize segments)
|
||||||
// ... but small enough so that our curves still look smooth
|
// ... but small enough so that our curves still look smooth
|
||||||
|
// When shift > 0, we're using AA and everything is scaled up so we can
|
||||||
|
// lower the accuracy.
|
||||||
|
#ifdef SK_SUPPORT_LEGACY_QUAD_SHIFT
|
||||||
dist = (dist + (1 << 4)) >> 5;
|
dist = (dist + (1 << 4)) >> 5;
|
||||||
|
#else
|
||||||
|
dist = (dist + (1 << 4)) >> (3 + shiftAA);
|
||||||
|
#endif
|
||||||
|
|
||||||
// each subdivision (shift value) cuts this dist (error) by 1/4
|
// each subdivision (shift value) cuts this dist (error) by 1/4
|
||||||
return (32 - SkCLZ(dist)) >> 1;
|
return (32 - SkCLZ(dist)) >> 1;
|
||||||
@ -214,7 +220,10 @@ bool SkQuadraticEdge::setQuadraticWithoutUpdate(const SkPoint pts[3], int shift)
|
|||||||
{
|
{
|
||||||
SkFDot6 dx = (SkLeftShift(x1, 1) - x0 - x2) >> 2;
|
SkFDot6 dx = (SkLeftShift(x1, 1) - x0 - x2) >> 2;
|
||||||
SkFDot6 dy = (SkLeftShift(y1, 1) - y0 - y2) >> 2;
|
SkFDot6 dy = (SkLeftShift(y1, 1) - y0 - y2) >> 2;
|
||||||
shift = diff_to_shift(dx, dy);
|
// This is a little confusing:
|
||||||
|
// before this line, shift is the scale up factor for AA;
|
||||||
|
// after this line, shift is the fCurveShift.
|
||||||
|
shift = diff_to_shift(dx, dy, shift);
|
||||||
SkASSERT(shift >= 0);
|
SkASSERT(shift >= 0);
|
||||||
}
|
}
|
||||||
// need at least 1 subdivision for our bias trick
|
// need at least 1 subdivision for our bias trick
|
||||||
|
Loading…
Reference in New Issue
Block a user