Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java
38840 views
/*1* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.awt.AWTException;24import java.awt.Canvas;25import java.awt.Color;26import java.awt.Component;27import java.awt.Dimension;28import java.awt.Frame;29import java.awt.Graphics;30import java.awt.Graphics2D;31import java.awt.GraphicsConfiguration;32import java.awt.GraphicsEnvironment;33import java.awt.HeadlessException;34import java.awt.Rectangle;35import java.awt.Robot;36import java.awt.Toolkit;37import java.awt.event.WindowAdapter;38import java.awt.event.WindowEvent;39import java.awt.image.BufferedImage;40import java.awt.image.VolatileImage;41import java.io.File;42import java.io.IOException;43import java.util.HashSet;44import javax.imageio.ImageIO;45import sun.awt.ConstrainableGraphics;4647/**48* @test49* @bug 6335200 641961050* @summary Tests that we don't render anything if specific empty clip is set51* @author [email protected]: area=Graphics52* @run main EmptyClipRenderingTest53* @run main/othervm -Dsun.java2d.noddraw=true EmptyClipRenderingTest54* @run main/othervm -Dsun.java2d.pmoffscreen=true EmptyClipRenderingTest55* @run main/othervm -Dsun.java2d.opengl=true EmptyClipRenderingTest56*/57public class EmptyClipRenderingTest {58static final int IMG_W = 400;59static final int IMG_H = 400;6061// generated rectangles62static HashSet<Rectangle> rects;6364volatile boolean isActivated = false;65volatile boolean isPainted;66private static boolean showErrors = false;6768public EmptyClipRenderingTest() {69// initialize clip/render region rectangles70initClips();7172HashSet<RuntimeException> errors = new HashSet<RuntimeException>();7374BufferedImage screenResult = testOnscreen();75try {76testResult(screenResult, "Screen");77} catch (RuntimeException e) {78errors.add(e);79}8081BufferedImage destBI =82new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_RGB);83runTest((Graphics2D)destBI.getGraphics());84try {85testResult(destBI, "BufferedImage");86} catch (RuntimeException e) {87errors.add(e);88}8990GraphicsConfiguration gc =91GraphicsEnvironment.getLocalGraphicsEnvironment().92getDefaultScreenDevice().getDefaultConfiguration();93VolatileImage destVI = gc.createCompatibleVolatileImage(IMG_W, IMG_H);94destVI.validate(gc);95runTest((Graphics2D)destVI.getGraphics());96try {97testResult(destVI.getSnapshot(), "VolatileImage");98} catch (RuntimeException e) {99errors.add(e);100}101102if (errors.isEmpty()) {103System.err.println("Test PASSED.");104} else {105for (RuntimeException re : errors) {106re.printStackTrace();107}108if (showErrors) {109System.err.println("Test FAILED: "+ errors.size() +110" subtest failures.");111} else {112throw new RuntimeException("Test FAILED: "+ errors.size() +113" subtest failures.");114}115}116}117118/**119* Recursively adds 4 new rectangles: two vertical and two horizontal120* based on the passed rectangle area. The area is then shrunk and the121* process repeated for smaller area.122*/123private static void add4Rects(HashSet<Rectangle> rects, Rectangle area) {124if (area.width < 10 || area.height < 10) {125rects.add(area);126return;127}128// two vertical rects129rects.add(new Rectangle(area.x, area.y, 5, area.height));130rects.add(new Rectangle(area.x + area.width - 5, area.y, 5, area.height));131// two horizontal rects132int width = area.width - 2*(5 + 1);133rects.add(new Rectangle(area.x+6, area.y, width, 5));134rects.add(new Rectangle(area.x+6, area.y + area.height - 5, width, 5));135// reduce the area and repeat136area.grow(-6, -6);137add4Rects(rects, area);138}139140/**141* Generate a bunch of non-intersecting rectangles142*/143private static void initClips() {144rects = new HashSet<Rectangle>();145add4Rects(rects, new Rectangle(0, 0, IMG_W, IMG_H));146System.err.println("Total number of test rects: " + rects.size());147}148149/**150* Render the pattern to the screen, capture the output with robot and151* return it.152*/153private BufferedImage testOnscreen() throws HeadlessException {154final Canvas destComponent;155final Object lock = new Object();156Frame f = new Frame("Test Frame");157f.setUndecorated(true);158f.add(destComponent = new Canvas() {159public void paint(Graphics g) {160isPainted = true;161}162public Dimension getPreferredSize() {163return new Dimension(IMG_W, IMG_H);164}165});166f.addWindowListener(new WindowAdapter() {167public void windowActivated(WindowEvent e) {168if (!isActivated) {169synchronized (lock) {170isActivated = true;171lock.notify();172}173}174}175});176f.pack();177f.setLocationRelativeTo(null);178f.setVisible(true);179synchronized(lock) {180while (!isActivated) {181try {182lock.wait(100);183} catch (InterruptedException ex) {184ex.printStackTrace();185}186}187}188Robot r;189try {190r = new Robot();191} catch (AWTException ex) {192throw new RuntimeException("Can't create Robot");193}194BufferedImage bi;195int attempt = 0;196do {197if (++attempt > 10) {198throw new RuntimeException("Too many attempts: " + attempt);199}200isPainted = false;201runTest((Graphics2D) destComponent.getGraphics());202r.waitForIdle();203Toolkit.getDefaultToolkit().sync();204bi = r.createScreenCapture(205new Rectangle(destComponent.getLocationOnScreen().x,206destComponent.getLocationOnScreen().y,207destComponent.getWidth(),208destComponent.getHeight()));209} while (isPainted);210f.setVisible(false);211f.dispose();212return bi;213}214215/**216* Run the test: cycle through all the rectangles, use one as clip and217* another as the area to render to.218* Set the clip in the same way Swing does it when repainting:219* first constrain the graphics to the damaged area, and repaint everything220*/221void runTest(Graphics2D destGraphics) {222destGraphics.setColor(Color.black);223destGraphics.fillRect(0, 0, IMG_W, IMG_H);224225destGraphics.setColor(Color.red);226for (Rectangle clip : rects) {227Graphics2D g2d = (Graphics2D)destGraphics.create();228g2d.setColor(Color.red);229// mimic what swing does in BufferStrategyPaintManager230if (g2d instanceof ConstrainableGraphics) {231((ConstrainableGraphics)g2d).constrain(clip.x, clip.y,232clip.width, clip.height);233}234g2d.setClip(clip);235236for (Rectangle renderRegion : rects) {237if (renderRegion != clip) {238// from CellRendererPane's paintComponent239Graphics2D rG = (Graphics2D)240g2d.create(renderRegion.x, renderRegion.y,241renderRegion.width, renderRegion.height);242rG.fillRect(0,0, renderRegion.width, renderRegion.height);243}244}245}246}247248void testResult(final BufferedImage bi, final String desc) {249for (int y = 0; y < bi.getHeight(); y++) {250for (int x = 0; x < bi.getWidth(); x++) {251if (bi.getRGB(x, y) != Color.black.getRGB()) {252if (showErrors) {253Frame f = new Frame("Error: " + desc);254f.add(new Component() {255public void paint(Graphics g) {256g.drawImage(bi, 0, 0, null);257}258public Dimension getPreferredSize() {259return new Dimension(bi.getWidth(),260bi.getHeight());261}262});263f.pack();264f.setVisible(true);265}266try {267String fileName =268"EmptyClipRenderingTest_"+desc+"_res.png";269System.out.println("Writing resulting image: "+fileName);270ImageIO.write(bi, "png", new File(fileName));271} catch (IOException ex) {272ex.printStackTrace();273}274throw new RuntimeException("Dest: "+desc+275" was rendered to at x="+276x + " y=" + y +277" pixel="+Integer.toHexString(bi.getRGB(x,y)));278}279}280}281}282283public static void main(String argv[]) {284for (String arg : argv) {285if (arg.equals("-show")) {286showErrors = true;287} else {288usage("Incorrect argument:" + arg);289}290}291new EmptyClipRenderingTest();292}293294private static void usage(String string) {295System.out.println(string);296System.out.println("Usage: EmptyClipRenderingTest [-show]");297}298}299300301