From 48e10b9daab320f6bb9a75dca93cf1d1512924e8 Mon Sep 17 00:00:00 2001 From: Shaoxing Wang Date: Sun, 26 Aug 2018 19:32:32 +0800 Subject: [PATCH 1/3] Work around for multiple displays with respective scales This should resolve Genymobile/scrcpy#15 --- app/src/scrcpy.c | 11 +++++++++++ app/src/screen.c | 10 ++++++++++ app/src/screen.h | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 23de498447..5bf4289d34 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -84,6 +84,17 @@ static SDL_bool event_loop(void) { case SDL_WINDOWEVENT_EXPOSED: case SDL_WINDOWEVENT_SIZE_CHANGED: screen_render(&screen); + int scale_x, scale_y; + get_window_scale(SDL_GetWindowFromID(event.button.windowID), &scale_x, &scale_y); + if (scale_x != screen.scale_x || scale_y != screen.scale_y) { + int logical_width, logical_height; + SDL_RenderGetLogicalSize(screen.renderer, &logical_width, &logical_height); + logical_width *= (float)scale_x / screen.scale_x; + logical_height *= (float)scale_y / screen.scale_y; + screen.scale_x = scale_x; + screen.scale_y = scale_y; + SDL_RenderSetLogicalSize(screen.renderer, logical_width, logical_height); + } break; } break; diff --git a/app/src/screen.c b/app/src/screen.c index 5b4f0634db..edd5aecfd8 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -65,6 +65,15 @@ static void set_window_size(struct screen *screen, struct size new_size) { } } +void get_window_scale(SDL_Window *window, int *scale_x, int *scale_y) { + int win_w, win_h; + SDL_GetWindowSize(window, &win_w, &win_h); + int output_w, output_h; + SDL_GL_GetDrawableSize(window, &output_w, &output_h); + *scale_x = output_w / win_w; + *scale_y = output_h / win_h; +} + // get the preferred display bounds (i.e. the screen bounds with some margins) static SDL_bool get_preferred_display_bounds(struct size *bounds) { SDL_Rect rect; @@ -168,6 +177,7 @@ SDL_bool screen_init_rendering(struct screen *screen, const char *device_name, s screen_destroy(screen); return SDL_FALSE; } + get_window_scale(screen->window, &screen->scale_x, &screen->scale_y); SDL_Surface *icon = read_xpm(icon_xpm); if (!icon) { diff --git a/app/src/screen.h b/app/src/screen.h index 13103eaa6f..ab2ebbd443 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -12,6 +12,8 @@ struct screen { SDL_Renderer *renderer; SDL_Texture *texture; struct size frame_size; + int scale_x; + int scale_y; //used only in fullscreen mode to know the windowed window size struct size windowed_window_size; SDL_bool has_frame; @@ -66,4 +68,6 @@ void screen_resize_to_fit(struct screen *screen); // resize window to 1:1 (pixel-perfect) void screen_resize_to_pixel_perfect(struct screen *screen); +void get_window_scale(SDL_Window *window, int *scale_x, int *scale_y); + #endif From 8313e60ee2c647a06ffa3ab3cd755df15743ee16 Mon Sep 17 00:00:00 2001 From: Shaoxing Wang Date: Wed, 5 Sep 2018 22:56:33 +0800 Subject: [PATCH 2/3] Extract out logical size update operation into screen.c --- app/src/scrcpy.c | 14 +++----------- app/src/screen.c | 18 ++++++++++++++++++ app/src/screen.h | 2 ++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 5bf4289d34..ec4bc46818 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -83,18 +83,10 @@ static SDL_bool event_loop(void) { switch (event.window.event) { case SDL_WINDOWEVENT_EXPOSED: case SDL_WINDOWEVENT_SIZE_CHANGED: - screen_render(&screen); - int scale_x, scale_y; - get_window_scale(SDL_GetWindowFromID(event.button.windowID), &scale_x, &scale_y); - if (scale_x != screen.scale_x || scale_y != screen.scale_y) { - int logical_width, logical_height; - SDL_RenderGetLogicalSize(screen.renderer, &logical_width, &logical_height); - logical_width *= (float)scale_x / screen.scale_x; - logical_height *= (float)scale_y / screen.scale_y; - screen.scale_x = scale_x; - screen.scale_y = scale_y; - SDL_RenderSetLogicalSize(screen.renderer, logical_width, logical_height); + if (!screen_update_logical_size_if_needed(&screen)) { + return SDL_FALSE; } + screen_render(&screen); break; } break; diff --git a/app/src/screen.c b/app/src/screen.c index edd5aecfd8..af9cc58c8d 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -74,6 +74,24 @@ void get_window_scale(SDL_Window *window, int *scale_x, int *scale_y) { *scale_y = output_h / win_h; } +SDL_bool screen_update_logical_size_if_needed(struct screen *screen) { + int scale_x, scale_y; + get_window_scale(screen->window, &scale_x, &scale_y); + if (scale_x != screen->scale_x || scale_y != screen->scale_y) { + int logical_width, logical_height; + SDL_RenderGetLogicalSize(screen->renderer, &logical_width, &logical_height); + logical_width *= (float)scale_x / screen->scale_x; + logical_height *= (float)scale_y / screen->scale_y; + screen->scale_x = scale_x; + screen->scale_y = scale_y; + if (SDL_RenderSetLogicalSize(screen->renderer, logical_width, logical_height)) { + LOGE("Could not set renderer logical size: %s", SDL_GetError()); + return SDL_FALSE; + } + } + return SDL_TRUE; +} + // get the preferred display bounds (i.e. the screen bounds with some margins) static SDL_bool get_preferred_display_bounds(struct size *bounds) { SDL_Rect rect; diff --git a/app/src/screen.h b/app/src/screen.h index ab2ebbd443..32a854b84f 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -70,4 +70,6 @@ void screen_resize_to_pixel_perfect(struct screen *screen); void get_window_scale(SDL_Window *window, int *scale_x, int *scale_y); +SDL_bool screen_update_logical_size_if_needed(struct screen *screen); + #endif From a5e690d2a062804df22cc6e181102d26d30e1864 Mon Sep 17 00:00:00 2001 From: Shaoxing Wang Date: Wed, 5 Sep 2018 23:26:13 +0800 Subject: [PATCH 3/3] Turn scale factor into float for better precision --- app/src/screen.c | 12 ++++++------ app/src/screen.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/src/screen.c b/app/src/screen.c index af9cc58c8d..9f8cff510e 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -65,23 +65,23 @@ static void set_window_size(struct screen *screen, struct size new_size) { } } -void get_window_scale(SDL_Window *window, int *scale_x, int *scale_y) { +void get_window_scale(SDL_Window *window, float *scale_x, float *scale_y) { int win_w, win_h; SDL_GetWindowSize(window, &win_w, &win_h); int output_w, output_h; SDL_GL_GetDrawableSize(window, &output_w, &output_h); - *scale_x = output_w / win_w; - *scale_y = output_h / win_h; + *scale_x = (float)output_w / win_w; + *scale_y = (float)output_h / win_h; } SDL_bool screen_update_logical_size_if_needed(struct screen *screen) { - int scale_x, scale_y; + float scale_x, scale_y; get_window_scale(screen->window, &scale_x, &scale_y); if (scale_x != screen->scale_x || scale_y != screen->scale_y) { int logical_width, logical_height; SDL_RenderGetLogicalSize(screen->renderer, &logical_width, &logical_height); - logical_width *= (float)scale_x / screen->scale_x; - logical_height *= (float)scale_y / screen->scale_y; + logical_width *= scale_x / screen->scale_x; + logical_height *= scale_y / screen->scale_y; screen->scale_x = scale_x; screen->scale_y = scale_y; if (SDL_RenderSetLogicalSize(screen->renderer, logical_width, logical_height)) { diff --git a/app/src/screen.h b/app/src/screen.h index 32a854b84f..41b96aeebc 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -12,8 +12,8 @@ struct screen { SDL_Renderer *renderer; SDL_Texture *texture; struct size frame_size; - int scale_x; - int scale_y; + float scale_x; + float scale_y; //used only in fullscreen mode to know the windowed window size struct size windowed_window_size; SDL_bool has_frame; @@ -68,7 +68,7 @@ void screen_resize_to_fit(struct screen *screen); // resize window to 1:1 (pixel-perfect) void screen_resize_to_pixel_perfect(struct screen *screen); -void get_window_scale(SDL_Window *window, int *scale_x, int *scale_y); +void get_window_scale(SDL_Window *window, float *scale_x, float *scale_y); SDL_bool screen_update_logical_size_if_needed(struct screen *screen);