[OpenJDK 2D-Dev] Different rounding applied by ProcessPath and ShapeSpanIterator

Jim Graham james.graham at oracle.com
Mon Sep 26 19:02:41 UTC 2016

Trying to remember some ancient reasoning (and probably failing at the memory thing), I think the original issue was 
that the existing non-AA rasterizer could only output spans, so rendering a tall line (one with a wide Y range) would 
result in a lot of rendering operations being sent to a hw rasterizer.  But, those hw rasterizers could understand 
things like "drawLine", it's just that the SpanIterator wasn't designed to express its output as a series of drawlines 
for the case of thin stroked shapes.  So, the ProcessPath rasterizer was created to express thin outlines as a series of 
drawLines.  it has to deal with issues such as not duplicating shared vertices and other anomalies you get when you want 
a downstream line renderer to render the shape accurately.  It was originally stroke-only and we still used the SSI for 
filling, but since the logic to break a stroked shape down into drawLine operations caused it to rasterizer slightly 
differently we'd end up with gaps or overruns when both filling and drawing a shape with different rasterizers - so an 
equivalent filling mechanism was created to be used in conjunction with the stroking pipeline.

I hope that explanation was at least 90% accurate...


On 9/26/16 11:55 AM, Jim Graham wrote:
> They do operate differently.  They aren't meant to be mixed and matched.
> One thing that may shed some light is the STROKE_CONTROL hint.  If it is sent to Pure then there is no heuristic for how
> to rasterize and all rasterizers should agree on how to scan convert shapes.
> But, if it is set to another value, then it has some latitude to adjust the path for cleanliness with respect to keeping
> line widths from varying depending on position and other consistency anomalies that can occur with a number of small
> related paths rendered near each other.  The two mechanisms were written with different goals and by different people to
> meet those consistency requirements in different ways.  The operation of one is more useful for a software renderer back
> end and the other is more useful for a hardware renderer back end (which was the primary reason for creating
> ProcessPath, not necessarily the distinction of how to apply the STROKE_CONTROL hint)...
>             ...jim
> On 9/25/16 4:33 AM, Clemens Eisserer wrote:
>> Hi,
>> I recently tried to track down JDK-8156100 (xrender: Subpixel drawing
>> bug in Java 8) -  under some circumstances paths do not align with
>> fills when subpixel coordinates are used.
>> The issue seems to be caused by ProcessPath and ShapeSpanIterator
>> behaving differently with regards to rounding.
>> I've created a small testcase to illustrate the issue:
>> http://pastebin.com/hy5zCkPR - where a rectangle with subpixel
>> coordinates is  "drawn" with bothl, SSI and ProcessPath.
>> The ShapeSpanIterator seems to truncate any subpixel values, whereas
>> ProcessPath always seems to "round up".
>> Is this expected behaviour? Should I avoid SSI and switch to
>> ProcessPath entirely?
>> Thank you in advance, Clemens

More information about the 2d-dev mailing list