Compare commits

...

4 Commits

Author SHA1 Message Date
Romain Vimont
97ee02ada6 Add compilation flag for HIDPI workaround
The HIDPI workaround is enabled by default. Expose a flag to be able to
disable it.
2019-11-06 21:24:36 +01:00
Louis Kruger
42780d0b0e Reset renderer on hidpi scaling change
Moving a window between hidpi and non-hidpi monitors is not correctly
handled by SDL.

Detect when this happens, and recreate the renderer.

Fixes <https://github.com/Genymobile/scrcpy/issues/15>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-11-06 21:24:36 +01:00
Romain Vimont
492668edd0 Remove HIDPI compilation flag
The flag had been added to avoid hidpi bugs.

A workaround will be implemented for these bugs, so the flag is not
needed anymore.
2019-11-06 21:24:36 +01:00
Romain Vimont
2f7586ad7f Handle window resizing in screen
Only the screen knows what to do when the window is resized.

This paves the way to do other actions on window resizing.
2019-11-06 21:24:36 +01:00
5 changed files with 100 additions and 27 deletions

View File

@ -109,15 +109,15 @@ conf.set('DEFAULT_MAX_SIZE', '0') # 0: unlimited
# overridden by option --bit-rate
conf.set('DEFAULT_BIT_RATE', '8000000') # 8Mbps
# enable High DPI support
conf.set('HIDPI_SUPPORT', get_option('hidpi_support'))
# disable console on Windows
conf.set('WINDOWS_NOCONSOLE', get_option('windows_noconsole'))
# run a server debugger and wait for a client to be attached
conf.set('SERVER_DEBUGGER', get_option('server_debugger'))
# enable a workaround for bug #15
conf.set('HIDPI_WORKAROUND', get_option('hidpi_workaround'))
configure_file(configuration: conf, output: 'config.h')
src_dir = include_directories('src')

View File

@ -145,9 +145,11 @@ handle_event(SDL_Event *event, bool control) {
case SDL_WINDOWEVENT:
switch (event->window.event) {
case SDL_WINDOWEVENT_EXPOSED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
screen_render(&screen);
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
screen_window_resized(&screen);
break;
}
break;
case SDL_TEXTINPUT:

View File

@ -134,16 +134,57 @@ create_texture(SDL_Renderer *renderer, struct size frame_size) {
frame_size.width, frame_size.height);
}
#ifdef HIDPI_WORKAROUND
static void
screen_get_sizes(struct screen *screen, struct screen_sizes *out) {
int ww, wh, dw, dh;
SDL_GetWindowSize(screen->window, &ww, &wh);
SDL_GL_GetDrawableSize(screen->window, &dw, &dh);
out->window.width = ww;
out->window.height = wh;
out->window.width = dw;
out->window.height = dh;
}
#endif
// This may be called more than once to work around SDL bugs
static bool
screen_init_renderer_and_texture(struct screen *screen) {
screen->renderer = SDL_CreateRenderer(screen->window, -1,
SDL_RENDERER_ACCELERATED);
if (!screen->renderer) {
LOGC("Could not create renderer: %s", SDL_GetError());
return false;
}
if (SDL_RenderSetLogicalSize(screen->renderer, screen->frame_size.width,
screen->frame_size.height)) {
LOGE("Could not set renderer logical size: %s", SDL_GetError());
return false;
}
screen->texture = create_texture(screen->renderer, screen->frame_size);
if (!screen->texture) {
LOGC("Could not create texture: %s", SDL_GetError());
return false;
}
#ifdef HIDPI_WORKAROUND
screen_get_sizes(screen, &screen->sizes);
#endif
return true;
}
bool
screen_init_rendering(struct screen *screen, const char *window_title,
struct size frame_size, bool always_on_top) {
screen->frame_size = frame_size;
struct size window_size = get_initial_optimal_size(frame_size);
uint32_t window_flags = SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
#ifdef HIDPI_SUPPORT
window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
#endif
uint32_t window_flags = SDL_WINDOW_HIDDEN
| SDL_WINDOW_RESIZABLE
| SDL_WINDOW_ALLOW_HIGHDPI;
if (always_on_top) {
#ifdef SCRCPY_SDL_HAS_WINDOW_ALWAYS_ON_TOP
window_flags |= SDL_WINDOW_ALWAYS_ON_TOP;
@ -162,21 +203,6 @@ screen_init_rendering(struct screen *screen, const char *window_title,
return false;
}
screen->renderer = SDL_CreateRenderer(screen->window, -1,
SDL_RENDERER_ACCELERATED);
if (!screen->renderer) {
LOGC("Could not create renderer: %s", SDL_GetError());
screen_destroy(screen);
return false;
}
if (SDL_RenderSetLogicalSize(screen->renderer, frame_size.width,
frame_size.height)) {
LOGE("Could not set renderer logical size: %s", SDL_GetError());
screen_destroy(screen);
return false;
}
SDL_Surface *icon = read_xpm(icon_xpm);
if (icon) {
SDL_SetWindowIcon(screen->window, icon);
@ -187,9 +213,7 @@ screen_init_rendering(struct screen *screen, const char *window_title,
LOGI("Initial texture: %" PRIu16 "x%" PRIu16, frame_size.width,
frame_size.height);
screen->texture = create_texture(screen->renderer, frame_size);
if (!screen->texture) {
LOGC("Could not create texture: %s", SDL_GetError());
if (!screen_init_renderer_and_texture(screen)) {
screen_destroy(screen);
return false;
}
@ -278,6 +302,43 @@ screen_update_frame(struct screen *screen, struct video_buffer *vb) {
return true;
}
#ifdef HIDPI_WORKAROUND
// workaround for <https://github.com/Genymobile/scrcpy/issues/15>
static inline bool
screen_fix_hidpi(struct screen *screen) {
struct screen_sizes cur;
screen_get_sizes(screen, &cur);
struct screen_sizes *prev = &screen->sizes;
bool width_ratio_changed = cur.window.width * prev->drawable.width !=
cur.drawable.width * prev->window.width;
bool height_ratio_changed = cur.window.height * prev->drawable.height !=
cur.drawable.height * prev->window.height;
if (width_ratio_changed || height_ratio_changed) {
SDL_DestroyTexture(screen->texture);
SDL_DestroyRenderer(screen->renderer);
if (!screen_init_renderer_and_texture(screen)) {
screen->texture = NULL;
screen->renderer = NULL;
return false;
}
LOGI("Renderer reset after hidpi scaling changed");
}
return true;
}
#endif
void
screen_window_resized(struct screen *screen) {
#ifdef HIDPI_WORKAROUND
screen_fix_hidpi(screen);
#endif
screen_render(screen);
}
void
screen_render(struct screen *screen) {
SDL_RenderClear(screen->renderer);

View File

@ -20,6 +20,12 @@ struct screen {
bool has_frame;
bool fullscreen;
bool no_window;
#ifdef HIDPI_WORKAROUND
struct screen_sizes {
struct size window;
struct size drawable;
} sizes;
#endif
};
#define SCREEN_INITIALIZER { \
@ -60,6 +66,10 @@ screen_destroy(struct screen *screen);
bool
screen_update_frame(struct screen *screen, struct video_buffer *vb);
// update content after window resizing
void
screen_window_resized(struct screen *screen);
// render the texture to the renderer
void
screen_render(struct screen *screen);

View File

@ -4,5 +4,5 @@ option('crossbuild_windows', type: 'boolean', value: false, description: 'Build
option('windows_noconsole', type: 'boolean', value: false, description: 'Disable console on Windows (pass -mwindows flag)')
option('prebuilt_server', type: 'string', description: 'Path of the prebuilt server')
option('portable', type: 'boolean', value: false, description: 'Use scrcpy-server from the same directory as the scrcpy executable')
option('hidpi_support', type: 'boolean', value: true, description: 'Enable High DPI support')
option('server_debugger', type: 'boolean', value: false, description: 'Run a server debugger and wait for a client to be attached')
option('hidpi_workaround', type: 'boolean', value: true, description: 'Enable a workaround for bug #15')