JDK-8072618 : Icon with TexturePaint throws InternalErrro: Surface not cachable
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 8u25
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: linux
  • CPU: x86_64
  • Submitted: 2014-10-29
  • Updated: 2021-03-10
  • Resolved: 2014-11-13
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux 3.11.0-18-generic #32-Ubuntu SMP Tue Feb 18 21:11:14 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
A custom javax.swing.Icon implementation which sets a TexturePaint on a Graphics2D and calls fillPolygon afterwards throws a java.lang.InternalError when the icon is being painted.

REGRESSION.  Last worked in version 7u71

ADDITIONAL REGRESSION INFORMATION: 
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A JFrame containing a JLabel with a custom Icon and some text
ACTUAL -
An InternalError is being thrown with message: Surface not cachable

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.InternalError: Surface not cachable
    at sun.java2d.xr.XRPaints$XRTexture.getAccSrcSurface(XRPaints.java:211)
    at sun.java2d.xr.XRPaints$XRTexture.isPaintValid(XRPaints.java:224)
    at sun.java2d.xr.XRPaints.isValid(XRPaints.java:75)
    at sun.java2d.xr.XRSurfaceData.getMaskFill(XRSurfaceData.java:205)
    at sun.java2d.SurfaceData.validatePipe(SurfaceData.java:675)
    at sun.java2d.xr.XRSurfaceData.validatePipe(XRSurfaceData.java:123)
    at sun.java2d.SunGraphics2D.validatePipe(SunGraphics2D.java:446)
    at sun.java2d.pipe.ValidatePipe.validate(ValidatePipe.java:55)
    at sun.java2d.pipe.ValidatePipe.fillPolygon(ValidatePipe.java:147)
    at sun.java2d.SunGraphics2D.fillPolygon(SunGraphics2D.java:2389)
    at TexturePaintIconTest$CustomIcon.paintIcon(TexturePaintIconTest.java:22)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;

public class TexturePaintIconTest {

  private static class CustomIcon implements Icon{

    private static final int[] sXArray = new int[]{2, 5, 7, 12, 12, 4, 1, 1, 2};
    private static final int[] sYArray = new int[]{4, 4, 2, 2, 11, 11, 8, 5, 4};
    private static final int sNumberOfPoints = 9;

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
      g.translate(x,y);

      Graphics2D g2d = (Graphics2D) g;
      Color fillColor = new Color( 140, 25, 25, 35);
      g2d.setPaint(createPatternPaint(fillColor));
      g2d.fillPolygon(sXArray, sYArray, sNumberOfPoints);

      g.translate(-x, -y);
    }

    private Paint createPatternPaint(Color color ){
      int[] colors = new int[]{color.getRGB(), 0};
      IndexColorModel colorModel = new IndexColorModel(1, 2, colors, 0, true, -1, DataBuffer.TYPE_BYTE);
      BufferedImage image = new BufferedImage(2, 2, BufferedImage.TYPE_BYTE_INDEXED, colorModel);
      DataBufferByte dataBuffer = (DataBufferByte) image.getRaster().getDataBuffer();
      byte[] data = dataBuffer.getData();
      data[0] = 0;
      data[1] = 1;
      data[2] = 1;
      data[3] = 0;
      return new TexturePaint(image, new Rectangle(2, 2));
    }

    @Override
    public int getIconWidth() {
      return 16;
    }

    @Override
    public int getIconHeight() {
      return 16;
    }
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        JFrame testFrame = new JFrame("TestFrame");

        JLabel label = new JLabel("Label with icon", new CustomIcon(), SwingConstants.LEFT);
        testFrame.add(label);

        testFrame.pack();
        testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        testFrame.setVisible(true);
      }
    });
  }

}
---------- END SOURCE ----------


Comments
Tested with 7u72, 8u25, and 8u40 and couldn't reproduce on Windows. Tested with 8u25, and 8u40 on Oracle Linux 6.5 and couldn't reproduce. Closing this as not an issue.
13-11-2014