Skip to content

Commit

Permalink
Add next_frame_context_in_async_thread.
Browse files Browse the repository at this point in the history
Only reclaim frame contexts when WSI thread actually goes to sleep.
  • Loading branch information
Themaister committed Oct 29, 2023
1 parent 0e82795 commit 79d8c1b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 1 deletion.
2 changes: 1 addition & 1 deletion video/ffmpeg_decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ void VideoDecoder::Impl::process_video_frame_in_task_upload(DecodedImage &img, A
// we don't leak unbounded memory when the window is minimized on Windows.
// In that scenario the main thread will not pump frame contexts regularly.
if (opts.realtime)
device->next_frame_context();
device->next_frame_context_in_async_thread();
}

void VideoDecoder::Impl::process_video_frame_in_task(unsigned frame, AVFrame *av_frame)
Expand Down
18 changes: 18 additions & 0 deletions vulkan/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2565,6 +2565,24 @@ void Device::promote_read_write_caches_to_read_only()
}
}

bool Device::set_enable_async_thread_frame_context(bool enable)
{
LOCK();
lock.async_frame_context = enable;
}

void Device::next_frame_context_in_async_thread()
{
bool do_next_frame_context;
{
LOCK();
do_next_frame_context = lock.async_frame_context;
}

if (do_next_frame_context)
next_frame_context();
}

void Device::next_frame_context()
{
DRAIN_FRAME_LOCK();
Expand Down
9 changes: 9 additions & 0 deletions vulkan/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@ class Device

// Frame-pushing interface.
void next_frame_context();

// Normally, the main thread ensures forward progress of the frame context
// so that async tasks don't have to care about it,
// but in the case where async threads are continuously pumping Vulkan work
// in the background, they need to reclaim memory if WSI goes to sleep for a long period of time.
void next_frame_context_in_async_thread();
bool set_enable_async_thread_frame_context(bool enable);

void wait_idle();
void end_frame_context();

Expand Down Expand Up @@ -587,6 +595,7 @@ class Device
std::condition_variable cond;
Util::RWSpinLock read_only_cache;
unsigned counter = 0;
bool async_frame_context = false;
} lock;

struct PerFrame
Expand Down
2 changes: 2 additions & 0 deletions vulkan/wsi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,9 @@ bool WSI::blocking_init_swapchain(unsigned width, unsigned height)
else if (err == SwapchainError::NoSurface)
{
LOGW("WSI cannot make forward progress due to minimization, blocking ...\n");
device->set_enable_async_thread_frame_context(true);
platform->block_until_wsi_forward_progress(*this);
device->set_enable_async_thread_frame_context(false);
LOGW("Woke up!\n");
}
} while (err != SwapchainError::None);
Expand Down

0 comments on commit 79d8c1b

Please sign in to comment.