Display.setParent(canvas) freezing Swing application [solved]

Started by eczkchtl, January 26, 2009, 08:11:17

Previous topic - Next topic

eczkchtl

I've got a problem with an OpenGL canvas inside a swing JFrame locking the whole program on some computers while working fine on others.

What I do is basically:

[in the main thread]
Set native look and feel.
Create the JFrame
Create a JPanel and add it to the frame
Create an java.awt.Canvas of a fixed size and add it to the Panel.
Use the JFrame's pack().
Setup the lwjgl display and use Display.setParent(canvas).
Set the JFrame to be visible.

I've tried some different combnations making the frame visible before creating the lwjgl display and so on. Almost anything seem to work on some computers (working on 5 comps) while nothing seem to work on some (not working on 2 comps). It works for that unfortunate 2 comps if the opengl context is in a separate window (i.e. Display.setParent(null)). All computers use Java 6 Update 11 and I have the latet stable lwjgl library.

The error is simply the program freezing. I get no exceptions and the log says that the display is initialized ok (no difference between working and non-working). If a debugger is attached the output gives me no useful information. These computers are in another town and I can't sit by them myself and test with a debugger. I just send the program and a friend tells me the results and sends debug output and log.

So... I would like to see a more detailed description of how you're supposed to use the Display.setParent (examples are nice) and are there any known issues (workarounds)? I will probably have to use the heavyweight hack for swing menues in the future also but that's another problem.

Thanks!

kappa

A possible reason for Display.setParent() locking up is crappy drivers on certain graphics cards. This crash/lock is caused when java2d hardware acceleration is switched on (on by default) and Display is created on the same application, this somehow causes a crash. A workaround is to run the application without java2d graphics acceleration. Run the application with the following parameter

-Dsun.java2d.noddraw=true


This will disable java2d's hardware acceleration.

A good example on how to use Display.setParent() is the GearsApplet found at
http://java-game-lib.svn.sourceforge.net/viewvc/java-game-lib/trunk/LWJGL/src/java/org/lwjgl/test/applet/GearsApplet.java?view=log
notice how the Display is run in a seperate thread to avoid it locking the main thread however this example is mainly for applet issues.

eczkchtl

Now I've got it to freeze also on my computer. I updated to Java 6 update 11 (from update 5 I think).

Disabling direct draw didn't help either. I think it's disabled by default on my comp. I any case I added System.setProperty("sun.java2d.noddraw","true"); to be on the safe side.

I've cut away much of my code to make a small example which freezes. I've tried to do it like the gears example. In short it is:

// In the main thread:
gameCanvas = new Canvas();
gameCanvas.setBackground(Color.blue);
gameCanvas.setBounds(0,0,screenWidth,screenHeight);
gameCanvas.setIgnoreRepaint(true);
gameCanvas.setFocusable(true);

frame.add(toolBar, BorderLayout.NORTH);
frame.add(contentPane, BorderLayout.CENTER);
frame.add(splitPane, BorderLayout.SOUTH);

frame.pack();
frame.setFocusable(true);

frame.setVisible(true);
gameCanvas.requestFocus();

try {
	System.out.println("Displayable: "+frame.gameCanvas.isDisplayable());
	Display.setParent(frame.gameCanvas);
	//Display.setDisplayMode(new DisplayMode(screenWidth,screenHeight));
	Display.create();
} catch (LWJGLException e) {
	e.printStackTrace();
}


From there the main thread continues while the swing thread locks up.
Displayable says true.

If I use Display.setParent(null); instead it works fine but in two windows.

I will do some more testing tomorrow.
Suggestions of what to try are welcome :)

kappa

the -Dsun.java2d.noddraw=true parameter has to be passed as a command line argument before the vm is launched and won't work if you do it once the vm has started.

eczkchtl

Quote from: javalwjgl on January 28, 2009, 21:22:13
the -Dsun.java2d.noddraw=true parameter has to be passed as a command line argument before the vm is launched and won't work if you do it once the vm has started.

I thought it would be that way so I also tried this with the same result. I'll make the smallest possible example which freezes later today and post the code here. Hopefully I'll figure out whats wrong while doing that :)

eczkchtl

This is the smallest example which freezes:

import java.awt.*;
import javax.swing.*;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.*;

public class DisplayTest extends JFrame {

	public static void main(String[] args) throws LWJGLException, InterruptedException {
		System.out.println("LWJGL Version: "+Sys.getVersion());
		
		DisplayTest test = new DisplayTest();
		test.setVisible(true);
		Display.setParent(test.c);
		Display.create();		
		
		while (true) {
			Display.swapBuffers();
			Thread.sleep(100);
		}
	}
	
	Canvas c;
	
	public DisplayTest() {
		c = new Canvas();
		c.setBackground(Color.blue);
		c.setSize(new Dimension(640,480));
		add(c);
		this.pack();
	}
}


It prints "LWJGL Version: 2.0rc1"
I've also tried with 2.0b and some different variations of the code like making the window visible before or after setParent and having a long sleep before setParent. The window works OK up until setParent is called.

I use jdk1.6.0_11 and jre1.6.0_11.

Matzon


eczkchtl

Quote from: Matzon on January 29, 2009, 21:29:10use Display.update instead of swapbuffers?

Ah, yes, that solves it. Thanks. Actually I am processing window messages in the real application but just as it starts it doesn't render anything so no lwjgl commands were used. Easily fixed and I'd better add noddraw to the launch program.