[OpenJDK 2D-Dev]  Review Request: 8167310 The graphics clip is incorrectly rounded for some fractional scales
james.graham at oracle.com
Mon Oct 10 20:34:34 UTC 2016
[CC'ing Phil in case he has some suggestions for how the API should work...]
Responding just to additional questions in this email...
On 10/10/16 12:45 PM, Sergey Bylokhov wrote:
> The additional questions:
> - In the current fix we change behavior of the clip. Before the fix if we set the clip to the nearest areas they can
> overlaps in the destination. Should we change the drawImage as well? Currently if I draw image to the nearest areas in
> the user space, the images can overlap in the destination(so the actual result in destination depends on what image was
> painted first).
Yes, I think adjacent drawImage requests should not overlap. We should look into this separately.
> - Should the clip be affected by the stroke(if it was set by the shape)? Right now if the clip was set by the shape it
> will produce different result than if it was set via rectangle.
I think we could have the clip never be affected by STROKE_NORMALIZE. That might make sense because the NORMALIZE code
is meant to deal with aesthetic issues, not rendering math issues. We'd have to add a getClipSSI() method that
hard-codes the "adjust" boolean to "false" to do that, but that is an easy fix.
The question is then that would meant that setClip(Shape) and fill(Shape) might disagree, though. This would argue that
we should have it affected by the normalization. This is also a fairly easy fix, you could have LoopPipe have a method
that would return the appropriate Rectangle representing which pixels are covered for a given Rectangle2D depending on
the normalize parameters.
On the other hand, we normalize differently for AA and non-AA. Calling getFillSSI() on LoopPipe basically performs
normalization only for non-AA fills. Arguably, though, clipping produces non-AA results in that it chooses whole pixels
to include or exclude. This might mean that it should never follow AA normalization. But, it also points out the
silliness of normalizing to match the results of fill when it can never do that for AA mode. (Potentially we could add
an AA-clip mode, but the implementation of that would require capturing every rendering operation to an intermediate
buffer and then pixel-filtering it through a mask created by AA-filling the clip shape - we do that in FX, but it would
require major surgery to add that to the SG2D pipeline so I don't think we would ever consider that at this stage.)
Any of those solutions are fairly easy to fix (except adding an AA clipping mode), but the question is which is more
useful and/or surprises the developers the least.
So we have the current case:
setClip(integers or int-Rectangle) => pure coverage
setClip(other shape) => non-AA normalized coverage
If we decide that clip should normalize always to non-AA parameters because it is an intrinsically non-AA type of
operation then we have to fix the setClip(integer rectangle) code which isn't hard.
If we decide that clip should normalize to the current AA parameters then it's basically the same, but we need to find a
way to query the right objects to perform the AA according to their chosen bias. LoopPipe/ShapeSpanIterator appear to
own non-AA normalization and I think AA normalization is hidden behind the TileGenerator API somewhere that
Ductus/Pisces/Marlin all implement.
If we decide that clip should not normalize then we only have to fix setClip(other shape) and it's just a question of
hard-coding the adjust boolean in the call to instantiate the ShapeSpanIterator.
More information about the 2d-dev