Explorar o código

Merge pull request #64710 from MinusKube/window-size-crash

Prevent windows from having a size greater than device limit
Clay John %!s(int64=2) %!d(string=hai) anos
pai
achega
8fd92ed867

+ 4 - 0
doc/classes/RenderingDevice.xml

@@ -1581,6 +1581,10 @@
 		</constant>
 		<constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z" value="34" enum="Limit">
 		</constant>
+		<constant name="LIMIT_MAX_VIEWPORT_DIMENSIONS_X" value="35" enum="Limit">
+		</constant>
+		<constant name="LIMIT_MAX_VIEWPORT_DIMENSIONS_Y" value="36" enum="Limit">
+		</constant>
 		<constant name="MEMORY_TEXTURES" value="0" enum="MemoryType">
 		</constant>
 		<constant name="MEMORY_BUFFERS" value="1" enum="MemoryType">

+ 1 - 0
drivers/gles3/storage/config.cpp

@@ -94,6 +94,7 @@ Config::Config() {
 	glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units);
 	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
 	glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_buffer_size);
+	glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &max_viewport_size);
 
 	glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_offset_alignment);
 

+ 1 - 0
drivers/gles3/storage/config.h

@@ -64,6 +64,7 @@ public:
 	int max_texture_image_units = 0;
 	int max_texture_size = 0;
 	int max_uniform_buffer_size = 0;
+	int max_viewport_size = 0;
 	int max_renderable_elements = 0;
 	int max_renderable_lights = 0;
 	int max_lights_per_object = 0;

+ 9 - 0
drivers/gles3/storage/utilities.cpp

@@ -356,4 +356,13 @@ String Utilities::get_video_adapter_api_version() const {
 	return (const char *)glGetString(GL_VERSION);
 }
 
+Size2i Utilities::get_maximum_viewport_size() const {
+	Config *config = Config::get_singleton();
+	if (!config) {
+		return Size2i();
+	}
+
+	return Size2i(config->max_viewport_size, config->max_viewport_size);
+}
+
 #endif // GLES3_ENABLED

+ 2 - 0
drivers/gles3/storage/utilities.h

@@ -150,6 +150,8 @@ public:
 	virtual String get_video_adapter_vendor() const override;
 	virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
 	virtual String get_video_adapter_api_version() const override;
+
+	virtual Size2i get_maximum_viewport_size() const override;
 };
 
 } // namespace GLES3

+ 4 - 0
drivers/vulkan/rendering_device_vulkan.cpp

@@ -9686,6 +9686,10 @@ uint64_t RenderingDeviceVulkan::limit_get(Limit p_limit) const {
 			return limits.maxComputeWorkGroupSize[1];
 		case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
 			return limits.maxComputeWorkGroupSize[2];
+		case LIMIT_MAX_VIEWPORT_DIMENSIONS_X:
+			return limits.maxViewportDimensions[0];
+		case LIMIT_MAX_VIEWPORT_DIMENSIONS_Y:
+			return limits.maxViewportDimensions[1];
 		case LIMIT_SUBGROUP_SIZE: {
 			VulkanContext::SubgroupCapabilities subgroup_capabilities = context->get_subgroup_capabilities();
 			return subgroup_capabilities.size;

+ 1 - 0
scene/main/viewport.cpp

@@ -1263,6 +1263,7 @@ void Viewport::_gui_show_tooltip() {
 
 	Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset");
 	Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size());
+	r.size = r.size.min(panel->get_max_size());
 
 	Window *window = gui.tooltip_popup->get_parent_visible_window();
 	Rect2i vr = window->get_usable_parent_rect();

+ 17 - 0
scene/main/window.cpp

@@ -587,6 +587,18 @@ bool Window::is_visible() const {
 }
 
 void Window::_update_window_size() {
+	// Force window to respect size limitations of rendering server
+	RenderingServer *rendering_server = RenderingServer::get_singleton();
+	if (rendering_server) {
+		Size2i max_window_size = rendering_server->get_maximum_viewport_size();
+
+		if (max_window_size != Size2i()) {
+			size = size.min(max_window_size);
+			min_size = min_size.min(max_window_size);
+			max_size = max_size.min(max_window_size);
+		}
+	}
+
 	Size2i size_limit;
 	if (wrap_controls) {
 		size_limit = get_contents_minimum_size();
@@ -1828,6 +1840,11 @@ void Window::_bind_methods() {
 }
 
 Window::Window() {
+	RenderingServer *rendering_server = RenderingServer::get_singleton();
+	if (rendering_server) {
+		max_size = rendering_server->get_maximum_viewport_size();
+	}
+
 	theme_owner = memnew(ThemeOwner);
 	RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
 }

+ 2 - 0
servers/rendering/dummy/storage/utilities.h

@@ -109,6 +109,8 @@ public:
 	virtual String get_video_adapter_vendor() const override { return String(); }
 	virtual RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; }
 	virtual String get_video_adapter_api_version() const override { return String(); }
+
+	virtual Size2i get_maximum_viewport_size() const override { return Size2i(); };
 };
 
 } // namespace RendererDummy

+ 8 - 0
servers/rendering/renderer_rd/storage_rd/utilities.cpp

@@ -321,3 +321,11 @@ RenderingDevice::DeviceType Utilities::get_video_adapter_type() const {
 String Utilities::get_video_adapter_api_version() const {
 	return RenderingDevice::get_singleton()->get_device_api_version();
 }
+
+Size2i Utilities::get_maximum_viewport_size() const {
+	RenderingDevice *device = RenderingDevice::get_singleton();
+
+	int max_x = device->limit_get(RenderingDevice::LIMIT_MAX_VIEWPORT_DIMENSIONS_X);
+	int max_y = device->limit_get(RenderingDevice::LIMIT_MAX_VIEWPORT_DIMENSIONS_Y);
+	return Size2i(max_x, max_y);
+}

+ 2 - 0
servers/rendering/renderer_rd/storage_rd/utilities.h

@@ -115,6 +115,8 @@ public:
 	virtual String get_video_adapter_vendor() const override;
 	virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
 	virtual String get_video_adapter_api_version() const override;
+
+	virtual Size2i get_maximum_viewport_size() const override;
 };
 
 } // namespace RendererRD

+ 2 - 0
servers/rendering/rendering_device.cpp

@@ -974,6 +974,8 @@ void RenderingDevice::_bind_methods() {
 	BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X);
 	BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y);
 	BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z);
+	BIND_ENUM_CONSTANT(LIMIT_MAX_VIEWPORT_DIMENSIONS_X);
+	BIND_ENUM_CONSTANT(LIMIT_MAX_VIEWPORT_DIMENSIONS_Y);
 
 	BIND_ENUM_CONSTANT(MEMORY_TEXTURES);
 	BIND_ENUM_CONSTANT(MEMORY_BUFFERS);

+ 2 - 0
servers/rendering/rendering_device.h

@@ -1252,6 +1252,8 @@ public:
 		LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X,
 		LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y,
 		LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z,
+		LIMIT_MAX_VIEWPORT_DIMENSIONS_X,
+		LIMIT_MAX_VIEWPORT_DIMENSIONS_Y,
 		LIMIT_SUBGROUP_SIZE,
 		LIMIT_SUBGROUP_IN_SHADERS, // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
 		LIMIT_SUBGROUP_OPERATIONS,

+ 8 - 0
servers/rendering/rendering_server_default.cpp

@@ -331,6 +331,14 @@ bool RenderingServerDefault::is_low_end() const {
 	return RendererCompositor::is_low_end();
 }
 
+Size2i RenderingServerDefault::get_maximum_viewport_size() const {
+	if (RSG::utilities) {
+		return RSG::utilities->get_maximum_viewport_size();
+	} else {
+		return Size2i();
+	}
+}
+
 void RenderingServerDefault::_thread_exit() {
 	exit.set();
 }

+ 2 - 0
servers/rendering/rendering_server_default.h

@@ -994,6 +994,8 @@ public:
 
 	virtual void set_print_gpu_profile(bool p_enable) override;
 
+	virtual Size2i get_maximum_viewport_size() const override;
+
 	RenderingServerDefault(bool p_create_thread = false);
 	~RenderingServerDefault();
 };

+ 2 - 0
servers/rendering/storage/utilities.h

@@ -181,6 +181,8 @@ public:
 	virtual String get_video_adapter_vendor() const = 0;
 	virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
 	virtual String get_video_adapter_api_version() const = 0;
+
+	virtual Size2i get_maximum_viewport_size() const = 0;
 };
 
 #endif // RENDERER_UTILITIES_H

+ 2 - 0
servers/rendering_server.h

@@ -1575,6 +1575,8 @@ public:
 
 	virtual void set_print_gpu_profile(bool p_enable) = 0;
 
+	virtual Size2i get_maximum_viewport_size() const = 0;
+
 	RenderingDevice *get_rendering_device() const;
 	RenderingDevice *create_local_rendering_device() const;