Reland "Use DAA for small cubics and non-convex paths that fit into a mask"
This reverts commit107d53971d
. Reason for revert: Ready to rebaseline Original change's description: > Revert "Use DAA for small cubics and non-convex paths that fit into a mask" > > This reverts commit1875e05384
. > > Reason for revert: > > I don't think there's anything wrong with this, but it looks like Yuqian is out today and there is a large number of GM, SKP, and SVG images to triage from this. This is just a triage-by-revert... should be fine to reland when you're ready to triage. > > Original change's description: > > Use DAA for small cubics and non-convex paths that fit into a mask > > > > I forgot to benchmark svgs and it turns out that DAA is specifically > > good for the small cubics and small non-convex paths in svgs. This > > should make our svg performance fast again: > > > > 2.84% faster in svgparse_Florida-StateSeal.svg_1 > > 2.90% faster in svgparse_NewYork-StateSeal.svg_1 > > 2.95% faster in svgparse_Seal_of_Texas.svg_1 > > 3.05% faster in car.svg_1 > > 3.53% faster in svgparse_Vermont_state_seal.svg_1 > > 3.68% faster in svgparse_Wyoming-StateSeal.svg_1 > > 4.88% faster in svgparse_Minnesota-StateSeal.svg_1 > > 5.22% faster in svgparse_NewMexico-StateSeal.svg_1 > > 6.49% faster in svgparse_fsm.svg_1 > > > > > > Bug: skia: > > Change-Id: Ia149944443d72c12c3dda178cb5ebc89d6d0bf18 > > Reviewed-on: https://skia-review.googlesource.com/116185 > > Reviewed-by: Cary Clark <caryclark@google.com> > > Commit-Queue: Yuqian Li <liyuqian@google.com> > > TBR=caryclark@google.com,liyuqian@google.com,reed@google.com,caryclark@skia.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: skia: > Change-Id: I232f34dcea1cdabef768879a261fe6796f3e4a79 > Reviewed-on: https://skia-review.googlesource.com/116400 > Reviewed-by: Mike Klein <mtklein@google.com> > Commit-Queue: Mike Klein <mtklein@google.com> TBR=mtklein@google.com,caryclark@google.com,liyuqian@google.com,reed@google.com,caryclark@skia.org Change-Id: I6a413e3a2f1ce9182f9e209f6e2654a602170378 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: skia: Reviewed-on: https://skia-review.googlesource.com/116620 Commit-Queue: Yuqian Li <liyuqian@google.com> Reviewed-by: Yuqian Li <liyuqian@google.com>
This commit is contained in:
parent
33f02edb14
commit
c26be9c50f
@ -46,6 +46,10 @@ int SkCoverageDeltaMask::ExpandWidth(int width) {
|
||||
}
|
||||
|
||||
bool SkCoverageDeltaMask::CanHandle(const SkIRect& bounds) {
|
||||
// Return early if either width or height is very large because width * height might overflow.
|
||||
if (bounds.width() >= MAX_MASK_SIZE || bounds.height() >= MAX_MASK_SIZE) {
|
||||
return false;
|
||||
}
|
||||
// Expand width so we don't have to worry about the boundary
|
||||
return ExpandWidth(bounds.width()) * bounds.height() + PADDING * 2 < MAX_MASK_SIZE;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "SkBlitter.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkAntiRun.h"
|
||||
#include "SkCoverageDelta.h"
|
||||
|
||||
#define SHIFT SK_SUPERSAMPLE_SHIFT
|
||||
#define SCALE (1 << SHIFT)
|
||||
@ -583,6 +584,19 @@ void MaskSuperBlitter::blitH(int x, int y, int width) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkIRect safeRoundOut(const SkRect& src) {
|
||||
// roundOut will pin huge floats to max/min int
|
||||
SkIRect dst = src.roundOut();
|
||||
|
||||
// intersect with a smaller huge rect, so the rect will not be considered empty for being
|
||||
// too large. e.g. { -SK_MaxS32 ... SK_MaxS32 } is considered empty because its width
|
||||
// exceeds signed 32bit.
|
||||
const int32_t limit = SK_MaxS32 >> SK_SUPERSAMPLE_SHIFT;
|
||||
(void)dst.intersect({ -limit, -limit, limit, limit});
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
static bool ShouldUseDAA(const SkPath& path) {
|
||||
if (gSkForceDeltaAA) {
|
||||
return true;
|
||||
@ -597,12 +611,18 @@ static bool ShouldUseDAA(const SkPath& path) {
|
||||
#else
|
||||
constexpr int kSampleSize = 8;
|
||||
constexpr SkScalar kComplexityThreshold = 0.25;
|
||||
constexpr SkScalar kSmallCubicThreshold = 16;
|
||||
|
||||
int n = path.countPoints();
|
||||
if (path.isConvex() || n < kSampleSize) {
|
||||
if (path.isConvex() || n < kSampleSize || path.getBounds().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// DAA is fast with mask
|
||||
if (SkCoverageDeltaMask::CanHandle(safeRoundOut(path.getBounds()))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SkScalar sumLength = 0;
|
||||
SkPoint lastPoint = path.getPoint(0);
|
||||
for(int i = 1; i < kSampleSize; ++i) {
|
||||
@ -610,11 +630,27 @@ static bool ShouldUseDAA(const SkPath& path) {
|
||||
sumLength += SkPoint::Distance(lastPoint, point);
|
||||
lastPoint = point;
|
||||
}
|
||||
SkScalar avgLength = sumLength / (kSampleSize - 1);
|
||||
|
||||
// DAA is much faster in small cubics (since we don't have to chop them).
|
||||
// If there are many cubics, and the average length if small, use DAA.
|
||||
if (avgLength < kSmallCubicThreshold) {
|
||||
uint8_t sampleVerbs[kSampleSize];
|
||||
int verbCount = SkTMin(kSampleSize, path.getVerbs(sampleVerbs, kSampleSize));
|
||||
int cubicCount = 0;
|
||||
for(int i = 0; i < verbCount; ++i) {
|
||||
cubicCount += (sampleVerbs[i] == SkPath::kCubic_Verb);
|
||||
}
|
||||
if (cubicCount * 2 >= verbCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
SkScalar diagonal = SkPoint::Length(path.getBounds().width(), path.getBounds().height());
|
||||
|
||||
// On average, what's the distance between two consecutive points; the number is normalized
|
||||
// to a range of [0, 1] where 1 corresponds to the maximum length of the diagonal.
|
||||
SkScalar sampleSpan = sumLength / (kSampleSize - 1) / diagonal;
|
||||
SkScalar sampleSpan = avgLength / diagonal;
|
||||
|
||||
|
||||
// If the path is consist of random line segments, the number of intersections should be
|
||||
@ -687,19 +723,6 @@ static int rect_overflows_short_shift(SkIRect rect, int shift) {
|
||||
overflows_short_shift(rect.fBottom, shift);
|
||||
}
|
||||
|
||||
static SkIRect safeRoundOut(const SkRect& src) {
|
||||
// roundOut will pin huge floats to max/min int
|
||||
SkIRect dst = src.roundOut();
|
||||
|
||||
// intersect with a smaller huge rect, so the rect will not be considered empty for being
|
||||
// too large. e.g. { -SK_MaxS32 ... SK_MaxS32 } is considered empty because its width
|
||||
// exceeds signed 32bit.
|
||||
const int32_t limit = SK_MaxS32 >> SK_SUPERSAMPLE_SHIFT;
|
||||
(void)dst.intersect({ -limit, -limit, limit, limit});
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
|
||||
SkBlitter* blitter, bool forceRLE, SkDAARecord* daaRecord) {
|
||||
if (origClip.isEmpty()) {
|
||||
|
Loading…
Reference in New Issue
Block a user