From: notaz Date: Wed, 14 May 2025 21:46:37 +0000 (+0300) Subject: frontend: rework sdl gl vout_method X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fremotes%2Fgithub%2Fmaster;p=pcsx_rearmed.git frontend: rework sdl gl vout_method --- diff --git a/frontend/libpicofe b/frontend/libpicofe index 80612f5f..ab0990ab 160000 --- a/frontend/libpicofe +++ b/frontend/libpicofe @@ -1 +1 @@ -Subproject commit 80612f5f31a3201e6c7f710109a9c8b48f6bb757 +Subproject commit ab0990ab434971e1ab1f7ebda61ce368bb7a4d11 diff --git a/frontend/plat_sdl.c b/frontend/plat_sdl.c index 4c397194..f207d2ae 100644 --- a/frontend/plat_sdl.c +++ b/frontend/plat_sdl.c @@ -12,6 +12,7 @@ #include #include +#include "../libpcsxcore/plugins.h" #include "libpicofe/input.h" #include "libpicofe/in_sdl.h" #include "libpicofe/menu.h" @@ -95,21 +96,36 @@ static const struct in_pdata in_sdl_platform_data = { static int psx_w = 256, psx_h = 240; static void *shadow_fb, *menubg_img; -static int resized, window_w, window_h; static int vout_fullscreen_old; static int forced_clears; static int forced_flips; static int sdl12_compat; +static int resized; static int in_menu; +static int gl_w_prev, gl_h_prev; +static float gl_vertices[] = { + -1.0f, 1.0f, 0.0f, // 0 0 1 + 1.0f, 1.0f, 0.0f, // 1 ^ + -1.0f, -1.0f, 0.0f, // 2 | 2 3 + 1.0f, -1.0f, 0.0f, // 3 +--> +}; + +static void handle_window_resize(void); static void handle_scaler_resize(int w, int h); static void centered_clear(void); -static void resize_cb(int w, int h) +static int plugin_owns_display(void) +{ + // if true, a plugin is drawing and flipping + return (pl_rearmed_cbs.gpu_caps & GPU_CAP_OWNS_DISPLAY); +} + +static void plugin_update(void) { // used by some plugins... - pl_rearmed_cbs.screen_w = w; - pl_rearmed_cbs.screen_h = h; + pl_rearmed_cbs.screen_w = plat_sdl_screen->w; + pl_rearmed_cbs.screen_h = plat_sdl_screen->h; pl_rearmed_cbs.gles_display = gl_es_display; pl_rearmed_cbs.gles_surface = gl_es_surface; plugin_call_rearmed_cbs(); @@ -125,6 +141,15 @@ static void sdl_event_handler(void *event_) window_w = event->resize.w & ~3; window_h = event->resize.h & ~1; resized = 1; + if (!in_menu && plat_sdl_gl_active && plugin_owns_display()) { + // the plugin flips by itself so resize has to be handled here + handle_window_resize(); + if (GPU_open != NULL) { + int ret = GPU_open(&gpuDisp, "PCSX", NULL); + if (ret) + fprintf(stderr, "GPU_open: %d\n", ret); + } + } } return; case SDL_ACTIVEEVENT: @@ -156,7 +181,6 @@ void plat_init(void) int ret; plat_sdl_quit_cb = quit_cb; - plat_sdl_resize_cb = resize_cb; ret = plat_sdl_init(); if (ret != 0) @@ -188,12 +212,10 @@ void plat_init(void) bgr_to_uyvy_init(); - // to "finish" init and set SDL_RESIZABLE - plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, -1); - if (plat_sdl_overlay) { - printf("overlay: %08x hw=%d\n", plat_sdl_overlay->format, - plat_sdl_overlay->hw_overlay); - } + assert(plat_sdl_screen); + plugin_update(); + if (plat_target.vout_method == vout_mode_gl) + gl_w_prev = plat_sdl_screen->w, gl_h_prev = plat_sdl_screen->h; } void plat_finish(void) @@ -258,21 +280,11 @@ static void overlay_resize(int force) SDL_UnlockYUVOverlay(plat_sdl_overlay); } } - else + else { fprintf(stderr, "overlay resize to %dx%d failed\n", w, h); - handle_scaler_resize(w, h); -} - -static void overlay_check_enable(void) -{ - // we no longer unconditionally call plat_sdl_change_video_mode() - // to not disturb the window, need to look for config change - if ((plat_target.vout_method == 0 || plat_sdl_gl_active) && plat_sdl_overlay) { - SDL_FreeYUVOverlay(plat_sdl_overlay); - plat_sdl_overlay = NULL; + plat_target.vout_method = 0; } - else if (plat_target.vout_method > 0 && !plat_sdl_gl_active) // lame - overlay_resize(0); + handle_scaler_resize(w, h); } static void overlay_blit(int doffs, const void *src_, int w, int h, @@ -310,6 +322,58 @@ static void overlay_hud_print(int x, int y, const char *str, int bpp) SDL_UnlockYUVOverlay(plat_sdl_overlay); } +static void gl_finish_pl(void) +{ + if (plugin_owns_display() && GPU_close != NULL) + GPU_close(); + gl_finish(); +} + +static void gl_resize(void) +{ + int w = in_menu ? g_menuscreen_w : psx_w; + int h = in_menu ? g_menuscreen_h : psx_h; + + if (plugin_owns_display()) + w = plat_sdl_screen->w, h = plat_sdl_screen->h; + if (plat_sdl_gl_active) { + if (w == gl_w_prev && h == gl_h_prev) + return; + gl_finish_pl(); + } + plat_sdl_gl_active = (gl_init(display, window, &gl_quirks, w, h) == 0); + if (plat_sdl_gl_active) + gl_w_prev = w, gl_h_prev = h; + else { + fprintf(stderr, "warning: could not init GL.\n"); + plat_target.vout_method = 0; + } + handle_scaler_resize(w, h); + plugin_update(); + forced_flips = 0; // interferes with gl +} + +static void overlay_or_gl_check_enable(void) +{ + int ovl_on = plat_target.vout_method == vout_mode_overlay || + plat_target.vout_method == vout_mode_overlay2x; + int gl_on = plat_target.vout_method == vout_mode_gl; + if (!gl_on && plat_sdl_gl_active) { + gl_finish_pl(); + pl_rearmed_cbs.gles_display = gl_es_display; + pl_rearmed_cbs.gles_surface = gl_es_surface; + plat_sdl_gl_active = 0; + } + if (!ovl_on && plat_sdl_overlay) { + SDL_FreeYUVOverlay(plat_sdl_overlay); + plat_sdl_overlay = NULL; + } + if (ovl_on) + overlay_resize(0); + else if (gl_on) + gl_resize(); +} + static void centered_clear(void) { int dstride = plat_sdl_screen->pitch / 2; @@ -317,6 +381,11 @@ static void centered_clear(void) int h = plat_sdl_screen->h; unsigned short *dst; + if (plat_sdl_gl_active) { + gl_clear(); + return; + } + if (SDL_MUSTLOCK(plat_sdl_screen)) SDL_LockSurface(plat_sdl_screen); dst = plat_sdl_screen->pixels; @@ -446,7 +515,7 @@ static void *setup_blit_callbacks(int w, int h) // different size overlay vs plat_sdl_screen layer static void change_mode(int w, int h) { - int set_w = w, set_h = h, had_overlay = 0; + int set_w = w, set_h = h, had_overlay = 0, had_gl = 0; if (plat_target.vout_fullscreen && (plat_target.vout_method != 0 || !sdl12_compat)) set_w = fs_w, set_h = fs_h; if (plat_sdl_screen->w != set_w || plat_sdl_screen->h != set_h || @@ -465,6 +534,11 @@ static void change_mode(int w, int h) plat_sdl_overlay = NULL; had_overlay = 1; } + if (plat_sdl_gl_active) { + gl_finish_pl(); + plat_sdl_gl_active = 0; + had_gl = 1; + } SDL_PumpEvents(); plat_sdl_screen = SDL_SetVideoMode(set_w, set_h, 16, flags); //printf("mode: %dx%d %x -> %dx%d\n", set_w, set_h, flags, @@ -473,10 +547,15 @@ static void change_mode(int w, int h) if (vout_fullscreen_old && !plat_target.vout_fullscreen) // why is this needed?? (on 1.2.68) SDL_WM_GrabInput(SDL_GRAB_OFF); + if (vout_mode_gl != -1) + update_wm_display_window(); // overlay needs the latest plat_sdl_screen if (had_overlay) overlay_resize(1); + if (had_gl) + gl_resize(); centered_clear(); + plugin_update(); vout_fullscreen_old = plat_target.vout_fullscreen; } } @@ -487,9 +566,20 @@ static void handle_scaler_resize(int w, int h) int wh = plat_sdl_screen->h; int layer_w_old = g_layer_w; int layer_h_old = g_layer_h; + float w_mul, h_mul; + int x, y; pl_update_layer_size(w, h, ww, wh); if (layer_w_old != g_layer_w || layer_h_old != g_layer_h) forced_clears = 3; + + w_mul = 2.0f / ww; + h_mul = 2.0f / wh; + x = (ww - g_layer_w) / 2; + y = (wh - g_layer_h) / 2; + gl_vertices[3*0+0] = gl_vertices[3*2+0] = -1.0f + x * w_mul; + gl_vertices[3*1+0] = gl_vertices[3*3+0] = -1.0f + (x + g_layer_w) * w_mul; + gl_vertices[3*2+1] = gl_vertices[3*3+1] = -1.0f + y * h_mul; + gl_vertices[3*0+1] = gl_vertices[3*1+1] = -1.0f + (y + g_layer_h) * h_mul; } static void handle_window_resize(void) @@ -499,8 +589,8 @@ static void handle_window_resize(void) change_mode(window_w, window_h); setup_blit_callbacks(psx_w, psx_h); forced_clears = 3; - resized = 0; } + resized = 0; } void *plat_gvideo_set_mode(int *w, int *h, int *bpp) @@ -508,10 +598,15 @@ void *plat_gvideo_set_mode(int *w, int *h, int *bpp) psx_w = *w; psx_h = *h; + if (plat_sdl_gl_active && plugin_owns_display()) + return NULL; + if (plat_sdl_overlay != NULL) overlay_resize(0); - else if (plat_sdl_gl_active) + else if (plat_sdl_gl_active) { memset(shadow_fb, 0, (*w) * (*h) * 2); + gl_resize(); + } else if (plat_target.vout_method == 0) // && sdl12_compat change_mode(*w, *h); @@ -529,11 +624,10 @@ void *plat_gvideo_flip(void) (plat_sdl_screen->h - g_layer_h) / 2, g_layer_w, g_layer_h }; - SDL_DisplayYUVOverlay(plat_sdl_overlay, &dstrect); } else if (plat_sdl_gl_active) { - gl_flip(shadow_fb, psx_w, psx_h); + gl_flip_v(shadow_fb, psx_w, psx_h, g_scaler != SCALE_FULLSCREEN ? gl_vertices : NULL); ret = shadow_fb; } else @@ -592,7 +686,7 @@ void plat_video_menu_enter(int is_rom_loaded) if (plat_target.vout_method == 0) change_mode(g_menuscreen_w, g_menuscreen_h); else - overlay_check_enable(); + overlay_or_gl_check_enable(); centered_clear(); } @@ -607,7 +701,7 @@ void plat_video_menu_begin(void) change_mode(g_menuscreen_w, g_menuscreen_h); } else - overlay_check_enable(); + overlay_or_gl_check_enable(); handle_scaler_resize(g_menuscreen_w, g_menuscreen_h); if (old_ovl != plat_sdl_overlay || scaler_changed) @@ -634,7 +728,8 @@ void plat_video_menu_end(void) SDL_DisplayYUVOverlay(plat_sdl_overlay, &dstrect); } else if (plat_sdl_gl_active) { - gl_flip(g_menuscreen_ptr, g_menuscreen_w, g_menuscreen_h); + gl_flip_v(g_menuscreen_ptr, g_menuscreen_w, g_menuscreen_h, + g_scaler != SCALE_FULLSCREEN ? gl_vertices : NULL); } else { centered_blit_menu(); @@ -661,7 +756,7 @@ void plat_video_menu_leave(void) if (plat_target.vout_fullscreen) change_mode(fs_w, fs_h); else - overlay_check_enable(); + overlay_or_gl_check_enable(); centered_clear(); } diff --git a/plugins/gpu-gles/gpulib_if.c b/plugins/gpu-gles/gpulib_if.c index 7207a09d..a09b3fb1 100644 --- a/plugins/gpu-gles/gpulib_if.c +++ b/plugins/gpu-gles/gpulib_if.c @@ -22,6 +22,8 @@ #include "gpuPrim.c" #include "hud.c" +static int is_opened; + static const short dispWidths[8] = {256,320,512,640,368,384,512,640}; short g_m1,g_m2,g_m3; short DrawSemiTrans; @@ -315,6 +317,9 @@ if(bUp) updateDisplay(); // yeah, real update (swap #define GPUwriteStatus_ext GPUwriteStatus_ext // for gpulib to see this void GPUwriteStatus_ext(unsigned int gdata) { + if (!is_opened) + return; + switch((gdata>>24)&0xff) { case 0x00: @@ -478,8 +483,6 @@ switch((gdata>>24)&0xff) #include "../gpulib/gpu.c" -static int is_opened; - static void set_vram(void *vram) { psxVub=vram; @@ -506,6 +509,34 @@ int renderer_init(void) return 0; } +static void clear_gl_state_for_menu(void) +{ + static const GLenum caps[] = { + GL_ALPHA_TEST, GL_BLEND, GL_COLOR_LOGIC_OP, GL_COLOR_MATERIAL, + GL_CULL_FACE, GL_DEPTH_TEST, GL_FOG, GL_LIGHTING, GL_NORMALIZE, + GL_POLYGON_OFFSET_FILL, GL_RESCALE_NORMAL, GL_SAMPLE_ALPHA_TO_COVERAGE, + GL_SAMPLE_ALPHA_TO_ONE, GL_SAMPLE_COVERAGE, GL_SCISSOR_TEST, GL_STENCIL_TEST + }; + static const GLenum cstates[] = { + GL_COLOR_ARRAY, GL_NORMAL_ARRAY, GL_POINT_SIZE_ARRAY_OES + }; + size_t i; + for (i = 0; i < sizeof(caps) / sizeof(caps[0]); i++) + glDisable(caps[i]); + for (i = 0; i < 6; i++) + glDisable(GL_CLIP_PLANE0 + i); + for (i = 0; i < 8; i++) + glDisable(GL_LIGHT0 + i); + for (i = 0; i < sizeof(cstates) / sizeof(cstates[0]); i++) + glDisableClientState(cstates[i]); + + glColor4ub(255, 255, 255, 255); + glLoadIdentity(); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); +} + void renderer_finish(void) { } @@ -687,6 +718,10 @@ long GPUopen(unsigned long *disp, char *cap, char *cfg) { int ret; + if (is_opened) { + fprintf(stderr, "double GPUopen\n"); + return -1; + } iResX = cbs->screen_w; iResY = cbs->screen_h; rRatioRect.left = rRatioRect.top=0; @@ -708,9 +743,12 @@ long GPUopen(unsigned long *disp, char *cap, char *cfg) long GPUclose(void) { + if (!is_opened) + return 0; is_opened = 0; KillDisplayLists(); + clear_gl_state_for_menu(); GLcleanup(); // close OGL return 0; } @@ -740,9 +778,12 @@ void renderer_set_config(const struct rearmed_cbs *cbs_) cbs->pl_set_gpu_caps(GPU_CAP_OWNS_DISPLAY); if (is_opened && cbs->gles_display != NULL && cbs->gles_surface != NULL) { - // HACK.. - GPUclose(); - GPUopen(NULL, NULL, NULL); + if (cbs->gles_display != display || cbs->gles_surface != surface) { + // HACK... + fprintf(stderr, "gles reinit hack\n"); + GPUclose(); + GPUopen(NULL, NULL, NULL); + } } set_vram(gpu.vram);