[Scummvm-git-logs] scummvm master -> 00e3208dd6f99d76f0e061607e52a8bceca0b356

lephilousophe noreply at scummvm.org
Sat Mar 25 12:18:22 UTC 2023


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
00e3208dd6 ANDROID: Fix GLES2 functions loading with EGL 1.4


Commit: 00e3208dd6f99d76f0e061607e52a8bceca0b356
    https://github.com/scummvm/scummvm/commit/00e3208dd6f99d76f0e061607e52a8bceca0b356
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2023-03-25T13:17:23+01:00

Commit Message:
ANDROID: Fix GLES2 functions loading with EGL 1.4

With older EGL 1.4, functions from core OpenGL may not be resolved using
eglGetProcAddress. A fallback to dlsym is needed.
We still use eglGetProcAddress only on EGL 1.5+ because it is simpler
and faster.

Changed paths:
    backends/platform/android/android.cpp
    backends/platform/android/android.h
    backends/platform/android/jni-android.cpp
    backends/platform/android/jni-android.h
    backends/platform/android/org/scummvm/scummvm/ScummVM.java


diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 96dc8dbadab..13a51736fdc 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -46,6 +46,7 @@
 #include <sys/system_properties.h>
 #include <time.h>
 #include <unistd.h>
+#include <dlfcn.h>
 
 #include "common/util.h"
 #include "common/textconsole.h"
@@ -167,6 +168,9 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
 	_touch_pt_dt(),
 	_eventScaleX(100),
 	_eventScaleY(100),
+#if defined(USE_OPENGL) && defined(USE_GLAD)
+	_gles2DL(nullptr),
+#endif
 	// TODO put these values in some option dlg?
 	_touch_mode(TOUCH_MODE_TOUCHPAD),
 	_touchpad_scale(66),
@@ -849,8 +853,24 @@ int OSystem_Android::getGraphicsMode() const {
 
 #if defined(USE_OPENGL) && defined(USE_GLAD)
 void *OSystem_Android::getOpenGLProcAddress(const char *name) const {
-	// This exists since Android 2.3 (API Level 9)
-	return (void *)eglGetProcAddress(name);
+	// eglGetProcAddress exists since Android 2.3 (API Level 9)
+	// EGL 1.5+ supports loading core functions too: try to optimize
+	if (JNI::eglVersion() >= 0x00010005) {
+		return (void *)eglGetProcAddress(name);
+	}
+
+	if (!_gles2DL) {
+		_gles2DL = dlopen("libGLESv2.so", RTLD_NOW | RTLD_LOCAL);
+		if (!_gles2DL) {
+			error("Can't load libGLESv2.so with old EGL context");
+		}
+	}
+
+	void *ptr = dlsym(_gles2DL, name);
+	if (!ptr) {
+		ptr = (void *)eglGetProcAddress(name);
+	}
+	return ptr;
 }
 #endif
 
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index f980bd0ac08..119dc07c3d7 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -167,6 +167,10 @@ private:
 
 	TouchControls _touchControls;
 
+#if defined(USE_OPENGL) && defined(USE_GLAD)
+	// Cached dlopen object
+	mutable void *_gles2DL;
+#endif
 public:
 	bool pollEvent(Common::Event &event) override;
 	Common::HardwareInputSet *getHardwareInputSet() override;
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index bc38d630c63..e94edde61e5 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -66,6 +66,7 @@ jobject JNI::_jobj_audio_track = 0;
 jobject JNI::_jobj_egl = 0;
 jobject JNI::_jobj_egl_display = 0;
 jobject JNI::_jobj_egl_surface = 0;
+int JNI::_egl_version = 0;
 
 Common::Archive *JNI::_asset_archive = 0;
 OSystem_Android *JNI::_system = 0;
@@ -98,6 +99,7 @@ jmethodID JNI::_MID_getSysArchives = 0;
 jmethodID JNI::_MID_getAllStorageLocations = 0;
 jmethodID JNI::_MID_initSurface = 0;
 jmethodID JNI::_MID_deinitSurface = 0;
+jmethodID JNI::_MID_eglVersion = 0;
 jmethodID JNI::_MID_getNewSAFTree = 0;
 jmethodID JNI::_MID_getSAFTrees = 0;
 jmethodID JNI::_MID_findSAFTree = 0;
@@ -637,6 +639,23 @@ void JNI::deinitSurface() {
 	}
 }
 
+int JNI::fetchEGLVersion() {
+	JNIEnv *env = JNI::getEnv();
+
+	_egl_version = env->CallIntMethod(_jobj, _MID_eglVersion);
+
+	if (env->ExceptionCheck()) {
+		LOGE("eglVersion failed");
+
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+
+		_egl_version = 0;
+	}
+
+	return _egl_version;
+}
+
 void JNI::setAudioPause() {
 	JNIEnv *env = JNI::getEnv();
 
@@ -731,6 +750,7 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
 	FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
 	FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
 	FIND_METHOD(, deinitSurface, "()V");
+	FIND_METHOD(, eglVersion, "()I");
 	FIND_METHOD(, getNewSAFTree,
 	            "(ZZLjava/lang/String;Ljava/lang/String;)Lorg/scummvm/scummvm/SAFFSTree;");
 	FIND_METHOD(, getSAFTrees, "()[Lorg/scummvm/scummvm/SAFFSTree;");
@@ -738,6 +758,7 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
 
 	_jobj_egl = env->NewGlobalRef(egl);
 	_jobj_egl_display = env->NewGlobalRef(egl_display);
+	_egl_version = 0;
 
 	env->DeleteLocalRef(cls);
 
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index 00719e5f40e..d0fbfb6ebe5 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -96,6 +96,12 @@ public:
 	static inline bool swapBuffers();
 	static bool initSurface();
 	static void deinitSurface();
+	static int eglVersion() {
+		if (_egl_version) {
+			return _egl_version;
+		}
+		return fetchEGLVersion();
+	}
 
 	static void setAudioPause();
 	static void setAudioPlay();
@@ -120,6 +126,8 @@ private:
 	static jobject _jobj_egl;
 	static jobject _jobj_egl_display;
 	static jobject _jobj_egl_surface;
+	// cached EGL version
+	static int _egl_version;
 
 	static Common::Archive *_asset_archive;
 	static OSystem_Android *_system;
@@ -145,6 +153,7 @@ private:
 	static jmethodID _MID_getAllStorageLocations;
 	static jmethodID _MID_initSurface;
 	static jmethodID _MID_deinitSurface;
+	static jmethodID _MID_eglVersion;
 	static jmethodID _MID_getNewSAFTree;
 	static jmethodID _MID_getSAFTrees;
 	static jmethodID _MID_findSAFTree;
@@ -185,6 +194,7 @@ private:
 	static PauseToken _pauseToken;
 
 	static JNIEnv *fetchEnv();
+	static int fetchEGLVersion();
 };
 
 inline bool JNI::haveSurface() {
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 0c2064917bf..e6368b77ae2 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -14,6 +14,7 @@ import android.view.SurfaceHolder;
 
 import java.util.LinkedHashMap;
 import java.util.Locale;
+import java.util.Scanner;
 
 import javax.microedition.khronos.egl.EGL10;
 import javax.microedition.khronos.egl.EGLConfig;
@@ -254,6 +255,20 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
 		_egl_surface = EGL10.EGL_NO_SURFACE;
 	}
 
+	// Callback from C++ peer instance
+	final protected int eglVersion() {
+		String version = _egl.eglQueryString(_egl_display, EGL10.EGL_VERSION);
+		if (version == null) {
+			// 1.0
+			return 0x00010000;
+		}
+
+		Scanner versionScan = new Scanner(version).useLocale(Locale.ROOT).useDelimiter("[ .]");
+		int versionInt = versionScan.nextInt() << 16;
+		versionInt |= versionScan.nextInt() & 0xffff;
+		return versionInt;
+	}
+
 	private void deinitEGL() {
 		if (_egl_display != EGL10.EGL_NO_DISPLAY) {
 			_egl.eglMakeCurrent(_egl_display, EGL10.EGL_NO_SURFACE,




More information about the Scummvm-git-logs mailing list