This has been requested enough times by the commuity that its time to bring this feature to a head and get a vote out about whether or not we ever intend to do this so people will know. Personally I'm in full agreement that buffer swapping is something that should be doable by the developer and after having had to go through the implementation og JOGL for the OSX stuff I really don't see any technical reason why doing it isn't possible or why this would lead to some performance degredation so I think this is fair game for the community process that we have in place.

All of the workarounds to not being able to call swap buffers that I have tried thus far involved thread acrobatics that I consider unnecessary and unwelcome. If we have dissenting voices - they should chime in.

setNoAutoRedrawMode() does not turn off the swapping buffers in on-screen contexts.

There should be a way of disabling swap buffers at least temporarily for specific canvas/context. This can be beneficial for implementing pick modes using GL_SELECT rendering mode where you don't need to swap buffers after rendering.

A'ight. I'm meeting with Ken and perhaps some others today and I will ask and see what is entailed in getting such a thing into the specification. There may be some heavy lifting required to actually make the change cleanly (and we as a community may need to make the change) - but I will find out what we need to do going forward to make this work.

As I started looking at the architecture - there doesn't seem to be a reason that we couldn't expose the swapbuffer functionality while keeping the core JOGL intent of wanting to swap intact. Really it seems that all that is required it to make swapping visible. This doesn't necessarily require exposing objects that we don't want to expose from an architectural perspective as we can use a Composite pattern to get the swap functionality up at a higher level for our use and leave the low level code mostly alone - which would be 'A Good Thing.' More tomorrow on how it goes Maybe I should take Ken out and get him drunk

I had an opportunity to meet Ken Russel last night and amongs other things we had a chance to discuss some of the potential architectural changes to the APIs, the strength of the community, etc. Ken is clearly a very cool and intelligent individual and it was good to associate some 'faces' to the people associated with this initiative. I won't get into much detail other than to say we aren't working with the bottom of the barrel

One of the things we've discussed is that we should go forward with the design of swap buffers being controlled at least in part by the developers. One of the other things we discussed is that we as a community can actually present a reference implementation of this to the community so that we can factor it into (hopefully) the 1.1 release of JOGL. To that end its time to discuss what the best approach is to achieving swap buffer functionality without breaking the soft requirement that we want to still allow the core JOGL engine to call swap buffers as IT needs to so shortly I think we need to start taking submissions on how we want to solve the problem architecturally.

If anyone has any ideas on how this could/should be best architected (lets not design a functional spec yet), please post your ideas as its clearly in our court to go beyond the 'it doesn't work' to the 'we would like it to work like this for these reasons'.

The only compelling reason I personally see for adding this functionality is that there are some kinds of applications that can not be implemented using JOGL without giving buffer swapping control to the end user. Two examples are given in this thread and a third in this one. I'd like to ask moorej, greggpatton and swh in particular to provide a prototype implementation that works for their applications.

I'd like to see the API kept minimal. Perhaps new methods setAutoSwapBuffer(boolean), boolean getAutoSwapBuffer(), and swapBuffer() added to GLDrawable. They must be specified as being advisory (because they will have no effect for single-buffered visuals) and it should be made clear that most applications should not need to call them. Note that the implementation is not quite trivial because the swapBuffers() call must be done with the underlying OpenGL context made current.

At least adding of methods setAutoSwapBuffer(boolean) of boolean getAutoSwapBuffer() without even manual swapBuffer() would be alreay enough to solve some questions regarding use of GL_SELECT rendering mode.

I entered an RFE, Issue #38, that contains the modifications I've made to the code that allows turning off the automatic buffer swap. The changes are minimal but it does add an extra boolean check to the swapBuffers method. I don't know if it adds enough overhead to swapBuffers to cause performance concerns or not. It's currently not an issue for me.

Initially I created new factory classes and new canvas and context classes, but that requires being able to extend GLCanvas or duplicating code.

I started coming up with a reference implementation but I am having to change many more things to really get it where I want it to go. For this first "trial" version are we to alter the least amount possible, or really make the implementation that we think is right. Once you allow OpenGL calls to be made outside of a current context, one needs to be able to query wether that context is current. That would be a lower level change than maybe at this stage is necessary. Any thoughts?

Gregg: the testing of the flag down in the swapBuffers implementation should be fine.

Jason: I think ultimately we are going to need to keep track of a per-thread "current context stack" in order to support calling display() recursively and for being able to call display() of other GLDrawables from within one's display() routine (which currently is not supported though I think this fact isn't well documented). Once we have this information it should be pretty easy to implement a test to see whether a given context is current on this thread. If you're interested in taking a crack at it then it should probably be implemented with a ThreadLocal pointing to a Stack of GLContext objects. Once makeCurrent() has succeeded the GLContext object should be pushed; upon free() the GLContext should be popped and the next one up the stack should be made current again. It seems to me that this might be somewhat tricky to get right so we should probably file an RFE for it to track it.

Ken, how will this impact some of the more interesting issues that remain with JOGL windows being minimized and not being realized again when they are maximized again? I've seen this particicularly in JInternalFrames where a JOGL contact is embedded in an MDI manner.

What I'm wondering is whether or not these two fixes should be developed by the same folks as they both relate to the same section of code. How do we get events from the windowing system down to the GLContext?

Is anyone working on this? I have got gp's issue 30 mostly resolved, as in the context shows up again after iconization though I still need to get the context destruction to work cleanly. I will be looking into the kbr's thread stack mojo next unless someone else already put the work in.

I'm in the process of implementing the per-thread GLContext stack, which is effectively a prerequisite for implementing any swap buffer functionality. I hope to have something checked in within the next week.

Excellent. I will post the fix for issue 30 soon. It appears that when a window is iconized in a jinternalframe a hierarchy event is issued which the canvas isn't listening for and then when the context is no longer attached to a renderable surface a swapbuffer error is thrown. It can be solved by either attaching a hierarchy event listener to the canvas or I can interrcept the call by overridding processEvents. I went for overridding processEvents since someone could grab all the hierarchy event listeners on the canvas and accidentally remove the fix. I am also reworking the pbuffer gljpanel code I posted before so hopefully it will be a little cleaner. What do you think about making the pbuffer a stand alone context rather than only being created by a glcanvas? Being able to resize itself will make it a lot easier to work with when it is backing a GLJPanel. I was also thinking that the reshape methods in GLCanvas and GLJPanel need to be changed so that they don't automatically make the viewport take up the full size of the component making the call. It should read in the current viewport size and then preserve the ratio in the resized canvas/panel.

Great; looking forward to seeing your fix for this issue. I am a little worried that the fix will solve the GLJPanel problem but won't address another basic problem, namely that if a GLCanvas is removed from its parent window and added to another one that the OpenGL context is silently destroyed and is never recreated. With the addition of the per-thread OpenGL context stack the context handling is becoming more complex, and I'm thinking that there must be a simpler solution.

That is one of the changes I made to WindowsOnscreenGLCanvas. A context can be passed to different HDC's as long as they are on the same device and have the same pixel format. So when the GLCanvas is removed from the internal frame only the device context is new, the rendering context is the same and you don't run through all the init code again. I assume it will work just the same if it was added to a different parent, but I have not tried. I am still trying the get the pbuffers to resize correctly. I just need to get it to init properly and I will post the code.

I am down to two last issues. The pbuffer gljpanel is still not being destroyed properly. I think I am going to have to make another invisible window/glcanvas to destroy it. The other issue is that if you use a pbuffer you have to flip the image when it is drawn. Currently gljpanel just draws the image upside down using a Graphics object and I am pretty sure it is slower than the MS software renderer. I am trying to use glPixelZoom and glCopyPixels to flip the framebuffer but I just can't get it to work. Something to do with clipping I think. This might not matter that much if Tiger has hardware accelerated image ops. The other option is to render to a texture rectanlge and just draw a big quad that covers the whole viewport but that won't be supported on ATI cards until 1.5 drivers show up.

GKW: Have you overridden the add/removeNotify methods? I saw that you had to mess with hierarchy events and such to destroy the context. I still believe these 'notify' methods are the cleanest way to solve this problem. When an internal frame is iconified for instance, removeNotify is called on it (and it's children), to destroy it's native resources. Also, when it's deiconfied, addNotify is called, to reconstruct the native resources. I modified GL4Java some time ago to work using these methods and it worked perfectly back then. I was hoping to be able to integrate this in Jogl as well, but my boss said I couldn't. I hope you or somebody else can integrate this in my place. If you're interested I can send you my GL4Java source code.

I thought about using the notify methods and I still may do that. It turns out what I was doing may be jvm specific so I went back to using a hierarchy listener. I am thinking we may have to use a hierarchy listener(ancestor moved) anyway to support moving a surface between multiple monitors. That is a little down the road but it is best to plan ahead. The modifications to the source that I have made do not destroy a context when it is removed from its parent. You have to explicitly call a destroy method on the canvas/jpanel. That way if you iconize a frame the animation stops, if you are using an animator, and you avoid calling init again.

I am down to just a last few intermittent errors when I am disposing of a glcanvas or a gljpanel. Hopefully I will be able to resolve the errors, comment my code, and post the finished code this weekend.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org