Browse Source

Merge pull request #65727 from clayjohn/GLES3-multiwindow

Fix multiwindow support in GLES3 for X11, Windows, and MacOS.
Rémi Verschelde 2 years ago
parent
commit
0b716fdb31

+ 0 - 8
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);
 	GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target);
 	ERR_FAIL_COND(!rt);
 	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) {
 	if (rt->external.fbo != 0) {
 		glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo);
 		glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo);
 	} else {
 	} 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?
 // 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) {
 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++) {
 	for (int i = 0; i < p_amount; i++) {
 		const BlitToScreen &blit = p_render_targets[i];
 		const BlitToScreen &blit = p_render_targets[i];
 
 

+ 11 - 13
platform/linuxbsd/gl_manager_x11.cpp

@@ -256,7 +256,11 @@ void GLManager_X11::release_current() {
 	if (!_current_window) {
 	if (!_current_window) {
 		return;
 		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) {
 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);
 	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);
 	_internal_set_current_window(&win);
 }
 }
@@ -290,13 +296,12 @@ void GLManager_X11::make_current() {
 		return;
 		return;
 	}
 	}
 	const GLDisplay &disp = get_current_display();
 	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() {
 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) {
 	if (!_current_window) {
 		return;
 		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);
 	glXSwapBuffers(_x_windisp.x11_display, _x_windisp.x11_window);
 }
 }
 
 

+ 2 - 3
platform/macos/gl_manager_macos_legacy.mm

@@ -167,9 +167,8 @@ void GLManager_MacOS::make_current() {
 }
 }
 
 
 void GLManager_MacOS::swap_buffers() {
 void GLManager_MacOS::swap_buffers() {
-	for (const KeyValue<DisplayServer::WindowID, GLWindow> &E : windows) {
-		[E.value.context flushBuffer];
-	}
+	GLWindow &win = windows[current_window];
+	[win.context flushBuffer];
 }
 }
 
 
 void GLManager_MacOS::window_update(DisplayServer::WindowID p_window_id) {
 void GLManager_MacOS::window_update(DisplayServer::WindowID p_window_id) {

+ 1 - 6
platform/windows/gl_manager_windows.cpp

@@ -289,12 +289,7 @@ void GLManager_Windows::make_current() {
 }
 }
 
 
 void GLManager_Windows::swap_buffers() {
 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<DisplayServer::WindowID, GLWindow> &entry : _windows) {
-		SwapBuffers(entry.value.hDC);
-	}
+	SwapBuffers(_current_window->hDC);
 }
 }
 
 
 Error GLManager_Windows::initialize() {
 Error GLManager_Windows::initialize() {

+ 8 - 1
servers/rendering/renderer_viewport.cpp

@@ -714,7 +714,14 @@ void RendererViewport::draw_viewports() {
 					blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
 					blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
 				}
 				}
 
 
-				blit_to_screen_list[vp->viewport_to_screen].push_back(blit);
+				if (OS::get_singleton()->get_current_rendering_driver_name() == "opengl3") {
+					Vector<BlitToScreen> 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);
+				}
 			}
 			}
 		}
 		}
 
 

+ 4 - 1
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::viewport->draw_viewports();
 	RSG::canvas_render->update();
 	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();
 	XRServer *xr_server = XRServer::get_singleton();
 	if (xr_server != nullptr) {
 	if (xr_server != nullptr) {