United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6758179 D3D: AlphaComposite is applied incorrectly for uncached opaque BufferedImage
JDK-6758179 : D3D: AlphaComposite is applied incorrectly for uncached opaque BufferedImage

Details
Type:
Bug
Submit Date:
2008-10-10
Status:
Resolved
Updated Date:
2011-01-19
Project Name:
JDK
Resolved Date:
2009-01-09
Component:
client-libs
OS:
windows
Sub-Component:
2d
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:

Sub Tasks

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

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);
                                     
2008-10-10
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.
                                     
2008-10-10
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.
                                     
2008-10-28
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..
                                     
2008-10-28
SUGGESTED FIX

http://hg.openjdk.java.net/jdk7/2d/jdk/rev/8eb24fc88242
                                     
2008-11-19
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.
                                     
2008-11-19



Hardware and Software, Engineered to Work Together