diff --git a/impeller/renderer/backend/gles/command_buffer_gles.cc b/impeller/renderer/backend/gles/command_buffer_gles.cc index c53c774330399..b360170aaac0d 100644 --- a/impeller/renderer/backend/gles/command_buffer_gles.cc +++ b/impeller/renderer/backend/gles/command_buffer_gles.cc @@ -38,6 +38,11 @@ bool CommandBufferGLES::OnSubmitCommands(CompletionCallback callback) { return result; } +// |CommandBuffer| +void CommandBufferGLES::OnWaitUntilScheduled() { + reactor_->GetProcTable().Flush(); +} + // |CommandBuffer| std::shared_ptr CommandBufferGLES::OnCreateRenderPass( RenderTarget target) { diff --git a/impeller/renderer/backend/gles/command_buffer_gles.h b/impeller/renderer/backend/gles/command_buffer_gles.h index 9aef71fa80842..ec78df92e20c6 100644 --- a/impeller/renderer/backend/gles/command_buffer_gles.h +++ b/impeller/renderer/backend/gles/command_buffer_gles.h @@ -34,6 +34,9 @@ class CommandBufferGLES final : public CommandBuffer { // |CommandBuffer| bool OnSubmitCommands(CompletionCallback callback) override; + // |CommandBuffer| + void OnWaitUntilScheduled() override; + // |CommandBuffer| std::shared_ptr OnCreateRenderPass(RenderTarget target) override; diff --git a/impeller/renderer/backend/gles/proc_table_gles.h b/impeller/renderer/backend/gles/proc_table_gles.h index 6fb00e83c4a5a..5e150c8a3acf0 100644 --- a/impeller/renderer/backend/gles/proc_table_gles.h +++ b/impeller/renderer/backend/gles/proc_table_gles.h @@ -119,6 +119,7 @@ struct GLProc { PROC(DrawElements); \ PROC(Enable); \ PROC(EnableVertexAttribArray); \ + PROC(Flush); \ PROC(FramebufferRenderbuffer); \ PROC(FramebufferTexture2D); \ PROC(FrontFace); \ diff --git a/impeller/renderer/backend/metal/command_buffer_mtl.h b/impeller/renderer/backend/metal/command_buffer_mtl.h index 30dd3f6f5d6a4..f6e4f0eb9cb9d 100644 --- a/impeller/renderer/backend/metal/command_buffer_mtl.h +++ b/impeller/renderer/backend/metal/command_buffer_mtl.h @@ -33,6 +33,9 @@ class CommandBufferMTL final : public CommandBuffer { // |CommandBuffer| bool OnSubmitCommands(CompletionCallback callback) override; + // |CommandBuffer| + void OnWaitUntilScheduled() override; + // |CommandBuffer| std::shared_ptr OnCreateRenderPass(RenderTarget target) override; diff --git a/impeller/renderer/backend/metal/command_buffer_mtl.mm b/impeller/renderer/backend/metal/command_buffer_mtl.mm index 144ce2c330ef1..75540679784a4 100644 --- a/impeller/renderer/backend/metal/command_buffer_mtl.mm +++ b/impeller/renderer/backend/metal/command_buffer_mtl.mm @@ -192,6 +192,8 @@ static bool LogMTLCommandBufferErrorIfPresent(id buffer) { return true; } +void CommandBufferMTL::OnWaitUntilScheduled() {} + std::shared_ptr CommandBufferMTL::OnCreateRenderPass( RenderTarget target) { if (!buffer_) { diff --git a/impeller/renderer/backend/vulkan/command_buffer_vk.cc b/impeller/renderer/backend/vulkan/command_buffer_vk.cc index b024d0be45995..37d6e7886e32b 100644 --- a/impeller/renderer/backend/vulkan/command_buffer_vk.cc +++ b/impeller/renderer/backend/vulkan/command_buffer_vk.cc @@ -55,6 +55,8 @@ bool CommandBufferVK::OnSubmitCommands(CompletionCallback callback) { return submit; } +void CommandBufferVK::OnWaitUntilScheduled() {} + std::shared_ptr CommandBufferVK::OnCreateRenderPass( RenderTarget target) { auto context = context_.lock(); diff --git a/impeller/renderer/backend/vulkan/command_buffer_vk.h b/impeller/renderer/backend/vulkan/command_buffer_vk.h index eb1ff0fa010f5..188cfb1a90ef3 100644 --- a/impeller/renderer/backend/vulkan/command_buffer_vk.h +++ b/impeller/renderer/backend/vulkan/command_buffer_vk.h @@ -41,6 +41,9 @@ class CommandBufferVK final // |CommandBuffer| bool OnSubmitCommands(CompletionCallback callback) override; + // |CommandBuffer| + void OnWaitUntilScheduled() override; + // |CommandBuffer| std::shared_ptr OnCreateRenderPass(RenderTarget target) override; diff --git a/impeller/renderer/command_buffer.cc b/impeller/renderer/command_buffer.cc index c5e9c5920d180..99e6be8ef5cbe 100644 --- a/impeller/renderer/command_buffer.cc +++ b/impeller/renderer/command_buffer.cc @@ -32,6 +32,10 @@ bool CommandBuffer::SubmitCommands() { return SubmitCommands(nullptr); } +void CommandBuffer::WaitUntilScheduled() { + return OnWaitUntilScheduled(); +} + std::shared_ptr CommandBuffer::CreateRenderPass( const RenderTarget& render_target) { auto pass = OnCreateRenderPass(render_target); diff --git a/impeller/renderer/command_buffer.h b/impeller/renderer/command_buffer.h index e043e165c2fd4..71703bb40f41a 100644 --- a/impeller/renderer/command_buffer.h +++ b/impeller/renderer/command_buffer.h @@ -65,6 +65,11 @@ class CommandBuffer { [[nodiscard]] bool SubmitCommands(); + //---------------------------------------------------------------------------- + /// @brief Force execution of pending GPU commands. + /// + void WaitUntilScheduled(); + //---------------------------------------------------------------------------- /// @brief Create a render pass to record render commands into. /// @@ -102,6 +107,8 @@ class CommandBuffer { [[nodiscard]] virtual bool OnSubmitCommands(CompletionCallback callback) = 0; + virtual void OnWaitUntilScheduled() = 0; + virtual std::shared_ptr OnCreateComputePass() const = 0; private: diff --git a/impeller/renderer/testing/mocks.h b/impeller/renderer/testing/mocks.h index 4df48f285410c..e845a2a4b1f18 100644 --- a/impeller/renderer/testing/mocks.h +++ b/impeller/renderer/testing/mocks.h @@ -78,6 +78,7 @@ class MockCommandBuffer : public CommandBuffer { MOCK_CONST_METHOD1(SetLabel, void(const std::string& label)); MOCK_CONST_METHOD0(OnCreateBlitPass, std::shared_ptr()); MOCK_METHOD1(OnSubmitCommands, bool(CompletionCallback callback)); + MOCK_METHOD0(OnWaitUntilScheduled, void()); MOCK_CONST_METHOD0(OnCreateComputePass, std::shared_ptr()); MOCK_METHOD1(OnCreateRenderPass, std::shared_ptr(RenderTarget render_target)); diff --git a/lib/ui/painting/image_decoder_impeller.cc b/lib/ui/painting/image_decoder_impeller.cc index bbb0ab67715d8..dd69129718faf 100644 --- a/lib/ui/painting/image_decoder_impeller.cc +++ b/lib/ui/painting/image_decoder_impeller.cc @@ -362,6 +362,7 @@ sk_sp ImageDecoderImpeller::UploadTextureToShared( FML_DLOG(ERROR) << "Failed to submit blit pass command buffer."; return nullptr; } + command_buffer->WaitUntilScheduled(); } return impeller::DlImageImpeller::Make(std::move(texture));