test/jdk/java/awt/image/VolatileImage/CustomCompositeTest.java
changeset 49217 3b820b878ebe
equal deleted inserted replaced
49216:577f96d4f3c9 49217:3b820b878ebe
       
     1 /*
       
     2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @key headful
       
    27  * @bug     7124347 8198613
       
    28  * @summary Verifies that rendering with XOR composite, and arbitraty
       
    29  *          custom composite doesn not cause internal errors.
       
    30  *
       
    31  * @run     main/othervm CustomCompositeTest
       
    32  */
       
    33 
       
    34 import java.awt.AWTException;
       
    35 import java.awt.Color;
       
    36 import java.awt.Composite;
       
    37 import java.awt.CompositeContext;
       
    38 import java.awt.Dimension;
       
    39 import java.awt.GradientPaint;
       
    40 import java.awt.Graphics;
       
    41 import java.awt.Graphics2D;
       
    42 import java.awt.GraphicsConfiguration;
       
    43 import java.awt.GraphicsEnvironment;
       
    44 import java.awt.ImageCapabilities;
       
    45 import java.awt.RenderingHints;
       
    46 import java.awt.image.BufferedImage;
       
    47 import java.awt.image.ColorModel;
       
    48 import java.awt.image.DataBufferInt;
       
    49 import java.awt.image.Raster;
       
    50 import java.awt.image.SinglePixelPackedSampleModel;
       
    51 import java.awt.image.VolatileImage;
       
    52 import java.awt.image.WritableRaster;
       
    53 import java.util.concurrent.CountDownLatch;
       
    54 import javax.swing.JComponent;
       
    55 import javax.swing.JFrame;
       
    56 import javax.swing.SwingUtilities;
       
    57 
       
    58 public class CustomCompositeTest {
       
    59 
       
    60     private static JFrame frame;
       
    61     private static CountDownLatch paintLatch;
       
    62     private static Throwable paintError;
       
    63 
       
    64     public static void main(String[] args) {
       
    65 
       
    66         paintLatch = new CountDownLatch(1);
       
    67         paintError = null;
       
    68 
       
    69         SwingUtilities.invokeLater(new Runnable() {
       
    70             public void run() {
       
    71                 initGUI();
       
    72             }
       
    73         });
       
    74 
       
    75         try {
       
    76             paintLatch.await();
       
    77         } catch (InterruptedException e) {
       
    78         };
       
    79         System.out.println("Paint is done!");
       
    80         if (paintError != null) {
       
    81             frame.dispose();
       
    82             throw new RuntimeException("Test FAILED.", paintError);
       
    83         }
       
    84 
       
    85         System.out.println("Phase 1: PASSED.");
       
    86 
       
    87         // now resise the frame in order to cause re-paint with accelerated
       
    88         // source images.
       
    89         paintError = null;
       
    90         paintLatch = new CountDownLatch(1);
       
    91 
       
    92         SwingUtilities.invokeLater(new Runnable() {
       
    93             @Override
       
    94             public void run() {
       
    95                 Dimension size = frame.getSize();
       
    96                 size.width += 50;
       
    97                 size.height += 50;
       
    98 
       
    99                 frame.setSize(size);
       
   100             }
       
   101         });
       
   102 
       
   103         try {
       
   104             paintLatch.await();
       
   105         } catch (InterruptedException e) {
       
   106         };
       
   107         if (paintError != null) {
       
   108             frame.dispose();
       
   109             throw new RuntimeException("Resize test FAILED.", paintError);
       
   110         }
       
   111         frame.dispose();
       
   112         System.out.println("Phase 2: PASSED.");
       
   113 
       
   114         GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
       
   115         GraphicsConfiguration cfg = env.getDefaultScreenDevice().getDefaultConfiguration();
       
   116         // test rendering to accelerated volatile image
       
   117         testVolatileImage(cfg, true);
       
   118         System.out.println("Phase 3: PASSED.");
       
   119 
       
   120         // test rendering to unaccelerated volatile image
       
   121         testVolatileImage(cfg, false);
       
   122         System.out.println("Phase 4: PASSED.");
       
   123     }
       
   124 
       
   125     private static void testVolatileImage(GraphicsConfiguration cfg,
       
   126             boolean accelerated)
       
   127     {
       
   128         VolatileImage dst = null;
       
   129         try {
       
   130             dst = cfg.createCompatibleVolatileImage(640, 480,
       
   131                 new ImageCapabilities(accelerated));
       
   132         } catch (AWTException e) {
       
   133             System.out.println("Unable to create volatile image, skip the test.");
       
   134             return;
       
   135         }
       
   136         renderToVolatileImage(dst);
       
   137     }
       
   138 
       
   139     private static void renderToVolatileImage(VolatileImage dst) {
       
   140         Graphics2D g = dst.createGraphics();
       
   141         do {
       
   142             System.out.println("Render to volatile image..");
       
   143             try {
       
   144                 MyComp.renderTest(g, dst.getHeight(), dst.getHeight());
       
   145             } catch (Throwable e) {
       
   146                 throw new RuntimeException("Test FAILED.", e);
       
   147             }
       
   148         } while (dst.contentsLost());
       
   149         System.out.println("Done.");
       
   150     }
       
   151 
       
   152     private static void initGUI() {
       
   153         frame = new JFrame("Silly composite");
       
   154         frame.getContentPane().add(new MyComp());
       
   155         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
   156         frame.pack();
       
   157         frame.setVisible(true);
       
   158     }
       
   159 
       
   160     private static class MyComp extends JComponent {
       
   161 
       
   162         private static BufferedImage theImage;
       
   163 
       
   164         public MyComp() {
       
   165         }
       
   166 
       
   167         private static BufferedImage getTestImage() {
       
   168             if (theImage == null) {
       
   169                 theImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
       
   170                 Graphics2D g2d = theImage.createGraphics();
       
   171                 g2d.setColor(Color.red);
       
   172                 g2d.fillRect(0, 0, 256, 256);
       
   173 
       
   174                 g2d.setPaint(new GradientPaint(0, 0, Color.red, 256, 256, Color.blue));
       
   175                 g2d.fillRect(0, 100, 256, 256);
       
   176                 g2d.dispose();
       
   177             }
       
   178             return theImage;
       
   179         }
       
   180 
       
   181         public Dimension getPreferredSize() {
       
   182             return new Dimension(640, 375);
       
   183         }
       
   184 
       
   185         public void paintComponent(Graphics g) {
       
   186 
       
   187 
       
   188             Graphics2D g2d = (Graphics2D) g;
       
   189             try {
       
   190                 renderTest(g2d, getWidth(), getHeight());
       
   191             } catch (Throwable e) {
       
   192                 paintError = e;
       
   193             }
       
   194             if (paintLatch != null) {
       
   195                 paintLatch.countDown();
       
   196             }
       
   197         }
       
   198 
       
   199         public static void renderTest(Graphics2D g2d, int w, int h) {
       
   200             g2d.setColor(Color.yellow);
       
   201             g2d.fillRect(0, 0, w, h);
       
   202 
       
   203             BufferedImage image = getTestImage();
       
   204             // draw original image
       
   205             g2d.drawRenderedImage(image, null);
       
   206 
       
   207             // draw image with custom composite
       
   208             g2d.translate(175, 25);
       
   209             Composite currentComposite = g2d.getComposite();
       
   210             g2d.setComposite(new TestComposite());
       
   211             g2d.drawRenderedImage(image, null);
       
   212             g2d.setComposite(currentComposite);
       
   213 
       
   214             // draw image with XOR
       
   215             g2d.translate(175, 25);
       
   216             g2d.setXORMode(Color.red);
       
   217             g2d.drawRenderedImage(image, null);
       
   218 
       
   219 
       
   220             System.out.println("Painting is done...");
       
   221         }
       
   222     }
       
   223 
       
   224     // A silly custom Composite to demonstrate the problem - just inverts the RGB
       
   225     private static class TestComposite implements Composite {
       
   226 
       
   227         public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
       
   228             return new TestCompositeContext();
       
   229         }
       
   230     }
       
   231 
       
   232     private static class TestCompositeContext implements CompositeContext {
       
   233 
       
   234         public void dispose() {
       
   235         }
       
   236 
       
   237         public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
       
   238             int w = src.getWidth();
       
   239             int h = src.getHeight();
       
   240 
       
   241             DataBufferInt srcDB = (DataBufferInt) src.getDataBuffer();
       
   242             DataBufferInt dstOutDB = (DataBufferInt) dstOut.getDataBuffer();
       
   243             int srcRGB[] = srcDB.getBankData()[0];
       
   244             int dstOutRGB[] = dstOutDB.getBankData()[0];
       
   245             int srcOffset = srcDB.getOffset();
       
   246             int dstOutOffset = dstOutDB.getOffset();
       
   247             int srcScanStride = ((SinglePixelPackedSampleModel) src.getSampleModel()).getScanlineStride();
       
   248             int dstOutScanStride = ((SinglePixelPackedSampleModel) dstOut.getSampleModel()).getScanlineStride();
       
   249             int srcAdjust = srcScanStride - w;
       
   250             int dstOutAdjust = dstOutScanStride - w;
       
   251 
       
   252             int si = srcOffset;
       
   253             int doi = dstOutOffset;
       
   254 
       
   255             for (int i = 0; i < h; i++) {
       
   256                 for (int j = 0; j < w; j++) {
       
   257                     dstOutRGB[doi] = srcRGB[si] ^ 0x00ffffff;
       
   258                     si++;
       
   259                     doi++;
       
   260                 }
       
   261 
       
   262                 si += srcAdjust;
       
   263                 doi += dstOutAdjust;
       
   264             }
       
   265         }
       
   266     }
       
   267 }