aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrTessellator.cpp
Commit message (Collapse)AuthorAge
* GrTessellator: when sanitizing contours, remove non-finite points.Gravatar Stephen White2017-08-23
| | | | | | | | | | | | NaNs can't be correctly sorted. Don't run the unit test on VK backend, since it requires large (>64K bytes) vertex buffer uploads. Bug: 757650 Change-Id: I667693f135a090a5d9076bb7a2ec6879fc06d645 Reviewed-on: https://skia-review.googlesource.com/37484 Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Greg Daniel <egdaniel@google.com>
* Fix artifacts on tiny stroked paths scaled up a lot.Gravatar Stephen White2017-08-23
| | | | | | | | | | | | | | | Set doConsumeDegenerates to false when calling SkPath::Iter::next() for all paths which are not in screen space. These lines are not degenerate for world space paths. Note: this change fixes only GrTessellatingPathRenderer and GrDefaultPathRenderer. GrMSAAPathRenderer still exhibits the bug. Bug: skia:6987 Change-Id: Ie3d494703211925c77052c68513948484e341486 Reviewed-on: https://skia-review.googlesource.com/37522 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* Revert "GrTessellator: when sanitizing contours, remove non-finite points."Gravatar Robert Phillips2017-08-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit 620cc248517a509040d3f94f29710edf3a151c5b. Reason for revert: Breaking the Vulkan bots Original change's description: > GrTessellator: when sanitizing contours, remove non-finite points. > > NaNs can't be correctly sorted. > > Bug: 757650 > Change-Id: Id1ca2fe1d1de7884da2a64ceef9491b1da7e8e77 > Reviewed-on: https://skia-review.googlesource.com/37220 > Reviewed-by: Brian Salomon <bsalomon@google.com> > Commit-Queue: Stephen White <senorblanco@chromium.org> TBR=bsalomon@google.com,senorblanco@chromium.org Change-Id: I64d5c35801f844b31745a9c7ff60812d96af5e55 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: 757650 Reviewed-on: https://skia-review.googlesource.com/37540 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
* Revert "Fix artifacts on tiny stroked paths scaled up a lot."Gravatar Robert Phillips2017-08-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit 267641a90cb18a430b0a84910f651e2181744fd3. Reason for revert: Seems to be turning the bots red Original change's description: > Fix artifacts on tiny stroked paths scaled up a lot. > > Set doConsumeDegenerates to false when calling SkPath::Iter::next() for > all paths which are not in screen space. These lines are not degenerate > for world space paths. > > Bug: skia:6987 > Change-Id: I411faf594bf8a15891bfff08691e86679b7741ac > Reviewed-on: https://skia-review.googlesource.com/36881 > Reviewed-by: Brian Salomon <bsalomon@google.com> > Commit-Queue: Stephen White <senorblanco@chromium.org> TBR=bsalomon@google.com,senorblanco@chromium.org Change-Id: I0d5a14670126ab3e0d99083a500ec8d3d0ef9961 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: skia:6987 Reviewed-on: https://skia-review.googlesource.com/37440 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
* Fix artifacts on tiny stroked paths scaled up a lot.Gravatar Stephen White2017-08-22
| | | | | | | | | | | | Set doConsumeDegenerates to false when calling SkPath::Iter::next() for all paths which are not in screen space. These lines are not degenerate for world space paths. Bug: skia:6987 Change-Id: I411faf594bf8a15891bfff08691e86679b7741ac Reviewed-on: https://skia-review.googlesource.com/36881 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: when sanitizing contours, remove non-finite points.Gravatar Stephen White2017-08-22
| | | | | | | | | | NaNs can't be correctly sorted. Bug: 757650 Change-Id: Id1ca2fe1d1de7884da2a64ceef9491b1da7e8e77 Reviewed-on: https://skia-review.googlesource.com/37220 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: fix for collinear out-of-range intersections.Gravatar Stephen White2017-08-16
| | | | | | | | | | | | | | | | | | | | | | | | Change 3b5a3fa8b1c11d4bd4499b040311f4c3553ebf8c introduced support for out-of-range intersections, which is necessary when the top and bottom vertices of an edge differ by only one ULP in the primary sort order and can't be split in-order. However, some out-of-range intersections produce edges which cancel each other out on splitting, in particular when the intersection is collinear with the newly-computed edge. This undoes the effect of the split. The tessellator then rewinds, re-detects the intersection, resplits, an infinite loop. The fix is to check for out-of-range intersections which are also collinear, and ignore them. This is ok, because these are not the cases we care about it change 3b5a3f above, which are never collinear. Bug: 753867 Change-Id: I590231e0e6f19c98f1ccf46cb7acc8a63ba35a9d Reviewed-on: https://skia-review.googlesource.com/34925 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: fix two NaN issues.Gravatar Stephen White2017-06-12
| | | | | | | | | | | | | | | If a point in the path rounds to +inf/-inf, the intersection code can produce NaN, which is unsortable. Fix: ignore non-finite intersections. Quadratic interpolation can sometimes produce NaN, which will never satisfy the flatness criterion. Abort if any of the interpolated points are non-finite. Bug:732023 Change-Id: If5881796e589c75b8f74459f42d00918619713a2 Reviewed-on: https://skia-review.googlesource.com/19467 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: fix logging; fix test comment.Gravatar Stephen White2017-06-09
| | | | | | | Change-Id: Iaded9025a1518d8c69dbe366deb1035e0bd4295b Reviewed-on: https://skia-review.googlesource.com/19289 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: fix intersection above the first vertex.Gravatar Stephen White2017-06-08
| | | | | | | | | | | | | | | | | | | | Handle the case where the an intersection falls not only above both edge endpoints, but above the first vertex in the mesh. This requires passing the mesh into check_for_intersection(), in order to modify the head. We also need to rewind the mesh after insertion, since we need to rewind to the newly-inserted vertex. This also cleans up vertex ID computation a little (for logging), so that vertices before the first vertex or after the last have a reasonable ID. It also cleans up the intersection-on-endpoint special cases by refactoring the calls to split_edge(). BUG=730687 Change-Id: Idea736eca7b7c3c5d8a470b1373a16ad8e649e80 Reviewed-on: https://skia-review.googlesource.com/19069 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: implement out-of-range splitting and AEL rewinding.Gravatar Stephen White2017-06-07
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Due to floating point inaccuracy, when intersecting edges, the intersection point may fall above one of the edges' top vertices or below one of the bottom vertices. In these cases, we were simply splitting one edge on the relevant endpoint of the other edge. This is incorrect if the intersection is far from the endpoint (e.g., the test case in the linked bug, where one of the intersected edges is near-horizontal but the intersection falls below both of its endpoints, in the middle of the edge.) The correct solution is to split both edges as normal, and take care to produce edges with the correct ordering where the intersection is above or below an edge. However, since the new vertex may be above the current vertex, simply restarting intersection checks at the current vertex won't work. We need to process the intersection vertex before the current one. This introduces another problem: unlike all other splitting modes (which always shorten edges), splitting an edge above the top or below the bottom can lengthen it, causing it to violate the AEL with an adjacent edge which then shortens it back to the original point (in cleanup_active_edges()). Since the splitting and merging code can't agree, we loop forever. Instead of simply fusing neighboring edges in cleanup_active_edges(), the proper fix to this problem is to detect the AEL violation and rewind all processing to the vertex above it. For performance, we only rewind when we detect that a split edge is no longer ordered within the mesh (merge_enclosing_edges()) or within the the AEL (rewind_if_necessary()). We also store the enclosing edges of each vertex, which allows us to rewind quickly, since we know exactly which edges need to be added/removed from the AEL. cleanup_active_edges(), fix_active_state() and Vertex::fProcessed have been removed. In their place are rewind_active_edges() and rewind_if_necessary(), which uses the same logic as cleanup_active_edges() but uses it to know when to rewind. Bug: skia:5026 Change-Id: I3638a429f5428498d6df6bb7b98c67374dc291aa Reviewed-on: https://skia-review.googlesource.com/18900 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: fix for three edges becoming collinear after splitting.Gravatar Stephen White2017-05-25
| | | | | | | | | | | | | In rare cases, a single edge can become collinear with two adjacent neighbour edges after it's split. The solution is to continue to merge until no collinear edges are found. BUG=722000 Change-Id: Ia5dd212b7acfb40ed1d6c74ebfa9e4a4746fe40a Reviewed-on: https://skia-review.googlesource.com/17963 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator AA: fix 1px wide paths.Gravatar Stephen White2017-05-08
| | | | | | | | | | | | | | Move 0 count check below the call to count outer polygons, so we don't abort on a path with outer but no inner geometry. This fixes the "thin_right_angle" and "thin_rect_and_triangle" samples when running GM:thinconcavepaths --pr tess. Change-Id: I9a75711787f729ce3a1d5313daa491098e397184 Reviewed-on: https://skia-review.googlesource.com/15661 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: fix for vertex coincident with enclosing edge.Gravatar Stephen White2017-05-04
| | | | | | | | | | | | | | | If a previously-enclosing edge coincides exactly with the current vertex, there are no two adjacent edges which enclose the vertex. Since find_enclosing_edges() ensures that the left enclosing edge is to the left of the vertex, the fix is to split the right enclosing edge on the current vertex and restart intersection tests. Bug: 716720 Change-Id: Id26c5b92a6d6139f348e99554638cded37e81a8e Reviewed-on: https://skia-review.googlesource.com/15261 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: speed up linearized quadratic Beziers.Gravatar Stephen White2017-03-28
| | | | | | | | | | | | | | | | | | | | | | | | | Linerization of quadratic Beziers was using recursive midpoint subdivision, which can exceed the number of required points by up to 2X if the second-last recursion level is just over the flatness threshold. (This is particularly bad for circular arcs, since all segments have a similar midpoint distance.) Instead, compute the points of maximum curvature, and progressively increase the number of segments until the flatness metric is satisfied at the points of maximum curvature. This is good for a 15-20% boost on MotionMark Fill Paths, and makes the performance on Canvas Arcs with the verb limit removed competitive with the software+upload path renderer. NOTE: this cause minor pixel diffs in a number of path-related GMs. BUG=skia: Change-Id: Ia2c22e00e45acec538b15a23c6edcb7a7d4566b7 Reviewed-on: https://skia-review.googlesource.com/9956 Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
* GrTessellator (AA): implement fast path for non-intersecting geometry.Gravatar Stephen White2017-03-13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the common case, there are no intersections in the inner or outer meshes generated for edge-AA. In that case, we don't have to build connector edges, and we don't need to run the full simplify and tessellate path on the full combined mesh. In order to maintain the correspondence between inner and outer meshes, we can keep partner pointers between inner and outer vertices instead. So the new flow is: - stroke the original boundaries to generate inner & outer meshes - assign partner pointers to join inner & outer vertices - build Edges only for Inner and Outer contours - sort the two meshes independently - do a complexity check on both meshes (simplified Bentley-Ottmann that just aborts on the first found intersection) - if neither mesh is complex, use the fast path: - tessellate only the inner mesh - return the outer mesh, and use the partner pointers to generate the outer geometry triangles - otherwise, use the complex path (as before): - connect the inner & outer partners with Connector Edges - merge the inner & outer meshes via sorted_merge() - simplify and tessellate the resulting complete mesh On a 2012 Retina MBP (Intel), this yields: Canvas Arcs +6% Stroke Shapes +6% Fill Shapes +15% On a Z620 Ubuntu w/NVidia GTX 650: Canvas Arcs: +5.0% Stroke Shapes: +1.8% Fill Shapes: +17.6% Other changes: - implemented VertexList::append(VertexList), for use by sorted_merge() - renamed boundary_to_aa_mesh() to stroke_boundary(), and made it append inner & outer contours to inner & outer meshes - the connect() loop at the bottom of stroke_boundary() now uses open VertexLists, since it can then append them easily to the inner & outer meshes - sort_and_simplify() changed to sort_mesh(), with merging and simplification done explicitly by the callers - sorted_merge() factored out of merge_sort(), for use when zipping together the inner and outer meshes Change-Id: Ib00f9f12a375412eff35dd2bb78ccd787d9c37ce Reviewed-on: https://skia-review.googlesource.com/9600 Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
* GrTessellator: convert contours to VertexLists.Gravatar Stephen White2017-03-07
| | | | | | | | | | | | | | This is a cleanup patch; should have no user-visible effects. Note that contours are now returned opened, rather than closed. This plays better with VertexList, and makes the code simpler. BUG=skia: Change-Id: I6a422fed0805cdca53cf0697b8427fff7cd77ad3 Reviewed-on: https://skia-review.googlesource.com/9343 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: Implement a fast path in poly emission.Gravatar Stephen White2017-03-03
| | | | | | | | | | | | When there's a single triangle remaining in the monotone, emit early and skip a convexity check. BUG=skia: Change-Id: I591acf4b7f567dbbf7681ba72181e578ca4623ec Reviewed-on: https://skia-review.googlesource.com/8797 Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
* GrTessellator: add a null-check for a clusterfuzz test case.Gravatar Stephen White2017-03-03
| | | | | | | | | BUG=695696 Change-Id: I1c001316721b3c042cff115c905ff0d2c2698ac0 Reviewed-on: https://skia-review.googlesource.com/9053 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator (AA): restore rounding in Line::intersect().Gravatar Stephen White2017-03-02
| | | | | | | | | | | | | | | | | | I removed this in https://skia-review.googlesource.com/8028, but that was actually just masking a problem properly fixed in https://skia-review.googlesource.com/8364. Now that it is fixed, we can restore the rounding, which actually improves performance by 5-10% on Canvas Arcs (when run with the tess verb limit disabled). NOTE: this change will affect many GMs, including strokes_poly, addarc, parsedpaths, dashcubics, beziers, nested_aa, etc. BUG=skia: Change-Id: Id10f82e35a344247cab27e6d59a0dd2e11c9944d Reviewed-on: https://skia-review.googlesource.com/9051 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: minor cleanups and speedups.Gravatar Stephen White2017-03-01
| | | | | | | | | | | | | | | Don't null out vertex's fPrev and fNext ptrs during MonotonePoly::emit(); list_insert() will do it for us. Don't normalize the tangent returned by get_unit_normal() to unit length, since we can do the dot product comparison without it. Copy Lines where possible, rather than recomputing them. Change-Id: I733b00dd9d9d493313ac9a1c71aac0b708e78201 Reviewed-on: https://skia-review.googlesource.com/9047 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: take sweep_gt out behind the woodshed.Gravatar Stephen White2017-02-28
| | | | | | | | | No need for it, since sweep_gt(a, b) == sweep_lt(b, a). Change-Id: I9244687845530a8e11673c5360d9ac700933baa0 Reviewed-on: https://skia-review.googlesource.com/8987 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator (AA): simplify boundary extraction.Gravatar Stephen White2017-02-23
| | | | | | | | | | | | | | Perform boundary simplification and meshing inline with extraction. Removed EdgeList::fNext (don't need to concatenate edge lists). Removed new_contour() (don't need to heap-allocate them either). BUG=skia: Change-Id: I0f89bad105c03f3021b0d2f021064f408a361b59 Reviewed-on: https://skia-review.googlesource.com/8794 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator (AA): sorting and comparison performance improvements.Gravatar Stephen White2017-02-23
| | | | | | | | | | | | | | | | | | | Change comparison functions to perform the common case first (a.fX > b.fX), and the uncommon case (a.fX == b.fX) after the short-circuit. Change Comparator to switch on a direction enum instead of using function pointers. Inline sorted_merge() and front_back_split() into merge_sort(), and template it on the comparator function, so it instantiates two versions. This is even faster (but costs us some code bloat of course). BUG=skia: Change-Id: I45a2376492240ed7e0552ca2aed75e303e918bc6 Reviewed-on: https://skia-review.googlesource.com/8791 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator: misc. cleanups and minor tweaks.Gravatar Stephen White2017-02-22
| | | | | | | | | | | | | | | | | | | | | Invert some math to remove a negation. Don't keep a persistent count in EdgeList; we'll test for degenerate boundaries in boundary_to_aa_mesh(). Make connect() use the top/bottom ordering that new_edge has already done for us. Don't add the an edge to the same poly twice when it's easily detectable. Remove some superfluous variables and intialization. BUG=skia: Change-Id: I0efd9ec385d6dfec8950b7acfc6dd25572f667b5 Reviewed-on: https://skia-review.googlesource.com/8784 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator (AA): implement fast path for removing non-boundary edges.Gravatar Stephen White2017-02-21
| | | | | | | | | | | | | | | Instead of using a full tessellate() pass, which allocates Polys, MonotonePolys, etc. It's faster to simply accumulate the winding number in the left-adjacent edge, and use that to remove non-boundary edges (edges for which apply_fill_type() returns the same value on either side of the edge). This gives ~4-5% boost on MotionMark Fill Shapes. Change-Id: I66bd4248ace01a8c35abd99519f4c455f936e5e5 Reviewed-on: https://skia-review.googlesource.com/8782 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator (AA): Performance tweaks and cleanup.Gravatar Stephen White2017-02-17
| | | | | | | | | | | | | | | | | | | | The SkArenaAlloc destructor was showing up as hot in profiling, especially on Linux. The reason is that it was being used incorrectly: the size estimate was being used as the chunk size. It turns out that the best performance seems to be achieved with no initial allocations and a fixed chunk size of 16K, as the CPU path renderer does. Also remove some unused code. (This is a partial re-land of https://skia-review.googlesource.com/c/8560/) TBR=bsalomon@google.com Change-Id: I277eb1a6e5718a221974cd694c8a7e481e432ca6 Reviewed-on: https://skia-review.googlesource.com/8561 Reviewed-by: Stephen White <senorblanco@chromium.org> Commit-Queue: Stephen White <senorblanco@chromium.org>
* Revert "GrTessellator (AA): Performance tweaks and cleanup."Gravatar Ben Wagner2017-02-16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit e595bbfba6e7dcdda0d7d700343e9d814a406771. Reason for revert: Breaking roll into Chromium. virtual/gpu/fast/canvas/canvas-arc-circumference-fill.html virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill.html https://build.chromium.org/p/tryserver.blink/builders/linux_trusty_blink_rel/builds/5170 https://storage.googleapis.com/chromium-layout-test-archives/linux_trusty_blink_rel/5170/layout-test-results/results.html Original change's description: > GrTessellator (AA): Performance tweaks and cleanup. > > The SkArenaAlloc destructor was showing up as hot in profiling, > especially on Linux. The reason is that it was being used > incorrectly: the size estimate was being used as the chunk size. It > turns out that the best performance seems to be achieved with no > initial allocations and a fixed chunk size of 16K, as the CPU path > renderer does. > > Also, allocate the bisectors used for edge inversions on the > stack, not the heap. And remove some unused code. > > BUG=skia: > > Change-Id: I754531c753c9e602713bf2c8bb5a0eaf174bb962 > Reviewed-on: https://skia-review.googlesource.com/8560 > Reviewed-by: Brian Salomon <bsalomon@google.com> > Commit-Queue: Stephen White <senorblanco@chromium.org> > TBR=bsalomon@google.com,senorblanco@chromium.org,reviews@skia.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Change-Id: I3cf6495c7345b6e6a79c2cb3a21dc6df0eed122f Reviewed-on: https://skia-review.googlesource.com/8605 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
* GrTessellator (AA): Performance tweaks and cleanup.Gravatar Stephen White2017-02-16
| | | | | | | | | | | | | | | | | | | The SkArenaAlloc destructor was showing up as hot in profiling, especially on Linux. The reason is that it was being used incorrectly: the size estimate was being used as the chunk size. It turns out that the best performance seems to be achieved with no initial allocations and a fixed chunk size of 16K, as the CPU path renderer does. Also, allocate the bisectors used for edge inversions on the stack, not the heap. And remove some unused code. BUG=skia: Change-Id: I754531c753c9e602713bf2c8bb5a0eaf174bb962 Reviewed-on: https://skia-review.googlesource.com/8560 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* GrTessellator (AA): fix "Canvas Arcs" coverage artifact.Gravatar Stephen White2017-02-13
| | | | | | | | | | | | | | | | | When sanitizing contours, if the first and last vertices coincide, continue with the previous vertex, not the next vertex, since we may otherwise exit prematurely. Also, round the last vertex before entering the loop, just in case it coincides with the first. Add a test case to exercise the above, and another one which exercises the intruding-vertex workaround. BUG=691593 Change-Id: Ic28a9308a21164d185edef0ee6fbc29b40742149 Reviewed-on: https://skia-review.googlesource.com/8364 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
* Move GrTessellator from SkChunckAlloc to SkArenaAlloc.Gravatar Herb Derby2017-02-13
| | | | | | | | | TBR=ethannicholas@google.com Change-Id: I2efcbe540a2bdc42b8c2f0a675a42fe9e9ed717d Reviewed-on: https://skia-review.googlesource.com/8383 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Herb Derby <herb@google.com>
* GrTessellator (AA): improve antialiasing of thin shapes.Gravatar Stephen White2017-02-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (Long description, but actually quite a small change.) This is the first change inspired by the "straight skeleton" algorithm. This algorithm gives us a mental model to describe the edge-antialiasing problem: consider the shape as walls of a house, the outer alpha geometry is a 45-degree "roof" up to a flat top at a height of 1.0 (the filled interior). The faces of the sloping roof join at the bisectors between the inner and outer points. When the shape being drawn is sufficiently thin, there should be no flat roof, and the sloping roof meets at an edge (the straight skeleton). This patch detects cases where an edge inverts on stroking, which indicates that the flat roof has turned inside out, and should be reduced to a point instead. The model above describes what to do: follow down the "roof" along the bisectors to their intersection. This is the point to which an inverted edge should be collapsed. Fortunately, the bisector edges are easy to compute: they're the connector edges joining inner and outer points. Linearly interpolating the distance from the top to the bottom point gives the alpha we should use to approximate coverage. Now that we are correctly handling inversions, bevelling outer edges is no longer necesary, since pointy outer edges won't cause nasty opaque artifacts. A couple of other quality improvements: on intersection, always lerp the alpha of connector edge, even if the opposite edge is an inner edge (later, when these edges are collapsed, we need this value to compute the correct alpha). Fix the case where an intruding outer vertex intersects exactly with an inner edge by maxing its alpha with the computed value in check_for_intersection(). Finally, we also no longer round off the intersections produced by Line::intersect(), since it introduces a loss of quality with no measurable performance benefit. Change-Id: I6fd93df3a57fffc0895e8cb68adbdba626ded0f1 Reviewed-on: https://skia-review.googlesource.com/8028 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephan White <senorblanco@chromium.org>
* GrTessellator (AA): Fix for missing fill artifacts.Gravatar Stephen White2017-02-03
| | | | | | | | | | | | | | | | | | | | Some regions were being incorrectly filled due to setting connector edges winding to zero *after* merging collinear edges. This would cause the merge to add the wrong winding value. Putting the adjust before the call to merge_collinear_edges() fixes the problem. Also, some pixels were not getting coverage due the inner edge being +1 winding. Using -2 winding for inner edges ensure the interior regions are -1 winding, which gives coverage in more cases of self-intersection. This required flipping the comparisons on the intruding-vertices workaround. BUG=skia: Change-Id: I216fa3d30c196a6b7773637e48802f6572c993c7 Reviewed-on: https://skia-review.googlesource.com/7962 Commit-Queue: Stephan White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
* GrTessellator (AA): improve AA quality for near-overlapping paths.Gravatar Stephen White2017-01-30
| | | | | | | | | | | | | | | When path features are very close together, the outer contours can overlap. This causes the connector edges (the ones joining the inner and outer vertices) to intersect other edges. Lerping the alpha along the connector edge gives us a good approximation of the coverage at that point. BUG=skia: Change-Id: I56bcc570fc185344c5f84d11ef995d3940a08793 Reviewed-on: https://skia-review.googlesource.com/7701 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephan White <senorblanco@chromium.org>
* AA GrTessellator: fix bevelling of acute angles.Gravatar Stephen White2017-01-27
| | | | | | | | | | | | | | | | | The code to handle acute outer angles in generated geometry was pretty broken: it did a simple runnning average of consecutive acute vertices, and didn't handle acute angles between the last and first edges. Replaced it with something simpler that does proper bevelling for angles less than 2.5 degrees. This revealed a bug with thin path segments, exposed by the thinconcavepaths test. This will be fixed by upcoming changes, but I've also dded a few more test cases to make it clearer. Change-Id: I23a628ab2e16acaab798c746a5fd87842cacbfab Reviewed-on: https://skia-review.googlesource.com/7660 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephan White <senorblanco@chromium.org>
* GrTessellator: fix for disappearing thin path.Gravatar Stephen White2017-01-17
| | | | | | | | | | | | | | | | | | simplify_boundary() was incorrectly comparing squared distances against a non-squared constant. For .25 of a pixel, we need to compare against 0.25 squared, or 0.0625. This also includes a fix to get_edge_normal(), We were actually returning edge "vectors", instead of edge normals. This wasn't causing problems, since the error cancels itself out, but it's confusing. BUG=skia: Change-Id: I0d50f2d001ed5e41de2900139c396b9ef75d2ddf Reviewed-on: https://skia-review.googlesource.com/7043 Commit-Queue: Stephan White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
* GrTessellator: fix artifact with exactly-1-px-wide edges.Gravatar Stephen White2017-01-12
| | | | | | | | | | | | | | | | | | | | | | | | When path features are exactly a pixel wide, the extruded inner edges can become collinear and then be removed, since their winding is zero. We need these edges to be preserved through triangulation, otherwise opaque portions of the geometry can become transparent. Since the simplify() pass can handle zero-winding edges just fine, the the fix is to simply not remove them. In addition, this changes refactors out disconnect() from all the calls to remove_edge_above()/remove_edge_below(). It also renames the remaining function erase_edge() (since it's now unconditional). Add a new test to a new "thinconcavepaths" GM. BUG=680260 NOTRY=true Change-Id: I1d3a436c95a01c4d4ef5dc05503de4312677f65d Reviewed-on: https://skia-review.googlesource.com/6902 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephan White <senorblanco@chromium.org>
* GrTessellator: fix compile when LOGGING_ENABLED.Gravatar Stephen White2017-01-09
| | | | | | | | | BUG=skia: Change-Id: I1f0df58ffe79e439f92a8c1cd3c39812c32d039f Reviewed-on: https://skia-review.googlesource.com/6743 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephan White <senorblanco@chromium.org>
* Modify GrTessellator to use a VertexList where possible.Gravatar Stephen White2017-01-04
| | | | | | | | | | | Prefer VertexList to a bare Vertex*. Also fix some 100-col issues. This should have no user-visible impact. Change-Id: I8fa260d5417c9832256529c232f532e69238fca0 Reviewed-on: https://skia-review.googlesource.com/6502 Commit-Queue: Stephan White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
* Quality and performance fixes for AA tessellating path renderer.Gravatar Stephen White2017-01-03
| | | | | | | | | | | | | | | | | | | | | | | | | | Use quads rather than triangles for the edge geometry. This allows us to perform a simpler edge categorization (see below). It also improves performance by reducing the number of edges processed during the simplify and tessellate steps. Label AA edges as three types: inner, outer, and connector. This results in correct alpha values for intersected edges, even when the top or bottom vertex has been merged with a vertex on edges of different types. Changed the "collinear edges" sample from the concavepaths GM for a "fast-foward" shape, which more clearly shows the problem being fixed here. (The collinearity from the "collinear edges" was actually being removed earlier up the stack, causing the path to become convex and not exercise the concave path renderers anyway.) NOTE: this will cause changes in the "concavepaths" GM results, and minor pixel diffs in a number of other tests. Change-Id: I6c2b0cdb35cda42b01cf1100621271fef5be35b0 Reviewed-on: https://skia-review.googlesource.com/6430 Reviewed-by: Stephan White <senorblanco@chromium.org> Commit-Queue: Stephan White <senorblanco@chromium.org>
* Revert "Quality and performance fixes for AA tessellating path renderer."Gravatar Stephan White2017-01-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit d4b21552481a6d313dfa9bc14b624c9ec94b56ce. Reason for revert: accidentally added some unwanted changes Original change's description: > Quality and performance fixes for AA tessellating path renderer. > > Use quads rather than triangles for the edge geometry. This allows > us to perform a simpler edge categorization (see below). It also > improves performance by reducing the number of edges processed during > the simplify and tessellate steps. > > Label AA edges as three types: inner, outer, and connector. This > results in correct alpha values for intersected edges, even when > the top or bottom vertex has been merged with a vertex on edges > of different types. > > Changed the "collinear edges" sample from the concavepaths GM for a > "fast-foward" shape, which more clearly shows the problem being fixed > here. (The collinearity from the "collinear edges" was actually being > removed earlier up the stack, causing the path to become convex and > not exercise the concave path renderers anyway.) > > NOTE: this will cause changes in the "concavepaths" GM results, and > minor pixel diffs in a number of other tests. > > BUG=660893 > > Change-Id: Ide49374d6d173404c7223f7316dd439df1435787 > Reviewed-on: https://skia-review.googlesource.com/6427 > Commit-Queue: Stephan White <senorblanco@chromium.org> > Reviewed-by: Brian Salomon <bsalomon@google.com> > TBR=bsalomon@google.com,senorblanco@chromium.org,reviews@skia.org BUG=660893 NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Change-Id: I06a36e397645bfc42442a5a9e7c27328f6048ab9 Reviewed-on: https://skia-review.googlesource.com/6428 Commit-Queue: Stephan White <senorblanco@chromium.org> Reviewed-by: Stephan White <senorblanco@chromium.org>
* Quality and performance fixes for AA tessellating path renderer.Gravatar Stephen White2017-01-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Use quads rather than triangles for the edge geometry. This allows us to perform a simpler edge categorization (see below). It also improves performance by reducing the number of edges processed during the simplify and tessellate steps. Label AA edges as three types: inner, outer, and connector. This results in correct alpha values for intersected edges, even when the top or bottom vertex has been merged with a vertex on edges of different types. Changed the "collinear edges" sample from the concavepaths GM for a "fast-foward" shape, which more clearly shows the problem being fixed here. (The collinearity from the "collinear edges" was actually being removed earlier up the stack, causing the path to become convex and not exercise the concave path renderers anyway.) NOTE: this will cause changes in the "concavepaths" GM results, and minor pixel diffs in a number of other tests. BUG=660893 Change-Id: Ide49374d6d173404c7223f7316dd439df1435787 Reviewed-on: https://skia-review.googlesource.com/6427 Commit-Queue: Stephan White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
* Remove SkAutoTDeleteArrayGravatar Ben Wagner2016-11-02
| | | | | | | | | | | | This class is already just an alias for std::unique_ptr<T[]>, so replace all uses with that and delete the class. CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-Clang-GCE-CPU-AVX2-x86_64-Debug-ASAN-Trybot,Test-Ubuntu-Clang-Golo-GPU-GT610-x86_64-Debug-ASAN-Trybot Change-Id: I40668d398356a22da071ee791666c7f728b59266 Reviewed-on: https://skia-review.googlesource.com/4362 Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Mike Klein <mtklein@chromium.org>
* GrTessellator: make inverse fill types more sane.Gravatar senorblanco2016-10-12
| | | | | | | | | | | | | | | | | | | | | In the screenspace AA tessellator, a path's fill types would be applied twice: once when extracting contours, and then again when filling polys. It was supposed to be forced to kWinding_FillType by the second call to mesh_to_polys(), but for hysterical reasons this parameter is unused! For kInverseWinding_FillType (the only mode where this actually caused a bug), I unwittingly papered over the problem by reversing the outer contour for the inverse fill types, and comparing against -1 instead of 1. The better fix is to actually pass a winding mode of kWinding_FillType to polys_to_triangles(), and remove the (ignored) param from mesh_to_polys(). Then we can pass a clockwise outer contour as before, and compare against 1 instead of -1. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2404403003 Review-Url: https://codereview.chromium.org/2404403003
* fix vertex alpha calculation in GrTesselatorGravatar lsalzman2016-10-11
| | | | | | | BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2405813003 Review-Url: https://codereview.chromium.org/2405813003
* GrTessellator: refactor Line out of Edge.Gravatar senorblanco2016-10-07
| | | | | | | | | | There are cases where we need only a line equation, and not a full Edge. Create a Line struct for this, and refactor Edge to use it. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2397963003 Review-Url: https://codereview.chromium.org/2397963003
* Screenspace AA tessellated GPU path rendering.Gravatar senorblanco2016-08-31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is an approach to antialiased concave path rendering on the GPU without using MSAA. It uses GrTessellator to extract boundary contours from the given path, then inflates by half a pixel in screen space each direction, then renders the result with zero alpha on the outer contour and one alpha on in the inner contour. This requires two passes through the tessellation code: one to extract the boundaries, then one to tessellate the result. This gives approximately a 3X improvement on the IE chalkboard demo in non-MSAA mode, a 30-40% improvement on MotionMark's "Fill Paths", and a ~3X improvement on MotionMark's "canvas arcTo segments". It works best for large, simple paths, so there's currently a limit of 10 verbs in the onCanDrawPath() check. This dovetails nicely with the distance field path renderer's support for small, detailed (and cached) paths. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1152733009 NOTRY=true Review-Url: https://codereview.chromium.org/1152733009
* Revert of Screenspace AA tessellated path rendering. (patchset #37 id:730001 ↵Gravatar senorblanco2016-08-31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | of https://codereview.chromium.org/1152733009/ ) Reason for revert: Causing asserts in GLPrograms test on Mac. Original issue's description: > Screenspace AA tessellated GPU path rendering. > > This is an approach to antialiased concave path rendering > on the GPU without using MSAA. It uses GrTessellator to > extract boundary contours from the given path, then > inflates by half a pixel in screen space each direction, > then renders the result with zero alpha on the outer > contour and one alpha on in the inner contour. This > requires two passes through the tessellation code: one > to extract the boundaries, then one to tessellate the > result. > > This gives approximately a 3X improvement on the IE > chalkboard demo in non-MSAA mode, a 30-40% improvement > on MotionMark's "Fill Paths", and a ~3X improvement on > MotionMark's "canvas arcTo segments". > > It works best for large, simple paths, so there's currently > a limit of 10 verbs in the onCanDrawPath() check. This > dovetails nicely with the distance field path renderer's > support for small, detailed (and cached) paths. > > BUG=skia: > GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1152733009 > > Committed: https://skia.googlesource.com/skia/+/9992bdef8ae97b3e5b109d278ccfab84c66bcbf0 TBR=bsalomon@google.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review-Url: https://codereview.chromium.org/2299683002
* Screenspace AA tessellated GPU path rendering.Gravatar senorblanco2016-08-31
| | | | | | | | | | | | | | | | | | | | | | | | | | | This is an approach to antialiased concave path rendering on the GPU without using MSAA. It uses GrTessellator to extract boundary contours from the given path, then inflates by half a pixel in screen space each direction, then renders the result with zero alpha on the outer contour and one alpha on in the inner contour. This requires two passes through the tessellation code: one to extract the boundaries, then one to tessellate the result. This gives approximately a 3X improvement on the IE chalkboard demo in non-MSAA mode, a 30-40% improvement on MotionMark's "Fill Paths", and a ~3X improvement on MotionMark's "canvas arcTo segments". It works best for large, simple paths, so there's currently a limit of 10 verbs in the onCanDrawPath() check. This dovetails nicely with the distance field path renderer's support for small, detailed (and cached) paths. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1152733009 Review-Url: https://codereview.chromium.org/1152733009
* Tessellator: better fix for reused-edges issue.Gravatar senorblanco2016-08-18
| | | | | | | | | | | | | | | | | The GrTessellator fix for doubly-added edges in https://codereview.chromium.org/2259493002/ could leave a MonotonePoly with zero edges. This is a problem for Poly::addEdge(), which assumes that MonotonePolys always have at least one edge. The fix is to move the check and early-out up to Poly::addEdge(). This should also tighten up the vertex count. (Unfortunately, the only repro I have for this issue is very convoluted, and requires non-landed code.) BUG=skia:5636 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2251643008 Review-Url: https://codereview.chromium.org/2251643008