Hi,
It has come to our attention that JDK-8048782 [1] can cause Pisces to perform
wrong renderings. This patch was originally developed for OpenJDK9, but has now
been backported to openjdk8u222, so it has become relevant again.
After diving into the issue, it is my understanding that fix was created to
solve potential RasterFormatException. That exception occurred by the fact that
internally, PiscesCache always works with a bound box one pixel larger than
specified, as it can see on its constructor [2]. That slightly larger bbox was
exposed outside by the PiscesTileGenerator::getBbox method, and could lead to
the RasterFormatException in some scenarios. JDK-8048782 addressed this by
ensuring the bbox exposed outside did not contain the additional pixel. Calls
to retrieve the bbox will now go to a PiscesCache::getBBox [3] method that
removed the extra pixel.
However, one thing that was not changed is the PiscesTileGenerator::nextTile
method [4]. This method is still accessing the internal value. The new problem
happens because now the AAShapePipe::renderTiles works with a different bbox
that the PiscesTileGenerator::nextTile. This means that for certain sizes of
the bbox (those multiple of 32, the tile size), AAShapePipe may start working
with the next row while PiscesTileGenerator still considers we are on the
current row. This issue generates patterns like the ones on the attached
tile_misalignment.png image. This could be fixed by aligning the
PiscesTileGenerator::nextTile method to use the same value for bboxX1 as the
one that was exposed outside (removing the extra pixel). Something functionally
equivalent to:
public void nextTile() {
if ((x += TILE_SIZE) >= cache.bboxX1 -1) {
x = cache.bboxX0;
y += TILE_SIZE;
}
}
However, the part that I haven’t been able to understand is why PiscesCache
works with that extra pixel. As far as I can tell, it has always been there,
but I've never seen it documented. I assume there was a legitimate reason for
that extra pixel to be there, but I don't know why or if it is still relevant.
I would love if someone with more knowledge in this area were able to explain
it. There seems to be three options here:
- Revert JDK-804782, leaving the original RasterFormatException bug.
- Address the misalignment by changing the PiscesTileGenerator::nextTile.
- If no longer needed, remove the additional pixel in PiscesCache bbox (and
reverting JDK-804782, that would no longer be needed)
Thanks,
David
---
[1] https://bugs.openjdk.java.net/browse/JDK-8048782
[2]
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/cecd70d27b27/src/share/classes/sun/java2d/pisces/PiscesCache.java#l62
[3]
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/d9da27985291/src/share/classes/sun/java2d/pisces/PiscesCache.java#l170
[4]
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/d9da27985291/src/share/classes/sun/java2d/pisces/PiscesTileGenerator.java#l135
[5]
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/d9da27985291/src/share/classes/sun/java2d/pipe/AAShapePipe.java#l162