From b4257a54bc59797bab5d401c7dafa72f977b0b7f Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Mon, 4 Mar 2024 22:11:17 +0300 Subject: [PATCH] ogc: restore blending mode after every frame The OGC_video_flip() function does not simply flip the current video frame: if the mouse cursor is visible, it will draw it. If/when we'll add support for the OSK keyboard, that will also be drawn at the end of every frame. Since these operations require a specific blending mode, we must make sure that it is restored to its original value before starting drawing the next frame. We could optimize this by having OGC_video_flip() return a boolean (or a bit mask, in case there are more settings beside the blending mode that it can alter) telling whether the blending mode was changed, in order not to perform an unneeded operation. It might make sense to do it once we decide to do the same for the vertex formats and the texture stages, which change more often and are heavier operations. --- src/render/ogc/SDL_render_ogc.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/render/ogc/SDL_render_ogc.c b/src/render/ogc/SDL_render_ogc.c index 705a0246792cc..3aa86c1c0500c 100644 --- a/src/render/ogc/SDL_render_ogc.c +++ b/src/render/ogc/SDL_render_ogc.c @@ -61,16 +61,10 @@ static void OGC_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event { } -static inline void OGC_SetBlendMode(SDL_Renderer *renderer, SDL_BlendMode blend_mode) +static void set_blend_mode_real(SDL_Renderer *renderer, SDL_BlendMode blend_mode) { OGC_RenderData *data = renderer->driverdata; - if (data->ops_after_present > 0 && - blend_mode == data->current_blend_mode) { - /* Nothing to do */ - return; - } - switch (blend_mode) { case SDL_BLENDMODE_NONE: GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_INVSRCALPHA, GX_LO_CLEAR); @@ -94,6 +88,19 @@ static inline void OGC_SetBlendMode(SDL_Renderer *renderer, SDL_BlendMode blend_ data->current_blend_mode = blend_mode; } +static inline void OGC_SetBlendMode(SDL_Renderer *renderer, SDL_BlendMode blend_mode) +{ + OGC_RenderData *data = renderer->driverdata; + + if (data->ops_after_present > 0 && + blend_mode == data->current_blend_mode) { + /* Nothing to do */ + return; + } + + set_blend_mode_real(renderer, blend_mode); +} + static void save_efb_to_texture(SDL_Renderer *renderer) { SDL_Texture *texture = renderer->target; @@ -539,6 +546,9 @@ static int OGC_RenderPresent(SDL_Renderer *renderer) OGC_video_flip(SDL_GetVideoDevice(), data->vsync); + /* Mouse cursor and OSK can change the blending mode; restore it. */ + set_blend_mode_real(renderer, data->current_blend_mode); + data->ops_after_present = 0; return 0; }