diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp index 23b59c9ee..4f2f97cdc 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp @@ -2074,73 +2074,67 @@ void handle_done_commits( void ) void check_new_wayland_res( void ) { - // We need to release buffers without having a commit queue lock, otherwise - // we won't be able to lock wlserver without a deadlock - std::vector release_queue; - + // When importing buffer, we'll potentially need to perform operations with + // a wlserver lock (e.g. wlr_buffer_lock). We can't do this with a + // wayland_commit_queue lock because that causes deadlocks. + std::vector tmp_queue; { std::lock_guard lock( wayland_commit_lock ); + tmp_queue = wayland_commit_queue; + wayland_commit_queue.clear(); + } - for ( uint32_t i = 0; i < wayland_commit_queue.size(); i++ ) - { - struct wlr_buffer *buf = wayland_commit_queue[ i ].buf; + for ( uint32_t i = 0; i < tmp_queue.size(); i++ ) + { + struct wlr_buffer *buf = tmp_queue[ i ].buf; - win *w = find_win( wayland_commit_queue[ i ].surf ); + win *w = find_win( tmp_queue[ i ].surf ); - if ( w == nullptr ) - { - release_queue.push_back( buf ); - fprintf (stderr, "waylandres but no win\n"); - continue; - } + if ( w == nullptr ) + { + wlserver_lock(); + wlr_buffer_unlock( buf ); + wlserver_unlock(); + fprintf (stderr, "waylandres but no win\n"); + continue; + } - struct wlr_dmabuf_attributes dmabuf = {}; - bool result = False; - if ( wlr_buffer_get_dmabuf( buf, &dmabuf ) ) { - result = true; - for ( int i = 0; i < dmabuf.n_planes; i++ ) { - dmabuf.fd[i] = dup( dmabuf.fd[i] ); - assert( dmabuf.fd[i] >= 0 ); - } - } else { - struct wlr_client_buffer *client_buf = (struct wlr_client_buffer *) buf; - result = wlr_texture_to_dmabuf( client_buf->texture, &dmabuf ); + struct wlr_dmabuf_attributes dmabuf = {}; + bool result = False; + if ( wlr_buffer_get_dmabuf( buf, &dmabuf ) ) { + result = true; + for ( int i = 0; i < dmabuf.n_planes; i++ ) { + dmabuf.fd[i] = dup( dmabuf.fd[i] ); + assert( dmabuf.fd[i] >= 0 ); } - assert( result == true ); + } else { + struct wlr_client_buffer *client_buf = (struct wlr_client_buffer *) buf; + result = wlr_texture_to_dmabuf( client_buf->texture, &dmabuf ); + } + assert( result == true ); - commit_t newCommit = {}; - bool bSuccess = import_commit( buf, &dmabuf, newCommit ); - wlr_dmabuf_attributes_finish( &dmabuf ); + commit_t newCommit = {}; + bool bSuccess = import_commit( buf, &dmabuf, newCommit ); + wlr_dmabuf_attributes_finish( &dmabuf ); - if ( bSuccess == true ) - { - newCommit.commitID = ++maxCommmitID; - w->commit_queue.push_back( newCommit ); - } + if ( bSuccess == true ) + { + newCommit.commitID = ++maxCommmitID; + w->commit_queue.push_back( newCommit ); + } - uint32_t fence = vulkan_get_texture_fence( newCommit.vulkanTex ); + uint32_t fence = vulkan_get_texture_fence( newCommit.vulkanTex ); - gpuvis_trace_printf( "pushing wait for commit %lu\n", newCommit.commitID ); - { - std::unique_lock< std::mutex > lock( waitListLock ); - - waitList.push_back( std::make_pair( fence, newCommit.commitID ) ); - } + gpuvis_trace_printf( "pushing wait for commit %lu\n", newCommit.commitID ); + { + std::unique_lock< std::mutex > lock( waitListLock ); - // Wake up commit wait thread if chilling - waitListSem.signal(); + waitList.push_back( std::make_pair( fence, newCommit.commitID ) ); } - wayland_commit_queue.clear(); - } - - wlserver_lock(); - for ( uint32_t i = 0; i < release_queue.size(); i++ ) - { - wlr_buffer_unlock( release_queue[ i ] ); + // Wake up commit wait thread if chilling + waitListSem.signal(); } - wlserver_unlock(); - release_queue.clear(); } int