Opinions on enhancement?

Hi. I created issue #63 to request an enhancement, and I’d like some opinions on it, please. I don’t know how many developers of Jogl are on the forum (vs developers using Jogl), but I’d appreciate thoughts about whether there is another way to do it, whether it makes sense, and whether there is a chance it would be done.

https://jogl.dev.java.net/issues/show_bug.cgi?id=63

Here’s a summary. The Jogl User’s Guide, in the Multithreading Issues sections, mentions two ways of interacting with Jogl: rendering on demand in the AWT thread, or continuously calling display() in a separate thread. Our system is in between, repainting on certain events rather than continuously, but using a separate thread from AWT so AWT can update controls while we’re rendering.

Currently, if I set NoAutoRedrawMode to true and call display when needed, an app using our system looks fine while I’m rotating or making other updates that I know about. But when the GLCanvas gets a paint event, I’m never told about it, because the paint method does nothing when the NoAutoRedrawMode is true. I’d like to know about this paint event so I can redraw in this case. I don’t want to go through all the context stuff or do a swap–that will all happen when I call display after I know about the paint event.

What I’ve done is to make a change to the GLCanvas.paint() method. I added an else to the condition for no auto redraw mode, where if it does not call display, it will instead call its parent’s paint method. That parent is our viewer, and we’ve overridden the paint method, so we’d get this call and can render.

If GLCanvas were not final, I’d extend that and override the paint() method.

This seems to me to be a small change, and if you didn’t want it to be the default, could be implemented with a flag to say whether no auto redraw mode does this, say a CallParentPaint property. I think it does add another way to use Jogl without me having to implement GLCanvas myself.

However, a lot of you have developed a lot of stuff with Jogl, and I’d like to know if I’m missing something. Does this open up troubling issues with Jogl? Is it unnecessary? (If so, tell me why!) Make sense?

If (in addition to the above) I could also call display() without a swap buffers automatically happening, I’d be all set. This is because when I want to do a pick, I call GLDrawable.display(), get the GLEventListener.display() call with the context all set up, and then do my pick work. I’m not updating the back buffer, and don’t want to swap at the end. Even a boolean parameter to GLDrawable.display(), saying whether to swap at the end, would help. There are already a couple of enhancement requests related to this, so I didn’t add another.

Thanks
andy
AVS

Do you call setRenderingThread? I am kind of confused as to what you are trying to do.

As far as I can tell, calling setRenderingThread with my rendering thread just means that attempts to call display() from the AWT thread won’t do anything. This seems to be a similar effect to setting NoAutoRedrawMode to true. (It is handled in a different place, though.)

What I’m trying to do:
I don’t want the AWT event thread rendering–I have a separate thread that should do the rendering. But I do want to know when AWT thinks I need to paint, because I’m not calling display() continuously. That’s why I feel like I fall in between the two cases mentioned by the User’s Guide.

If I don’t make the suggested change, I can set NoAutoRedrawMode to true and call GLDrawable.display() whenever I want to render. But because the GLCanvas is eating the paint event, I don’t know when AWT is telling me I should repaint. If I expose the window, for example, AWT calls paint() on GLCanvas, but it isn’t telling me that it happened.

If GLCanvas would call its parent’s paint method (which I can override) when it isn’t going to display itself, then I can render when I initiate something (user rotates view) as well as when AWT initiates something (because it’ll tell me it needed to paint, and I can tell my rendering thread to go do it).

Any clearer? Thanks for responding.

andy
AVS

Why do you have no autoredraw set? I would wrap the GLCanvas in a custom JPanel that will catch repaint events and pass that message to your rendering thread.

I have NoAutoRedraw set because I don’t want the GLCanvas to do any Jogl stuff when paint() gets called, because it will be in the AWT thread.

Do you mean why do that in addition or instead of setting the rendering thread? I guess I wanted to stop the AWT thread from getting any further at all. The invokeGL method in GLCanvas is syncronized, and I’d rather AWT didn’t go into that at all. The current implementation of NoAutoRedrawMode (it might change, according to the User’s Guide) stops the AWT thread at the paint() method, which is fine with me. The Guide also doesn’t build a lot of confidence in setting the rendering thread always preventing AWT from getting into rendering.

I’ve currently got the GLCanvas inside a class extending a Panel. GLCanvas gets paint() calls that the Panel does not. You’re saying the JPanel would actually get those? Any problem with having a swing component in between a Panel (my viewer) and a Canvas (GLCanvas)?

thanks,
andy

I am hoping that the JPanel will also recieve the repaint event that the GLCanvas is getting. If not then you might have to try something more exotic. I have no idea if this works since I have never done it before but, you can use an AWTEventListener attached to the default toolkit and look for the PAINT_EVENT that intersects your GLCanvas. Then the listener would notify the GLCanvas that it needs to repaint. I have no idea if that will work. You may be boned without being able to subclass GLCanvas.

Thanks, that’s the sort of thing that makes the most sense to me. I really don’t think I want to add a Swing component between my Panel and the Canvas.

Looking for alternative ways to know I need to refresh may be the best idea.

That would save me from having to make changes to Jogl, the way I am now. But it matches the existing system (which uses an old JNI OpenGL project also called jogl, which we’ve been extending over the years) better to have the GLCanvas.paint() call its parents paint().

Now if I could get it to not swap the buffers after calling display() on the listeners, so that I could just do a pick in that call, I’d be a bit better off. :slight_smile:

Thanks for your comments.

Anybody else?

andy

As of disabling swap buffers, this is also very old topic, and there is a patch to JOGL in JOGL IssueZilla. I personally use patched version of JOGL, so I have this functionality and hope this will become part of core JOGL.

Yuri

Just wondering if I put this another way, whether anybody else will think it makes sense.

I want to use NoAutoRedrawMode (to keep AWT out of the GLContext). But I think it doesn’t make sense for GLCanvas to not report to someone when it gets a paint event. Thus, I suggested the enhancement.

We are going to look at whether we can see the events some other way, but we’re a bit concerned that we might try to miss something that calls paint() on a Canvas. There is a PaintEvent class, but the doc says it isn’t supposed to be used with a listener. The best way for us to know that the GLCanvas got a paint event is for it to tell us.

(We have a separate thread for rendering, and don’t want to call display repeatedly.)

thanks,
andy

I wanted to say how this has resolved for now.

We are examining paint events by looking for AWT events from the method on the Toolkit. When we get one for the GLCanvas, we tell our viewer (the parent of the canvas) to repaint. This has allowed us to quit changing JOGL as I’ve requested as an enhancement.

However, I do still think it is a mistake for the GLCanvas.paint() call to be lost when NoAutoRedrawMode is true. There are paints that go there but don’t go to the parent, and I’d rather be told about them by the GLCanvas than have to listen for the paint events.

Thanks, GKW for suggesting listening for the paint event, rather than being told by the paint method. That works for now. There still may be a way to do what I originally tried, where we let AWT call GLEventListener.display() and then we call our repaint, but I really would prefer only one thread going into invokeGL().

thanks
andy