mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-02-14 02:14:27 +01:00
Factorize icon rendering
Replace SDL "logical rendering" with explicit computation of icon location, and unify rendering of video frames and icons using the same common code.
This commit is contained in:
@@ -12,15 +12,6 @@ sc_display_init_novideo_icon(struct sc_display *display,
|
||||
SDL_Surface *icon_novideo) {
|
||||
assert(icon_novideo);
|
||||
|
||||
bool ok = SDL_SetRenderLogicalPresentation(display->renderer,
|
||||
icon_novideo->w,
|
||||
icon_novideo->h,
|
||||
SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
if (!ok) {
|
||||
LOGW("Could not set renderer logical size: %s", SDL_GetError());
|
||||
// don't fail
|
||||
}
|
||||
|
||||
display->texture = SDL_CreateTextureFromSurface(display->renderer,
|
||||
icon_novideo);
|
||||
if (!display->texture) {
|
||||
|
||||
@@ -145,7 +145,7 @@ sc_screen_is_relative_mode(struct sc_screen *screen) {
|
||||
|
||||
static void
|
||||
compute_content_rect(struct sc_size render_size, struct sc_size content_size,
|
||||
SDL_Rect *rect) {
|
||||
bool can_upscale, SDL_Rect *rect) {
|
||||
if (is_optimal_size(render_size, content_size)) {
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
@@ -154,6 +154,16 @@ compute_content_rect(struct sc_size render_size, struct sc_size content_size,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!can_upscale && content_size.width <= render_size.width
|
||||
&& content_size.height <= render_size.height) {
|
||||
// Center without upscaling
|
||||
rect->x = (render_size.width - content_size.width) / 2;
|
||||
rect->y = (render_size.height - content_size.height) / 2;
|
||||
rect->w = content_size.width;
|
||||
rect->h = content_size.height;
|
||||
return;
|
||||
}
|
||||
|
||||
bool keep_width = content_size.width * render_size.height
|
||||
> content_size.height * render_size.width;
|
||||
if (keep_width) {
|
||||
@@ -173,11 +183,13 @@ compute_content_rect(struct sc_size render_size, struct sc_size content_size,
|
||||
|
||||
static void
|
||||
sc_screen_update_content_rect(struct sc_screen *screen) {
|
||||
assert(screen->video);
|
||||
// Only upscale video frames, not icon
|
||||
bool can_upscale = screen->video;
|
||||
|
||||
struct sc_size render_size =
|
||||
sc_sdl_get_render_output_size(screen->renderer);
|
||||
compute_content_rect(render_size, screen->content_size, &screen->rect);
|
||||
compute_content_rect(render_size, screen->content_size, can_upscale,
|
||||
&screen->rect);
|
||||
}
|
||||
|
||||
// render the texture to the renderer
|
||||
@@ -186,8 +198,7 @@ sc_screen_update_content_rect(struct sc_screen *screen) {
|
||||
// changed, so that the content rectangle is recomputed
|
||||
static void
|
||||
sc_screen_render(struct sc_screen *screen, bool update_content_rect) {
|
||||
assert(screen->video);
|
||||
assert(screen->has_video_window);
|
||||
assert(!screen->video || screen->has_video_window);
|
||||
|
||||
if (update_content_rect) {
|
||||
sc_screen_update_content_rect(screen);
|
||||
@@ -243,23 +254,6 @@ end:
|
||||
sc_sdl_render_present(renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
sc_screen_render_novideo(struct sc_screen *screen) {
|
||||
SDL_Renderer *renderer = screen->renderer;
|
||||
|
||||
sc_sdl_render_clear(renderer);
|
||||
|
||||
SDL_Texture *texture = screen->display.texture;
|
||||
assert(texture);
|
||||
|
||||
bool ok = SDL_RenderTexture(renderer, texture, NULL, NULL);
|
||||
if (!ok) {
|
||||
LOGE("Could not render texture: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
sc_sdl_render_present(renderer);
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
# define CONTINUOUS_RESIZING_WORKAROUND
|
||||
#endif
|
||||
@@ -475,8 +469,17 @@ sc_screen_init(struct sc_screen *screen,
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Surface *icon_novideo = params->video ? NULL : icon;
|
||||
bool mipmaps = params->video && params->mipmaps;
|
||||
SDL_Surface *icon_novideo;
|
||||
bool mipmaps;
|
||||
if (params->video) {
|
||||
icon_novideo = NULL;
|
||||
mipmaps = params->mipmaps;
|
||||
} else {
|
||||
icon_novideo = icon;
|
||||
mipmaps = false;
|
||||
screen->content_size.width = icon->w;
|
||||
screen->content_size.height = icon->h;
|
||||
}
|
||||
ok = sc_display_init(&screen->display, screen->renderer, icon_novideo,
|
||||
mipmaps);
|
||||
if (icon) {
|
||||
@@ -874,9 +877,7 @@ sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
if (!screen->video) {
|
||||
sc_screen_render_novideo(screen);
|
||||
} else if (screen->has_video_window) {
|
||||
if (!screen->video || screen->has_video_window) {
|
||||
sc_screen_render(screen, true);
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user