Forráskód Böngészése

Skip swapchain logic if there is nothing to present (Android OpenXR)

Bastiaan Olij 1 éve
szülő
commit
d6caa69e11

+ 3 - 1
drivers/d3d12/d3d12_context.cpp

@@ -889,7 +889,9 @@ void D3D12Context::_wait_for_idle_queue(ID3D12CommandQueue *p_queue) {
 #endif
 }
 
-void D3D12Context::flush(bool p_flush_setup, bool p_flush_pending) {
+void D3D12Context::flush(bool p_flush_setup, bool p_flush_pending, bool p_sync) {
+	ERR_FAIL_COND_MSG(!p_sync, "Flush without sync is not supported."); // This is a special case for Vulkan on mobile XR hardware, not applicable to D3D12
+
 	if (p_flush_setup && command_list_queue[0]) {
 		md.queue->ExecuteCommandLists(1, command_list_queue.ptr());
 		command_list_queue[0] = nullptr;

+ 1 - 1
drivers/d3d12/d3d12_context.h

@@ -234,7 +234,7 @@ public:
 	virtual void set_setup_buffer(RDD::CommandBufferID p_command_buffer) override final;
 	virtual void append_command_buffer(RDD::CommandBufferID p_command_buffer) override final;
 	void resize_notify();
-	virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false) override final;
+	virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false, bool p_sync = true) override final;
 	virtual Error prepare_buffers(RDD::CommandBufferID p_command_buffer) override final;
 	virtual void postpare_buffers(RDD::CommandBufferID p_command_buffer) override final;
 	virtual Error swap_buffers() override final;

+ 6 - 8
drivers/gles3/rasterizer_gles3.cpp

@@ -103,6 +103,11 @@ void RasterizerGLES3::begin_frame(double frame_step) {
 }
 
 void RasterizerGLES3::end_frame(bool p_swap_buffers) {
+	GLES3::Utilities *utils = GLES3::Utilities::get_singleton();
+	utils->capture_timestamps_end();
+}
+
+void RasterizerGLES3::end_viewport(bool p_swap_buffers) {
 	if (p_swap_buffers) {
 		DisplayServer::get_singleton()->swap_buffers();
 	} else {
@@ -352,13 +357,6 @@ RasterizerGLES3::~RasterizerGLES3() {
 }
 
 void RasterizerGLES3::prepare_for_blitting_render_targets() {
-	// This is a hack, but this function is called one time after all viewports have been updated.
-	// So it marks the end of the frame for all viewports
-	// In the OpenGL renderer we have to call end_frame for each viewport so we can swap the
-	// buffers for each window before proceeding to the next.
-	// This allows us to only increment the frame after all viewports are done.
-	GLES3::Utilities *utils = GLES3::Utilities::get_singleton();
-	utils->capture_timestamps_end();
 }
 
 void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect, uint32_t p_layer, bool p_first) {
@@ -474,7 +472,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
 	copy_effects->copy_to_rect(screenrect);
 	glBindTexture(GL_TEXTURE_2D, 0);
 
-	end_frame(true);
+	end_viewport(true);
 
 	texture_storage->texture_free(texture);
 }

+ 1 - 0
drivers/gles3/rasterizer_gles3.h

@@ -93,6 +93,7 @@ public:
 	void prepare_for_blitting_render_targets();
 	void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount);
 
+	void end_viewport(bool p_swap_buffers);
 	void end_frame(bool p_swap_buffers);
 
 	void finalize();

+ 8 - 4
drivers/vulkan/vulkan_context.cpp

@@ -2395,9 +2395,11 @@ void VulkanContext::append_command_buffer(RDD::CommandBufferID p_command_buffer)
 	command_buffer_count++;
 }
 
-void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
+void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending, bool p_sync) {
 	// Ensure everything else pending is executed.
-	vkDeviceWaitIdle(device);
+	if (p_sync) {
+		vkDeviceWaitIdle(device);
+	}
 
 	// Flush the pending setup buffer.
 
@@ -2440,7 +2442,9 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
 		ERR_FAIL_COND(err);
 	}
 
-	vkDeviceWaitIdle(device);
+	if (p_sync) {
+		vkDeviceWaitIdle(device);
+	}
 }
 
 Error VulkanContext::prepare_buffers(RDD::CommandBufferID p_command_buffer) {
@@ -2504,7 +2508,7 @@ Error VulkanContext::swap_buffers() {
 		return OK;
 	}
 
-	//	print_line("swapbuffers?");
+	//print_line("swap_buffers");
 	VkResult err;
 
 #if 0

+ 1 - 1
drivers/vulkan/vulkan_context.h

@@ -321,7 +321,7 @@ public:
 	virtual void set_setup_buffer(RDD::CommandBufferID p_command_buffer) override final;
 	virtual void append_command_buffer(RDD::CommandBufferID p_command_buffer) override final;
 	void resize_notify();
-	virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false) override final;
+	virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false, bool p_sync = true) override final;
 	virtual Error prepare_buffers(RDD::CommandBufferID p_command_buffer) override final;
 	virtual void postpare_buffers(RDD::CommandBufferID p_command_buffer) override final;
 	virtual Error swap_buffers() override final;

+ 2 - 0
servers/rendering/dummy/rasterizer_dummy.h

@@ -89,6 +89,8 @@ public:
 	void prepare_for_blitting_render_targets() override {}
 	void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) override {}
 
+	void end_viewport(bool p_swap_buffers) override {}
+
 	void end_frame(bool p_swap_buffers) override {
 		if (p_swap_buffers) {
 			DisplayServer::get_singleton()->swap_buffers();

+ 1 - 0
servers/rendering/renderer_compositor.h

@@ -99,6 +99,7 @@ public:
 	virtual void prepare_for_blitting_render_targets() = 0;
 	virtual void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) = 0;
 
+	virtual void end_viewport(bool p_swap_buffers) = 0;
 	virtual void end_frame(bool p_swap_buffers) = 0;
 	virtual void finalize() = 0;
 	virtual uint64_t get_frame_number() const = 0;

+ 1 - 1
servers/rendering/renderer_rd/api_context_rd.h

@@ -58,7 +58,7 @@ public:
 
 	virtual void set_setup_buffer(RDD::CommandBufferID p_command_buffer) = 0;
 	virtual void append_command_buffer(RDD::CommandBufferID p_command_buffer) = 0;
-	virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false) = 0;
+	virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false, bool p_sync = true) = 0;
 	virtual Error prepare_buffers(RDD::CommandBufferID p_command_buffer) = 0;
 	virtual void postpare_buffers(RDD::CommandBufferID p_command_buffer) = 0;
 	virtual Error swap_buffers() = 0;

+ 1 - 0
servers/rendering/renderer_rd/renderer_compositor_rd.h

@@ -123,6 +123,7 @@ public:
 	void prepare_for_blitting_render_targets();
 	void blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount);
 
+	void end_viewport(bool p_swap_buffers) {}
 	void end_frame(bool p_swap_buffers);
 	void finalize();
 

+ 4 - 4
servers/rendering/renderer_viewport.cpp

@@ -754,7 +754,6 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
 						if (blits.size() > 0) {
 							RSG::rasterizer->blit_render_targets_to_screen(vp->viewport_to_screen, blits.ptr(), blits.size());
 						}
-						RSG::rasterizer->end_frame(true);
 					} else if (blits.size() > 0) {
 						if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
 							blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
@@ -764,6 +763,7 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
 							blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
 						}
 					}
+					RSG::rasterizer->end_viewport(p_swap_buffers && blits.size() > 0);
 				}
 			}
 		} else {
@@ -793,10 +793,10 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
 					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);
 				}
+				RSG::rasterizer->end_viewport(p_swap_buffers);
 			}
 		}
 
@@ -823,8 +823,8 @@ void RendererViewport::draw_viewports(bool p_swap_buffers) {
 
 	RENDER_TIMESTAMP("< Render Viewports");
 
-	if (p_swap_buffers) {
-		//this needs to be called to make screen swapping more efficient
+	if (p_swap_buffers && !blit_to_screen_list.is_empty()) {
+		// This needs to be called to make screen swapping more efficient.
 		RSG::rasterizer->prepare_for_blitting_render_targets();
 
 		for (const KeyValue<int, Vector<BlitToScreen>> &E : blit_to_screen_list) {

+ 6 - 2
servers/rendering/rendering_device.cpp

@@ -5467,9 +5467,13 @@ void RenderingDevice::swap_buffers() {
 	context->postpare_buffers(frames[frame].draw_command_buffer);
 	_finalize_command_bufers();
 
-	screen_prepared = false;
 	// Swap buffers.
-	context->swap_buffers();
+	if (!screen_prepared) {
+		context->flush(true, true, false);
+	} else {
+		screen_prepared = false;
+		context->swap_buffers();
+	}
 
 	frame = (frame + 1) % frame_count;
 

+ 1 - 4
servers/rendering/rendering_server_default.cpp

@@ -91,10 +91,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
 	RSG::viewport->draw_viewports(p_swap_buffers);
 	RSG::canvas_render->update();
 
-	if (!OS::get_singleton()->get_current_rendering_driver_name().begins_with("opengl3")) {
-		// Already called for gl_compatibility renderer.
-		RSG::rasterizer->end_frame(p_swap_buffers);
-	}
+	RSG::rasterizer->end_frame(p_swap_buffers);
 
 	XRServer *xr_server = XRServer::get_singleton();
 	if (xr_server != nullptr) {