aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-09-03 14:56:17 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-09-03 14:56:17 +0000
commitb8bd6cbbcde9846094ade18cafadfad46dc00889 (patch)
tree43c334ad5bc8b19c27341e8cfa108b9ffd01f17a /src
parent91f4d704ce16e147125b790a060575a1b74bcfa3 (diff)
Fix bounds computation in GrAAHairlineRenderer
R=robertphillips@google.com, jvanverth@google.com Author: bsalomon@google.com Review URL: https://chromiumcodereview.appspot.com/23684008 git-svn-id: http://skia.googlecode.com/svn/trunk@11054 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.cpp47
1 files changed, 31 insertions, 16 deletions
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 60992fd806..5078467fff 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -589,10 +589,8 @@ void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice,
c1.fPos = c;
c1.fPos -= cbN;
- // This point may not be within 1 pixel of a control point. We update the bounding box to
- // include it.
intersect_lines(a0.fPos, abN, c0.fPos, cbN, &b0.fPos);
- devBounds->growToInclude(b0.fPos.fX, b0.fPos.fY);
+ devBounds->growToInclude(&verts[0].fPos, sizeof(BezierVertex), kVertsPerQuad);
if (toSrc) {
toSrc->mapPointsWithStride(&verts[0].fPos, sizeof(BezierVertex), kVertsPerQuad);
@@ -723,8 +721,6 @@ bool GrAAHairLinePathRenderer::createLineGeom(
const SkMatrix& viewM = drawState->getViewMatrix();
- *devBounds = path.getBounds();
- viewM.mapRect(devBounds);
devBounds->outset(SK_Scalar1, SK_Scalar1);
int vertCnt = kVertsPerLineSeg * lineCnt;
@@ -746,10 +742,14 @@ bool GrAAHairLinePathRenderer::createLineGeom(
toSrc = &ivm;
}
}
-
+ devBounds->set(lines.begin(), lines.count());
for (int i = 0; i < lineCnt; ++i) {
add_line(&lines[2*i], rtHeight, toSrc, drawState->getCoverage(), &verts);
}
+ // All the verts computed by add_line are within unit distance of the end points. Add a little
+ // extra to account for vector normalization precision.
+ static const SkScalar kOutset = SK_Scalar1 + SK_Scalar1 / 20;
+ devBounds->outset(kOutset, kOutset);
return true;
}
@@ -769,13 +769,6 @@ bool GrAAHairLinePathRenderer::createBezierGeom(
const SkMatrix& viewM = drawState->getViewMatrix();
- // All the vertices that we compute are within 1 of path control points with the exception of
- // one of the bounding vertices for each quad. The add_quads() function will update the bounds
- // for each quad added.
- *devBounds = path.getBounds();
- viewM.mapRect(devBounds);
- devBounds->outset(SK_Scalar1, SK_Scalar1);
-
int vertCnt = kVertsPerQuad * quadCnt + kVertsPerQuad * conicCnt;
target->drawState()->setVertexAttribs<gHairlineBezierAttribs>(SK_ARRAY_COUNT(gHairlineBezierAttribs));
@@ -798,6 +791,21 @@ bool GrAAHairLinePathRenderer::createBezierGeom(
}
}
+ // Seed the dev bounds with some pts known to be inside. Each quad and conic grows the bounding
+ // box to include its vertices.
+ SkPoint seedPts[2];
+ if (quadCnt) {
+ seedPts[0] = quads[0];
+ seedPts[1] = quads[2];
+ } else if (conicCnt) {
+ seedPts[0] = conics[0];
+ seedPts[1] = conics[2];
+ }
+ if (NULL != toDevice) {
+ toDevice->mapPoints(seedPts, 2);
+ }
+ devBounds->set(seedPts[0], seedPts[1]);
+
int unsubdivQuadCnt = quads.count() / 3;
for (int i = 0; i < unsubdivQuadCnt; ++i) {
SkASSERT(qSubdivs[i] >= 0);
@@ -830,7 +838,14 @@ template <class VertexType>
bool check_bounds(GrDrawState* drawState, const SkRect& devBounds, void* vertices, int vCount)
{
SkRect tolDevBounds = devBounds;
- tolDevBounds.outset(SK_Scalar1 / 10000, SK_Scalar1 / 10000);
+ // The bounds ought to be tight, but in perspective the below code runs the verts
+ // through the view matrix to get back to dev coords, which can introduce imprecision.
+ if (drawState->getViewMatrix().hasPerspective()) {
+ tolDevBounds.outset(SK_Scalar1 / 1000, SK_Scalar1 / 1000);
+ } else {
+ // Non-persp matrices cause this path renderer to draw in device space.
+ SkASSERT(drawState->getViewMatrix().isIdentity());
+ }
SkRect actualBounds;
VertexType* verts = reinterpret_cast<VertexType*>(vertices);
@@ -880,7 +895,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
conicCnt = conics.count() / 3;
// do lines first
- {
+ if (lineCnt) {
GrDrawTarget::AutoReleaseGeometry arg;
SkRect devBounds;
@@ -926,7 +941,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
}
// then quadratics/conics
- {
+ if (quadCnt || conicCnt) {
GrDrawTarget::AutoReleaseGeometry arg;
SkRect devBounds;