Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit

Permalink
vm_tools: sommelier: Add quirk to fix viewport destination.
Browse files Browse the repository at this point in the history
Fixes viewport destination to size of the screen for games using randr
emulation. For some games (like Barotrauma), xwayland sends the wrong
viewport destination, causing the game to render in a small box. This
adds a quirk to set the destination to the whole screen.

Not sure if the bug here is in xwayland or the game, but if it is
xwayland it should probably be fixed there at some point. This also
reproduces on other wayland compositors.

BUG=b:336844348
TEST=run barotrauma

Change-Id: Ie1e23c3b5c383a4c99dfbf10b2f4928b610a1253
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/5555696
Commit-Queue: Arjun Srinivasan <[email protected]>
Reviewed-by: Chloe Pelling <[email protected]>
Tested-by: Arjun Srinivasan <[email protected]>
  • Loading branch information
Arjun Srinivasan authored and Chromeos LUCI committed May 24, 2024
1 parent b45672a commit d3e8b8b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
1 change: 1 addition & 0 deletions quirks/quirks.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ enum Feature {
FEATURE_BLACK_SCREEN_FIX = 2;
FEATURE_CONTAINERIZE_WINDOWS = 3;
FEATURE_FORCE_X11_UNMAXIMIZE = 4;
FEATURE_RANDR_EMU_FIX = 5;
}
54 changes: 44 additions & 10 deletions sommelier-window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@ void sl_internal_toplevel_configure_size_containerized(struct sl_window* window,
int safe_window_height =
window->max_height ? window->max_height : window->min_height;
if (window->use_emulated_rects) {
LOG(VERBOSE) << "using emulated rects " << window->emulated_width << "x"
<< window->emulated_height;
// If screen size emulation is set by XWayland, set the window size to the
// emulated size and adjust the viewport size as Exo had requested it to be.
safe_window_width = window->emulated_width;
Expand All @@ -487,6 +489,17 @@ void sl_internal_toplevel_configure_size_containerized(struct sl_window* window,
<< safe_window_height;

if (window->use_emulated_rects && window->compositor_fullscreen) {
// Some games using emulated rects have xwayland send the wrong viewport
// destination, causing the game to render in a small box. This overrides
// that via quirk to set the destination to the size of the screen.
if (sl_window_should_fix_randr_emu(window)) {
window->viewport_override = true;
window->viewport_width = host_width;
window->viewport_height = host_height;
window->viewport_pointer_scale =
static_cast<float>(output->logical_width) / window->viewport_width;
return;
}
// If we are using emulated rects and the window is fullscreen in
// compositor, we only have to report the emulated size (done above). Aspect
// ratio changes are moot (since compositor fullscreen). We don't have to
Expand Down Expand Up @@ -594,16 +607,28 @@ void sl_internal_toplevel_configure_size(struct sl_window* window,
int32_t width_in_pixels,
int32_t height_in_pixels,
int& mut_config_idx) {
// Workaround using viewport for when Exo sets sizes that are not
// within the bounds the client requested.
// TODO(b/316990641): Implement resizing via viewports if
// window->fullscreen==true but window->compositor_fullscreen==false.
// Only do this when --only-client-can-exit-fullscreen is set.
if (window->ctx->viewport_resize &&
((window->max_width != 0 && width_in_pixels > window->max_width) ||
(window->min_width != 0 && width_in_pixels < window->min_width) ||
(window->max_height != 0 && height_in_pixels > window->max_height) ||
(window->min_height != 0 && height_in_pixels < window->min_height))) {
// For games with issues with incorrect viewport destination when using randr
// emulation, this will override the viewport destination with the screen size
// when in fullscreen mode.
if (window->use_emulated_rects && window->compositor_fullscreen &&
sl_window_should_fix_randr_emu(window)) {
window->viewport_override = true;
window->viewport_width = host_width;
window->viewport_height = host_height;
window->viewport_pointer_scale =
static_cast<float>(window->width) / window->viewport_width;
// Workaround using viewport for when Exo sets sizes that are not
// within the bounds the client requested.
// TODO(b/316990641): Implement resizing via viewports if
// window->fullscreen==true but window->compositor_fullscreen==false.
// Only do this when --only-client-can-exit-fullscreen is set.
} else if (window->ctx->viewport_resize &&
((window->max_width != 0 && width_in_pixels > window->max_width) ||
(window->min_width != 0 && width_in_pixels < window->min_width) ||
(window->max_height != 0 &&
height_in_pixels > window->max_height) ||
(window->min_height != 0 &&
height_in_pixels < window->min_height))) {
window->viewport_override = true;
float width_ratio = static_cast<float>(window->width) / width_in_pixels;
float height_ratio = static_cast<float>(window->height) / height_in_pixels;
Expand Down Expand Up @@ -1329,6 +1354,15 @@ bool sl_window_is_client_positioned(struct sl_window* window) {
return window->ctx->enable_x11_move_windows;
}

bool sl_window_should_fix_randr_emu(struct sl_window* window) {
#ifdef QUIRKS_SUPPORT
if (window->ctx->quirks.IsEnabled(window, quirks::FEATURE_RANDR_EMU_FIX)) {
return true;
}
#endif
return false;
}

void sl_window_get_x_y(struct sl_window* window, uint32_t* x, uint32_t* y) {
if (x != nullptr) {
*x = window->x;
Expand Down
4 changes: 4 additions & 0 deletions sommelier-window.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ std::set<int> sl_window_logged_quirks(struct sl_window* window);

bool sl_window_is_client_positioned(struct sl_window* window);

// Set correct viewport destination from xwayland for incorrectly behaving
// games.
bool sl_window_should_fix_randr_emu(struct sl_window* window);

// Get position of the window.
void sl_window_get_x_y(struct sl_window* window, uint32_t* x, uint32_t* y);
// Get size of the window, taking account of emulated status.
Expand Down

0 comments on commit d3e8b8b

Please sign in to comment.