diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/GLInfoUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/GLInfoUtils.java index 98a8bd742..15af997c7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/GLInfoUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/GLInfoUtils.java @@ -4,6 +4,7 @@ import android.opengl.EGL14; import android.opengl.EGLConfig; import android.opengl.EGLContext; import android.opengl.EGLDisplay; +import android.opengl.EGLSurface; import android.opengl.GLES20; import android.opengl.GLES30; import android.util.Log; @@ -46,13 +47,27 @@ public class GLInfoUtils { private static EGLContext tryCreateContext(EGLDisplay eglDisplay, EGLConfig config, int majorVersion) { int[] egl_context_attributes = new int[] { EGL14.EGL_CONTEXT_CLIENT_VERSION, majorVersion, EGL14.EGL_NONE }; EGLContext context = EGL14.eglCreateContext(eglDisplay, config, EGL14.EGL_NO_CONTEXT, egl_context_attributes, 0); - if(context == EGL14.EGL_NO_CONTEXT) { + if(context == EGL14.EGL_NO_CONTEXT || context == null) { Log.e("GLInfoUtils", "Failed to create a context with major version "+majorVersion); return null; } return context; } + private static EGLContext tryMakeCurrent(EGLDisplay eglDisplay, EGLConfig config, EGLSurface surface, int majorVersion) { + EGLContext context = tryCreateContext(eglDisplay, config, majorVersion); + if(context == null) return null; + // Old Mali drivers are broken, and will actually let us create a context with GLES 3 + // But won't let us make it current, which will break the check anyway... + boolean makeCurrentResult = EGL14.eglMakeCurrent(eglDisplay, surface, surface, context); + if(!makeCurrentResult) { + Log.i("GLInfoUtils", "Failed to make context GL version "+majorVersion +" current"); + EGL14.eglDestroyContext(eglDisplay, context); + return null; + } + return context; + } + private static boolean initAndQueryInfo() { // This is here just to satisfy Android M which incorrectly null-checks it int[] egl_version = new int[2]; @@ -64,7 +79,7 @@ public class GLInfoUtils { EGL14.EGL_RED_SIZE, 8, EGL14.EGL_ALPHA_SIZE, 8, EGL14.EGL_DEPTH_SIZE, 24, - EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT|EGL14.EGL_WINDOW_BIT, + EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT, EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL14.EGL_NONE }; @@ -76,19 +91,33 @@ public class GLInfoUtils { return false; } - int contextGLVersion = 3; + // Create PBuffer surface as some devices might actually not support surfaceless. + int[] pbuffer_attributes = new int[] { + EGL14.EGL_WIDTH, 16, + EGL14.EGL_HEIGHT, 16, + EGL14.EGL_NONE + }; - EGLContext context; - context = tryCreateContext(eglDisplay, config[0], 3); - if(context == null) { - contextGLVersion = 2; - context = tryCreateContext(eglDisplay, config[0], 2); + EGLSurface surface = EGL14.eglCreatePbufferSurface(eglDisplay, config[0], pbuffer_attributes, 0); + if(surface == null || surface == EGL14.EGL_NO_SURFACE) { + Log.e("GLInfoUtils", "Failed to create pbuffer surface"); + EGL14.eglTerminate(eglDisplay); + return false; } - if(!EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, context)) { - Log.e("GLInfoUtils", "Failed to make context current"); - EGL14.eglDestroyContext(eglDisplay, context); + int contextGLVersion = 3; + EGLContext context = tryMakeCurrent(eglDisplay, config[0], surface, contextGLVersion); + if(context == null) { + contextGLVersion = 2; + context = tryMakeCurrent(eglDisplay, config[0], surface, contextGLVersion); + } + + // Creation/currenting failed in both cases + if(context == null) { + Log.e("GLInfoUtils", "Failed to create and make context current"); + EGL14.eglDestroySurface(eglDisplay, surface); EGL14.eglTerminate(eglDisplay); + return false; } info = queryInfo(contextGLVersion);