From 96b7cb66df340e7f2ab379c7eefd29d74ea9e3a9 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Mon, 12 Sep 2022 14:57:11 -0700 Subject: Fix multiwindow support in GLES3 for X11, Windows, and MacOS. Instead of updating all viewports, then blitting all viewports to the backbuffer, then swapping all buffers, we run through all viewports and render, blit, and swap backbuffer before going to the next viewport. --- drivers/gles3/rasterizer_gles3.cpp | 8 -------- platform/linuxbsd/gl_manager_x11.cpp | 24 +++++++++++------------- platform/macos/gl_manager_macos_legacy.mm | 5 ++--- platform/windows/gl_manager_windows.cpp | 7 +------ servers/rendering/renderer_viewport.cpp | 9 ++++++++- servers/rendering/rendering_server_default.cpp | 5 ++++- 6 files changed, 26 insertions(+), 32 deletions(-) diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index cc96294ca5..3575837794 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -280,11 +280,6 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); ERR_FAIL_COND(!rt); - // TODO: do we need a keep 3d linear option? - - // Make sure we are drawing to the right context. - DisplayServer::get_singleton()->gl_window_make_current(p_screen); - if (rt->external.fbo != 0) { glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo); } else { @@ -298,9 +293,6 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display // is this p_screen useless in a multi window environment? void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { - // All blits are going to the system framebuffer, so just bind once. - glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); - for (int i = 0; i < p_amount; i++) { const BlitToScreen &blit = p_render_targets[i]; diff --git a/platform/linuxbsd/gl_manager_x11.cpp b/platform/linuxbsd/gl_manager_x11.cpp index 04c1df71fb..838be2c042 100644 --- a/platform/linuxbsd/gl_manager_x11.cpp +++ b/platform/linuxbsd/gl_manager_x11.cpp @@ -256,7 +256,11 @@ void GLManager_X11::release_current() { if (!_current_window) { return; } - glXMakeCurrent(_x_windisp.x11_display, None, nullptr); + + if (!glXMakeCurrent(_x_windisp.x11_display, None, nullptr)) { + ERR_PRINT("glXMakeCurrent failed"); + } + _current_window = nullptr; } void GLManager_X11::window_make_current(DisplayServer::WindowID p_window_id) { @@ -276,7 +280,9 @@ void GLManager_X11::window_make_current(DisplayServer::WindowID p_window_id) { const GLDisplay &disp = get_display(win.gldisplay_id); - glXMakeCurrent(disp.x11_display, win.x11_window, disp.context->glx_context); + if (!glXMakeCurrent(disp.x11_display, win.x11_window, disp.context->glx_context)) { + ERR_PRINT("glXMakeCurrent failed"); + } _internal_set_current_window(&win); } @@ -290,13 +296,12 @@ void GLManager_X11::make_current() { return; } const GLDisplay &disp = get_current_display(); - glXMakeCurrent(_x_windisp.x11_display, _x_windisp.x11_window, disp.context->glx_context); + if (!glXMakeCurrent(_x_windisp.x11_display, _x_windisp.x11_window, disp.context->glx_context)) { + ERR_PRINT("glXMakeCurrent failed"); + } } 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; } @@ -315,13 +320,6 @@ void GLManager_X11::swap_buffers() { } } - // 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); } diff --git a/platform/macos/gl_manager_macos_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm index e6bb7aaa85..dec4821b86 100644 --- a/platform/macos/gl_manager_macos_legacy.mm +++ b/platform/macos/gl_manager_macos_legacy.mm @@ -167,9 +167,8 @@ void GLManager_MacOS::make_current() { } void GLManager_MacOS::swap_buffers() { - for (const KeyValue &E : windows) { - [E.value.context flushBuffer]; - } + GLWindow &win = windows[current_window]; + [win.context flushBuffer]; } void GLManager_MacOS::window_update(DisplayServer::WindowID p_window_id) { diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp index d509ff8c51..7689751f1b 100644 --- a/platform/windows/gl_manager_windows.cpp +++ b/platform/windows/gl_manager_windows.cpp @@ -289,12 +289,7 @@ void GLManager_Windows::make_current() { } void GLManager_Windows::swap_buffers() { - // on other platforms, OpenGL swaps buffers for all windows (on all displays, really?) - // Windows swaps buffers on a per-window basis - // REVISIT: this could be structurally bad, should we have "dirty" flags then? - for (KeyValue &entry : _windows) { - SwapBuffers(entry.value.hDC); - } + SwapBuffers(_current_window->hDC); } Error GLManager_Windows::initialize() { diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index d466f90e79..5771def45f 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -714,7 +714,14 @@ void RendererViewport::draw_viewports() { blit_to_screen_list[vp->viewport_to_screen] = Vector(); } - blit_to_screen_list[vp->viewport_to_screen].push_back(blit); + if (OS::get_singleton()->get_current_rendering_driver_name() == "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); + RSG::rasterizer->end_frame(true); + } else { + blit_to_screen_list[vp->viewport_to_screen].push_back(blit); + } } } diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 1f686069bd..9103b0cf56 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -91,7 +91,10 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { RSG::viewport->draw_viewports(); RSG::canvas_render->update(); - RSG::rasterizer->end_frame(p_swap_buffers); + if (OS::get_singleton()->get_current_rendering_driver_name() != "opengl3") { + // Already called for gl_compatibility renderer. + RSG::rasterizer->end_frame(p_swap_buffers); + } XRServer *xr_server = XRServer::get_singleton(); if (xr_server != nullptr) { -- cgit v1.2.3