Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android : Fixing rendering for all FPS (> 60 or < 60) - Thread to trigger rendering manually #2125

Draft
wants to merge 12 commits into
base: dev
Choose a base branch
from
15 changes: 2 additions & 13 deletions core/platform/android/java/src/org/axmol/lib/AxmolActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -229,17 +229,6 @@ private void resume() {
mGLSurfaceView.onResume();
rendererPaused = false;
}
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}

private void resumeIfHasFocus() {
//It is possible for the app to receive the onWindowsFocusChanged(true) event
//even though it is locked or asleep
boolean readyToPlay = !isDeviceLocked() && !isDeviceAsleep();

if(hasFocus && readyToPlay) {
resume();
}
}

@Override
Expand All @@ -249,7 +238,6 @@ protected void onPause() {
super.onPause();
AxmolEngine.onPause();
mGLSurfaceView.onPause();
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}

@Override
Expand Down Expand Up @@ -325,7 +313,8 @@ public void init() {
//if (isAndroidEmulator())
// this.mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

this.mGLSurfaceView.setRenderer(new AxmolRenderer());
this.mGLSurfaceView.setRenderer(new AxmolRenderer(this.mGLSurfaceView));
this.mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
this.mGLSurfaceView.setEditText(edittext);

// Set framelayout as the content view
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ public void run() {
// ===========================================================
// Methods
// ===========================================================

// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
Expand Down
94 changes: 72 additions & 22 deletions core/platform/android/java/src/org/axmol/lib/AxmolRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,66 @@ of this software and associated documentation files (the "Software"), to deal
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class AxmolRenderer implements GLSurfaceView.Renderer {

private static class RendererThread extends Thread {

private GLSurfaceView gameSurfaceView;
private AxmolRenderer renderer;
private boolean pausing = false;
private Object drawMonitor = new Object();
private Object pauseMonitor = new Object();

public RendererThread(GLSurfaceView gameSurfaceView, AxmolRenderer renderer) {
this.gameSurfaceView = gameSurfaceView;
this.renderer = renderer;
}

public void onPause(){
pausing = true;
}

public void onResume(){
if (pausing) {
pausing = false;
synchronized (pauseMonitor) {
pauseMonitor.notify();
}
}
}

public void drawFrameDone() {
synchronized (drawMonitor) {
drawMonitor.notify();
}
}

@Override
public void run() {

while (true) {
try {
synchronized (pauseMonitor) {
if (pausing) {
pauseMonitor.wait();
}
}

long now = System.nanoTime();
synchronized (drawMonitor) {
this.gameSurfaceView.requestRender();
drawMonitor.wait();
}
long wait = (AxmolRenderer.sAnimationInterval - (System.nanoTime()-now)) / AxmolRenderer.NANOSECONDSPERMICROSECOND;
if (wait > 0) {
sleep(wait);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

// ===========================================================
// Constants
// ===========================================================
Expand All @@ -44,16 +104,22 @@ public class AxmolRenderer implements GLSurfaceView.Renderer {
// Fields
// ===========================================================

private long mLastTickInNanoSeconds;
private int mScreenWidth;
private int mScreenHeight;
private boolean mNativeInitCompleted = false;
private boolean mIsPaused = false;
private RendererThread mRendererThread = null;

// ===========================================================
// Constructors
// ===========================================================

public AxmolRenderer(GLSurfaceView surfaceView){

super();
this.mRendererThread = new RendererThread(surfaceView, this);
}

// ===========================================================
// Getter & Setter
// ===========================================================
Expand All @@ -74,13 +140,13 @@ public void setScreenWidthAndHeight(final int surfaceWidth, final int surfaceHei
@Override
public void onSurfaceCreated(final GL10 GL10, final EGLConfig EGLConfig) {
AxmolRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);
this.mLastTickInNanoSeconds = System.nanoTime();


if (mNativeInitCompleted) {
// This must be from an OpenGL context loss
nativeOnContextLost();
} else {
mNativeInitCompleted = true;
mRendererThread.start();
}
}

Expand All @@ -91,26 +157,8 @@ public void onSurfaceChanged(final GL10 GL10, final int width, final int height)

@Override
public void onDrawFrame(final GL10 gl) {
/*
* Render time MUST be counted in, or the FPS will slower than appointed.
*/
AxmolRenderer.nativeRender();
/*
* No need to use algorithm in default(60,90,120... FPS) situation,
* since onDrawFrame() was called by system 60 times per second by default.
*/
if (AxmolRenderer.sAnimationInterval > AxmolRenderer.FPS_CONTROL_THRESHOLD) {
final long interval = System.nanoTime() - this.mLastTickInNanoSeconds;

if (interval < AxmolRenderer.sAnimationInterval) {
try {
Thread.sleep((AxmolRenderer.sAnimationInterval - interval) / AxmolRenderer.NANOSECONDSPERMICROSECOND);
} catch (final Exception e) {
}
}

this.mLastTickInNanoSeconds = System.nanoTime();
}
mRendererThread.drawFrameDone();
}

// ===========================================================
Expand Down Expand Up @@ -163,12 +211,14 @@ public void handleOnPause() {
if (!mNativeInitCompleted)
return;

mRendererThread.onPause();
AxmolRenderer.nativeOnPause();
mIsPaused = true;
}

public void handleOnResume() {
if (mIsPaused) {
mRendererThread.onResume();
AxmolRenderer.nativeOnResume();
mIsPaused = false;
}
Expand Down