summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/SCsub4
-rw-r--r--platform/linuxbsd/detect.py4
-rw-r--r--platform/linuxbsd/detect_prime_x11.cpp2
-rw-r--r--platform/linuxbsd/display_server_x11.cpp127
-rw-r--r--platform/linuxbsd/display_server_x11.h15
-rw-r--r--platform/linuxbsd/gl_manager_x11.cpp (renamed from platform/linuxbsd/context_gl_x11.cpp)251
-rw-r--r--platform/linuxbsd/gl_manager_x11.h (renamed from platform/linuxbsd/context_gl_x11.h)83
-rw-r--r--platform/linuxbsd/platform_config.h3
8 files changed, 374 insertions, 115 deletions
diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub
index 8aebd57fd2..05393f6246 100644
--- a/platform/linuxbsd/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -14,12 +14,14 @@ common_linuxbsd = [
if "x11" in env and env["x11"]:
common_linuxbsd += [
- "context_gl_x11.cpp",
+ "gl_manager_x11.cpp",
"detect_prime_x11.cpp",
"display_server_x11.cpp",
"key_mapping_x11.cpp",
]
+#"context_gl_x11.cpp",
+
if "vulkan" in env and env["vulkan"]:
common_linuxbsd.append("vulkan_context_x11.cpp")
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 4b3804d049..04da082b16 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -381,8 +381,8 @@ def configure(env):
# No pkgconfig file for glslang so far
env.Append(LIBS=["glslang", "SPIRV"])
- # env.Append(CPPDEFINES=['OPENGL_ENABLED'])
- env.Append(LIBS=["GL"])
+ env.Append(CPPDEFINES=["OPENGL_ENABLED"])
+ env.Append(LIBS=["GL"])
env.Append(LIBS=["pthread"])
diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp
index da1c95a593..f074c9e9d8 100644
--- a/platform/linuxbsd/detect_prime_x11.cpp
+++ b/platform/linuxbsd/detect_prime_x11.cpp
@@ -31,7 +31,7 @@
#ifdef X11_ENABLED
#if defined(OPENGL_ENABLED)
-#include "detect_prime.h"
+#include "detect_prime_x11.h"
#include "core/string/print_string.h"
#include "core/string/ustring.h"
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index dd296ec3b4..18247deafb 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -34,6 +34,7 @@
#include "core/config/project_settings.h"
#include "core/string/print_string.h"
+#include "core/string/ustring.h"
#include "detect_prime_x11.h"
#include "key_mapping_x11.h"
#include "main/main.h"
@@ -43,6 +44,10 @@
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
+#if defined(GLES_X11_ENABLED)
+#include "drivers/gles2/rasterizer_gles2.h"
+#endif
+
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -884,6 +889,12 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
context_vulkan->window_destroy(p_id);
}
#endif
+#ifdef GLES_X11_ENABLED
+ if (gl_manager) {
+ gl_manager->window_destroy(p_id);
+ }
+#endif
+
XUnmapWindow(x11_display, wd.x11_window);
XDestroyWindow(x11_display, wd.x11_window);
if (wd.xic) {
@@ -1052,6 +1063,13 @@ int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
return screen_index;
}
+void DisplayServerX11::gl_window_make_current(DisplayServer::WindowID p_window_id) {
+#if defined(GLES_X11_ENABLED)
+ if (gl_manager)
+ gl_manager->window_make_current(p_window_id);
+#endif
+}
+
void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window) {
_THREAD_SAFE_METHOD_
@@ -2648,6 +2666,11 @@ void DisplayServerX11::_window_changed(XEvent *event) {
context_vulkan->window_resize(window_id, wd.size.width, wd.size.height);
}
#endif
+#if defined(GLES_X11_ENABLED)
+ if (gl_manager) {
+ gl_manager->window_resize(window_id, wd.size.width, wd.size.height);
+ }
+#endif
if (!wd.rect_changed_callback.is_null()) {
Rect2i r = new_rect;
@@ -3524,12 +3547,23 @@ void DisplayServerX11::process_events() {
}
void DisplayServerX11::release_rendering_thread() {
+#if defined(GLES_X11_ENABLED)
+// gl_manager->release_current();
+#endif
}
void DisplayServerX11::make_rendering_thread() {
+#if defined(GLES_X11_ENABLED)
+// gl_manager->make_current();
+#endif
}
void DisplayServerX11::swap_buffers() {
+#if defined(GLES_X11_ENABLED)
+ if (gl_manager) {
+ gl_manager->swap_buffers();
+ }
+#endif
}
void DisplayServerX11::_update_context(WindowData &wd) {
@@ -3671,17 +3705,31 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
- context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+ if (context_vulkan) {
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+ }
+#endif
+
+#if defined(GLES_X11_ENABLED)
+ if (gl_manager) {
+ gl_manager->set_use_vsync(p_vsync_mode == DisplayServer::VSYNC_ENABLED);
+ }
#endif
}
DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
- return context_vulkan->get_vsync_mode(p_window);
-#else
- return DisplayServer::VSYNC_ENABLED;
+ if (context_vulkan) {
+ return context_vulkan->get_vsync_mode(p_window);
+ }
+#endif
+#if defined(GLES_X11_ENABLED)
+ if (gl_manager) {
+ return gl_manager->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED;
+ }
#endif
+ return DisplayServer::VSYNC_ENABLED;
}
Vector<String> DisplayServerX11::get_rendering_drivers_func() {
@@ -3690,8 +3738,10 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
#ifdef VULKAN_ENABLED
drivers.push_back("vulkan");
#endif
-#ifdef OPENGL_ENABLED
- drivers.push_back("opengl");
+#ifdef GLES_X11_ENABLED
+ // drivers.push_back("opengl");
+ drivers.push_back("GLES2");
+ drivers.push_back("GLES3");
#endif
return drivers;
@@ -3876,6 +3926,13 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan window");
}
#endif
+#ifdef GLES_X11_ENABLED
+ print_line("rendering_driver " + rendering_driver);
+ if (gl_manager) {
+ Error err = gl_manager->window_create(id, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height);
+ ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a GLES2 window");
+ }
+#endif
//set_class_hint(x11_display, wd.x11_window);
XFlush(x11_display);
@@ -4061,10 +4118,13 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
rendering_driver = p_rendering_driver;
#ifndef _MSC_VER
-#warning Forcing vulkan rendering driver because OpenGL not implemented yet
+//#warning Forcing vulkan rendering driver because OpenGL not implemented yet
+//#warning Forcing opengl rendering driver because selecting properly is too much effort
#endif
- rendering_driver = "vulkan";
+ // rendering_driver = "vulkan";
+ //rendering_driver = "GLES2";
+ bool driver_found = false;
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextX11);
@@ -4074,11 +4134,13 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
r_error = ERR_CANT_CREATE;
ERR_FAIL_MSG("Could not initialize Vulkan");
}
+ driver_found = true;
}
#endif
// Init context and rendering device
-#if defined(OPENGL_ENABLED)
- if (rendering_driver == "opengl_es") {
+#if defined(GLES_X11_ENABLED)
+ print_line("rendering_driver " + rendering_driver);
+ if (rendering_driver == "GLES2") {
if (getenv("DRI_PRIME") == nullptr) {
int use_prime = -1;
@@ -4120,28 +4182,37 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
}
- ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
+ GLManager_X11::ContextType opengl_api_type = GLManager_X11::GLES_2_0_COMPATIBLE;
- context_gles2 = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
+ gl_manager = memnew(GLManager_X11(p_resolution, opengl_api_type));
- if (context_gles2->initialize() != OK) {
- memdelete(context_gles2);
- context_gles2 = nullptr;
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ if (gl_manager->initialize() != OK) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ return;
}
+ driver_found = true;
- context_gles2->set_use_vsync(current_videomode.use_vsync);
+ // gl_manager->set_use_vsync(current_videomode.use_vsync);
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
+ if (true) {
+ // if (RasterizerGLES2::is_viable() == OK) {
+ // RasterizerGLES2::register_config();
RasterizerGLES2::make_current();
} else {
- memdelete(context_gles2);
- context_gles2 = nullptr;
- ERR_FAIL_V(ERR_UNAVAILABLE);
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ return;
}
}
#endif
+ if (!driver_found) {
+ r_error = ERR_UNAVAILABLE;
+ ERR_FAIL_MSG("Video driver not found");
+ }
+
Point2i window_position(
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
@@ -4344,6 +4415,11 @@ DisplayServerX11::~DisplayServerX11() {
context_vulkan->window_destroy(E.key);
}
#endif
+#ifdef GLES_X11_ENABLED
+ if (rendering_driver == "GLES2") {
+ gl_manager->window_destroy(E->key());
+ }
+#endif
WindowData &wd = E.value;
if (wd.xic) {
@@ -4368,6 +4444,13 @@ DisplayServerX11::~DisplayServerX11() {
}
#endif
+#ifdef GLES_X11_ENABLED
+ if (gl_manager) {
+ memdelete(gl_manager);
+ gl_manager = nullptr;
+ }
+#endif
+
if (xrandr_handle) {
dlclose(xrandr_handle);
}
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 4575714bf2..bbf0e64fd3 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -31,6 +31,8 @@
#ifndef DISPLAY_SERVER_X11_H
#define DISPLAY_SERVER_X11_H
+#include "drivers/gles_common/rasterizer_platforms.h"
+
#ifdef X11_ENABLED
#include "servers/display_server.h"
@@ -46,8 +48,8 @@
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
-#if defined(OPENGL_ENABLED)
-#include "context_gl_x11.h"
+#if defined(GLES_X11_ENABLED)
+#include "gl_manager_x11.h"
#endif
#if defined(VULKAN_ENABLED)
@@ -99,12 +101,12 @@ class DisplayServerX11 : public DisplayServer {
Atom requested;
int xdnd_version;
-#if defined(OPENGL_ENABLED)
- ContextGL_X11 *context_gles2;
+#if defined(GLES_X11_ENABLED)
+ GLManager_X11 *gl_manager = nullptr;
#endif
#if defined(VULKAN_ENABLED)
- VulkanContextX11 *context_vulkan;
- RenderingDeviceVulkan *rendering_device_vulkan;
+ VulkanContextX11 *context_vulkan = nullptr;
+ RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
#if defined(DBUS_ENABLED)
@@ -337,6 +339,7 @@ public:
virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void gl_window_make_current(DisplayServer::WindowID p_window_id);
virtual void window_set_transient(WindowID p_window, WindowID p_parent) override;
diff --git a/platform/linuxbsd/context_gl_x11.cpp b/platform/linuxbsd/gl_manager_x11.cpp
index 1f92370ab7..e3d12dcb01 100644
--- a/platform/linuxbsd/context_gl_x11.cpp
+++ b/platform/linuxbsd/gl_manager_x11.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* context_gl_x11.cpp */
+/* gl_manager_x11.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,10 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "context_gl_x11.h"
+#include "gl_manager_x11.h"
#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED)
+#if defined(GLES_X11_ENABLED)
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -45,20 +46,17 @@
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
-struct ContextGL_X11_Private {
+struct GLManager_X11_Private {
::GLXContext glx_context;
};
-void ContextGL_X11::release_current() {
- glXMakeCurrent(x11_display, None, nullptr);
-}
-
-void ContextGL_X11::make_current() {
- glXMakeCurrent(x11_display, x11_window, p->glx_context);
-}
-
-void ContextGL_X11::swap_buffers() {
- glXSwapBuffers(x11_display, x11_window);
+GLManager_X11::GLDisplay::~GLDisplay() {
+ if (context) {
+ //release_current();
+ glXDestroyContext(x11_display, context->glx_context);
+ memdelete(context);
+ context = nullptr;
+ }
}
static bool ctxErrorOccurred = false;
@@ -67,20 +65,35 @@ static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
return 0;
}
-static void set_class_hint(Display *p_display, Window p_window) {
- XClassHint *classHint;
-
- /* set the name and class hints for the window manager to use */
- classHint = XAllocClassHint();
- if (classHint) {
- classHint->res_name = (char *)"Godot_Engine";
- classHint->res_class = (char *)"Godot";
+int GLManager_X11::_find_or_create_display(Display *p_x11_display) {
+ for (unsigned int n = 0; n < _displays.size(); n++) {
+ const GLDisplay &d = _displays[n];
+ if (d.x11_display == p_x11_display)
+ return n;
}
- XSetClassHint(p_display, p_window, classHint);
- XFree(classHint);
+
+ // create
+ GLDisplay d_temp;
+ d_temp.x11_display = p_x11_display;
+ _displays.push_back(d_temp);
+ int new_display_id = _displays.size() - 1;
+
+ // create context
+ GLDisplay &d = _displays[new_display_id];
+
+ d.context = memnew(GLManager_X11_Private);
+ ;
+ d.context->glx_context = 0;
+
+ //Error err = _create_context(d);
+ _create_context(d);
+ return new_display_id;
}
-Error ContextGL_X11::initialize() {
+Error GLManager_X11::_create_context(GLDisplay &gl_display) {
+ // some aliases
+ ::Display *x11_display = gl_display.x11_display;
+
//const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB");
@@ -114,10 +127,9 @@ Error ContextGL_X11::initialize() {
GLXFBConfig fbconfig = 0;
XVisualInfo *vi = nullptr;
- XSetWindowAttributes swa;
- swa.event_mask = StructureNotifyMask;
- swa.border_pixel = 0;
- unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
+ gl_display.x_swa.event_mask = StructureNotifyMask;
+ gl_display.x_swa.border_pixel = 0;
+ gl_display.x_valuemask = CWBorderPixel | CWColormap | CWEventMask;
if (OS::get_singleton()->is_layered_allowed()) {
GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs_layered, &fbcount);
@@ -141,12 +153,13 @@ Error ContextGL_X11::initialize() {
}
}
XFree(fbc);
+
ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED);
- swa.background_pixmap = None;
- swa.background_pixel = 0;
- swa.border_pixmap = None;
- valuemask |= CWBackPixel;
+ gl_display.x_swa.background_pixmap = None;
+ gl_display.x_swa.background_pixel = 0;
+ gl_display.x_swa.border_pixmap = None;
+ gl_display.x_valuemask |= CWBackPixel;
} else {
GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount);
@@ -162,52 +175,167 @@ Error ContextGL_X11::initialize() {
switch (context_type) {
case GLES_2_0_COMPATIBLE: {
- p->glx_context = glXCreateNewContext(x11_display, fbconfig, GLX_RGBA_TYPE, 0, true);
- ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED);
+ gl_display.context->glx_context = glXCreateNewContext(gl_display.x11_display, fbconfig, GLX_RGBA_TYPE, 0, true);
+ ERR_FAIL_COND_V(!gl_display.context->glx_context, ERR_UNCONFIGURED);
} break;
}
- swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
- x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa);
- XStoreName(x11_display, x11_window, "Godot Engine");
-
- ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED);
- set_class_hint(x11_display, x11_window);
- XMapWindow(x11_display, x11_window);
+ gl_display.x_swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone);
XSync(x11_display, False);
XSetErrorHandler(oldHandler);
- glXMakeCurrent(x11_display, x11_window, p->glx_context);
+ // make our own copy of the vi data
+ // for later creating windows using this display
+ if (vi) {
+ gl_display.x_vi = *vi;
+ }
XFree(vi);
return OK;
}
-int ContextGL_X11::get_window_width() {
- XWindowAttributes xwa;
- XGetWindowAttributes(x11_display, x11_window, &xwa);
+Error GLManager_X11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) {
+ print_line("window_create window id " + itos(p_window_id));
+
+ // make sure vector is big enough...
+ // we can mirror the external vector, it is simpler
+ // to keep the IDs identical for fast lookup
+ if (p_window_id >= (int)_windows.size()) {
+ _windows.resize(p_window_id + 1);
+ }
+
+ GLWindow &win = _windows[p_window_id];
+ win.in_use = true;
+ win.window_id = p_window_id;
+ win.width = p_width;
+ win.height = p_height;
+ win.x11_window = p_window;
+ win.gldisplay_id = _find_or_create_display(p_display);
+
+ // the display could be invalid .. check NYI
+ GLDisplay &gl_display = _displays[win.gldisplay_id];
+ //const XVisualInfo &vi = gl_display.x_vi;
+ //XSetWindowAttributes &swa = gl_display.x_swa;
+ ::Display *x11_display = gl_display.x11_display;
+ ::Window &x11_window = win.x11_window;
+
+ if (!glXMakeCurrent(x11_display, x11_window, gl_display.context->glx_context)) {
+ ERR_PRINT("glXMakeCurrent failed");
+ }
+
+ _internal_set_current_window(&win);
+
+ return OK;
+}
+
+void GLManager_X11::_internal_set_current_window(GLWindow *p_win) {
+ _current_window = p_win;
+
+ // quick access to x info
+ _x_windisp.x11_window = _current_window->x11_window;
+ const GLDisplay &disp = get_current_display();
+ _x_windisp.x11_display = disp.x11_display;
+}
+
+void GLManager_X11::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+ get_window(p_window_id).width = p_width;
+ get_window(p_window_id).height = p_height;
+}
+
+void GLManager_X11::window_destroy(DisplayServer::WindowID p_window_id) {
+ GLWindow &win = get_window(p_window_id);
+ win.in_use = false;
+
+ if (_current_window == &win) {
+ _current_window = nullptr;
+ _x_windisp.x11_display = nullptr;
+ _x_windisp.x11_window = -1;
+ }
+}
+
+void GLManager_X11::release_current() {
+ if (!_current_window)
+ return;
+ glXMakeCurrent(_x_windisp.x11_display, None, nullptr);
+}
+
+void GLManager_X11::window_make_current(DisplayServer::WindowID p_window_id) {
+ if (p_window_id == -1)
+ return;
+
+ GLWindow &win = _windows[p_window_id];
+ if (!win.in_use)
+ return;
+
+ // noop
+ if (&win == _current_window)
+ return;
+
+ const GLDisplay &disp = get_display(win.gldisplay_id);
+
+ glXMakeCurrent(disp.x11_display, win.x11_window, disp.context->glx_context);
- return xwa.width;
+ _internal_set_current_window(&win);
}
-int ContextGL_X11::get_window_height() {
- XWindowAttributes xwa;
- XGetWindowAttributes(x11_display, x11_window, &xwa);
+void GLManager_X11::make_current() {
+ if (!_current_window)
+ return;
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+ const GLDisplay &disp = get_current_display();
+ glXMakeCurrent(_x_windisp.x11_display, _x_windisp.x11_window, disp.context->glx_context);
+}
- return xwa.height;
+void GLManager_X11::swap_buffers() {
+ // NO NEED TO CALL SWAP BUFFERS for each window...
+ // see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml
+
+ if (!_current_window)
+ return;
+ if (!_current_window->in_use) {
+ WARN_PRINT("current window not in use!");
+ return;
+ }
+
+ // print_line("\tswap_buffers");
+
+ // only for debugging without drawing anything
+ // glClearColor(Math::randf(), 0, 1, 1);
+ //glClear(GL_COLOR_BUFFER_BIT);
+
+ //const GLDisplay &disp = get_current_display();
+ glXSwapBuffers(_x_windisp.x11_display, _x_windisp.x11_window);
}
-void ContextGL_X11::set_use_vsync(bool p_use) {
+Error GLManager_X11::initialize() {
+ return OK;
+}
+
+void GLManager_X11::set_use_vsync(bool p_use) {
static bool setup = false;
static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr;
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalMESA = nullptr;
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr;
+ // force vsync in the editor for now, as a safety measure
+ bool is_editor = Engine::get_singleton()->is_editor_hint();
+ if (is_editor) {
+ p_use = true;
+ }
+
+ // we need an active window to get a display to set the vsync
+ if (!_current_window)
+ return;
+ const GLDisplay &disp = get_current_display();
+
if (!setup) {
setup = true;
- String extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
+ String extensions = glXQueryExtensionsString(disp.x11_display, DefaultScreen(disp.x11_display));
if (extensions.find("GLX_EXT_swap_control") != -1)
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalEXT");
if (extensions.find("GLX_MESA_swap_control") != -1)
@@ -222,35 +350,28 @@ void ContextGL_X11::set_use_vsync(bool p_use) {
glXSwapIntervalSGI(val);
} else if (glXSwapIntervalEXT) {
GLXDrawable drawable = glXGetCurrentDrawable();
- glXSwapIntervalEXT(x11_display, drawable, val);
+ glXSwapIntervalEXT(disp.x11_display, drawable, val);
} else
return;
use_vsync = p_use;
}
-bool ContextGL_X11::is_using_vsync() const {
+bool GLManager_X11::is_using_vsync() const {
return use_vsync;
}
-ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type) :
- x11_window(p_x11_window) {
- default_video_mode = p_default_video_mode;
- x11_display = p_x11_display;
-
+GLManager_X11::GLManager_X11(const Vector2i &p_size, ContextType p_context_type) {
context_type = p_context_type;
double_buffer = false;
direct_render = false;
glx_minor = glx_major = 0;
- p = memnew(ContextGL_X11_Private);
- p->glx_context = 0;
use_vsync = false;
+ _current_window = nullptr;
}
-ContextGL_X11::~ContextGL_X11() {
+GLManager_X11::~GLManager_X11() {
release_current();
- glXDestroyContext(x11_display, p->glx_context);
- memdelete(p);
}
#endif
diff --git a/platform/linuxbsd/context_gl_x11.h b/platform/linuxbsd/gl_manager_x11.h
index d089886f4d..6781312074 100644
--- a/platform/linuxbsd/context_gl_x11.h
+++ b/platform/linuxbsd/gl_manager_x11.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* context_gl_x11.h */
+/* gl_manager_x11.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,53 +28,100 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CONTEXT_GL_X11_H
-#define CONTEXT_GL_X11_H
+#pragma once
#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED)
+#include "drivers/gles_common/rasterizer_platforms.h"
+
+#if defined(GLES_X11_ENABLED)
#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "servers/display_server.h"
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
-struct ContextGL_X11_Private;
+struct GLManager_X11_Private;
-class ContextGL_X11 {
+class GLManager_X11 {
public:
enum ContextType {
GLES_2_0_COMPATIBLE,
};
private:
- ContextGL_X11_Private *p;
- OS::VideoMode default_video_mode;
- ::Display *x11_display;
- ::Window &x11_window;
+ // any data specific to the window
+ struct GLWindow {
+ GLWindow() { in_use = false; }
+ bool in_use;
+
+ // the external ID .. should match the GL window number .. unused I think
+ DisplayServer::WindowID window_id;
+ int width;
+ int height;
+ ::Window x11_window;
+ int gldisplay_id;
+ };
+
+ struct GLDisplay {
+ GLDisplay() { context = nullptr; }
+ ~GLDisplay();
+ GLManager_X11_Private *context;
+ ::Display *x11_display;
+ XVisualInfo x_vi;
+ XSetWindowAttributes x_swa;
+ unsigned long x_valuemask;
+ };
+
+ // just for convenience, window and display struct
+ struct XWinDisp {
+ ::Window x11_window;
+ ::Display *x11_display;
+ } _x_windisp;
+
+ LocalVector<GLWindow> _windows;
+ LocalVector<GLDisplay> _displays;
+
+ GLWindow *_current_window;
+
+ void _internal_set_current_window(GLWindow *p_win);
+
+ GLWindow &get_window(unsigned int id) { return _windows[id]; }
+ const GLWindow &get_window(unsigned int id) const { return _windows[id]; }
+
+ const GLDisplay &get_current_display() const { return _displays[_current_window->gldisplay_id]; }
+ const GLDisplay &get_display(unsigned int id) { return _displays[id]; }
+
bool double_buffer;
bool direct_render;
int glx_minor, glx_major;
bool use_vsync;
ContextType context_type;
+private:
+ int _find_or_create_display(Display *p_x11_display);
+ Error _create_context(GLDisplay &gl_display);
+
public:
+ Error window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height);
+ void window_destroy(DisplayServer::WindowID p_window_id);
+ void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
+
void release_current();
void make_current();
void swap_buffers();
- int get_window_width();
- int get_window_height();
+
+ void window_make_current(DisplayServer::WindowID p_window_id);
Error initialize();
void set_use_vsync(bool p_use);
bool is_using_vsync() const;
- ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type);
- ~ContextGL_X11();
+ GLManager_X11(const Vector2i &p_size, ContextType p_context_type);
+ ~GLManager_X11();
};
-#endif
-
-#endif
-#endif
+#endif // GLES_X11_ENABLED
+#endif // X11_ENABLED
diff --git a/platform/linuxbsd/platform_config.h b/platform/linuxbsd/platform_config.h
index 3195d08935..cdf989fee7 100644
--- a/platform/linuxbsd/platform_config.h
+++ b/platform/linuxbsd/platform_config.h
@@ -43,3 +43,6 @@
#define PTHREAD_BSD_SET_NAME
#endif
#endif
+
+#define GLES3_INCLUDE_H "thirdparty/glad/glad/glad.h"
+#define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h"