mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-08-03 07:36:31 -04:00
Feat[launcher]: remove duplicate GLES initializations
This commit is contained in:
parent
5de68224c6
commit
a9815b2ac9
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ local.properties
|
||||
app_pojavlauncher/.cxx/
|
||||
.vs/
|
||||
/curseforge_key.txt
|
||||
/app_pojavlauncher/libs/ltw-release.aar
|
||||
|
@ -70,6 +70,7 @@ import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import net.kdt.pojavlaunch.utils.DateUtils;
|
||||
import net.kdt.pojavlaunch.utils.DownloadUtils;
|
||||
import net.kdt.pojavlaunch.utils.FileUtils;
|
||||
import net.kdt.pojavlaunch.utils.GLInfoUtils;
|
||||
import net.kdt.pojavlaunch.utils.JREUtils;
|
||||
import net.kdt.pojavlaunch.utils.JSONUtils;
|
||||
import net.kdt.pojavlaunch.utils.MCOptionUtils;
|
||||
@ -233,8 +234,7 @@ public final class Tools {
|
||||
* Initialize OpenGL and do checks to see if the GPU of the device is affected by the render
|
||||
* distance issue.
|
||||
|
||||
* Currently only checks whether the user has an Adreno GPU capable of OpenGL ES 3
|
||||
* and surfaceless rendering installed.
|
||||
* Currently only checks whether the user has an Adreno GPU capable of OpenGL ES 3.
|
||||
|
||||
* This issue is caused by a very severe limit on the amount of GL buffer names that could be allocated
|
||||
* by the Adreno properietary GLES driver.
|
||||
@ -242,44 +242,8 @@ public final class Tools {
|
||||
* @return whether the GPU is affected by the Large Thin Wrapper render distance issue on vanilla
|
||||
*/
|
||||
private static boolean affectedByRenderDistanceIssue() {
|
||||
EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
|
||||
if(eglDisplay == EGL14.EGL_NO_DISPLAY || !EGL14.eglInitialize(eglDisplay, null, 0, null, 0)) return false;
|
||||
int[] egl_attributes = new int[] {
|
||||
EGL14.EGL_BLUE_SIZE, 8,
|
||||
EGL14.EGL_GREEN_SIZE, 8,
|
||||
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_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
|
||||
EGL14.EGL_NONE
|
||||
};
|
||||
EGLConfig[] config = new EGLConfig[1];
|
||||
int[] num_configs = new int[]{0};
|
||||
if(!EGL14.eglChooseConfig(eglDisplay, egl_attributes, 0, config, 0, 1, num_configs, 0) || num_configs[0] == 0) {
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
Log.e("CheckVendor", "Failed to choose an EGL config");
|
||||
return false;
|
||||
}
|
||||
int[] egl_context_attributes = new int[] { EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL14.EGL_NONE };
|
||||
EGLContext context = EGL14.eglCreateContext(eglDisplay, config[0], EGL14.EGL_NO_CONTEXT, egl_context_attributes, 0);
|
||||
if(context == EGL14.EGL_NO_CONTEXT) {
|
||||
Log.e("CheckVendor", "Failed to create a context");
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
return false;
|
||||
}
|
||||
if(!EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, context)) {
|
||||
Log.e("CheckVendor", "Failed to make context current");
|
||||
EGL14.eglDestroyContext(eglDisplay, context);
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
}
|
||||
boolean is_adreno = GLES30.glGetString(GLES30.GL_VENDOR).equals("Qualcomm") &&
|
||||
GLES30.glGetString(GLES30.GL_RENDERER).contains("Adreno");
|
||||
Log.e("CheckVendor", "Running Adreno graphics: "+is_adreno);
|
||||
EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
|
||||
EGL14.eglDestroyContext(eglDisplay, context);
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
return is_adreno;
|
||||
GLInfoUtils.GLInfo info = GLInfoUtils.getInfo();
|
||||
return info.renderer.contains("Adreno") && info.vendor.equals("Qualcomm") && info.glesMajorVersion >= 3;
|
||||
}
|
||||
|
||||
private static boolean checkRenderDistance(File gamedir) {
|
||||
@ -1071,6 +1035,8 @@ public final class Tools {
|
||||
Logger.appendToLog("Info: API version: " + SDK_INT);
|
||||
Logger.appendToLog("Info: Selected Minecraft version: " + gameVersion);
|
||||
Logger.appendToLog("Info: Custom Java arguments: \"" + javaArguments + "\"");
|
||||
GLInfoUtils.GLInfo info = GLInfoUtils.getInfo();
|
||||
Logger.appendToLog("Info: Graphics device: "+info.vendor+ " "+info.renderer+" (OpenGL ES "+info.glesMajorVersion+")");
|
||||
}
|
||||
|
||||
public interface DownloaderFeedback {
|
||||
|
@ -0,0 +1,125 @@
|
||||
package net.kdt.pojavlaunch.utils;
|
||||
|
||||
import android.opengl.EGL14;
|
||||
import android.opengl.EGLConfig;
|
||||
import android.opengl.EGLContext;
|
||||
import android.opengl.EGLDisplay;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLES30;
|
||||
import android.util.Log;
|
||||
|
||||
public class GLInfoUtils {
|
||||
public static String GLES_VERSION_PREFIX = "OpenGL ES ";
|
||||
private static GLInfo info;
|
||||
|
||||
private static int getMajorGLVersion(String versionString) {
|
||||
if(versionString.startsWith(GLES_VERSION_PREFIX)) {
|
||||
versionString = versionString.substring(GLES_VERSION_PREFIX.length());
|
||||
}
|
||||
int firstDot = versionString.indexOf('.');
|
||||
String majorVersion = versionString.substring(0, firstDot).trim();
|
||||
return Integer.parseInt(majorVersion);
|
||||
}
|
||||
|
||||
private static GLInfo queryInfo(int contextGLVersion) {
|
||||
String vendor = GLES20.glGetString(GLES20.GL_VENDOR);
|
||||
String renderer = GLES20.glGetString(GLES20.GL_RENDERER);
|
||||
String versionString = GLES20.glGetString(GLES30.GL_VERSION);
|
||||
int version = 2;
|
||||
try {
|
||||
version = getMajorGLVersion(versionString);
|
||||
}catch (NumberFormatException e) {
|
||||
Log.w("GLInfoUtils","Failed to parse GL version number, falling back to 2", e);
|
||||
}
|
||||
// LTW depends on the ability to create a context with a major version of 3,
|
||||
// and even if the string parse returns 3 while EGL can only create 2,
|
||||
// it's still a noncompilant implementation
|
||||
version = Math.min(version, contextGLVersion);
|
||||
return new GLInfo(vendor, renderer, version);
|
||||
}
|
||||
|
||||
private static void initDummyInfo() {
|
||||
Log.e("GLInfoUtils", "An error happened during info query. Will use dummy info. This should be investigated.");
|
||||
info = new GLInfo("<Unknown>", "<Unknown>", 2);
|
||||
}
|
||||
|
||||
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) {
|
||||
Log.e("GLInfoUtils", "Failed to create a context with major version "+majorVersion);
|
||||
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];
|
||||
EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
|
||||
if(eglDisplay == EGL14.EGL_NO_DISPLAY || !EGL14.eglInitialize(eglDisplay, egl_version, 0 , egl_version, 1)) return false;
|
||||
int[] egl_attributes = new int[] {
|
||||
EGL14.EGL_BLUE_SIZE, 8,
|
||||
EGL14.EGL_GREEN_SIZE, 8,
|
||||
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_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
|
||||
EGL14.EGL_NONE
|
||||
};
|
||||
EGLConfig[] config = new EGLConfig[1];
|
||||
int[] num_configs = new int[]{0};
|
||||
if(!EGL14.eglChooseConfig(eglDisplay, egl_attributes, 0, config, 0, 1, num_configs, 0) || num_configs[0] == 0) {
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
Log.e("GLInfoUtils", "Failed to choose an EGL config");
|
||||
return false;
|
||||
}
|
||||
|
||||
int contextGLVersion = 3;
|
||||
|
||||
EGLContext context;
|
||||
context = tryCreateContext(eglDisplay, config[0], 3);
|
||||
if(context == null) {
|
||||
contextGLVersion = 2;
|
||||
context = tryCreateContext(eglDisplay, config[0], 2);
|
||||
}
|
||||
|
||||
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);
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
}
|
||||
|
||||
info = queryInfo(contextGLVersion);
|
||||
|
||||
EGL14.eglMakeCurrent(eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
|
||||
EGL14.eglDestroyContext(eglDisplay, context);
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static GLInfo getInfo() {
|
||||
if(info != null) return info;
|
||||
Log.i("GLInfoUtils", "Querying graphics device info...");
|
||||
boolean infoQueryResult = false;
|
||||
try {
|
||||
infoQueryResult = initAndQueryInfo();
|
||||
}catch (Throwable e) {
|
||||
Log.e("GLInfoUtils", "Throwable when trying to initialize GL info", e);
|
||||
}
|
||||
if(!infoQueryResult) initDummyInfo();
|
||||
return info;
|
||||
}
|
||||
|
||||
public static class GLInfo {
|
||||
public final String vendor;
|
||||
public final String renderer;
|
||||
public final int glesMajorVersion;
|
||||
protected GLInfo(String vendor, String renderer, int glesMajorVersion) {
|
||||
this.vendor = vendor;
|
||||
this.renderer = renderer;
|
||||
this.glesMajorVersion = glesMajorVersion;
|
||||
}
|
||||
}
|
||||
}
|
@ -240,8 +240,10 @@ public class JREUtils {
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
|
||||
GLInfoUtils.GLInfo info = GLInfoUtils.getInfo();
|
||||
if(!envMap.containsKey("LIBGL_ES") && LOCAL_RENDERER != null) {
|
||||
int glesMajor = getDetectedVersion();
|
||||
int glesMajor = info.glesMajorVersion;
|
||||
Log.i("glesDetect","GLES version detected: "+glesMajor);
|
||||
|
||||
if (glesMajor < 3) {
|
||||
@ -255,6 +257,11 @@ public class JREUtils {
|
||||
envMap.put("LIBGL_ES", "3");
|
||||
}
|
||||
}
|
||||
|
||||
if(info.vendor.equals("Qualcomm") && info.renderer.contains("Adreno")) {
|
||||
envMap.put("POJAV_LOAD_TURNIP", "1");
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> env : envMap.entrySet()) {
|
||||
Logger.appendToLog("Added custom env: " + env.getKey() + "=" + env.getValue());
|
||||
try {
|
||||
@ -512,61 +519,7 @@ public class JREUtils {
|
||||
}
|
||||
|
||||
public static int getDetectedVersion() {
|
||||
/*
|
||||
* Get all the device configurations and check the EGL_RENDERABLE_TYPE attribute
|
||||
* to determine the highest ES version supported by any config. The
|
||||
* EGL_KHR_create_context extension is required to check for ES3 support; if the
|
||||
* extension is not present this test will fail to detect ES3 support. This
|
||||
* effectively makes the extension mandatory for ES3-capable devices.
|
||||
*/
|
||||
EGL10 egl = (EGL10) EGLContext.getEGL();
|
||||
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||
int[] numConfigs = new int[1];
|
||||
if (egl.eglInitialize(display, null)) {
|
||||
try {
|
||||
boolean checkES3 = hasExtension(egl.eglQueryString(display, EGL10.EGL_EXTENSIONS),
|
||||
"EGL_KHR_create_context");
|
||||
if (egl.eglGetConfigs(display, null, 0, numConfigs)) {
|
||||
EGLConfig[] configs = new EGLConfig[numConfigs[0]];
|
||||
if (egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
|
||||
int highestEsVersion = 0;
|
||||
int[] value = new int[1];
|
||||
for (int i = 0; i < numConfigs[0]; i++) {
|
||||
if (egl.eglGetConfigAttrib(display, configs[i],
|
||||
EGL10.EGL_RENDERABLE_TYPE, value)) {
|
||||
if (checkES3 && ((value[0] & EGL_OPENGL_ES3_BIT_KHR) ==
|
||||
EGL_OPENGL_ES3_BIT_KHR)) {
|
||||
if (highestEsVersion < 3) highestEsVersion = 3;
|
||||
} else if ((value[0] & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT) {
|
||||
if (highestEsVersion < 2) highestEsVersion = 2;
|
||||
} else if ((value[0] & EGL_OPENGL_ES_BIT) == EGL_OPENGL_ES_BIT) {
|
||||
if (highestEsVersion < 1) highestEsVersion = 1;
|
||||
}
|
||||
} else {
|
||||
Log.w("glesDetect", "Getting config attribute with "
|
||||
+ "EGL10#eglGetConfigAttrib failed "
|
||||
+ "(" + i + "/" + numConfigs[0] + "): "
|
||||
+ egl.eglGetError());
|
||||
}
|
||||
}
|
||||
return highestEsVersion;
|
||||
} else {
|
||||
Log.e("glesDetect", "Getting configs with EGL10#eglGetConfigs failed: "
|
||||
+ egl.eglGetError());
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
Log.e("glesDetect", "Getting number of configs with EGL10#eglGetConfigs failed: "
|
||||
+ egl.eglGetError());
|
||||
return -2;
|
||||
}
|
||||
} finally {
|
||||
egl.eglTerminate(display);
|
||||
}
|
||||
} else {
|
||||
Log.e("glesDetect", "Couldn't initialize EGL.");
|
||||
return -3;
|
||||
}
|
||||
return GLInfoUtils.getInfo().glesMajorVersion;
|
||||
}
|
||||
public static native int chdir(String path);
|
||||
public static native boolean dlopen(String libPath);
|
||||
|
@ -38,7 +38,6 @@ LOCAL_SRC_FILES := \
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||
LOCAL_CFLAGS += -DADRENO_POSSIBLE
|
||||
LOCAL_LDLIBS += -lEGL -lGLESv2
|
||||
endif
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
|
@ -99,41 +99,8 @@ EXTERNAL_API void* pojavGetCurrentContext() {
|
||||
|
||||
//#define ADRENO_POSSIBLE
|
||||
#ifdef ADRENO_POSSIBLE
|
||||
//Checks if your graphics are Adreno. Returns true if your graphics are Adreno, false otherwise or if there was an error
|
||||
bool checkAdrenoGraphics() {
|
||||
EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if(eglDisplay == EGL_NO_DISPLAY || eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE) return false;
|
||||
EGLint egl_attributes[] = { EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
|
||||
EGLint num_configs = 0;
|
||||
if(eglChooseConfig(eglDisplay, egl_attributes, NULL, 0, &num_configs) != EGL_TRUE || num_configs == 0) {
|
||||
eglTerminate(eglDisplay);
|
||||
return false;
|
||||
}
|
||||
EGLConfig eglConfig;
|
||||
eglChooseConfig(eglDisplay, egl_attributes, &eglConfig, 1, &num_configs);
|
||||
const EGLint egl_context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE };
|
||||
EGLContext context = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, egl_context_attributes);
|
||||
if(context == EGL_NO_CONTEXT) {
|
||||
eglTerminate(eglDisplay);
|
||||
return false;
|
||||
}
|
||||
if(eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context) != EGL_TRUE) {
|
||||
eglDestroyContext(eglDisplay, context);
|
||||
eglTerminate(eglDisplay);
|
||||
}
|
||||
const char* vendor = glGetString(GL_VENDOR);
|
||||
const char* renderer = glGetString(GL_RENDERER);
|
||||
bool is_adreno = false;
|
||||
if(strcmp(vendor, "Qualcomm") == 0 && strstr(renderer, "Adreno") != NULL) {
|
||||
is_adreno = true; // TODO: check for Turnip support
|
||||
}
|
||||
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglDestroyContext(eglDisplay, context);
|
||||
eglTerminate(eglDisplay);
|
||||
return is_adreno;
|
||||
}
|
||||
void* load_turnip_vulkan() {
|
||||
if(!checkAdrenoGraphics()) return NULL;
|
||||
if(getenv("POJAV_LOAD_TURNIP") == NULL) return NULL;
|
||||
const char* native_dir = getenv("POJAV_NATIVEDIR");
|
||||
const char* cache_dir = getenv("TMPDIR");
|
||||
if(!linker_ns_load(native_dir)) return NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user