7160609: [macosx] JDK crash in libjvm.dylib ( C [GeForceGLDriver+0x675a] gldAttachDrawable+0x941)
authoranthony
Fri, 24 Aug 2012 14:58:04 +0400
changeset 13550 648dd6fa0dee
parent 13549 d3ec89e4a9ab
child 13551 65c162507e57
7160609: [macosx] JDK crash in libjvm.dylib ( C [GeForceGLDriver+0x675a] gldAttachDrawable+0x941) Summary: Constrain window dimensions with screen bounds and GL_MAX_TEXTURE_SIZE Reviewed-by: art, serb
jdk/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m
jdk/src/share/classes/sun/awt/TextureSizeConstraining.java
jdk/test/java/awt/Frame/HugeFrame/HugeFrame.java
--- a/jdk/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java	Fri Aug 24 11:35:51 2012 +0800
+++ b/jdk/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java	Fri Aug 24 14:58:04 2012 +0400
@@ -31,8 +31,12 @@
 import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
 import java.awt.Image;
 import java.awt.ImageCapabilities;
+import java.awt.Rectangle;
 import java.awt.Transparency;
 import java.awt.color.ColorSpace;
 import java.awt.image.BufferedImage;
@@ -44,6 +48,7 @@
 
 import sun.awt.CGraphicsConfig;
 import sun.awt.CGraphicsDevice;
+import sun.awt.TextureSizeConstraining;
 import sun.awt.image.OffScreenImage;
 import sun.awt.image.SunVolatileImage;
 import sun.awt.image.SurfaceManager;
@@ -65,7 +70,7 @@
 import sun.lwawt.macosx.CPlatformView;
 
 public class CGLGraphicsConfig extends CGraphicsConfig
-    implements OGLGraphicsConfig
+    implements OGLGraphicsConfig, TextureSizeConstraining
 {
     //private static final int kOpenGLSwapInterval = RuntimeOptions.getCurrentOptions().OpenGLSwapInterval;
     private static final int kOpenGLSwapInterval = 0; // TODO
@@ -242,6 +247,8 @@
         } finally {
             rq.unlock();
         }
+
+        updateTotalDisplayBounds();
     }
 
     @Override
@@ -478,4 +485,50 @@
     public void removeDeviceEventListener(AccelDeviceEventListener l) {
         AccelDeviceEventNotifier.removeListener(l);
     }
+
+    private static final Rectangle totalDisplayBounds = new Rectangle();
+
+    private static void updateTotalDisplayBounds() {
+        synchronized (totalDisplayBounds) {
+            Rectangle virtualBounds = new Rectangle();
+            for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
+                for (GraphicsConfiguration gc : gd.getConfigurations()) {
+                    virtualBounds = virtualBounds.union(gc.getBounds());
+                }
+            }
+            totalDisplayBounds.setBounds(virtualBounds);
+        }
+    }
+
+    // 7160609: GL still fails to create a square texture of this size,
+    //          so we use this value to cap the total display bounds.
+    native private static int getMaxTextureSize();
+
+    @Override
+    public int getMaxTextureWidth() {
+        int width;
+
+        synchronized (totalDisplayBounds) {
+            if (totalDisplayBounds.width == 0) {
+                updateTotalDisplayBounds();
+            }
+            width = totalDisplayBounds.width;
+        }
+
+        return Math.min(width, getMaxTextureSize());
+    }
+
+    @Override
+    public int getMaxTextureHeight() {
+        int height;
+
+        synchronized (totalDisplayBounds) {
+            if (totalDisplayBounds.height == 0) {
+                updateTotalDisplayBounds();
+            }
+            height = totalDisplayBounds.height;
+        }
+
+        return Math.min(height, getMaxTextureSize());
+    }
 }
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Fri Aug 24 11:35:51 2012 +0800
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Fri Aug 24 14:58:04 2012 +0400
@@ -338,6 +338,18 @@
             h = MINIMUM_HEIGHT;
         }
 
+        if (graphicsConfig instanceof TextureSizeConstraining) {
+            final int maxW = ((TextureSizeConstraining)graphicsConfig).getMaxTextureWidth();
+            final int maxH = ((TextureSizeConstraining)graphicsConfig).getMaxTextureHeight();
+
+            if (w > maxW) {
+                w = maxW;
+            }
+            if (h > maxH) {
+                h = maxH;
+            }
+        }
+
         // Don't post ComponentMoved/Resized and Paint events
         // until we've got a notification from the delegate
         setBounds(x, y, w, h, op, false, false);
@@ -405,14 +417,33 @@
 
     @Override
     public void updateMinimumSize() {
-        Dimension d = null;
+        final Dimension min;
         if (getTarget().isMinimumSizeSet()) {
-            d = getTarget().getMinimumSize();
+            min = getTarget().getMinimumSize();
+            min.width = Math.max(min.width, MINIMUM_WIDTH);
+            min.height = Math.max(min.height, MINIMUM_HEIGHT);
+        } else {
+            min = new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT);
         }
-        if (d == null) {
-            d = new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT);
+
+        final int maxW, maxH;
+        if (graphicsConfig instanceof TextureSizeConstraining) {
+            maxW = ((TextureSizeConstraining)graphicsConfig).getMaxTextureWidth();
+            maxH = ((TextureSizeConstraining)graphicsConfig).getMaxTextureHeight();
+        } else {
+            maxW = maxH = Integer.MAX_VALUE;
         }
-        platformWindow.setMinimumSize(d.width, d.height);
+
+        final Dimension max;
+        if (getTarget().isMaximumSizeSet()) {
+            max = getTarget().getMaximumSize();
+            max.width = Math.min(max.width, maxW);
+            max.height = Math.min(max.height, maxH);
+        } else {
+            max = new Dimension(maxW, maxH);
+        }
+
+        platformWindow.setSizeConstraints(min.width, min.height, max.width, max.height);
     }
 
     @Override
--- a/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Fri Aug 24 11:35:51 2012 +0800
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java	Fri Aug 24 14:58:04 2012 +0400
@@ -131,7 +131,10 @@
 
     public void setResizable(boolean resizable);
 
-    public void setMinimumSize(int width, int height);
+    /**
+     * Applies the minimum and maximum size to the platform window.
+     */
+    public void setSizeConstraints(int minW, int minH, int maxW, int maxH);
 
     /**
      * Transforms the given Graphics object according to the native
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Fri Aug 24 11:35:51 2012 +0800
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Fri Aug 24 14:58:04 2012 +0400
@@ -180,7 +180,7 @@
     public void setResizable(boolean resizable) {}
 
     @Override
-    public void setMinimumSize(int width, int height) {}
+    public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {}
 
     @Override
     public Graphics transformGraphics(Graphics g) {
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Aug 24 11:35:51 2012 +0800
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Aug 24 14:58:04 2012 +0400
@@ -672,20 +672,15 @@
 
         // Re-apply the size constraints and the size to ensure the space
         // occupied by the grow box is counted properly
-        setMinimumSize(1, 1); // the method ignores its arguments
+        peer.updateMinimumSize();
 
         Rectangle bounds = peer.getBounds();
         setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
     }
 
     @Override
-    public void setMinimumSize(int width, int height) {
-        //TODO width, height should be used
-        //NOTE: setResizable() calls setMinimumSize(1,1) relaying on the logic below
-        final long nsWindowPtr = getNSWindowPtr();
-        final Dimension min = target.getMinimumSize();
-        final Dimension max = target.getMaximumSize();
-        nativeSetNSWindowMinMax(nsWindowPtr, min.getWidth(), min.getHeight(), max.getWidth(), max.getHeight());
+    public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {
+        nativeSetNSWindowMinMax(getNSWindowPtr(), minW, minH, maxW, maxH);
     }
 
     @Override
--- a/jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m	Fri Aug 24 11:35:51 2012 +0800
+++ b/jdk/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m	Fri Aug 24 14:58:04 2012 +0400
@@ -447,3 +447,20 @@
         return cglinfo->context->caps;
     }
 }
+
+JNIEXPORT jint JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_getMaxTextureSize
+    (JNIEnv *env, jclass cglgc)
+{
+    J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getMaxTextureSize");
+
+    __block int max = 0;
+
+    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+        [sharedContext makeCurrentContext];
+        j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
+    }];
+
+    return (jint)max;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/awt/TextureSizeConstraining.java	Fri Aug 24 14:58:04 2012 +0400
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.awt;
+
+/**
+ * A GraphicsConfiguration implements the TextureSizeConstraining
+ * interface to indicate that it imposes certain limitations on the
+ * maximum size of supported textures.
+ */
+public interface TextureSizeConstraining {
+
+    /**
+     * Returns the maximum width of any texture image.
+     */
+    public int getMaxTextureWidth();
+
+    /**
+     * Returns the maximum height of any texture image.
+     */
+    public int getMaxTextureHeight();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/HugeFrame/HugeFrame.java	Fri Aug 24 14:58:04 2012 +0400
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+  @test
+  @bug 7160609
+  @summary A window with huge dimensions shouldn't crash JVM
+  @author anthony.petrov@oracle.com: area=awt.toplevel
+  @run main HugeFrame
+*/
+
+import java.awt.*;
+
+public class HugeFrame {
+    public static void main(String[] args) throws Exception {
+        Frame f = new Frame("Huge");
+
+        // 8193+ should already produce a crash, but let's go extreme...
+        f.setBounds(10, 10, 30000, 500000);
+        f.setVisible(true);
+
+        // We would crash by now if the bug wasn't fixed
+        Thread.sleep(1000);
+        System.err.println(f.getBounds());
+
+        // Cleanup
+        f.dispose();
+    }
+}