After the feedback on my last post i had to implement non-continuous rendering. It was easier then expected. Thanks to Romain and P.T. for subtly pointing out that the proposed “solution” for fake non-continuous rendering is pretty terrible. I will repent 🙂
Here’s how it works. The Graphics interface has three new methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
interface Graphics { /** * Sets whether to render continuously. In case rendering is performed non-continuously, the * following events will trigger a redraw: * * <ul> * <li>A call to {@link #requestRendering()}</li> * <li>Input events from the touch screen/mouse or keyboard</li> * <li>A {@link Runnable} is posted to the rendering thread via {@link Application#postRunnable(Runnable)}</li> * </ul> * * Life-cycle events will also be reported as usual, see {@link ApplicationListener}. * This method can be called from any thread. * * @param isContinuous whether the rendering should be continuous or not. */ public void setContinuousRendering(boolean isContinuous); /** * @return wheter rendering is continuous. */ public boolean isContinuousRendering(); /** * Requests a new frame to be rendered if the rendering mode is non-continuous. This method * can be called from any thread. */ public void requestRendering(); } |
Not sure this needs more explanation. Read the Javadocs 🙂
Caveat: This is currently a NOP in the Lwjgl backend, I added it to the Jogl backend already. It will take a bit before those are up to speed. I hope to finish that of today.
Try it out and let me know of any issues you have.
Would be cool to see your exploitation of this new interface in reddittv and how it affects CPU consumption. Liking your posts, very open and interesting.
Nice! I hope this improves the CPU usage of reddittv even more. Otherwise I’m going to feel bad about wasting your time. 🙂 The new API looks good. I’ll have to sync up and give this a try …
Yeah, improved it by a lot. Hardly use any battery at all now. Good stuff 🙂
Nice feature! I am testing with it. However I found a problem, the screen didn’t load on resume, and if I redraw right after resume, but not after, there is the portrait landscape problem, i.e. my app is landscape only and it draw something weird on the screen. I am thinking whether there would be some nice workaround
a quick work around using at the moment, sending at least one rendering request for every 500 sec solved the problem
sorry it should be 500 msec
What Android version are you on? Did you use GLES 2.0 or GLES 1.x? Do you have a piece of code that reproduces the problem consistently? I use this feature heavily and did not see that problem on any of my test devices.
Android 2.3.7, defy, cm7
fixed to landscape in application.xml
GLES1.x
only 1 requestRendering after resume
I guess I didn’t make it clear, it is not just any resume, it is on close with power button with screen locked. When power back on, screen locked with portrait mode, after unlock, it shows what I mentioned.
P.S. didn’t touch the screen after unlock, i.e. no requestRendering from touch event.
Can you please update this into live wallpaper library? I naively thought it just takes recompiling with new nightly but apparently api distance is somewhat huge…
cheers.
I’m not in control of the LW backend i’m afraid. I’d suggest leaving an issue on the backend’s issue tracker.
Oh, sorry. It’s awkward to be confused…
Hi Mario,
I am attempting to implement non continuous rendering but am have a few problems.
My game excepts change from an external source that update the view.
I also have animation objects that would also update the view.
From what I have read in various sites and blogs I should use a timer to decide if I should request a render via a call to Gdx.graphics.requestRendering();
This is how I create the timer:
if (graphicsManager.getRenderMode() == RenderMode.OnUpdate) {
Timer.schedule(new Task() {
float lastUpdateTime = System.nanoTime();
public void run() {
float thisUpdateTime = System.nanoTime();
AbstractScreen screen = (AbstractScreen) getScreen();
if (screen != null && screen.update(updateDelta))
graphicsManager.updateRequired((thisUpdateTime – lastUpdateTime) * MathUtils.nanoToSec);
lastUpdateTime = thisUpdateTime;
}, 0, 1f / GameUpdatesPerSecond); [currently set to 40fps]
}
As you can see I am using my own frame timer, this is probably incorrect and I should still render to the delta provided by render(delta) but this isn’t my real problem.
Whenever run is invoked a render is automatically started by LibGdx via postRunnable, this breaks my control over rendering.
I have seen the update from Nate here:
http://code.google.com/p/libgdx/issues/detail?id=932
But I can’t see how I should change my code to enable his changes.
I assume the way I define the timer is wrong.
Thanks for all your work on libGdx Mario.
yeah, LibGDX is so cool. I need to pause the rendering loop when showing a webview (for highscores & achievements), so this is exactly what I needed. And it works like charm.
Great Work! Thanks alot!
– thomas