Linux + OpenGL pipeline + windowed = no display until resize

Hi,

I searched the forums for recent posts with a similar issue, but haven’t found any, so here’s the situation.

I run Ubuntu 8.10 on a laptop, with an ATI Mobile HD 2600, res 1680x1050, using the ATI fglrx video driver.

I wrote some test in Java2D to “simulate” another system with graphics, and all got pretty well.
Then I tried the OpenGL pipeline, hoping it would bring me useful acceleration when things would get heavier.

It doesn’t work that bad, but I have a strange issue: using opengl, the Canvas I use in my Frame stays gray as long as I don’t resize the frame. Is there a known reason for that, am I missing something obvious ?

I tried many differents things over time, to no avail:

  • use a Frame or a JFrame for the main window
  • use a Canvas or a JPanel for the component I render to (it is the only component in the window)
  • at first I used manual double buffering, creating a BufferedImage, drawing stuff to it, then drawImage() it to the component. But then there was a problem with opengl: the rendered frames had an important vertical offset even though the buffer was copied to the component at pos 0,0 (the bottom of the rendered frame was near the top of the component, and wrapping to the bottom)
  • I now use a BufferStrategy on the Component (Canvas), either with 2 or 3 buffers, and there’s no more offset (only the gray/no-display problem)
  • I tried paint()/update()/… rendering, but now I use active rendering every N milliseconds (with strategy.show())
  • since I use active rendering, I setIgnoreRepaint(true) on the component, but even when I don’t, the issue remains
  • I tried to use or not use setSize(), setPreferredSize(), pack()/no pack() on the window and/or component
  • maybe I’m forgetting some other things I tried…

For info, the BufferStrategy is created for the component after the window and the component have been created (of course), associated, sized, shown, …
Also, the stuff I usually compute inside the app regarding the number of rendered frames and the like, is computed correctly even when I only see an “empty” component, so the frames are effectively rendered, I just can’t see them.

Has anyone encountered this kind of problem, do I need an additional step to “wake up” the opengl pipeline and display the first frame ?

The OpenGL pipeline in our experience is quite unstable, so I considered it unusable for myself. You can however experiment a bit with the AWT Event Thread. Just make sure everything drawing-related you do (including opening the window) is done on the AWT thread. This might be difficult for your active rendering, but you could create an updater implementing Runnable and call SwingUtilities.invokeAndWait(updater), from your main loop.

But I am not sure, it will help anything.

Thanks for your quick answer.

In the beginning I had a second thread for some stuff, but now I put everything in one thread.
By the AWT thread, you mean the main thread of my app ?
(sorry for the dumb question, I’m only coming back to Java after many years… god it feels so much better now we have generics, autoboxing and so much progress has been made in the IDEs department :smiley: )

Also, I must say I’m quite disappointed that the opengl pipeline is still largely considered unstable/unusable in 2009, especially since I found so many lengthy articles from 2004 (!) and later, explaining all the benefits of it, what is accelerated and how (pretty much everything, in the end).

It’s a shame, because Java is 99% portable, and getting accelerated 2D right from the standard libs would make it a good choice for many apps, but with OpenGL acceleration out of the equation, it leaves us with… Windows, as usual, and bye bye portability.
(unless you tell me acceleration on Windows is unstable too, then I’m wondering what happened in the Java2D world during the past 5 years)

I was happy because I thought I had found a way to develop something that would work pretty well on Mac & Linux too, but I’m not so sure anymore. :-\

The AWT Event Thread (sometimes called the EDT) is the event dispatching thread of swing and awt. It is usually not the same thread as your main() method, but is the thread in which all listeners (Action, Mouse, Keyboard etc.) get called. You can check for it using java.awt.EventQueue.isDispatchThread(), but you should not try to make a main loop in this thread, but insert Runnables into the execution queue via SwingUtilities.invokeLater() and SwingUtilities.invokeAndWait().

The original OpenGL pipeline worked quite good, but it turns out, that they used an implementation path becoming notoriously unstable after driver updates. The implementation team anounced some time ago, that they try to find a more stable path, but I don’t know how far they have come.

If you are doing game related stuff, I would advice you to use Slick (http://slick.cokeandcode.com/) for development, which has some Java2D like feeling in places but an OpenGL backend using LWJGL.

Ok, I understand now. I should’ve known better, that’s what is called the event thread in so many other toolkits and languages.

I’ll take a look at Slick and see if I can use it on Windows/Linux/Mac.

Thank you, it’s so much info in such a short time :smiley:

I tried my game on Ubuntu using OpenGL pipeline, with great success lately
but its fullscreen
I’m gonna try it windowed sometime

Graphics2D is thread-safe, and especially with the current STR implementations it doesn’t make any difference which thread paints to your OGL surface. Its mutexed anyway, executed by a single (non-EDT) thread later.

The problem is drivers are borken, period.

  • Clemens

Sometimes you have to call revalidate() on Swing components to get them to show up… give that a try and maybe the frame will show up without re-sizing.