diff options
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r-- | platform/linuxbsd/SCsub | 4 | ||||
-rw-r--r-- | platform/linuxbsd/detect.py | 4 | ||||
-rw-r--r-- | platform/linuxbsd/detect_prime_x11.cpp | 2 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 127 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.h | 15 | ||||
-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.h | 3 |
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" |