android: run renderer in a separate native thread

fixes simultaneous gamepad button presses not being registered on some
platforms
This commit is contained in:
Flyinghead 2019-04-09 10:39:29 +02:00
parent 37a533740b
commit 1fa052987b
3 changed files with 49 additions and 49 deletions

View File

@ -21,8 +21,7 @@ public final class JNIdc
public static native int send(int cmd, int opt);
public static native int data(int cmd, byte[] data);
public static native void rendinitNative(Surface surface, int w, int h);
public static native boolean rendframeNative();
public static native void rendinitNative(Surface surface);
public static native void rendinitJava(int w, int h);
public static native boolean rendframeJava();
public static native void rendtermJava();

View File

@ -19,8 +19,6 @@ import com.reicast.emulator.NativeGLActivity;
import com.reicast.emulator.config.Config;
public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback {
private Handler handler = new Handler();
private boolean surfaceReady = false;
private boolean paused = false;
VirtualJoystickDelegate vjoyDelegate;
@ -66,23 +64,6 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
if (NativeGLActivity.syms != null)
JNIdc.data(1, NativeGLActivity.syms);
startRendering();
}
private void startRendering() {
// Continuously render frames
handler.removeCallbacksAndMessages(null);
handler.postAtTime(new Runnable() {
@Override
public void run() {
if (!paused)
{
JNIdc.rendframeNative();
handler.post(this);
}
}
}, SystemClock.uptimeMillis() + 500);
}
@Override
@ -111,7 +92,7 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int w, int h) {
//Log.i("reicast", "NativeGLView.surfaceChanged: " + w + "x" + h);
surfaceReady = true;
JNIdc.rendinitNative(surfaceHolder.getSurface(), w, h);
JNIdc.rendinitNative(surfaceHolder.getSurface());
Emulator.getCurrentActivity().handleStateChange(false);
}
@ -119,7 +100,7 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//Log.i("reicast", "NativeGLView.surfaceDestroyed");
surfaceReady = false;
JNIdc.rendinitNative(null, 0, 0);
JNIdc.rendinitNative(null);
Emulator.getCurrentActivity().handleStateChange(true);
}
@ -142,7 +123,6 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
requestFocus();
JNIdc.resume();
}
startRendering();
}
@TargetApi(19)

View File

@ -91,8 +91,7 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,j
JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_send(JNIEnv *env,jobject obj,jint id, jint v) __attribute__((visibility("default")));
JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env,jobject obj,jint id, jbyteArray d) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv *env, jobject obj, jobject surface, jint w, jint h) __attribute__((visibility("default")));
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframeNative(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv *env, jobject obj, jobject surface) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitJava(JNIEnv *env, jobject obj, jint w, jint h) __attribute__((visibility("default")));
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframeJava(JNIEnv *env, jobject obj) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendtermJava(JNIEnv *env, jobject obj) __attribute__((visibility("default")));
@ -404,35 +403,57 @@ JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env, job
extern void gl_swap();
extern void egl_stealcntx();
volatile static bool render_running;
volatile static bool render_reinit;
JNIEXPORT jboolean JNICALL Java_com_reicast_emulator_emu_JNIdc_rendframeNative(JNIEnv *env,jobject obj)
void *render_thread_func(void *)
{
if (g_window == NULL)
return false;
if (!egl_makecurrent())
return false;
jboolean ret = (jboolean)rend_single_frame();
if (ret)
gl_swap();
return ret;
render_running = true;
rend_init_renderer();
while (render_running) {
if (render_reinit)
{
render_reinit = false;
rend_init_renderer();
}
else
if (!egl_makecurrent())
break;;
bool ret = rend_single_frame();
if (ret)
gl_swap();
}
egl_makecurrent();
rend_term_renderer();
ANativeWindow_release(g_window);
g_window = NULL;
render_running = false;
return NULL;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv * env, jobject obj, jobject surface, jint width, jint height)
static cThread render_thread(render_thread_func, NULL);
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitNative(JNIEnv * env, jobject obj, jobject surface)
{
if (g_window != NULL)
{
egl_makecurrent();
rend_term_renderer();
ANativeWindow_release(g_window);
g_window = NULL;
}
if (surface != NULL)
{
if (render_thread.hThread != NULL)
{
if (surface == NULL)
{
render_running = false;
render_thread.WaitToEnd();
}
else
render_reinit = true;
}
else if (surface != NULL)
{
g_window = ANativeWindow_fromSurface(env, surface);
rend_init_renderer();
screen_width = width;
screen_height = height;
}
render_thread.Start();
}
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_rendinitJava(JNIEnv * env, jobject obj, jint width, jint height)