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.
This commit is contained in:
parent
c3fdd5a3fb
commit
a56d26bff8
5 changed files with 72 additions and 2 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue