Possible to know if glCanvas display() was called by Animator or because a redraw is required?
I'm using a GLCanvas and an Animator to draw inside a JPanel. Therefore the display() callback is executed at 60Hz (or whatever vsync happens to be.)
To reduce GPU load, I'd like to do some checks at the beginning of display() to decide if I have to redraw or if I can return early and leave the existing image on screen. Obviously there may be times where I have to redraw because the OS has invalided the buffer. Is there any way for me to know this?
In case this isn't clear, here's some pseudocode explaining what I'd like to do:
This way I don't waste GPU resources to redraw a static screen unless I am forced to redraw the static screen. I know I could pause the animator when my code doesn't need to redraw, but it would be cleaner if I could just decide that when display() is called.
Re: Possible to know if glCanvas display() was called by Animator or because a redraw is required?
I handled this differently in Jzy3D :
- a "repaint continuously" mode use the animator as you do and do not check if a repaint was necessary or not.
- a "repaint on demand" mode use no animator but force a canvas repaint if the scene changes. Hence I only have to deal with scene change detection in my code rather than trying to decipher what AWT/Swing/SWT/JavaFX decided to do for reason that are not easy to fully understand, that may depend on the OS you are actually running and that may change among JDK versions.
Trying to understand when AWT will render took me lot of time and I just understood that it is quite unpredictable. I summarized this here. Maybe other windowing toolkit are easier to understand, I don't know.
For example I tried overriding the AWT canvas paint() method (or paintComponent(), I forgot) but as you may read from the link above, you can't be sure that the call to canvas.paint() will actually lead to screen repaint in the JVM. Overriding your canvas paint() method to store this info somewhere may be a way to know if your GLEventListener was invoked because of an OS query, but you are not sure if this will really be applied.
Another idea would be to understand what part of your rendering is slow and fix this to let the animator run.
I tend to favor "repaint on demain" over "repaint continuously". I mainly kept the animator for rare cases where the GLEventListener (and actually the canvas) does not get properly notified of reshape queries. This mainly occured when combining a GLCanvas with an old version of MigLayout.