Fix aspect ratio accuracy

The window aspect ratio was previously enforced by calling
`SDL_SetWindowAspectRatio()` before explicitly setting the window size,
using the width/height ratio of the new size.

However, this size may already be a scaled version of the actual content
size, subject to integer rounding. Using this derived size instead of
the actual content size could result in an inaccurate ratio, causing a
mismatch between the content and window aspect ratios, which may result
in a thin row or column of black pixels.

To avoid this issue, always set the aspect ratio based on the content
size.

Refs 1b4fd67286
Refs #6761 <https://github.com/Genymobile/scrcpy/pull/6761>
PR #6774 <https://github.com/Genymobile/scrcpy/pull/6774>
This commit is contained in:
Romain Vimont 2026-04-17 18:17:57 +02:00
parent 6034110140
commit f4a872bef4

View file

@ -15,18 +15,16 @@
#define DOWNCAST(SINK) container_of(SINK, struct sc_screen, frame_sink)
static void
set_window_size_ar(struct sc_screen *screen, struct sc_size window_size) {
assert(window_size.width && window_size.height);
set_aspect_ratio(struct sc_screen *screen, struct sc_size content_size) {
assert(content_size.width && content_size.height);
if (screen->window_aspect_ratio_lock) {
float ar = (float) window_size.width / window_size.height;
float ar = (float) content_size.width / content_size.height;
bool ok = SDL_SetWindowAspectRatio(screen->window, ar, ar);
if (!ok) {
LOGW("Could not set window aspect ratio: %s", SDL_GetError());
}
}
sc_sdl_set_window_size(screen->window, window_size);
}
static inline struct sc_size
@ -625,7 +623,8 @@ sc_screen_show_initial_window(struct sc_screen *screen) {
screen->req.height);
assert(is_windowed(screen));
set_window_size_ar(screen, window_size);
set_aspect_ratio(screen, screen->content_size);
sc_sdl_set_window_size(screen->window, window_size);
sc_sdl_set_window_position(screen->window, position);
if (screen->req.fullscreen) {
@ -711,7 +710,8 @@ resize_for_content(struct sc_screen *screen, struct sc_size old_content_size,
};
target_size = get_optimal_size(target_size, new_content_size, true);
assert(is_windowed(screen));
set_window_size_ar(screen, target_size);
set_aspect_ratio(screen, new_content_size);
sc_sdl_set_window_size(screen->window, target_size);
}
static void
@ -887,7 +887,8 @@ sc_screen_resize_to_fit(struct sc_screen *screen) {
.y = point.y + (window_size.height - optimal_size.height) / 2,
};
set_window_size_ar(screen, optimal_size);
set_aspect_ratio(screen, screen->content_size);
sc_sdl_set_window_size(screen->window, optimal_size);
sc_sdl_set_window_position(screen->window, new_position);
LOGD("Resized to optimal size: %ux%u", optimal_size.width,
optimal_size.height);
@ -902,7 +903,8 @@ sc_screen_resize_to_pixel_perfect(struct sc_screen *screen) {
}
struct sc_size content_size = screen->content_size;
set_window_size_ar(screen, content_size);
set_aspect_ratio(screen, content_size);
sc_sdl_set_window_size(screen->window, content_size);
LOGD("Resized to pixel-perfect: %ux%u", content_size.width,
content_size.height);
}