1
0
Fork 0
forked from len0rd/rockbox

sdl: fix: concurrent drawing on Windows

On Windows, we need to prevent the event thread
from drawing at the same time as the main thread,
when window is being adjusted.

Change-Id: I2b4e4a50fec427e53e310593850e2a556a594b31
This commit is contained in:
Christian Soffke 2024-12-26 12:11:55 +01:00
parent 0a88b818e9
commit fa8b095f29
5 changed files with 18 additions and 0 deletions

View file

@ -243,7 +243,9 @@ static bool event_handler(SDL_Event *event)
sdl_app_has_input_focus = 0; sdl_app_has_input_focus = 0;
else if(event->window.event == SDL_WINDOWEVENT_RESIZED) else if(event->window.event == SDL_WINDOWEVENT_RESIZED)
{ {
SDL_LockMutex(window_mutex);
sdl_window_adjustment_needed(false); sdl_window_adjustment_needed(false);
SDL_UnlockMutex(window_mutex);
#if !defined (__APPLE__) && !defined(__WIN32) #if !defined (__APPLE__) && !defined(__WIN32)
static unsigned long last_tick; static unsigned long last_tick;
if (TIME_AFTER(current_tick, last_tick + HZ/20) && !button_queue_full()) if (TIME_AFTER(current_tick, last_tick + HZ/20) && !button_queue_full())
@ -354,8 +356,10 @@ static void button_event(int key, bool pressed)
case SDLK_TAB: case SDLK_TAB:
if (!pressed) if (!pressed)
{ {
SDL_LockMutex(window_mutex);
background = !background; background = !background;
sdl_window_adjustment_needed(true); sdl_window_adjustment_needed(true);
SDL_UnlockMutex(window_mutex);
#if !defined(__WIN32) && !defined (__APPLE__) #if !defined(__WIN32) && !defined (__APPLE__)
button_queue_post(SDLK_UNKNOWN, 0); /* update window on main thread */ button_queue_post(SDLK_UNKNOWN, 0); /* update window on main thread */
#endif #endif
@ -375,12 +379,14 @@ static void button_event(int key, bool pressed)
display_zoom = 0; display_zoom = 0;
return; return;
} }
SDL_LockMutex(window_mutex);
if (!display_zoom) if (!display_zoom)
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,
strcmp(SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY) ?: strcmp(SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY) ?:
"best", "best") ? "best": "nearest"); "best", "best") ? "best": "nearest");
sdl_window_adjustment_needed(!display_zoom); sdl_window_adjustment_needed(!display_zoom);
SDL_UnlockMutex(window_mutex);
#if !defined(__WIN32) && !defined (__APPLE__) #if !defined(__WIN32) && !defined (__APPLE__)
button_queue_post(SDLK_UNKNOWN, 0); /* update window on main thread */ button_queue_post(SDLK_UNKNOWN, 0); /* update window on main thread */
#endif #endif

View file

@ -102,6 +102,9 @@ void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width,
SDL_Rect dest= {ui_x + x_start, ui_y + y_start, width, height}; SDL_Rect dest= {ui_x + x_start, ui_y + y_start, width, height};
uint8_t alpha; uint8_t alpha;
SDL_LockMutex(window_mutex);
if (SDL_GetSurfaceAlphaMod(surface,&alpha) == 0 && alpha < 255) if (SDL_GetSurfaceAlphaMod(surface,&alpha) == 0 && alpha < 255)
SDL_FillRect(sim_lcd_surface, NULL, 0); /* alpha needs a black background */ SDL_FillRect(sim_lcd_surface, NULL, 0); /* alpha needs a black background */
@ -111,6 +114,7 @@ void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width,
if (!sdl_window_adjust()) /* already calls sdl_window_render itself */ if (!sdl_window_adjust()) /* already calls sdl_window_render itself */
sdl_window_render(); sdl_window_render();
SDL_UnlockMutex(window_mutex);
} }
/* set a range of bitmap indices to a gradient from startcolour to endcolour */ /* set a range of bitmap indices to a gradient from startcolour to endcolour */

View file

@ -175,6 +175,8 @@ void power_off(void)
void sim_do_exit() void sim_do_exit()
{ {
sim_kernel_shutdown(); sim_kernel_shutdown();
SDL_UnlockMutex(window_mutex);
SDL_DestroyMutex(window_mutex);
SDL_Quit(); SDL_Quit();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View file

@ -33,6 +33,8 @@ extern SDL_Surface *remote_surface;
SDL_Texture *gui_texture; SDL_Texture *gui_texture;
SDL_Surface *sim_lcd_surface; SDL_Surface *sim_lcd_surface;
SDL_mutex *window_mutex;
static SDL_Window *window; static SDL_Window *window;
static SDL_Renderer *sdlRenderer; static SDL_Renderer *sdlRenderer;
static SDL_Surface *picture_surface; static SDL_Surface *picture_surface;
@ -220,4 +222,5 @@ void sdl_window_setup(void)
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, display_zoom == 1 ? "best" : "nearest"); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, display_zoom == 1 ? "best" : "nearest");
display_zoom = 0; /* reset to 0 unless/until user requests a scale level change */ display_zoom = 0; /* reset to 0 unless/until user requests a scale level change */
window_mutex = SDL_CreateMutex();
} }

View file

@ -26,6 +26,9 @@
extern SDL_Texture *gui_texture; /* Window content, including background */ extern SDL_Texture *gui_texture; /* Window content, including background */
extern SDL_Surface *sim_lcd_surface; /* LCD content */ extern SDL_Surface *sim_lcd_surface; /* LCD content */
extern SDL_mutex *window_mutex; /* prevent concurrent drawing from event thread &
main thread on MS Windows */
/* Renders GUI texture. Sets up new texture, if necessary */ /* Renders GUI texture. Sets up new texture, if necessary */
void sdl_window_render(void); void sdl_window_render(void);