cull edges that are to the right of the clip

BUG=skia:

Review URL: https://codereview.chromium.org/913503002
This commit is contained in:
reed 2015-02-09 08:33:07 -08:00 committed by Commit bot
parent 70a8ca8351
commit 31223e0cb7
7 changed files with 30 additions and 24 deletions

View File

@ -80,7 +80,7 @@ static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
}
int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shiftUp,
bool clipToTheRight) {
bool canCullToTheRight) {
SkPath::Iter iter(path, true);
SkPoint pts[4];
SkPath::Verb verb;
@ -115,7 +115,7 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
break;
case SkPath::kLine_Verb: {
SkPoint lines[SkLineClipper::kMaxPoints];
int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
int lineCount = SkLineClipper::ClipLine(pts, clip, lines, canCullToTheRight);
SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments);
for (int i = 0; i < lineCount; i++) {
if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
@ -162,13 +162,13 @@ static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) {
}
int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
bool clipToTheRight) {
bool canCullToTheRight) {
fAlloc.reset();
fList.reset();
fShiftUp = shiftUp;
if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) {
return this->buildPoly(path, iclip, shiftUp, clipToTheRight);
return this->buildPoly(path, iclip, shiftUp, canCullToTheRight);
}
SkAutoConicToQuads quadder;
@ -181,7 +181,7 @@ int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
if (iclip) {
SkRect clip;
setShiftedClip(&clip, *iclip, shiftUp);
SkEdgeClipper clipper;
SkEdgeClipper clipper(canCullToTheRight);
while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
switch (verb) {
@ -192,7 +192,7 @@ int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
break;
case SkPath::kLine_Verb: {
SkPoint lines[SkLineClipper::kMaxPoints];
int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
int lineCount = SkLineClipper::ClipLine(pts, clip, lines, canCullToTheRight);
for (int i = 0; i < lineCount; i++) {
this->addLine(&lines[i]);
}

View File

@ -148,7 +148,9 @@ void SkEdgeClipper::clipMonoQuad(const SkPoint srcPts[3], const SkRect& clip) {
return;
}
if (pts[0].fX >= clip.fRight) { // wholly to the right
this->appendVLine(clip.fRight, pts[0].fY, pts[2].fY, reverse);
if (!this->canCullToTheRight()) {
this->appendVLine(clip.fRight, pts[0].fY, pts[2].fY, reverse);
}
return;
}
@ -350,7 +352,9 @@ void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) {
return;
}
if (pts[0].fX >= clip.fRight) { // wholly to the right
this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
if (!this->canCullToTheRight()) {
this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
}
return;
}

View File

@ -17,14 +17,19 @@
*/
class SkEdgeClipper {
public:
SkEdgeClipper(bool canCullToTheRight) : fCanCullToTheRight(canCullToTheRight) {}
bool clipQuad(const SkPoint pts[3], const SkRect& clip);
bool clipCubic(const SkPoint pts[4], const SkRect& clip);
SkPath::Verb next(SkPoint pts[]);
bool canCullToTheRight() const { return fCanCullToTheRight; }
private:
SkPoint* fCurrPoint;
SkPath::Verb* fCurrVerb;
const bool fCanCullToTheRight;
enum {
kMaxVerbs = 13,

View File

@ -1,10 +1,10 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkLineClipper.h"
template <typename T> T pin_unsorted(T value, T limit0, T limit1) {
@ -172,12 +172,8 @@ static void sect_with_horizontal_test_for_pin_results() {
}
#endif
int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
SkPoint lines[], bool canClipToTheRight) {
#if 1
// Disable this while we investigate layouttest failures
canClipToTheRight = false;
#endif
int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip, SkPoint lines[],
bool canCullToTheRight) {
#ifdef SK_DEBUG
{
@ -246,7 +242,7 @@ int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
result = tmp;
reverse = false;
} else if (tmp[index0].fX >= clip.fRight) { // wholly to the right
if (canClipToTheRight) {
if (canCullToTheRight) {
return 0;
}
tmp[0].fX = tmp[1].fX = clip.fRight;

View File

@ -30,7 +30,7 @@ public:
3rd segment: lines[2]..lines[3]
*/
static int ClipLine(const SkPoint pts[2], const SkRect& clip,
SkPoint lines[kMaxPoints], bool canClipToTheRight);
SkPoint lines[kMaxPoints], bool canCullToTheRight);
/* Intersect the line segment against the rect. If there is a non-empty
resulting segment, return true and set dst[] to that segment. If not,
@ -40,8 +40,7 @@ public:
segments on the sides to show where the line extended beyond the
left or right sides. IntersectLine does not.
*/
static bool IntersectLine(const SkPoint src[2], const SkRect& clip,
SkPoint dst[2]);
static bool IntersectLine(const SkPoint src[2], const SkRect& clip, SkPoint dst[2]);
};
#endif

View File

@ -431,12 +431,14 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
SkEdgeBuilder builder;
// If we're convex, then we need both edges, even the right edge is past the clip
const bool cullToTheRight = !path.isConvex();
const bool canCullToTheRight = !path.isConvex();
int count = builder.build(path, clipRect, shiftEdgesUp, canCullToTheRight);
SkASSERT(count >= 0);
int count = builder.build(path, clipRect, shiftEdgesUp, cullToTheRight);
SkEdge** list = builder.edgeList();
if (count < 2) {
if (0 == count) {
if (path.isInverseFillType()) {
/*
* Since we are in inverse-fill, our caller has already drawn above
@ -458,7 +460,6 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
rect.height() << shiftEdgesUp);
}
}
return;
}
@ -498,6 +499,7 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
}
if (path.isConvex() && (NULL == proc)) {
SkASSERT(count >= 2); // convex walker does not handle missing right edges
walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, NULL);
} else {
int rightEdge;

View File

@ -48,7 +48,7 @@ static void test_hairclipping(skiatest::Reporter* reporter) {
}
static void test_edgeclipper() {
SkEdgeClipper clipper;
SkEdgeClipper clipper(false);
const SkPoint pts[] = {
{ 3.0995476e+010f, 42.929779f },