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

Work around for multiple displays with respective scales #245

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 11 additions & 0 deletions app/src/scrcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The computing should be done in screen.c.

Typically, add a set_logical_size() wrapper for this call and this one.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, but I'm stupid, you need it there so that it changes when you moves the window from/to the secondary screen (it still needs be done in screen.c though).

break;
}
break;
Expand Down
10 changes: 10 additions & 0 deletions app/src/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loses precision if the scale is not an integer.

}

// 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;
Expand Down Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions app/src/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scale is not necessary an integer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get any non-integral scale display device for now 😅.
So I will just turn the variables into float, but some tests on such devices are still necessary.

Copy link
Collaborator

@rom1v rom1v Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to use floating point values here (the ratio will lose precision), you can use a "rational" instead (cf here)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean use rational to denote the scale factor?
But we still have to convert it to float when performing the new logical size scale calculation.

Copy link
Collaborator

@rom1v rom1v Sep 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we still have to convert it to float when performing the new logical size scale calculation.

No, we don't: the width and height fit into 16 bits, so using 32 bits, you can get the best possible precision using only integers:
2f6db25#diff-cbb13e05de08766971505804dff53448R139


#endif