Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for commit-queue-v1 #1026

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions protocol/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ protocols = [
# Upstream protocols
wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
wl_protocol_dir / 'stable/presentation-time/presentation-time.xml',
wl_protocol_dir / 'staging/commit-queue/commit-queue-v1.xml',

# Gamescope protocols
'gamescope-xwayland.xml',
Expand Down
2 changes: 1 addition & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ stb_dep = dependency('stb')

wlroots_dep = dependency(
'wlroots',
version: ['>= 0.17.0', '< 0.18.0'],
version: ['>= 0.18.0', '< 0.19.0'],
fallback: ['wlroots', 'wlroots'],
default_options: ['default_library=static', 'examples=false', 'xwayland=enabled', 'backends=libinput', 'renderers=[]', 'allocators=[]', 'session=enabled'],
)
Expand Down
38 changes: 33 additions & 5 deletions src/steamcompmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <string>
#include <queue>
#include <variant>
#include <unordered_set>

#include <assert.h>
#include <stdlib.h>
Expand Down Expand Up @@ -130,6 +131,8 @@ extern float g_flInternalDisplayBrightnessNits;
extern float g_flHDRItmSdrNits;
extern float g_flHDRItmTargetNits;

uint64_t g_lastWinSeq = 0;

extern std::atomic<uint64_t> g_lastVblank;

static std::shared_ptr<wlserver_ctm> s_scRGB709To2020Matrix;
Expand Down Expand Up @@ -753,8 +756,10 @@ struct commit_t : public gamescope::IWaitable
uint64_t commitID = 0;
bool done = false;
bool async = false;
bool fifo = false;
std::optional<wlserver_vk_swapchain_feedback> feedback = std::nullopt;

uint64_t win_seq = 0;
struct wlr_surface *surf = nullptr;
std::vector<struct wl_resource*> presentation_feedbacks;

Expand Down Expand Up @@ -791,7 +796,12 @@ struct commit_t : public gamescope::IWaitable
// When we get the new IWaitable stuff in there.
{
std::unique_lock< std::mutex > lock( pDoneCommits->listCommitsDoneLock );
pDoneCommits->listCommitsDone.push_back( CommitDoneEntry_t{ commitID, desired_present_time } );
pDoneCommits->listCommitsDone.push_back( CommitDoneEntry_t{
.winSeq = win_seq,
.commitID = commitID,
.desiredPresentTime = desired_present_time,
.fifo = fifo,
} );
}

if ( m_bMangoNudge )
Expand Down Expand Up @@ -1364,14 +1374,16 @@ destroy_buffer( struct wl_listener *listener, void * )
}

static std::shared_ptr<commit_t>
import_commit ( struct wlr_surface *surf, struct wlr_buffer *buf, bool async, std::shared_ptr<wlserver_vk_swapchain_feedback> swapchain_feedback, std::vector<struct wl_resource*> presentation_feedbacks, std::optional<uint32_t> present_id, uint64_t desired_present_time )
import_commit ( steamcompmgr_win_t *w, struct wlr_surface *surf, struct wlr_buffer *buf, bool async, std::shared_ptr<wlserver_vk_swapchain_feedback> swapchain_feedback, std::vector<struct wl_resource*> presentation_feedbacks, std::optional<uint32_t> present_id, uint64_t desired_present_time, bool fifo )
{
std::shared_ptr<commit_t> commit = std::make_shared<commit_t>();
std::unique_lock<std::mutex> lock( wlr_buffer_map_lock );

commit->win_seq = w->seq;
commit->surf = surf;
commit->buf = buf;
commit->async = async;
commit->fifo = fifo;
commit->presentation_feedbacks = std::move(presentation_feedbacks);
if (swapchain_feedback)
commit->feedback = *swapchain_feedback;
Expand Down Expand Up @@ -4580,6 +4592,7 @@ add_win(xwayland_ctx_t *ctx, Window id, Window prev, unsigned long sequence)
if (!new_win)
return;

new_win->seq = ++g_lastWinSeq;
new_win->type = steamcompmgr_win_type_t::XWAYLAND;
new_win->_window_types.emplace<steamcompmgr_xwayland_win_t>();

Expand Down Expand Up @@ -6361,7 +6374,7 @@ bool handle_done_commit( steamcompmgr_win_t *w, xwayland_ctx_t *ctx, uint64_t co
}

// TODO: Merge these two functions.
void handle_done_commits_xwayland( xwayland_ctx_t *ctx )
void handle_done_commits_xwayland( xwayland_ctx_t *ctx, bool vblank )
{
std::lock_guard<std::mutex> lock( ctx->doneCommits.listCommitsDoneLock );

Expand All @@ -6370,11 +6383,20 @@ void handle_done_commits_xwayland( xwayland_ctx_t *ctx )
// commits that were not ready to be presented based on their display timing.
std::vector< CommitDoneEntry_t > commits_before_their_time;

// windows in FIFO mode we got a new frame to present for this vblank
std::unordered_set< uint64_t > fifo_win_seqs;

uint64_t now = get_time_in_nanos();

// very fast loop yes
for ( auto& entry : ctx->doneCommits.listCommitsDone )
{
if (entry.fifo && (!vblank || fifo_win_seqs.count(entry.winSeq) > 0))
{
commits_before_their_time.push_back( entry );
continue;
}

if (!entry.earliestPresentTime)
{
entry.earliestPresentTime = next_refresh_time;
Expand All @@ -6389,8 +6411,14 @@ void handle_done_commits_xwayland( xwayland_ctx_t *ctx )

for ( steamcompmgr_win_t *w = ctx->list; w; w = w->xwayland().next )
{
if (w->seq != entry.winSeq)
continue;
if (handle_done_commit(w, ctx, entry.commitID, entry.earliestPresentTime, entry.earliestLatchTime))
{
if (entry.fifo)
fifo_win_seqs.insert(entry.winSeq);
break;
}
}
}

Expand Down Expand Up @@ -6575,7 +6603,7 @@ void update_wayland_res(CommitDoneList_t *doneCommits, steamcompmgr_win_t *w, Re
return;
}

std::shared_ptr<commit_t> newCommit = import_commit( reslistentry.surf, buf, reslistentry.async, std::move(reslistentry.feedback), std::move(reslistentry.presentation_feedbacks), reslistentry.present_id, reslistentry.desired_present_time );
std::shared_ptr<commit_t> newCommit = import_commit( w, reslistentry.surf, buf, reslistentry.async, std::move(reslistentry.feedback), std::move(reslistentry.presentation_feedbacks), reslistentry.present_id, reslistentry.desired_present_time, reslistentry.fifo );

int fence = -1;
if ( newCommit )
Expand Down Expand Up @@ -7918,7 +7946,7 @@ steamcompmgr_main(int argc, char **argv)
gamescope_xwayland_server_t *server = NULL;
for (size_t i = 0; (server = wlserver_get_xwayland_server(i)); i++)
{
handle_done_commits_xwayland(server->ctx.get());
handle_done_commits_xwayland(server->ctx.get(), vblank);

// When we have observed both a complete commit and a VBlank, we should request a new frame.
if (vblank)
Expand Down
1 change: 1 addition & 0 deletions src/steamcompmgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ extern float focusedWindowOffsetY;
extern bool g_bFSRActive;

extern uint32_t inputCounter;
extern uint64_t g_lastWinSeq;

void nudge_steamcompmgr( void );
void take_screenshot( int flags = TAKE_SCREENSHOT_BASEPLANE_ONLY );
Expand Down
2 changes: 2 additions & 0 deletions src/steamcompmgr_shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ struct steamcompmgr_xdg_win_t
struct steamcompmgr_win_t {
unsigned int opacity;

uint64_t seq;

std::shared_ptr<std::string> title;
bool utf8_title;
pid_t pid;
Expand Down
30 changes: 17 additions & 13 deletions src/wlserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern "C" {
#include <wlr/util/log.h>
#include <wlr/xwayland/server.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_commit_queue_v1.h>
#undef static
#undef class
}
Expand All @@ -43,6 +44,7 @@ extern "C" {
#include "gamescope-swapchain-protocol.h"
#include "gamescope-tearing-control-unstable-v1-protocol.h"
#include "presentation-time-protocol.h"
#include "commit-queue-v1-protocol.h"

#include "wlserver.hpp"
#include "drm.hpp"
Expand Down Expand Up @@ -104,10 +106,13 @@ void gamescope_xwayland_server_t::wayland_commit(struct wlr_surface *surf, struc

auto wl_surf = get_wl_surface_info( surf );

auto queue_mode = wlr_commit_queue_v1_get_surface_mode(surf);

ResListEntry_t newEntry = {
.surf = surf,
.buf = buf,
.async = wlserver_surface_is_async(surf),
.fifo = queue_mode == WP_COMMIT_QUEUE_V1_QUEUE_MODE_FIFO,
.feedback = wlserver_surface_swapchain_feedback(surf),
.presentation_feedbacks = std::move(wl_surf->pending_presentation_feedbacks),
.present_id = wl_surf->present_id,
Expand Down Expand Up @@ -1177,7 +1182,8 @@ bool wlsession_init( void ) {
if ( BIsNested() )
return true;

wlserver.wlr.session = wlr_session_create( wlserver.display );
auto loop = wl_display_get_event_loop( wlserver.display );
wlserver.wlr.session = wlr_session_create( loop );
if ( wlserver.wlr.session == nullptr )
{
wl_log.errorf( "Failed to create session" );
Expand Down Expand Up @@ -1265,7 +1271,7 @@ gamescope_xwayland_server_t::gamescope_xwayland_server_t(wl_display *display)

update_output_info();

wlr_output_create_global(output);
wlr_output_create_global(output, wlserver.display);
}

gamescope_xwayland_server_t::~gamescope_xwayland_server_t()
Expand Down Expand Up @@ -1344,15 +1350,10 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
wlserver_surface->xdg_surface = nullptr;
}

void xdg_surface_new(struct wl_listener *listener, void *data)
void xdg_toplevel_new(struct wl_listener *listener, void *data)
{
struct wlr_xdg_surface *xdg_surface = (struct wlr_xdg_surface *)data;

if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
{
wl_log.infof("Not top level surface.");
return;
}
struct wlr_xdg_toplevel *xdg_toplevel = (struct wlr_xdg_toplevel *)data;
struct wlr_xdg_surface *xdg_surface = xdg_toplevel->base;

wlserver_wl_surface_info *wlserver_surface = get_wl_surface_info(xdg_surface->surface);
if (!wlserver_surface)
Expand All @@ -1367,6 +1368,7 @@ void xdg_surface_new(struct wl_listener *listener, void *data)
wlserver.xdg_wins.emplace_back(window);
}

window->seq = ++g_lastWinSeq;
window->type = steamcompmgr_win_type_t::XDG;
window->_window_types.emplace<steamcompmgr_xdg_win_t>();

Expand All @@ -1376,7 +1378,7 @@ void xdg_surface_new(struct wl_listener *listener, void *data)
wlserver_xdg_surface_info* xdg_surface_info = &window->xdg().surface;
xdg_surface_info->main_surface = xdg_surface->surface;
xdg_surface_info->win = window.get();
xdg_surface_info->xdg_toplevel = xdg_surface->toplevel;
xdg_surface_info->xdg_toplevel = xdg_toplevel;

wlserver_surface->xdg_surface = xdg_surface_info;

Expand Down Expand Up @@ -1461,14 +1463,16 @@ bool wlserver_init( void ) {

create_presentation_time();

wlr_commit_queue_manager_v1_create(wlserver.display, 1);

wlserver.xdg_shell = wlr_xdg_shell_create(wlserver.display, 3);
if (!wlserver.xdg_shell)
{
wl_log.infof("Unable to create XDG shell interface");
return false;
}
wlserver.new_xdg_surface.notify = xdg_surface_new;
wl_signal_add(&wlserver.xdg_shell->events.new_surface, &wlserver.new_xdg_surface);
wlserver.new_xdg_toplevel.notify = xdg_toplevel_new;
wl_signal_add(&wlserver.xdg_shell->events.new_toplevel, &wlserver.new_xdg_toplevel);

int result = -1;
int display_slot = 0;
Expand Down
3 changes: 2 additions & 1 deletion src/wlserver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct ResListEntry_t {
struct wlr_surface *surf;
struct wlr_buffer *buf;
bool async;
bool fifo;
std::shared_ptr<wlserver_vk_swapchain_feedback> feedback;
std::vector<struct wl_resource*> presentation_feedbacks;
std::optional<uint32_t> present_id;
Expand Down Expand Up @@ -131,7 +132,7 @@ struct wlserver_t {
struct wl_listener new_input_method;

struct wlr_xdg_shell *xdg_shell;
struct wl_listener new_xdg_surface;
struct wl_listener new_xdg_toplevel;
std::vector<std::shared_ptr<steamcompmgr_win_t>> xdg_wins;
std::atomic<bool> xdg_dirty;
std::mutex xdg_commit_lock;
Expand Down
2 changes: 2 additions & 0 deletions src/xwayland_ctx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ struct focus_t

struct CommitDoneEntry_t
{
uint64_t winSeq;
uint64_t commitID;
uint64_t desiredPresentTime;
uint64_t earliestPresentTime;
uint64_t earliestLatchTime;
bool fifo;
};

struct CommitDoneList_t
Expand Down
Loading