Enable GLES3 on Android

Add necessary build flags and switch from using a
GLES2 context to a GLES3 one.

This also enables building for OpenXR

Co-authored-by: m4gr3d <fhuyakou@gmail.com>
Co-authored-by: dsnopek <dsnopek@gmail.com>
This commit is contained in:
clayjohn 2022-11-11 15:30:06 -08:00
parent cdd99e9bec
commit 9141984e7e
13 changed files with 40 additions and 44 deletions

View File

@ -38,7 +38,6 @@ vec2 unpackSnorm2x16(uint p) {
vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16))); vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16)));
return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0)); return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
} }
#endif
uint packUnorm4x8(vec4 v) { uint packUnorm4x8(vec4 v) {
uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0)); uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
@ -58,3 +57,5 @@ vec4 unpackSnorm4x8(uint p) {
vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24))); vec4 v = vec4(float(p & uint(0xff)), float((p >> uint(8)) & uint(0xff)), float((p >> uint(16)) & uint(0xff)), float(p >> uint(24)));
return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0)); return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0));
} }
#endif

View File

@ -1540,6 +1540,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (rendering_driver.is_empty() && rendering_method.is_empty() && project_manager) { if (rendering_driver.is_empty() && rendering_method.is_empty() && project_manager) {
rendering_driver = "opengl3"; rendering_driver = "opengl3";
rendering_method = "gl_compatibility"; rendering_method = "gl_compatibility";
default_renderer_mobile = "gl_compatibility";
} }
#endif #endif
if (renderer_hints.is_empty()) { if (renderer_hints.is_empty()) {

View File

@ -138,7 +138,7 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
graphics_binding_gl.display = eglGetCurrentDisplay(); graphics_binding_gl.display = eglGetCurrentDisplay();
graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122 graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122
graphics_binding_gl.context = eglGetCurrentContext(); graphics_binding_gl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
#else #else
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR; graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
graphics_binding_gl.next = p_next_pointer; graphics_binding_gl.next = p_next_pointer;

View File

@ -51,7 +51,7 @@
#define XR_USE_GRAPHICS_API_VULKAN #define XR_USE_GRAPHICS_API_VULKAN
#endif #endif
#ifdef GLES3_ENABLED #ifdef GLES3_ENABLED
#ifdef ANDROID #ifdef ANDROID_ENABLED
#define XR_USE_GRAPHICS_API_OPENGL_ES #define XR_USE_GRAPHICS_API_OPENGL_ES
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
@ -59,7 +59,7 @@
#include <GLES3/gl3ext.h> #include <GLES3/gl3ext.h>
#else #else
#define XR_USE_GRAPHICS_API_OPENGL #define XR_USE_GRAPHICS_API_OPENGL
#endif // ANDROID #endif // ANDROID_ENABLED
#ifdef X11_ENABLED #ifdef X11_ENABLED
#include OPENGL_INCLUDE_H #include OPENGL_INCLUDE_H
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1

View File

@ -161,7 +161,6 @@ def configure(env: "Environment"):
"-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing".split() "-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing".split()
) )
) )
env.Append(CPPDEFINES=["GLES_ENABLED"])
if get_min_sdk_version(env["ndk_platform"]) >= 24: if get_min_sdk_version(env["ndk_platform"]) >= 24:
env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)]) env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
@ -184,9 +183,13 @@ def configure(env: "Environment"):
env.Prepend(CPPPATH=["#platform/android"]) env.Prepend(CPPPATH=["#platform/android"])
env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"]) env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"])
env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "android", "log", "z", "dl"]) env.Append(LIBS=["OpenSLES", "EGL", "android", "log", "z", "dl"])
if env["vulkan"]: if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"]) env.Append(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]: if not env["use_volk"]:
env.Append(LIBS=["vulkan"]) env.Append(LIBS=["vulkan"])
if env["opengl3"]:
env.Append(CPPDEFINES=["GLES3_ENABLED"])
env.Append(LIBS=["GLESv3"])

View File

@ -41,6 +41,10 @@
#include "platform/android/vulkan/vulkan_context_android.h" #include "platform/android/vulkan/vulkan_context_android.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif #endif
#ifdef GLES3_ENABLED
#include "drivers/gles3/rasterizer_gles3.h"
#include <EGL/egl.h>
#endif
DisplayServerAndroid *DisplayServerAndroid::get_singleton() { DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
return static_cast<DisplayServerAndroid *>(DisplayServer::get_singleton()); return static_cast<DisplayServerAndroid *>(DisplayServer::get_singleton());
@ -323,7 +327,7 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type,
} }
#ifdef GLES3_ENABLED #ifdef GLES3_ENABLED
case OPENGL_CONTEXT: { case OPENGL_CONTEXT: {
return eglGetCurrentContext(); return reinterpret_cast<int64_t>(eglGetCurrentContext());
} }
#endif #endif
default: { default: {
@ -449,6 +453,14 @@ DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_drive
DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error)); DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
if (r_error != OK) { if (r_error != OK) {
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver"); OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
if (p_rendering_driver == "vulkan") {
OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n"
"Please try exporting your game using the gl_compatibility renderer.",
"Unable to initialize Video driver");
} else {
OS::get_singleton()->alert("Your video card driver does not support OpenGL ES 3.0.",
"Unable to initialize Video driver");
}
} }
return ds; return ds;
} }
@ -493,28 +505,11 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) {
DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver; rendering_driver = p_rendering_driver;
// TODO: rendering_driver is broken, change when different drivers are supported again
rendering_driver = "vulkan";
keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on"); keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") { if (rendering_driver == "opengl3") {
bool gl_initialization_error = false; RasterizerGLES3::make_current();
if (RasterizerGLES3::is_viable() == OK) {
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
} else {
gl_initialization_error = true;
}
if (gl_initialization_error) {
OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
"Please try updating your Android version.",
"Unable to initialize video driver");
return;
}
} }
#endif #endif

View File

@ -13,7 +13,7 @@
android:xlargeScreens="true" /> android:xlargeScreens="true" />
<uses-feature <uses-feature
android:glEsVersion="0x00020000" android:glEsVersion="0x00030000"
android:required="true" /> android:required="true" />
<application <application

View File

@ -11,7 +11,7 @@
android:xlargeScreens="true" /> android:xlargeScreens="true" />
<uses-feature <uses-feature
android:glEsVersion="0x00020000" android:glEsVersion="0x00030000"
android:required="true" /> android:required="true" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"

View File

@ -68,7 +68,7 @@ import java.io.InputStream;
* See ContextFactory class definition below. * See ContextFactory class definition below.
* *
* - The class must use a custom EGLConfigChooser to be able to select * - The class must use a custom EGLConfigChooser to be able to select
* an EGLConfig that supports 2.0. This is done by providing a config * an EGLConfig that supports 3.0. This is done by providing a config
* specification to eglChooseConfig() that has the attribute * specification to eglChooseConfig() that has the attribute
* EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
* set. See ConfigChooser class definition below. * set. See ConfigChooser class definition below.

View File

@ -45,20 +45,18 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
private int[] mValue = new int[1]; private int[] mValue = new int[1];
// FIXME: Add support for Vulkan. /* This EGL config specification is used to specify 3.0 rendering.
/* This EGL config specification is used to specify 2.0 rendering.
* We use a minimum size of 4 bits for red/green/blue, but will * We use a minimum size of 4 bits for red/green/blue, but will
* perform actual matching in chooseConfig() below. * perform actual matching in chooseConfig() below.
*/ */
private static int EGL_OPENGL_ES2_BIT = 4; private static int EGL_OPENGL_ES2_BIT = 4;
private static int[] s_configAttribs2 = { private static int[] s_configAttribs = {
EGL10.EGL_RED_SIZE, 4, EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4,
// EGL10.EGL_DEPTH_SIZE, 16, // EGL10.EGL_DEPTH_SIZE, 16,
// EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //apparently there is no EGL_OPENGL_ES3_BIT
EGL10.EGL_NONE EGL10.EGL_NONE
}; };
@ -75,7 +73,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
/* Get the number of minimally matching EGL configurations /* Get the number of minimally matching EGL configurations
*/ */
int[] num_config = new int[1]; int[] num_config = new int[1];
egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); egl.eglChooseConfig(display, s_configAttribs, null, 0, num_config);
int numConfigs = num_config[0]; int numConfigs = num_config[0];
@ -86,7 +84,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
/* Allocate then read the array of minimally matching EGL configs /* Allocate then read the array of minimally matching EGL configs
*/ */
EGLConfig[] configs = new EGLConfig[numConfigs]; EGLConfig[] configs = new EGLConfig[numConfigs];
egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); egl.eglChooseConfig(display, s_configAttribs, configs, numConfigs, num_config);
if (GLUtils.DEBUG) { if (GLUtils.DEBUG) {
GLUtils.printConfigs(egl, display, configs); GLUtils.printConfigs(egl, display, configs);

View File

@ -52,17 +52,16 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
// FIXME: Add support for Vulkan. Log.w(TAG, "creating OpenGL ES 3.0 context :");
Log.w(TAG, "creating OpenGL ES 2.0 context :");
GLUtils.checkEglError(TAG, "Before eglCreateContext", egl); GLUtils.checkEglError(TAG, "Before eglCreateContext", egl);
EGLContext context; EGLContext context;
if (GLUtils.use_debug_opengl) { if (GLUtils.use_debug_opengl) {
int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE }; int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 3, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
} else { } else {
int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
} }
GLUtils.checkEglError(TAG, "After eglCreateContext", egl); GLUtils.checkEglError(TAG, "After eglCreateContext", egl);
return context; return context;

View File

@ -17,4 +17,4 @@ target_include_directories(${PROJECT_NAME}
SYSTEM PUBLIC SYSTEM PUBLIC
${GODOT_ROOT_DIR}) ${GODOT_ROOT_DIR})
add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED) add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED)

View File

@ -478,7 +478,6 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
#if defined(GLES3_ENABLED) #if defined(GLES3_ENABLED)
gl_extensions = nullptr; gl_extensions = nullptr;
use_gl2 = false;
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)