Fix[glinfoutils]: more robust error handling for checks

This commit is contained in:
artdeell 2025-01-24 11:44:04 +03:00 committed by Maksim Belov
parent a39cd84e08
commit 5b99165160

View File

@ -4,6 +4,7 @@ import android.opengl.EGL14;
import android.opengl.EGLConfig; import android.opengl.EGLConfig;
import android.opengl.EGLContext; import android.opengl.EGLContext;
import android.opengl.EGLDisplay; import android.opengl.EGLDisplay;
import android.opengl.EGLSurface;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.opengl.GLES30; import android.opengl.GLES30;
import android.util.Log; import android.util.Log;
@ -46,13 +47,27 @@ public class GLInfoUtils {
private static EGLContext tryCreateContext(EGLDisplay eglDisplay, EGLConfig config, int majorVersion) { 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 }; 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); 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); Log.e("GLInfoUtils", "Failed to create a context with major version "+majorVersion);
return null; return null;
} }
return context; 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() { private static boolean initAndQueryInfo() {
// This is here just to satisfy Android M which incorrectly null-checks it // This is here just to satisfy Android M which incorrectly null-checks it
int[] egl_version = new int[2]; int[] egl_version = new int[2];
@ -64,7 +79,7 @@ public class GLInfoUtils {
EGL14.EGL_RED_SIZE, 8, EGL14.EGL_RED_SIZE, 8,
EGL14.EGL_ALPHA_SIZE, 8, EGL14.EGL_ALPHA_SIZE, 8,
EGL14.EGL_DEPTH_SIZE, 24, 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_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
EGL14.EGL_NONE EGL14.EGL_NONE
}; };
@ -76,19 +91,33 @@ public class GLInfoUtils {
return false; 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; EGLSurface surface = EGL14.eglCreatePbufferSurface(eglDisplay, config[0], pbuffer_attributes, 0);
context = tryCreateContext(eglDisplay, config[0], 3); if(surface == null || surface == EGL14.EGL_NO_SURFACE) {
if(context == null) { Log.e("GLInfoUtils", "Failed to create pbuffer surface");
contextGLVersion = 2; EGL14.eglTerminate(eglDisplay);
context = tryCreateContext(eglDisplay, config[0], 2); return false;
} }
if(!EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, context)) { int contextGLVersion = 3;
Log.e("GLInfoUtils", "Failed to make context current"); EGLContext context = tryMakeCurrent(eglDisplay, config[0], surface, contextGLVersion);
EGL14.eglDestroyContext(eglDisplay, context); 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); EGL14.eglTerminate(eglDisplay);
return false;
} }
info = queryInfo(contextGLVersion); info = queryInfo(contextGLVersion);