diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e69dcb22781..0037b356d05 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -4473,7 +4473,7 @@ String EditorNode::_get_system_info() const { } if (driver_name == "vulkan") { driver_name = "Vulkan"; - } else if (driver_name == "opengl3") { + } else if (driver_name.begins_with("opengl3")) { driver_name = "GLES3"; } diff --git a/main/main.cpp b/main/main.cpp index 5df44c9ddf4..ef0de8d2bfe 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1746,9 +1746,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph { String driver_hints = ""; String driver_hints_angle = ""; + String driver_hints_egl = ""; #ifdef GLES3_ENABLED driver_hints = "opengl3"; driver_hints_angle = "opengl3,opengl3_angle"; + driver_hints_egl = "opengl3,opengl3_es"; #endif String default_driver = driver_hints.get_slice(",", 0); @@ -1759,11 +1761,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF_RST("rendering/gl_compatibility/driver", default_driver); GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.windows", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.linuxbsd", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.linuxbsd", PROPERTY_HINT_ENUM, driver_hints_egl), default_driver); GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.web", PROPERTY_HINT_ENUM, driver_hints), default_driver); GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.android", PROPERTY_HINT_ENUM, driver_hints), default_driver); GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.ios", PROPERTY_HINT_ENUM, driver_hints), default_driver); GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver_macos); + GLOBAL_DEF_RST("rendering/gl_compatibility/nvidia_disable_threaded_optimization", true); GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_angle", true); @@ -1841,7 +1844,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // Set a default renderer if none selected. Try to choose one that matches the driver. if (rendering_method.is_empty()) { - if (rendering_driver == "opengl3" || rendering_driver == "opengl3_angle") { + if (rendering_driver == "opengl3" || rendering_driver == "opengl3_angle" || rendering_driver == "opengl3_es") { rendering_method = "gl_compatibility"; } else { rendering_method = "forward_plus"; @@ -1860,6 +1863,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph if (rendering_method == "gl_compatibility") { available_drivers.push_back("opengl3"); available_drivers.push_back("opengl3_angle"); + available_drivers.push_back("opengl3_es"); } #endif if (available_drivers.is_empty()) { diff --git a/platform/linuxbsd/platform_gl.h b/platform/linuxbsd/platform_gl.h index 1c19c4518af..5d4c2d89786 100644 --- a/platform/linuxbsd/platform_gl.h +++ b/platform/linuxbsd/platform_gl.h @@ -35,6 +35,10 @@ #define GL_API_ENABLED // Allow using desktop GL. #endif +#ifndef GLES_API_ENABLED +#define GLES_API_ENABLED // Allow using GLES. +#endif + #include "thirdparty/glad/glad/egl.h" #include "thirdparty/glad/glad/gl.h" diff --git a/platform/linuxbsd/x11/SCsub b/platform/linuxbsd/x11/SCsub index a4890391ce8..bbfaaf10d1c 100644 --- a/platform/linuxbsd/x11/SCsub +++ b/platform/linuxbsd/x11/SCsub @@ -25,7 +25,9 @@ if env["vulkan"]: if env["opengl3"]: env.Append(CPPDEFINES=["GLAD_GLX_NO_X11"]) - source_files.append(["gl_manager_x11.cpp", "detect_prime_x11.cpp", "#thirdparty/glad/glx.c"]) + source_files.append( + ["gl_manager_x11_egl.cpp", "gl_manager_x11.cpp", "detect_prime_x11.cpp", "#thirdparty/glad/glx.c"] + ) objects = [] diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 678ec340c0f..31846c80a21 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1495,6 +1495,9 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) { if (gl_manager) { gl_manager->window_destroy(p_id); } + if (gl_manager_egl) { + gl_manager_egl->window_destroy(p_id); + } #endif if (wd.xic) { @@ -1534,6 +1537,9 @@ int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, Win if (gl_manager) { return (int64_t)gl_manager->get_glx_context(p_window); } + if (gl_manager_egl) { + return (int64_t)gl_manager_egl->get_context(p_window); + } return 0; } #endif @@ -1711,6 +1717,9 @@ void DisplayServerX11::gl_window_make_current(DisplayServer::WindowID p_window_i if (gl_manager) { gl_manager->window_make_current(p_window_id); } + if (gl_manager_egl) { + gl_manager_egl->window_make_current(p_window_id); + } #endif } @@ -2012,6 +2021,9 @@ void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) { if (gl_manager) { gl_manager->window_resize(p_window, xwa.width, xwa.height); } + if (gl_manager_egl) { + gl_manager_egl->window_resize(p_window, xwa.width, xwa.height); + } #endif } @@ -3721,6 +3733,9 @@ void DisplayServerX11::_window_changed(XEvent *event) { if (gl_manager) { gl_manager->window_resize(window_id, wd.size.width, wd.size.height); } + if (gl_manager_egl) { + gl_manager_egl->window_resize(window_id, wd.size.width, wd.size.height); + } #endif if (!wd.rect_changed_callback.is_null()) { @@ -4855,6 +4870,9 @@ void DisplayServerX11::release_rendering_thread() { if (gl_manager) { gl_manager->release_current(); } + if (gl_manager_egl) { + gl_manager_egl->release_current(); + } #endif } @@ -4863,6 +4881,9 @@ void DisplayServerX11::make_rendering_thread() { if (gl_manager) { gl_manager->make_current(); } + if (gl_manager_egl) { + gl_manager_egl->make_current(); + } #endif } @@ -4871,6 +4892,9 @@ void DisplayServerX11::swap_buffers() { if (gl_manager) { gl_manager->swap_buffers(); } + if (gl_manager_egl) { + gl_manager_egl->swap_buffers(); + } #endif } @@ -5024,6 +5048,9 @@ void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo if (gl_manager) { gl_manager->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); } + if (gl_manager_egl) { + gl_manager_egl->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); + } #endif } @@ -5038,6 +5065,9 @@ DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_wind if (gl_manager) { return gl_manager->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; } + if (gl_manager_egl) { + return gl_manager_egl->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; + } #endif return DisplayServer::VSYNC_ENABLED; } @@ -5050,6 +5080,7 @@ Vector DisplayServerX11::get_rendering_drivers_func() { #endif #ifdef GLES3_ENABLED drivers.push_back("opengl3"); + drivers.push_back("opengl3_es"); #endif return drivers; @@ -5092,6 +5123,21 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't acquire visual info from display."); vi_selected = true; } + if (gl_manager_egl) { + XVisualInfo visual_info_template; + int visual_id = gl_manager_egl->display_get_native_visual_id(x11_display); + ERR_FAIL_COND_V_MSG(visual_id < 0, INVALID_WINDOW_ID, "Unable to get a visual id."); + + visual_info_template.visualid = (VisualID)visual_id; + + int number_of_visuals = 0; + XVisualInfo *vi_list = XGetVisualInfo(x11_display, VisualIDMask, &visual_info_template, &number_of_visuals); + ERR_FAIL_COND_V(number_of_visuals <= 0, INVALID_WINDOW_ID); + + visualInfo = vi_list[0]; + + XFree(vi_list); + } #endif if (!vi_selected) { @@ -5364,8 +5410,12 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V if (gl_manager) { Error err = gl_manager->window_create(id, wd.x11_window, x11_display, win_rect.size.width, win_rect.size.height); ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL window"); - window_set_vsync_mode(p_vsync_mode, id); } + if (gl_manager_egl) { + Error err = gl_manager_egl->window_create(id, x11_display, &wd.x11_window, win_rect.size.width, win_rect.size.height); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Failed to create an OpenGLES window."); + } + window_set_vsync_mode(p_vsync_mode, id); #endif //set_class_hint(x11_display, wd.x11_window); @@ -5766,7 +5816,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode #endif // Initialize context and rendering device. #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (rendering_driver == "opengl3" || rendering_driver == "opengl3_es") { if (getenv("DRI_PRIME") == nullptr) { int use_prime = -1; @@ -5807,7 +5857,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode setenv("DRI_PRIME", "1", 1); } } - + } + if (rendering_driver == "opengl3") { GLManager_X11::ContextType opengl_api_type = GLManager_X11::GLES_3_0_COMPATIBLE; gl_manager = memnew(GLManager_X11(p_resolution, opengl_api_type)); @@ -5820,14 +5871,20 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } driver_found = true; - if (true) { - RasterizerGLES3::make_current(true); - } else { - memdelete(gl_manager); - gl_manager = nullptr; + RasterizerGLES3::make_current(true); + } + if (rendering_driver == "opengl3_es") { + gl_manager_egl = memnew(GLManagerEGL_X11); + + if (gl_manager_egl->initialize() != OK) { + memdelete(gl_manager_egl); + gl_manager_egl = nullptr; r_error = ERR_UNAVAILABLE; return; } + driver_found = true; + + RasterizerGLES3::make_current(false); } #endif if (!driver_found) { @@ -6044,6 +6101,9 @@ DisplayServerX11::~DisplayServerX11() { if (gl_manager) { gl_manager->window_destroy(E.key); } + if (gl_manager_egl) { + gl_manager_egl->window_destroy(E.key); + } #endif WindowData &wd = E.value; @@ -6094,6 +6154,10 @@ DisplayServerX11::~DisplayServerX11() { memdelete(gl_manager); gl_manager = nullptr; } + if (gl_manager_egl) { + memdelete(gl_manager_egl); + gl_manager_egl = nullptr; + } #endif if (xrandr_handle) { diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 71beddce762..9706a4aa110 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -54,6 +54,7 @@ #if defined(GLES3_ENABLED) #include "x11/gl_manager_x11.h" +#include "x11/gl_manager_x11_egl.h" #endif #if defined(VULKAN_ENABLED) @@ -138,6 +139,7 @@ class DisplayServerX11 : public DisplayServer { #if defined(GLES3_ENABLED) GLManager_X11 *gl_manager = nullptr; + GLManagerEGL_X11 *gl_manager_egl = nullptr; #endif #if defined(VULKAN_ENABLED) VulkanContextX11 *context_vulkan = nullptr; diff --git a/platform/linuxbsd/x11/gl_manager_x11_egl.cpp b/platform/linuxbsd/x11/gl_manager_x11_egl.cpp new file mode 100644 index 00000000000..544684ebf1e --- /dev/null +++ b/platform/linuxbsd/x11/gl_manager_x11_egl.cpp @@ -0,0 +1,63 @@ +/**************************************************************************/ +/* gl_manager_x11_egl.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "gl_manager_x11_egl.h" + +#if defined(X11_ENABLED) && defined(GLES3_ENABLED) + +#include +#include + +const char *GLManagerEGL_X11::_get_platform_extension_name() const { + return "EGL_KHR_platform_x11"; +} + +EGLenum GLManagerEGL_X11::_get_platform_extension_enum() const { + return EGL_PLATFORM_X11_KHR; +} + +Vector GLManagerEGL_X11::_get_platform_display_attributes() const { + return Vector(); +} + +EGLenum GLManagerEGL_X11::_get_platform_api_enum() const { + return EGL_OPENGL_ES_API; +} + +Vector GLManagerEGL_X11::_get_platform_context_attribs() const { + Vector ret; + ret.push_back(EGL_CONTEXT_CLIENT_VERSION); + ret.push_back(3); + ret.push_back(EGL_NONE); + + return ret; +} + +#endif // WINDOWS_ENABLED && GLES3_ENABLED diff --git a/platform/linuxbsd/x11/gl_manager_x11_egl.h b/platform/linuxbsd/x11/gl_manager_x11_egl.h new file mode 100644 index 00000000000..b9c96619c42 --- /dev/null +++ b/platform/linuxbsd/x11/gl_manager_x11_egl.h @@ -0,0 +1,61 @@ +/**************************************************************************/ +/* gl_manager_x11_egl.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef GL_MANAGER_X11_EGL_H +#define GL_MANAGER_X11_EGL_H + +#if defined(X11_ENABLED) && defined(GLES3_ENABLED) + +#include "core/error/error_list.h" +#include "core/os/os.h" +#include "core/templates/local_vector.h" +#include "drivers/egl/egl_manager.h" +#include "servers/display_server.h" + +#include + +class GLManagerEGL_X11 : public EGLManager { +private: + virtual const char *_get_platform_extension_name() const override; + virtual EGLenum _get_platform_extension_enum() const override; + virtual EGLenum _get_platform_api_enum() const override; + virtual Vector _get_platform_display_attributes() const override; + virtual Vector _get_platform_context_attribs() const override; + +public: + void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {} + + GLManagerEGL_X11(){}; + ~GLManagerEGL_X11(){}; +}; + +#endif // X11_ENABLED && GLES3_ENABLED + +#endif // GL_MANAGER_X11_EGL_H diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 86631ae9d90..e43036f1779 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -732,7 +732,7 @@ void RendererViewport::draw_viewports() { // commit our eyes Vector blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect); if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID) { - if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3" || OS::get_singleton()->get_current_rendering_driver_name() == "opengl3_angle") { + if (OS::get_singleton()->get_current_rendering_driver_name().begins_with("opengl3")) { if (blits.size() > 0) { RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size()); } @@ -771,7 +771,7 @@ void RendererViewport::draw_viewports() { blit_to_screen_list[vp->viewport_to_screen] = Vector(); } - if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3" || OS::get_singleton()->get_current_rendering_driver_name() == "opengl3_angle") { + if (OS::get_singleton()->get_current_rendering_driver_name().begins_with("opengl3")) { Vector blit_to_screen_vec; blit_to_screen_vec.push_back(blit); RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blit_to_screen_vec.ptr(), 1); diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index b13d33de9eb..38fecbe323d 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -91,7 +91,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { RSG::viewport->draw_viewports(); RSG::canvas_render->update(); - if (OS::get_singleton()->get_current_rendering_driver_name() != "opengl3" && OS::get_singleton()->get_current_rendering_driver_name() != "opengl3_angle") { + if (!OS::get_singleton()->get_current_rendering_driver_name().begins_with("opengl3")) { // Already called for gl_compatibility renderer. RSG::rasterizer->end_frame(p_swap_buffers); }