Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Unified Diff: src/gpu/GrAAHairLinePathRenderer.cpp

Issue 15465005: Reland path bounds change with correct bounds for convex and hairline path renderers. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: tighter tolerances Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.h ('k') | src/gpu/GrDefaultPathRenderer.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrAAHairLinePathRenderer.cpp
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index da54ed643c1d99a990791cd19848a78e45a82747..8e3ec5b02e9e433b966f4fc00dc10b8112f244c6 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -360,7 +360,8 @@ void intersect_lines(const SkPoint& ptA, const SkVector& normA,
}
void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice,
- const SkMatrix* toSrc, Vertex verts[kVertsPerQuad]) {
+ const SkMatrix* toSrc, Vertex verts[kVertsPerQuad],
+ SkRect* devBounds) {
GrAssert(!toDevice == !toSrc);
// original quad is specified by tri a,b,c
SkPoint a = qpts[0];
@@ -427,7 +428,10 @@ 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);
if (toSrc) {
toSrc->mapPointsWithStride(&verts[0].fPos, sizeof(Vertex), kVertsPerQuad);
@@ -439,15 +443,16 @@ void add_quads(const SkPoint p[3],
int subdiv,
const SkMatrix* toDevice,
const SkMatrix* toSrc,
- Vertex** vert) {
+ Vertex** vert,
+ SkRect* devBounds) {
GrAssert(subdiv >= 0);
if (subdiv) {
SkPoint newP[5];
SkChopQuadAtHalf(p, newP);
- add_quads(newP + 0, subdiv-1, toDevice, toSrc, vert);
- add_quads(newP + 2, subdiv-1, toDevice, toSrc, vert);
+ add_quads(newP + 0, subdiv-1, toDevice, toSrc, vert, devBounds);
+ add_quads(newP + 2, subdiv-1, toDevice, toSrc, vert, devBounds);
} else {
- bloat_quad(p, toDevice, toSrc, *vert);
+ bloat_quad(p, toDevice, toSrc, *vert, devBounds);
*vert += kVertsPerQuad;
}
}
@@ -704,7 +709,8 @@ bool GrAAHairLinePathRenderer::createGeom(
GrDrawTarget* target,
int* lineCnt,
int* quadCnt,
- GrDrawTarget::AutoReleaseGeometry* arg) {
+ GrDrawTarget::AutoReleaseGeometry* arg,
+ SkRect* devBounds) {
GrDrawState* drawState = target->drawState();
int rtHeight = drawState->getRenderTarget()->height();
@@ -714,6 +720,13 @@ bool GrAAHairLinePathRenderer::createGeom(
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);
+
PREALLOC_PTARRAY(128) lines;
PREALLOC_PTARRAY(128) quads;
IntArray qSubdivs;
@@ -750,7 +763,7 @@ bool GrAAHairLinePathRenderer::createGeom(
int unsubdivQuadCnt = quads.count() / 3;
for (int i = 0; i < unsubdivQuadCnt; ++i) {
GrAssert(qSubdivs[i] >= 0);
- add_quads(&quads[3*i], qSubdivs[i], toDevice, toSrc, &verts);
+ add_quads(&quads[3*i], qSubdivs[i], toDevice, toSrc, &verts, devBounds);
}
return true;
@@ -781,11 +794,14 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
int lineCnt;
int quadCnt;
GrDrawTarget::AutoReleaseGeometry arg;
+ SkRect devBounds;
+
if (!this->createGeom(path,
target,
&lineCnt,
&quadCnt,
- &arg)) {
+ &arg,
+ &devBounds)) {
return false;
}
@@ -816,6 +832,33 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
GrEffectRef* hairLineEffect = HairLineEdgeEffect::Create();
GrEffectRef* hairQuadEffect = HairQuadEdgeEffect::Create();
+ // Check devBounds
+#if GR_DEBUG
robertphillips 2013/05/20 13:50:42 I have needed an SkRect::contains with a tolerance
+ SkRect tolDevBounds = devBounds;
+ tolDevBounds.outset(SK_Scalar1 / 10000, SK_Scalar1 / 10000);
+ SkRect actualBounds;
+ Vertex* verts = reinterpret_cast<Vertex*>(arg.vertices());
+ int vCount = kVertsPerLineSeg * lineCnt + kVertsPerQuad * quadCnt;
+ bool first = true;
+ for (int i = 0; i < vCount; ++i) {
+ SkPoint pos = verts[i].fPos;
+ // This is a hack to workaround the fact that we move some degenerate segments offscreen.
+ if (SK_ScalarMax == pos.fX) {
+ continue;
+ }
+ drawState->getViewMatrix().mapPoints(&pos, 1);
+ if (first) {
+ actualBounds.set(pos.fX, pos.fY, pos.fX, pos.fY);
+ first = false;
+ } else {
+ actualBounds.growToInclude(pos.fX, pos.fY);
+ }
+ }
+ if (!first) {
+ GrAssert(tolDevBounds.contains(actualBounds));
+ }
+#endif
+
target->setIndexSourceToBuffer(fLinesIndexBuffer);
int lines = 0;
int nBufLines = fLinesIndexBuffer->maxQuads();
@@ -826,7 +869,8 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
kVertsPerLineSeg*lines, // startV
0, // startI
kVertsPerLineSeg*n, // vCount
- kIdxsPerLineSeg*n); // iCount
+ kIdxsPerLineSeg*n,
+ &devBounds); // iCount
lines += n;
}
@@ -839,7 +883,8 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
4 * lineCnt + kVertsPerQuad*quads, // startV
0, // startI
kVertsPerQuad*n, // vCount
- kIdxsPerQuad*n); // iCount
+ kIdxsPerQuad*n, // iCount
+ &devBounds);
quads += n;
}
target->resetIndexSource();
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.h ('k') | src/gpu/GrDefaultPathRenderer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698