From 6b14ce18ca3c0cd804329815b501d7e30e377698 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 24 Jan 2026 22:40:54 +0100 Subject: [PATCH] Move renderer from sc_display to sc_screen Make sc_screen the owner of both the SDL window and the SDL renderer. This is the first step toward limiting the role of sc_display to texture management. --- app/src/display.c | 39 +++------------------------------------ app/src/display.h | 11 ++--------- app/src/screen.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- app/src/screen.h | 9 +++++++++ 4 files changed, 57 insertions(+), 47 deletions(-) diff --git a/app/src/display.c b/app/src/display.c index b68f6f8b..e7795c76 100644 --- a/app/src/display.c +++ b/app/src/display.c @@ -33,45 +33,16 @@ sc_display_init_novideo_icon(struct sc_display *display, } bool -sc_display_init(struct sc_display *display, SDL_Window *window, +sc_display_init(struct sc_display *display, SDL_Renderer *renderer, SDL_Surface *icon_novideo, bool mipmaps) { - display->renderer = SDL_CreateRenderer(window, NULL); - if (!display->renderer) { - LOGE("Could not create renderer: %s", SDL_GetError()); - return false; - } - - const char *renderer_name = SDL_GetRendererName(display->renderer); + const char *renderer_name = SDL_GetRendererName(renderer); LOGI("Renderer: %s", renderer_name ? renderer_name : "(unknown)"); display->mipmaps = false; -#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE - display->gl_context = NULL; -#endif - // starts with "opengl" bool use_opengl = renderer_name && !strncmp(renderer_name, "opengl", 6); if (use_opengl) { - -#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE - // Persuade macOS to give us something better than OpenGL 2.1. - // If we create a Core Profile context, we get the best OpenGL version. - bool ok = SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, - SDL_GL_CONTEXT_PROFILE_CORE); - if (!ok) { - LOGW("Could not set a GL Core Profile Context"); - } - - LOGD("Creating OpenGL Core Profile context"); - display->gl_context = SDL_GL_CreateContext(window); - if (!display->gl_context) { - LOGE("Could not create OpenGL context: %s", SDL_GetError()); - SDL_DestroyRenderer(display->renderer); - return false; - } -#endif - struct sc_opengl *gl = &display->gl; sc_opengl_init(gl); @@ -95,6 +66,7 @@ sc_display_init(struct sc_display *display, SDL_Window *window, LOGD("Trilinear filtering disabled (not an OpenGL renderer)"); } + display->renderer = renderer; display->texture = NULL; if (icon_novideo) { @@ -104,7 +76,6 @@ sc_display_init(struct sc_display *display, SDL_Window *window, #ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE SDL_GL_DestroyContext(display->gl_context); #endif - SDL_DestroyRenderer(display->renderer); return false; } } @@ -114,13 +85,9 @@ sc_display_init(struct sc_display *display, SDL_Window *window, void sc_display_destroy(struct sc_display *display) { -#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE - SDL_GL_DestroyContext(display->gl_context); -#endif if (display->texture) { SDL_DestroyTexture(display->texture); } - SDL_DestroyRenderer(display->renderer); } static enum SDL_Colorspace diff --git a/app/src/display.h b/app/src/display.h index dccf797f..a8d0141b 100644 --- a/app/src/display.h +++ b/app/src/display.h @@ -12,25 +12,18 @@ #include "opengl.h" #include "options.h" -#ifdef __APPLE__ -# define SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE -#endif - struct sc_display { - SDL_Renderer *renderer; + SDL_Renderer *renderer; // owned by the caller SDL_Texture *texture; struct sc_opengl gl; -#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE - SDL_GLContext gl_context; -#endif bool mipmaps; uint32_t texture_id; // only set if mipmaps is enabled }; bool -sc_display_init(struct sc_display *display, SDL_Window *window, +sc_display_init(struct sc_display *display, SDL_Renderer *renderer, SDL_Surface *icon_novideo, bool mipmaps); void diff --git a/app/src/screen.c b/app/src/screen.c index a0da5ccb..6e2bcb15 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -389,15 +389,45 @@ sc_screen_init(struct sc_screen *screen, goto error_destroy_window; } + screen->renderer = SDL_CreateRenderer(screen->window, NULL); + if (!screen->renderer) { + LOGE("Could not create renderer: %s", SDL_GetError()); + goto error_destroy_window; + } + +#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE + screen->gl_context = NULL; + + // starts with "opengl" + const char *renderer_name = SDL_GetRendererName(screen->renderer); + bool use_opengl = renderer_name && !strncmp(renderer_name, "opengl", 6); + if (use_opengl) { + // Persuade macOS to give us something better than OpenGL 2.1. + // If we create a Core Profile context, we get the best OpenGL version. + bool ok = SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_CONTEXT_PROFILE_CORE); + if (!ok) { + LOGW("Could not set a GL Core Profile Context"); + } + + LOGD("Creating OpenGL Core Profile context"); + screen->gl_context = SDL_GL_CreateContext(screen->window); + if (!screen->gl_context) { + LOGE("Could not create OpenGL context: %s", SDL_GetError()); + goto error_destroy_renderer; + } + } +#endif + SDL_Surface *icon_novideo = params->video ? NULL : icon; bool mipmaps = params->video && params->mipmaps; - ok = sc_display_init(&screen->display, screen->window, icon_novideo, + ok = sc_display_init(&screen->display, screen->renderer, icon_novideo, mipmaps); if (icon) { scrcpy_icon_destroy(icon); } if (!ok) { - goto error_destroy_window; + goto error_destroy_renderer; } screen->frame = av_frame_alloc(); @@ -461,6 +491,13 @@ sc_screen_init(struct sc_screen *screen, error_destroy_display: sc_display_destroy(&screen->display); +error_destroy_renderer: +#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE + if (screen->gl_context) { + SDL_GL_DestroyContext(screen->gl_context); + } +#endif + SDL_DestroyRenderer(screen->renderer); error_destroy_window: SDL_DestroyWindow(screen->window); error_destroy_fps_counter: @@ -524,6 +561,10 @@ sc_screen_destroy(struct sc_screen *screen) { #endif sc_display_destroy(&screen->display); av_frame_free(&screen->frame); +#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE + SDL_GL_DestroyContext(screen->gl_context); +#endif + SDL_DestroyRenderer(screen->renderer); SDL_DestroyWindow(screen->window); sc_fps_counter_destroy(&screen->fps_counter); sc_frame_buffer_destroy(&screen->fb); diff --git a/app/src/screen.h b/app/src/screen.h index 1d8070e8..50634796 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -22,6 +22,10 @@ #include "trait/frame_sink.h" #include "trait/mouse_processor.h" +#ifdef __APPLE__ +# define SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE +#endif + struct sc_screen { struct sc_frame_sink frame_sink; // frame sink trait @@ -49,6 +53,11 @@ struct sc_screen { } req; SDL_Window *window; + SDL_Renderer *renderer; +#ifdef SC_DISPLAY_FORCE_OPENGL_CORE_PROFILE + SDL_GLContext gl_context; +#endif + struct sc_size frame_size; struct sc_size content_size; // rotated frame_size