Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8165212

VolatileImage should not be compatible with GraphicsConfiguration which transform is changed

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 9
    • Fix Version/s: 9
    • Component/s: client-libs
    • Labels:
    • Subcomponent:
      2d
    • Resolved In Build:
      b147

      Description

      The issue is reproduced on HiDPI display when screen DPI is changed.
      VolatileImage.validate(GraphicsConfiguration) IMAGE_OK for a graphics configuration when its default transform is updated.

      Steps to reproduce:
      - Use the Windows 8.1 or higher with HiDPI display
      - Open Control Panel->All Control Panel Items->Display and select DPI 96 on the "Make text and other items on the desktop smaller or larger" slider
      - Run the code below which draws a garphics and graphics configuration scales directly to component and using a VolatileImage.
      Both scales are 1.0 (see the attached screenshot left window)
      - Select DPI 192 on the "Make text and other items on the desktop smaller or larger" slider
       The graphics scale is now 2.0 but VolatileImage graphics scale is still 1 because VolatileImage.validate(GraphicsConfiguration) returns IMAGE_OK for new graphics configuration and it was not recreated (see attached screenshot right window) (note that there is a known issue that a window is not correctly repainted JDK-8147016).

      Code sample
      ------------------------
      import java.awt.Color;
      import java.awt.Frame;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.GraphicsConfiguration;
      import java.awt.HeadlessException;
      import java.awt.event.WindowAdapter;
      import java.awt.event.WindowEvent;
      import java.awt.geom.AffineTransform;
      import java.awt.image.VolatileImage;

      public class BackingStoreImageTest {

          public static void main(String[] args) {

              TestFrame frame = new TestFrame();
              frame.setVisible(true);
          }

          static class TestFrame extends Frame {

              static int TEST_WIDTH = 600;
              static int TEST_HEIGHT = 500;
              static int TEST_X = 20;
              static int TEST_Y = 80;

              static String MSG = "%s scale: [%2.2f, %2.2f]";

              private VolatileImage vImg;

              public TestFrame() throws HeadlessException {
                  setSize(TEST_WIDTH, TEST_HEIGHT);
                  addWindowListener(new WindowAdapter() {
                      @Override
                      public void windowClosing(WindowEvent e) {
                          System.exit(0);
                      }
                  });
              }

              @Override
              public void paint(Graphics g) {
                  super.paint(g);

                  drawInfo(g, TEST_X, TEST_Y, "component", Color.BLUE);

                  int attempts = 0;
                  do {
                      drawBackingStoreImage(g);
                  } while (vImg.contentsLost() && ++attempts < 3);
              }

              private void drawInfo(Graphics g, int x, int y, String msg, Color color) {

                  g.setColor(color);
                  g.setFont(g.getFont().deriveFont(24f));
                  Graphics2D g2d = (Graphics2D) g;
                  AffineTransform tx = g2d.getTransform();
                  g.drawString(msg, x, y);
                  String text = String.format(MSG, "graphics", tx.getScaleX(), tx.getScaleY());
                  int dy = 20;
                  g.drawString(text, x, y + dy);
                  tx = g2d.getDeviceConfiguration().getDefaultTransform();
                  text = String.format(MSG, "graphics config", tx.getScaleX(), tx.getScaleY());
                  g.drawString(text, x, y + 2 * dy);
              }

              private void drawBackingStoreImage(Graphics g) {

                  GraphicsConfiguration gc = ((Graphics2D) g).getDeviceConfiguration();
                  if (vImg == null || vImg.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
                      vImg = createVolatileImage(TEST_WIDTH, TEST_HEIGHT / 3);
                  }

                  Graphics vImgGraphics = vImg.createGraphics();
                  drawInfo(vImgGraphics, TEST_X, TEST_Y, "backbuffer", Color.MAGENTA);
                  g.drawImage(vImg, 0, TEST_Y * 2, this);
              }
          }
      }
      ------------------------

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              pnarayanan Prahalad Kumar Narayanan (Inactive)
              Reporter:
              alexsch Alexandr Scherbatiy
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: