Преглед изворни кода

[X11] Add fallback from desktop GL to GLES, suppress PRIME detector error spam.

bruvzg пре 1 година
родитељ
комит
f3d4f5a77e

+ 1 - 1
core/string/string_name.cpp

@@ -122,7 +122,7 @@ void StringName::unref() {
 	if (_data && _data->refcount.unref()) {
 		MutexLock lock(mutex);
 
-		if (_data->static_count.get() > 0) {
+		if (CoreGlobals::leak_reporting_enabled && _data->static_count.get() > 0) {
 			if (_data->cname) {
 				ERR_PRINT("BUG: Unreferenced static string to 0: " + String(_data->cname));
 			} else {

+ 4 - 0
doc/classes/ProjectSettings.xml

@@ -2393,6 +2393,10 @@
 			If [code]true[/code], the compatibility renderer will fall back to ANGLE if native OpenGL is not supported or the device is listed in [member rendering/gl_compatibility/force_angle_on_devices].
 			[b]Note:[/b] This setting is implemented only on Windows.
 		</member>
+		<member name="rendering/gl_compatibility/fallback_to_gles" type="bool" setter="" getter="" default="true">
+			If [code]true[/code], the compatibility renderer will fall back to OpenGLES if desktop OpenGL is not supported.
+			[b]Note:[/b] This setting is implemented only on Linux/X11.
+		</member>
 		<member name="rendering/gl_compatibility/fallback_to_native" type="bool" setter="" getter="" default="true">
 			If [code]true[/code], the compatibility renderer will fall back to native OpenGL if ANGLE over Metal is not supported.
 			[b]Note:[/b] This setting is implemented only on macOS.

+ 1 - 0
main/main.cpp

@@ -1774,6 +1774,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 		GLOBAL_DEF_RST("rendering/gl_compatibility/nvidia_disable_threaded_optimization", true);
 		GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_angle", true);
 		GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_native", true);
+		GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_gles", true);
 
 		GLOBAL_DEF_RST(PropertyInfo(Variant::ARRAY, "rendering/gl_compatibility/force_angle_on_devices", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::DICTIONARY, PROPERTY_HINT_NONE, String())), Array());
 	}

+ 14 - 0
platform/linuxbsd/x11/detect_prime_x11.cpp

@@ -137,6 +137,19 @@ void create_context() {
 	XFree(vi);
 }
 
+int silent_error_handler(Display *display, XErrorEvent *error) {
+	static char message[1024];
+	XGetErrorText(display, error->error_code, message, sizeof(message));
+	print_verbose(vformat("XServer error: %s"
+						  "\n   Major opcode of failed request: %d"
+						  "\n   Serial number of failed request: %d"
+						  "\n   Current serial number in output stream: %d",
+			String::utf8(message), (uint64_t)error->request_code, (uint64_t)error->minor_code, (uint64_t)error->serial));
+
+	quick_exit(1);
+	return 0;
+}
+
 int detect_prime() {
 	pid_t p;
 	int priorities[2] = {};
@@ -189,6 +202,7 @@ int detect_prime() {
 			// cleaning up these processes, and fork() makes a copy
 			// of all globals.
 			CoreGlobals::leak_reporting_enabled = false;
+			XSetErrorHandler(&silent_error_handler);
 
 			char string[201];
 

+ 16 - 13
platform/linuxbsd/x11/display_server_x11.cpp

@@ -6065,33 +6065,36 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
 		}
 	}
 	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));
-
-		if (gl_manager->initialize(x11_display) != OK) {
+		gl_manager = memnew(GLManager_X11(p_resolution, GLManager_X11::GLES_3_0_COMPATIBLE));
+		if (gl_manager->initialize(x11_display) != OK || gl_manager->open_display(x11_display) != OK) {
 			memdelete(gl_manager);
 			gl_manager = nullptr;
-			r_error = ERR_UNAVAILABLE;
-			return;
+			bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_gles");
+			if (fallback) {
+				WARN_PRINT("Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES.");
+				rendering_driver = "opengl3_es";
+			} else {
+				r_error = ERR_UNAVAILABLE;
+				ERR_FAIL_MSG("Could not initialize OpenGL.");
+			}
+		} else {
+			driver_found = true;
+			RasterizerGLES3::make_current(true);
 		}
-		driver_found = true;
-
-		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;
+			ERR_FAIL_MSG("Could not initialize OpenGLES.");
 		}
 		driver_found = true;
-
 		RasterizerGLES3::make_current(false);
 	}
+
 #endif
 	if (!driver_found) {
 		r_error = ERR_UNAVAILABLE;

+ 9 - 0
platform/linuxbsd/x11/gl_manager_x11.cpp

@@ -208,6 +208,15 @@ XVisualInfo GLManager_X11::get_vi(Display *p_display, Error &r_error) {
 	return _displays[display_id].x_vi;
 }
 
+Error GLManager_X11::open_display(Display *p_display) {
+	int gldisplay_id = _find_or_create_display(p_display);
+	if (gldisplay_id < 0) {
+		return ERR_CANT_CREATE;
+	} else {
+		return OK;
+	}
+}
+
 Error GLManager_X11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) {
 	// make sure vector is big enough...
 	// we can mirror the external vector, it is simpler

+ 1 - 0
platform/linuxbsd/x11/gl_manager_x11.h

@@ -129,6 +129,7 @@ public:
 
 	void *get_glx_context(DisplayServer::WindowID p_window_id);
 
+	Error open_display(Display *p_display);
 	GLManager_X11(const Vector2i &p_size, ContextType p_context_type);
 	~GLManager_X11();
 };

+ 3 - 4
platform/macos/display_server_macos.mm

@@ -4509,8 +4509,8 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
 				WARN_PRINT("Your video card drivers seem not to support the required Metal version, switching to native OpenGL.");
 				rendering_driver = "opengl3";
 			} else {
-				ERR_FAIL_MSG("Could not initialize OpenGL.");
-				return;
+				r_error = ERR_UNAVAILABLE;
+				ERR_FAIL_MSG("Could not initialize ANGLE OpenGL.");
 			}
 		}
 	}
@@ -4521,8 +4521,7 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
 			memdelete(gl_manager_legacy);
 			gl_manager_legacy = nullptr;
 			r_error = ERR_UNAVAILABLE;
-			ERR_FAIL_MSG("Could not initialize OpenGL.");
-			return;
+			ERR_FAIL_MSG("Could not initialize native OpenGL.");
 		}
 	}
 #endif