JDK-8049351 : Custom composite Internal Error not supported yet on Java 1.7+ for Mac OS X
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7u51,8
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: os_x
  • CPU: x86
  • Submitted: 2014-06-27
  • Updated: 2014-07-07
  • Resolved: 2014-07-07
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 9
9Resolved
Related Reports
Duplicate :  
Duplicate :  
Description
FULL PRODUCT VERSION :
Java Version 1.7.0_51, 64-bit, Oracle Corporation

ADDITIONAL OS VERSION INFORMATION :
Mac OS X 10.9.3 x86_64

A DESCRIPTION OF THE PROBLEM :
Here������s a sample demonstrating the custom composite issue that is not supported in any version (1.7+) of the OpenJDK on Mac OS X. This works fine in the Apple 1.6 JRE.


REGRESSION.  Last worked in version 6u45

ADDITIONAL REGRESSION INFORMATION: 
This used to work fine in the Apple 1.6 JRE. 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
see attached source code sample

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
display a custom composite
ACTUAL -
getting an Internal Error

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.InternalError: not implemented yet
	at sun.java2d.opengl.OGLSurfaceData.getRaster(OGLSurfaceData.java:397)
	at sun.java2d.pipe.GeneralCompositePipe.renderPathTile(GeneralCompositePipe.java:100)
	at sun.java2d.pipe.SpanShapeRenderer$Composite.renderBox(SpanShapeRenderer.java:60)
	at sun.java2d.pipe.SpanShapeRenderer.renderRect(SpanShapeRenderer.java:165)
	at sun.java2d.pipe.SpanShapeRenderer.fill(SpanShapeRenderer.java:107)
	at sun.java2d.pipe.ValidatePipe.fill(ValidatePipe.java:160)
	at sun.java2d.SunGraphics2D.fill(SunGraphics2D.java:2466)
	at BlendMultiplySample$2.paintComponent(BlendMultiplySample.java:81)
	at javax.swing.JComponent.paint(JComponent.java:1054)
	at javax.swing.JComponent.paintChildren(JComponent.java:887)
	at javax.swing.JComponent.paint(JComponent.java:1063)
	at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
	at javax.swing.JComponent.paintChildren(JComponent.java:887)
	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5226)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1529)
	at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1452)
	at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
	at javax.swing.JComponent.paint(JComponent.java:1040)
	at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
	at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:78)
	at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:115)
	at java.awt.Container.paint(Container.java:1967)
	at java.awt.Window.paint(Window.java:3877)
	at javax.swing.RepaintManager$3.run(RepaintManager.java:819)
	at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
	at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
	at java.awt.EventQueue.access$200(EventQueue.java:103)
	at java.awt.EventQueue$3.run(EventQueue.java:694)
	at java.awt.EventQueue$3.run(EventQueue.java:692)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Color;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class BlendMultiplySample extends JFrame
{

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		SwingUtilities.invokeLater(new Runnable() {
			public void run()
			{
				BlendMultiplySample thisClass = new BlendMultiplySample();
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				thisClass.setVisible(true);
			}
		});
	}

	/**
	 * This is the default constructor
	 */
	public BlendMultiplySample()
	{
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize()
	{
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		this.setTitle("Blend Multiply");
		this.setLocationRelativeTo(null);
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane()
	{
		if (jContentPane == null)
		{
			jContentPane = new JPanel() {
				protected void paintComponent(Graphics g)
				{
					g.setColor(Color.black);
					String text = "This text should be visible";
					Rectangle2D bounds2d = g.getFontMetrics().getStringBounds(text, g);
					g.drawString(text, 20, 40);
					
					// This is not supported on Java 1.7+ for Mac OS X
					((Graphics2D) g).setComposite(new CompositeImpl());
					
					g.setColor(Color.yellow);
					g.translate(20, 40);
					((Graphics2D) g).fill(bounds2d);
				};
			};
		}
		return jContentPane;
	}

	class CompositeImpl implements Composite
	{
	    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints)
	    {
	        return new CompRGB(srcColorModel.hasAlpha(), dstColorModel.hasAlpha());
	    }
	    
	    public class CompRGB implements CompositeContext
	    {
	        private boolean mSrcHasAlpha;
	        private boolean mDstHasAlpha;
	        
	        CompRGB (boolean srcHasAlpha, boolean dstHasAlpha)
	        {
	            mSrcHasAlpha = srcHasAlpha;
	            mDstHasAlpha = dstHasAlpha;
	        }

	        public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
	        {
	            float [] srcARGB = new float [4];
	            float [] dstInARGB = new float [4];
	            float [] blendARGB = new float [4];
	            
	            int [] dataElement = new int [1];

	            int dstInHeight = dstIn.getHeight();
	            int dstInWidth = dstIn.getWidth();
	            for (int y = 0; y < dstInHeight; ++y)
	            {
	                for (int x = 0; x < dstInWidth; ++x)
	                {
	                    // Get pixels
	                    src.getDataElements(x, y, dataElement);
	                    getFloatARGB (dataElement[0], srcARGB, mSrcHasAlpha);
	                    dstIn.getDataElements(x, y, dataElement);
	                    getFloatARGB (dataElement[0], dstInARGB, mDstHasAlpha);
	                    
	                    // Blend the colors
	                    blend (srcARGB, dstInARGB, blendARGB);
	                                            
	                    dataElement[0] = getIntARGB (blendARGB);
	                    dstOut.setDataElements(x, y, dataElement);
	                }
	            }
	        }    
	        
	        public void dispose() {};
	    }
	    
	    public void blend(float[] srcPixels, float[] dstInPixels, float[] dstOutPixels)
	    {
	        dstOutPixels [0] = (dstInPixels [0] * srcPixels [0]);
	        dstOutPixels [1] = (dstInPixels [1] * srcPixels [1]);
	        dstOutPixels [2] = (dstInPixels [2] * srcPixels [2]);
	        dstOutPixels [3] = (dstInPixels [3] * srcPixels [3]);
	    }
	    
	    private void getFloatARGB (int argb, float [] outARGB, boolean hasAlpha)
	    {
	        outARGB [0] = hasAlpha ? ((argb >> 24) & 0xff) / 255f : 1f;
	        outARGB [1] = ((argb >> 16) & 0xff) / 255f;
	        outARGB [2] = ((argb >> 8) & 0xff) / 255f;
	        outARGB [3] = ((argb >> 0) & 0xff) / 255f;
	    }
	    
	    private int getIntARGB (float [] inARGB)
	    {
	        int a = (int)(inARGB [0] * 255f);
	        int r = (int)(inARGB [1] * 255f);
	        int g = (int)(inARGB [2] * 255f);
	        int b = (int)(inARGB [3] * 255f);
	        
	        return (a << 24) | (r << 16) | (g << 8) | b;
	    }
	}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
We haven't found a workaround other than reverting to an alpha composite which really does not look crisp on text highlights...

We're continuing to require our users to download Java 1.6 until this is fixed.