JDK-6758179 : D3D: AlphaComposite is applied incorrectly for uncached opaque BufferedImage
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • CPU: generic
  • Submitted: 2008-10-10
  • Updated: 2011-01-19
  • Resolved: 2009-01-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u12Fixed 7 b43Fixed
Description
Run attached test. It shows a frame with 4 components. Each component draws two rectangles in different modes: with opaque/translucent buffered image and with AlphaComposite alpha value of 0.99999f/1.0f 

When the test is run with the latest 7.0 build, with D3D pipeline enabled, opaque/0.99999f component is rendered incorrectly (top-right component): buffered image is not composited with white area at all. Attached screenshot Test2.png shows the final picture, and Test2-correct.png is a right frame (when D3D pipeline is turned off).

Comments
EVALUATION A better fix is to use proper convert loop from IntRgb to Argb instead of generic Iso one, so that destination alpha is set to FF during the conversion.
19-11-2008

SUGGESTED FIX http://hg.openjdk.java.net/jdk7/2d/jdk/rev/8eb24fc88242
19-11-2008

EVALUATION There may be something else to this as well, as this fix addresses some artifacts in the demos which it doesn't look like it should..
28-10-2008

EVALUATION The problem is that the source image, while opaque, has non-ff alpha in some of the pixels. The pipeline uses ARGB tile texture for rendering from sw image, and since in this case alpha compositing is enabled, we end up getting unexpected results from compositing. The fix is to use an opaque tile texture for opaque sources. While we should only really need opaque source when AC is enabled, it's probably no harm in using it any time there's an opaque source. It's possible that there will be more texture switching because of this.
28-10-2008

EVALUATION Yes, it looks like a bug in our bi to accel surface blit loop. If the test is modified to cache the image instead of creating it on every repaint (see diff below), it works correctly, which means that once we cache the image in a texture, the extra alpha is applied correctly.
10-10-2008

EVALUATION If the test is modified, so all the buffered images are cached (see diffs below), the problem goes away: *************** *** 21,26 **** --- 21,27 ---- private int tr; private float a; + BufferedImage bim; public AlphaComponent(int transparency, float alpha) { *************** *** 39,50 **** gg.setColor(Color.RED); gg.fillRect(GAP, GAP, w * 3 / 4, h * 3 / 4); ! GraphicsConfiguration gc = getGraphicsConfiguration(); ! BufferedImage bim = gc.createCompatibleImage(w * 3 / 4, h * 3 / 4, tr); ! Graphics2D g2 = bim.createGraphics(); ! g2.setColor(new Color(0, 0, 255, 150)); ! g2.fillRect(0, 0, w * 3 / 4, h * 3 / 4); ! g2.dispose(); gg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, a)); gg.drawImage(bim, GAP + w / 4, GAP + h / 4, null); --- 40,54 ---- gg.setColor(Color.RED); gg.fillRect(GAP, GAP, w * 3 / 4, h * 3 / 4); ! int bw = w * 3 / 4, bh = h * 3 / 4; ! if (bim == null || bim.getWidth() != w || bim.getHeight() != bh) { ! GraphicsConfiguration gc = getGraphicsConfiguration(); ! bim = gc.createCompatibleImage(bw,bh, tr); ! Graphics2D g2 = bim.createGraphics(); ! g2.setColor(new Color(0, 0, 255, 150)); ! g2.fillRect(0, 0, bw, bh); ! g2.dispose(); ! } gg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, a)); gg.drawImage(bim, GAP + w / 4, GAP + h / 4, null);
10-10-2008