[OpenJDK 2D-Dev] [9] Review Request: 8167310 The graphics clip is incorrectly rounded for some fractional scales

Jim Graham james.graham at oracle.com
Tue Oct 11 18:32:55 UTC 2016

On 10/10/16 3:53 PM, Sergey Bylokhov wrote:
> On 11.10.16 1:23, Phil Race wrote:
>>> Yes, I think adjacent drawImage requests should not overlap.  We
>>> should look into this separately.
>> So previously, overlapping of the clip bounds ensured adjacent images
>> were not drawn
>> over-lapped .. but with this fix they might be ?
> The fix change only behavior of the rectangle clip. So using the setClip we can prevent overlaping of the images. But i
> think that even without clip such images should not overlap.

I'm pretty sure that setClip(x,y,w,h) would ensure adjacency (no overlaps and no gaps) with another call to itself with 
adjacent parameters.

And setClip(RectShape) would also ensure proper adjacency with itself.

But, I think we had cases before this fix where setClip(x,y,w,h) could violate proper adjacency with setClip(RectShape). 
  This fix addresses most of that, particularly it works if we have STROKE_PURE.  I believe that it still has issues 
with STROKE_NORMALIZE, though, because one of them honors it and the other doesn't.  So, we need to have them both honor 
the STROKE_CONTROL in the same way.

>>> 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.
>> That last sentence sounds like the right answer in principle but I don't
>> know if we'll be unpleasantly surprised
>> by some  consequence of "... that setClip(Shape) and fill(Shape) might
>> disagree .."
> I just tested fillRect vs fill(RectShape), and both work differently in some cases as well-=((.
> So we have a few similar methods which works differently(even if VALUE_STROKE_PURE is set), which became visible on
> fractional(1.5) scales....
>  - setClip(Rectangle)
>  - setClip(Shape)
>  - fillRect(Rectangle)
>  - fill(Shape)
>  - DrawImage(Rectangle)

I'd like to see which cases cause differences.  The main one that I can see by a brief examination of the code is the 
case of non-integer translations (but no scale).

I think we end up using the simplified FillRect primitives in the case of a non-integer translate, and that can cause a 
difference in effect.  We could fix SurfaceData's validation to not use the primitive pipeline unless the translation is 
integer, but that could cost performance for that case.  I'm not sure how often a non-integer translation with no other 
transform elements (i.e. scale) occurs, though.  We could teach the FillRect primitive (or its caller) to adjust for the 
STROKE_CONTROL more properly in the case of a non-integer translation, but I'm not sure how often that will come into 
play and benefit us.  Also, this might be fixable in the code that comes up with sg2d.transXY, which probably doesn't 
take STROKE hint into account...


More information about the 2d-dev mailing list