summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.cpp106
-rw-r--r--platform/linuxbsd/freedesktop_portal_desktop.h8
-rw-r--r--platform/linuxbsd/platform_gl.h4
-rw-r--r--platform/linuxbsd/x11/SCsub4
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp84
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h2
-rw-r--r--platform/linuxbsd/x11/gl_manager_x11_egl.cpp63
-rw-r--r--platform/linuxbsd/x11/gl_manager_x11_egl.h61
8 files changed, 287 insertions, 45 deletions
diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp
index 91c14e0e91..cf4354139a 100644
--- a/platform/linuxbsd/freedesktop_portal_desktop.cpp
+++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp
@@ -142,36 +142,40 @@ void FreeDesktopPortalDesktop::append_dbus_string(DBusMessageIter *p_iter, const
}
}
-void FreeDesktopPortalDesktop::append_dbus_dict_filters(DBusMessageIter *p_iter, const Vector<String> &p_filters) {
+void FreeDesktopPortalDesktop::append_dbus_dict_filters(DBusMessageIter *p_iter, const Vector<String> &p_filter_names, const Vector<String> &p_filter_exts) {
DBusMessageIter dict_iter;
DBusMessageIter var_iter;
DBusMessageIter arr_iter;
const char *filters_key = "filters";
+ ERR_FAIL_COND(p_filter_names.size() != p_filter_exts.size());
+
dbus_message_iter_open_container(p_iter, DBUS_TYPE_DICT_ENTRY, nullptr, &dict_iter);
dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &filters_key);
dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, "a(sa(us))", &var_iter);
dbus_message_iter_open_container(&var_iter, DBUS_TYPE_ARRAY, "(sa(us))", &arr_iter);
- for (int i = 0; i < p_filters.size(); i++) {
- Vector<String> tokens = p_filters[i].split(";");
- if (tokens.size() == 2) {
- DBusMessageIter struct_iter;
- DBusMessageIter array_iter;
- DBusMessageIter array_struct_iter;
- dbus_message_iter_open_container(&arr_iter, DBUS_TYPE_STRUCT, nullptr, &struct_iter);
- append_dbus_string(&struct_iter, tokens[0]);
-
- dbus_message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "(us)", &array_iter);
+ for (int i = 0; i < p_filter_names.size(); i++) {
+ DBusMessageIter struct_iter;
+ DBusMessageIter array_iter;
+ DBusMessageIter array_struct_iter;
+ dbus_message_iter_open_container(&arr_iter, DBUS_TYPE_STRUCT, nullptr, &struct_iter);
+ append_dbus_string(&struct_iter, p_filter_names[i]);
+
+ dbus_message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "(us)", &array_iter);
+ String flt = p_filter_exts[i];
+ int filter_slice_count = flt.get_slice_count(",");
+ for (int j = 0; j < filter_slice_count; j++) {
dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, nullptr, &array_struct_iter);
+ String str = (flt.get_slice(",", j).strip_edges());
{
const unsigned nil = 0;
dbus_message_iter_append_basic(&array_struct_iter, DBUS_TYPE_UINT32, &nil);
}
- append_dbus_string(&array_struct_iter, tokens[1]);
+ append_dbus_string(&array_struct_iter, str);
dbus_message_iter_close_container(&array_iter, &array_struct_iter);
- dbus_message_iter_close_container(&struct_iter, &array_iter);
- dbus_message_iter_close_container(&arr_iter, &struct_iter);
}
+ dbus_message_iter_close_container(&struct_iter, &array_iter);
+ dbus_message_iter_close_container(&arr_iter, &struct_iter);
}
dbus_message_iter_close_container(&var_iter, &arr_iter);
dbus_message_iter_close_container(&dict_iter, &var_iter);
@@ -219,7 +223,7 @@ void FreeDesktopPortalDesktop::append_dbus_dict_bool(DBusMessageIter *p_iter, co
dbus_message_iter_close_container(p_iter, &dict_iter);
}
-bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_iter, bool &r_cancel, Vector<String> &r_urls) {
+bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_iter, const Vector<String> &p_names, bool &r_cancel, Vector<String> &r_urls, int &r_index) {
ERR_FAIL_COND_V(dbus_message_iter_get_arg_type(p_iter) != DBUS_TYPE_UINT32, false);
dbus_uint32_t resp_code;
@@ -243,7 +247,22 @@ bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_it
DBusMessageIter var_iter;
dbus_message_iter_recurse(&iter, &var_iter);
- if (strcmp(key, "uris") == 0) {
+ if (strcmp(key, "current_filter") == 0) { // (sa(us))
+ if (dbus_message_iter_get_arg_type(&var_iter) == DBUS_TYPE_STRUCT) {
+ DBusMessageIter struct_iter;
+ dbus_message_iter_recurse(&var_iter, &struct_iter);
+ while (dbus_message_iter_get_arg_type(&struct_iter) == DBUS_TYPE_STRING) {
+ const char *value;
+ dbus_message_iter_get_basic(&struct_iter, &value);
+ String name = String::utf8(value);
+
+ r_index = p_names.find(name);
+ if (!dbus_message_iter_next(&struct_iter)) {
+ break;
+ }
+ }
+ }
+ } else if (strcmp(key, "uris") == 0) { // as
if (dbus_message_iter_get_arg_type(&var_iter) == DBUS_TYPE_ARRAY) {
DBusMessageIter uri_iter;
dbus_message_iter_recurse(&var_iter, &uri_iter);
@@ -266,17 +285,43 @@ bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_it
return true;
}
-Error FreeDesktopPortalDesktop::file_dialog_show(const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) {
+Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_window_id, const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) {
if (unsupported) {
return FAILED;
}
+ ERR_FAIL_INDEX_V(int(p_mode), DisplayServer::FILE_DIALOG_MODE_SAVE_MAX, FAILED);
+
+ Vector<String> filter_names;
+ Vector<String> filter_exts;
+ for (int i = 0; i < p_filters.size(); i++) {
+ Vector<String> tokens = p_filters[i].split(";");
+ if (tokens.size() >= 1) {
+ String flt = tokens[0].strip_edges();
+ if (!flt.is_empty()) {
+ if (tokens.size() == 2) {
+ filter_exts.push_back(flt);
+ filter_names.push_back(tokens[1]);
+ } else {
+ filter_exts.push_back(flt);
+ filter_names.push_back(flt);
+ }
+ }
+ }
+ }
+ if (filter_names.is_empty()) {
+ filter_exts.push_back("*.*");
+ filter_names.push_back(RTR("All Files"));
+ }
+
DBusError err;
dbus_error_init(&err);
// Open connection and add signal handler.
FileDialogData fd;
fd.callback = p_callback;
+ fd.prev_focus = p_window_id;
+ fd.filter_names = filter_names;
CryptoCore::RandomGenerator rng;
ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator.");
@@ -307,16 +352,10 @@ Error FreeDesktopPortalDesktop::file_dialog_show(const String &p_xid, const Stri
// Generate FileChooser message.
const char *method = nullptr;
- switch (p_mode) {
- case DisplayServer::FILE_DIALOG_MODE_SAVE_FILE: {
- method = "SaveFile";
- } break;
- case DisplayServer::FILE_DIALOG_MODE_OPEN_ANY:
- case DisplayServer::FILE_DIALOG_MODE_OPEN_FILE:
- case DisplayServer::FILE_DIALOG_MODE_OPEN_DIR:
- case DisplayServer::FILE_DIALOG_MODE_OPEN_FILES: {
- method = "OpenFile";
- } break;
+ if (p_mode == DisplayServer::FILE_DIALOG_MODE_SAVE_FILE) {
+ method = "SaveFile";
+ } else {
+ method = "OpenFile";
}
DBusMessage *message = dbus_message_new_method_call(BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_FILE_CHOOSER, method);
@@ -333,7 +372,7 @@ Error FreeDesktopPortalDesktop::file_dialog_show(const String &p_xid, const Stri
append_dbus_dict_string(&arr_iter, "handle_token", token);
append_dbus_dict_bool(&arr_iter, "multiple", p_mode == DisplayServer::FILE_DIALOG_MODE_OPEN_FILES);
append_dbus_dict_bool(&arr_iter, "directory", p_mode == DisplayServer::FILE_DIALOG_MODE_OPEN_DIR);
- append_dbus_dict_filters(&arr_iter, p_filters);
+ append_dbus_dict_filters(&arr_iter, filter_names, filter_exts);
append_dbus_dict_string(&arr_iter, "current_folder", p_current_directory, true);
if (p_mode == DisplayServer::FILE_DIALOG_MODE_SAVE_FILE) {
append_dbus_dict_string(&arr_iter, "current_name", p_filename);
@@ -408,13 +447,18 @@ void FreeDesktopPortalDesktop::_thread_file_dialog_monitor(void *p_ud) {
if (dbus_message_iter_init(msg, &iter)) {
bool cancel = false;
Vector<String> uris;
- file_chooser_parse_response(&iter, cancel, uris);
+ int index = 0;
+ file_chooser_parse_response(&iter, fd.filter_names, cancel, uris, index);
if (fd.callback.is_valid()) {
Variant v_status = !cancel;
Variant v_files = uris;
- Variant *v_args[2] = { &v_status, &v_files };
- fd.callback.call_deferredp((const Variant **)&v_args, 2);
+ Variant v_index = index;
+ Variant *v_args[3] = { &v_status, &v_files, &v_index };
+ fd.callback.call_deferredp((const Variant **)&v_args, 3);
+ }
+ if (fd.prev_focus != DisplayServer::INVALID_WINDOW_ID) {
+ callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus);
}
}
dbus_message_unref(msg);
diff --git a/platform/linuxbsd/freedesktop_portal_desktop.h b/platform/linuxbsd/freedesktop_portal_desktop.h
index a9b83b3844..503c382207 100644
--- a/platform/linuxbsd/freedesktop_portal_desktop.h
+++ b/platform/linuxbsd/freedesktop_portal_desktop.h
@@ -49,13 +49,15 @@ private:
bool read_setting(const char *p_namespace, const char *p_key, int p_type, void *r_value);
static void append_dbus_string(DBusMessageIter *p_iter, const String &p_string);
- static void append_dbus_dict_filters(DBusMessageIter *p_iter, const Vector<String> &p_filters);
+ static void append_dbus_dict_filters(DBusMessageIter *p_iter, const Vector<String> &p_filter_names, const Vector<String> &p_filter_exts);
static void append_dbus_dict_string(DBusMessageIter *p_iter, const String &p_key, const String &p_value, bool p_as_byte_array = false);
static void append_dbus_dict_bool(DBusMessageIter *p_iter, const String &p_key, bool p_value);
- static bool file_chooser_parse_response(DBusMessageIter *p_iter, bool &r_cancel, Vector<String> &r_urls);
+ static bool file_chooser_parse_response(DBusMessageIter *p_iter, const Vector<String> &p_names, bool &r_cancel, Vector<String> &r_urls, int &r_index);
struct FileDialogData {
+ Vector<String> filter_names;
DBusConnection *connection = nullptr;
+ DisplayServer::WindowID prev_focus = DisplayServer::INVALID_WINDOW_ID;
Callable callback;
String path;
};
@@ -73,7 +75,7 @@ public:
bool is_supported() { return !unsupported; }
- Error file_dialog_show(const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback);
+ Error file_dialog_show(DisplayServer::WindowID p_window_id, const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback);
// Retrieve the system's preferred color scheme.
// 0: No preference or unknown.
diff --git a/platform/linuxbsd/platform_gl.h b/platform/linuxbsd/platform_gl.h
index 1c19c4518a..5d4c2d8978 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 a4890391ce..bbfaaf10d1 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 897a6438d2..31846c80a2 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -364,14 +364,14 @@ bool DisplayServerX11::is_dark_mode() const {
}
Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) {
- WindowID window_id = _get_focused_window_or_popup();
+ WindowID window_id = last_focused_window;
if (!windows.has(window_id)) {
window_id = MAIN_WINDOW_ID;
}
String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window);
- return portal_desktop->file_dialog_show(xid, p_title, p_current_directory, p_filename, p_mode, p_filters, p_callback);
+ return portal_desktop->file_dialog_show(last_focused_window, xid, p_title, p_current_directory, p_filename, p_mode, p_filters, p_callback);
}
#endif
@@ -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<String> 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 71beddce76..9706a4aa11 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 0000000000..544684ebf1
--- /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 <stdio.h>
+#include <stdlib.h>
+
+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<EGLAttrib> GLManagerEGL_X11::_get_platform_display_attributes() const {
+ return Vector<EGLAttrib>();
+}
+
+EGLenum GLManagerEGL_X11::_get_platform_api_enum() const {
+ return EGL_OPENGL_ES_API;
+}
+
+Vector<EGLint> GLManagerEGL_X11::_get_platform_context_attribs() const {
+ Vector<EGLint> 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 0000000000..b9c96619c4
--- /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 <X11/Xlib.h>
+
+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<EGLAttrib> _get_platform_display_attributes() const override;
+ virtual Vector<EGLint> _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