From a7ac4d560f3cc3410df019297f6e4f31d9cb913c Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 31 Jan 2026 21:37:40 +0100 Subject: [PATCH] Set display texture from a surface Add a function to set a texture from a surface on a sc_display. --- app/src/display.c | 45 +++++++++++------------------ app/src/display.h | 6 +++- app/src/screen.c | 73 ++++++++++++++++++++++++----------------------- 3 files changed, 59 insertions(+), 65 deletions(-) diff --git a/app/src/display.c b/app/src/display.c index 839d9627..727a6374 100644 --- a/app/src/display.c +++ b/app/src/display.c @@ -7,24 +7,9 @@ #include "util/log.h" -static bool -sc_display_init_novideo_icon(struct sc_display *display, - SDL_Surface *icon_novideo) { - assert(icon_novideo); - - display->texture = SDL_CreateTextureFromSurface(display->renderer, - icon_novideo); - if (!display->texture) { - LOGE("Could not create texture: %s", SDL_GetError()); - return false; - } - - return true; -} - bool sc_display_init(struct sc_display *display, SDL_Renderer *renderer, - SDL_Surface *icon_novideo, bool mipmaps) { + bool mipmaps) { const char *renderer_name = SDL_GetRendererName(renderer); LOGI("Renderer: %s", renderer_name ? renderer_name : "(unknown)"); @@ -58,18 +43,6 @@ sc_display_init(struct sc_display *display, SDL_Renderer *renderer, display->renderer = renderer; display->texture = NULL; - - if (icon_novideo) { - // Without video, set a static scrcpy icon as window content - bool ok = sc_display_init_novideo_icon(display, icon_novideo); - if (!ok) { -#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE - SDL_GL_DestroyContext(display->gl_context); -#endif - return false; - } - } - return true; } @@ -223,3 +196,19 @@ sc_display_update_texture(struct sc_display *display, const AVFrame *frame) { return true; } + +bool +sc_display_set_texture_from_surface(struct sc_display *display, + SDL_Surface *surface) { + if (display->texture) { + SDL_DestroyTexture(display->texture); + } + + display->texture = SDL_CreateTextureFromSurface(display->renderer, surface); + if (!display->texture) { + LOGE("Could not create texture: %s", SDL_GetError()); + return false; + } + + return true; +} diff --git a/app/src/display.h b/app/src/display.h index 9ba0d0bd..cda907d3 100644 --- a/app/src/display.h +++ b/app/src/display.h @@ -23,7 +23,7 @@ struct sc_display { bool sc_display_init(struct sc_display *display, SDL_Renderer *renderer, - SDL_Surface *icon_novideo, bool mipmaps); + bool mipmaps); void sc_display_destroy(struct sc_display *display); @@ -36,4 +36,8 @@ sc_display_prepare_texture(struct sc_display *display, struct sc_size size, bool sc_display_update_texture(struct sc_display *display, const AVFrame *frame); +bool +sc_display_set_texture_from_surface(struct sc_display *display, + SDL_Surface *surface); + #endif diff --git a/app/src/screen.c b/app/src/screen.c index e12074ac..c988dbc7 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -415,26 +415,6 @@ sc_screen_init(struct sc_screen *screen, goto error_destroy_fps_counter; } - ok = SDL_StartTextInput(screen->window); - if (!ok) { - LOGE("Could not enable text input: %s", SDL_GetError()); - goto error_destroy_window; - } - - SDL_Surface *icon = scrcpy_icon_load(); - if (icon) { - if (!SDL_SetWindowIcon(screen->window, icon)) { - LOGW("Could not set window icon: %s", SDL_GetError()); - } - } else if (params->video) { - // just a warning - LOGW("Could not load icon"); - } else { - // without video, the icon is used as window content, it must be present - LOGE("Could not load icon"); - goto error_destroy_window; - } - screen->renderer = SDL_CreateRenderer(screen->window, NULL); if (!screen->renderer) { LOGE("Could not create renderer: %s", SDL_GetError()); @@ -465,26 +445,47 @@ sc_screen_init(struct sc_screen *screen, } #endif - 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) { - scrcpy_icon_destroy(icon); - } + bool mipmaps = params->video; + ok = sc_display_init(&screen->display, screen->renderer, mipmaps); if (!ok) { goto error_destroy_renderer; } + ok = SDL_StartTextInput(screen->window); + if (!ok) { + LOGE("Could not enable text input: %s", SDL_GetError()); + goto error_destroy_display; + } + + SDL_Surface *icon = scrcpy_icon_load(); + if (icon) { + if (!SDL_SetWindowIcon(screen->window, icon)) { + LOGW("Could not set window icon: %s", SDL_GetError()); + } + } else if (params->video) { + // just a warning + LOGW("Could not load icon"); + } else { + // without video, the icon is used as window content, it must be present + LOGE("Could not load icon"); + goto error_destroy_display; + } + + if (!params->video) { + assert(icon); + screen->content_size.width = icon->w; + screen->content_size.height = icon->h; + ok = sc_display_set_texture_from_surface(&screen->display, icon); + if (!ok) { + scrcpy_icon_destroy(icon); + goto error_destroy_display; + } + } + + if (icon) { + scrcpy_icon_destroy(icon); + } + screen->frame = av_frame_alloc(); if (!screen->frame) { LOG_OOM();