Skip to content

Speed up scan-line rendering using "Active Edge Table" #90

Description

@antonfirsov

Currently, brute force search is being used when calculating intersections, the scanline is being tested against all lines in the polygon for each row. This means O(h*n) intersection tests where h is the number of horizontal edges and n is the number of lines.

The fastest way to achieve significant improvement with a (relatively) scoped change is to refactor the intersection detection logic to use an "Active Edge Table". In short this means:

  • Sorting edges by both minimum y and maximum y
  • Maintaining a list of edges which are currently intersected ("active") while iterating the scanlines
  • .. so intersection tests are no longer needed, it's enough to calculate intersection points only for edges which are active.

This should reduce the number of intersection calculations to O(n*log(n) + h*p), where p is the highest number of intersection points in a row during the scan.

Some sources describing the algorithm:

Not in scope

Improving accuracy further (aka #5 and #15) is not my main goal here, the only criteria is to not regress. But I hope I can achieve better results, or at least get some insights.

Plan

  1. Expose an API on IPath returning tessellation results to be consumed by a horizontal scanline rasterizer. These should be stored in a memory-efficient, cache friendly form. A data structure equivalent to (PointF, Orientation)[][] could probably do the job, where Orientation is always assuming a horizontal scanline crossing the point.
  2. Introduce a separate ScanlineIterator class that takes the tessellation, and exposes an API to iterate the horizontal scanlines.
  3. Utilize ScanlineIterator in drawing code where we currently use FindIntersections, particularly: FillRegionProcessor<T>, DrawTextProcessor<T>

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions