Description
Environment:
- axmol version: Latest 2.1.5
- devices test on: Pixel 6, Samsung S8
Issue:
Hi,
I use scheduleUpdate()
so that my code is updated on each frame drawn. If I set the frame interval to 1/60s I expect the update()
to be called once every 1/60s, but on my Pixel 6 it will be called twice.
So the issue occurs on high rate devices (120FPS) like the Pixel 6.
The code itself tells they are not handled:
@Override
public void onDrawFrame(final GL10 gl) {
/*
* Fix 60fps limiting doesn't work when high-end device is working in 120fps mode.
*/
if (AxmolRenderer.sAnimationInterval <= 1.0f / 1200.0f * AxmolRenderer.NANOSECONDSPERSECOND) {
AxmolRenderer.nativeRender();
} else {
final long now = System.nanoTime();
final long interval = now - this.mLastTickInNanoSeconds;
/*
* Render time MUST be counted in, or the FPS will slower than appointed.
*/
this.mLastTickInNanoSeconds = now;
AxmolRenderer.nativeRender();
if (interval < AxmolRenderer.sAnimationInterval) {
try {
Thread.sleep((AxmolRenderer.sAnimationInterval - interval) / AxmolRenderer.NANOSECONDSPERMICROSECOND);
} catch (final Exception e) {
}
}
}
}
A possible fix to this is this following code:
@Override
public void onDrawFrame(final GL10 gl) {
/*
* Fix 60fps limiting doesn't work when high-end device is working in 120fps mode.
*/
if (AxmolRenderer.sAnimationInterval <= 1.0f / 1200.0f * AxmolRenderer.NANOSECONDSPERSECOND) {
AxmolRenderer.nativeRender();
} else {
/*
* Render time MUST be counted in, or the FPS will slower than appointed.
*/
this.mLastTickInNanoSeconds = System.nanoTime();
AxmolRenderer.nativeRender();
final long interval = System.nanoTime() - this.mLastTickInNanoSeconds;
if (interval < AxmolRenderer.sAnimationInterval) {
try {
Thread.sleep((AxmolRenderer.sAnimationInterval - interval) / AxmolRenderer.NANOSECONDSPERMICROSECOND);
} catch (final Exception e) {
}
}
}
}
It works, but in any case (current and possible fix) the UI rendering seems a bit laggy because the renderer is using RENDERMODE_CONTINUOUSLY
mode meaning it's the java thread that triggers the call periodically and sleeping in the onDrawFrame()
might cause troubles to it.
I explored this solution and a new one using our own thread to trigger manually the rendering (see PR #2125) and the thread solution was giving better performance, overall when you do much work at each frame.