66
77#include " flutter/fml/trace_event.h"
88#include " impeller/base/validation.h"
9- #include " impeller/renderer/backend/vulkan/barrier_vk.h"
109#include " impeller/renderer/backend/vulkan/command_buffer_vk.h"
11- #include " impeller/renderer/backend/vulkan/fence_waiter_vk.h"
12- #include " impeller/renderer/backend/vulkan/gpu_tracer_vk.h"
1310#include " impeller/renderer/backend/vulkan/swapchain/ahb/ahb_formats.h"
1411#include " impeller/renderer/backend/vulkan/swapchain/surface_vk.h"
1512#include " impeller/toolkit/android/surface_transaction.h"
1613#include " impeller/toolkit/android/surface_transaction_stats.h"
17- #include " vulkan/vulkan_to_string.hpp"
1814
1915namespace impeller {
2016
@@ -96,6 +92,7 @@ std::unique_ptr<Surface> AHBSwapchainImplVK::AcquireNextDrawable() {
9692 }
9793 }
9894
95+ frame_index_ = (frame_index_ + 1 ) % kMaxPendingPresents ;
9996 AutoSemaSignaler auto_sema_signaler =
10097 std::make_shared<fml::ScopedCleanupClosure>(
10198 [sema = pending_presents_]() { sema->Signal (); });
@@ -111,8 +108,8 @@ std::unique_ptr<Surface> AHBSwapchainImplVK::AcquireNextDrawable() {
111108 return nullptr ;
112109 }
113110
114- // Ask the GPU to wait for the render ready semaphore to be signaled before
115- // performing rendering operations .
111+ // Import the render ready semaphore that will block onscreen rendering until
112+ // it is ready .
116113 if (!SubmitWaitForRenderReady (pool_entry.render_ready_fence ,
117114 pool_entry.texture )) {
118115 VALIDATION_LOG << " Could wait on render ready fence." ;
@@ -194,11 +191,7 @@ bool AHBSwapchainImplVK::Present(
194191
195192void AHBSwapchainImplVK::AddFinalCommandBuffer (
196193 std::shared_ptr<CommandBuffer> cmd_buffer) {
197- auto context = transients_->GetContext ().lock ();
198- if (!context) {
199- return ;
200- }
201- context->GetCommandQueue ()->Submit ({std::move (cmd_buffer)});
194+ frame_data_[frame_index_].command_buffer = std::move (cmd_buffer);
202195}
203196
204197std::shared_ptr<ExternalFenceVK>
@@ -213,34 +206,26 @@ AHBSwapchainImplVK::SubmitSignalForPresentReady(
213206 return nullptr ;
214207 }
215208
216- auto command_buffer = context-> CreateCommandBuffer () ;
209+ auto command_buffer = frame_data_[frame_index_]. command_buffer ;
217210 if (!command_buffer) {
218211 return nullptr ;
219212 }
220- command_buffer->SetLabel (" AHBSubmitSignalForPresentReadyCB" );
221213 CommandBufferVK& command_buffer_vk = CommandBufferVK::Cast (*command_buffer);
222-
223214 const auto command_encoder_vk = command_buffer_vk.GetCommandBuffer ();
224-
225- BarrierVK barrier;
226- barrier.cmd_buffer = command_encoder_vk;
227- barrier.new_layout = vk::ImageLayout::eGeneral;
228- barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
229- barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
230- barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
231- barrier.dst_access = {};
232-
233- if (!texture->SetLayout (barrier).ok ()) {
234- return nullptr ;
235- }
236-
237215 command_buffer_vk.Track (fence->GetSharedHandle ());
238216
239217 if (!command_buffer_vk.EndCommandBuffer ()) {
240218 return nullptr ;
241219 }
242220
243221 vk::SubmitInfo submit_info;
222+ vk::PipelineStageFlags wait_stage =
223+ vk::PipelineStageFlagBits::eColorAttachmentOutput;
224+ if (frame_data_[frame_index_].semaphore ) {
225+ submit_info.setPWaitSemaphores (&frame_data_[frame_index_].semaphore .get ());
226+ submit_info.setWaitSemaphoreCount (1 );
227+ submit_info.setWaitDstStageMask (wait_stage);
228+ }
244229 submit_info.setCommandBuffers (command_encoder_vk);
245230
246231 auto result = ContextVK::Cast (*context).GetGraphicsQueue ()->Submit (
@@ -251,7 +236,7 @@ AHBSwapchainImplVK::SubmitSignalForPresentReady(
251236 return fence;
252237}
253238
254- vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence (
239+ vk::UniqueSemaphore AHBSwapchainImplVK::CreateRenderReadySemaphore (
255240 const std::shared_ptr<fml::UniqueFD>& fd) const {
256241 if (!fd->is_valid ()) {
257242 return {};
@@ -265,22 +250,22 @@ vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence(
265250 const auto & context_vk = ContextVK::Cast (*context);
266251 const auto & device = context_vk.GetDevice ();
267252
268- auto signal_wait = device.createFenceUnique ({});
253+ auto signal_wait = device.createSemaphoreUnique ({});
269254
270255 if (signal_wait.result != vk::Result::eSuccess) {
271256 return {};
272257 }
273258
274- context_vk.SetDebugName (*signal_wait.value , " AHBRenderReadyFence " );
259+ context_vk.SetDebugName (*signal_wait.value , " AHBRenderReadySemaphore " );
275260
276- vk::ImportFenceFdInfoKHR import_info;
277- import_info.fence = *signal_wait.value ;
261+ vk::ImportSemaphoreFdInfoKHR import_info;
262+ import_info.semaphore = *signal_wait.value ;
278263 import_info.fd = fd->get ();
279- import_info.handleType = vk::ExternalFenceHandleTypeFlagBits ::eSyncFd;
264+ import_info.handleType = vk::ExternalSemaphoreHandleTypeFlagBits ::eSyncFd;
280265 // From the spec: Sync FDs can only be imported temporarily.
281- import_info.flags = vk::FenceImportFlagBitsKHR ::eTemporary;
266+ import_info.flags = vk::SemaphoreImportFlagBitsKHR ::eTemporary;
282267
283- const auto import_result = device.importFenceFdKHR (import_info);
268+ const auto import_result = device.importSemaphoreFdKHR (import_info);
284269
285270 if (import_result != vk::Result::eSuccess) {
286271 VALIDATION_LOG << " Could not import semaphore FD: "
@@ -299,10 +284,11 @@ vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence(
299284
300285bool AHBSwapchainImplVK::SubmitWaitForRenderReady (
301286 const std::shared_ptr<fml::UniqueFD>& render_ready_fence,
302- const std::shared_ptr<AHBTextureSourceVK>& texture) const {
287+ const std::shared_ptr<AHBTextureSourceVK>& texture) {
303288 // If there is no render ready fence, we are already ready to render into
304289 // the texture. There is nothing more to do.
305290 if (!render_ready_fence || !render_ready_fence->is_valid ()) {
291+ frame_data_[frame_index_].semaphore = {};
306292 return true ;
307293 }
308294
@@ -311,20 +297,13 @@ bool AHBSwapchainImplVK::SubmitWaitForRenderReady(
311297 return false ;
312298 }
313299
314- auto fence = CreateRenderReadyFence (render_ready_fence);
315-
316- auto result = ContextVK::Cast (*context).GetDevice ().waitForFences (
317- *fence, // fence
318- true , // wait all
319- std::numeric_limits<uint64_t >::max () // timeout (ns)
320- );
321-
322- if (!(result == vk::Result::eSuccess || result == vk::Result::eTimeout)) {
323- VALIDATION_LOG << " Encountered error while waiting on swapchain image: "
324- << vk::to_string (result);
300+ auto semaphore = CreateRenderReadySemaphore (render_ready_fence);
301+ if (!semaphore) {
325302 return false ;
326303 }
327-
304+ // This semaphore will be later used to block the onscreen render pass
305+ // from starting until the system is done reading the onscreen.
306+ frame_data_[frame_index_].semaphore = std::move (semaphore);
328307 return true ;
329308}
330309
0 commit comments