diff --git a/gfx/common/d3d9_common.c b/gfx/common/d3d9_common.c index 4a338418c51..38c59c490c5 100644 --- a/gfx/common/d3d9_common.c +++ b/gfx/common/d3d9_common.c @@ -336,13 +336,25 @@ void d3d9_make_d3dpp(d3d9_video_t *d3d, if (!windowed_enable) { #ifdef _XBOX + /* Xbox: query the actual display size, publish it to video_st + * and track it in d3d->vp.full_width/full_height so subsequent + * read sites can pull from the local field instead of locking + * video_st. */ unsigned width = 0; unsigned height = 0; d3d9_get_video_size(d3d, &width, &height); video_driver_set_size(width, height); + d3d->vp.full_width = width; + d3d->vp.full_height = height; + d3dpp->BackBufferWidth = width; + d3dpp->BackBufferHeight = height; +#else + /* Non-Xbox: by the time make_d3dpp runs, d3d9_*_init_internal + * has already published the size and written d3d->vp. + * full_width/full_height; read from there. */ + d3dpp->BackBufferWidth = d3d->vp.full_width; + d3dpp->BackBufferHeight = d3d->vp.full_height; #endif - video_driver_get_size(&d3dpp->BackBufferWidth, - &d3dpp->BackBufferHeight); } #ifdef _XBOX diff --git a/gfx/common/gdi_defines.h b/gfx/common/gdi_defines.h index 18f636ff5f4..9bbaa6d29e2 100644 --- a/gfx/common/gdi_defines.h +++ b/gfx/common/gdi_defines.h @@ -41,6 +41,11 @@ typedef struct gdi unsigned video_height; unsigned screen_width; unsigned screen_height; + /* Surface (window) size last published via video_driver_set_size, + * tracked here so gdi_alive can read it without locking. Distinct + * from video_width / video_height which is the core's frame size. */ + unsigned full_width; + unsigned full_height; unsigned menu_width; unsigned menu_height; diff --git a/gfx/drivers/d3d8.c b/gfx/drivers/d3d8.c index f9f861623f9..72c353970c4 100644 --- a/gfx/drivers/d3d8.c +++ b/gfx/drivers/d3d8.c @@ -409,9 +409,8 @@ static void d3d8_set_vertices( unsigned pass, unsigned vert_width, unsigned vert_height, uint64_t frame_count) { - unsigned width, height; - - video_driver_get_size(&width, &height); + unsigned width = d3d->vp.full_width; + unsigned height = d3d->vp.full_height; if (chain->last_width != vert_width || chain->last_height != vert_height) { @@ -572,15 +571,14 @@ static bool d3d8_setup_init(void *data, bool rgb32 ) { - unsigned width, height; d3d8_video_t *d3d = (d3d8_video_t*)data; settings_t *settings = config_get_ptr(); LPDIRECT3DDEVICE8 d3dr = (LPDIRECT3DDEVICE8)d3d->dev; d3d8_renderchain_t *chain = (d3d8_renderchain_t*)d3d->renderchain_data; unsigned fmt = (rgb32) ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; video_viewport_t *custom_vp = &settings->video_vp_custom; - - video_driver_get_size(&width, &height); + unsigned width = d3d->vp.full_width; + unsigned height = d3d->vp.full_height; chain->dev = dev_data; chain->pixel_size = (fmt == RETRO_PIXEL_FORMAT_RGB565) @@ -659,23 +657,6 @@ static void *gfx_display_d3d8_get_default_mvp(void *data) return &id; } -static INT32 gfx_display_prim_to_d3d8_enum( - enum gfx_display_prim_type prim_type) -{ - switch (prim_type) - { - case GFX_DISPLAY_PRIM_TRIANGLES: - case GFX_DISPLAY_PRIM_TRIANGLESTRIP: - return D3DPT_TRIANGLESTRIP; - case GFX_DISPLAY_PRIM_NONE: - default: - break; - } - - /* TODO/FIXME - hack */ - return 0; -} - static void gfx_display_d3d8_blend_begin(void *data) { d3d8_video_t *d3d = (d3d8_video_t*)data; @@ -712,7 +693,6 @@ static void gfx_display_d3d8_draw(gfx_display_ctx_draw_t *draw, math_matrix_4x4 mop, m1, m2; LPDIRECT3DVERTEXBUFFER8 vbo; LPDIRECT3DDEVICE8 dev; - D3DPRIMITIVETYPE type; unsigned start = 0; unsigned count = 0; d3d8_video_t *d3d = (d3d8_video_t*)data; @@ -1007,32 +987,22 @@ static void gfx_display_d3d8_draw(gfx_display_ctx_draw_t *draw, IDirect3DDevice8_SetTextureStageState(dev, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - type = gfx_display_prim_to_d3d8_enum(draw->prim_type); start = d3d->menu_display.offset; - /* For tristrips, the primitive count is vertices - 2. Guard - * against vertices < 3 which would underflow the unsigned - * subtraction and pass a huge primitive count to the GPU. */ - if (draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP) - { - if (draw->coords->vertices < 3) - { - d3d->menu_display.offset += draw->coords->vertices; - return; - } - count = draw->coords->vertices - 2; - } - else - count = draw->coords->vertices; - - if (count == 0) + /* Menu draws issued by gfx_display always pass a triangle-strip layout + * (4 vertices = 2 triangles for a quad). D3D8 expects PrimitiveCount, + * not vertex count, hence (vertices - 2). Guard against vertices < 3 + * which would underflow the unsigned subtraction and pass a huge + * primitive count to the GPU. */ + if (draw->coords->vertices < 3) { d3d->menu_display.offset += draw->coords->vertices; return; } + count = draw->coords->vertices - 2; IDirect3DDevice8_BeginScene(dev); - IDirect3DDevice8_DrawPrimitive(dev, type, start, count); + IDirect3DDevice8_DrawPrimitive(dev, D3DPT_TRIANGLESTRIP, start, count); IDirect3DDevice8_EndScene(dev); d3d->menu_display.offset += draw->coords->vertices; @@ -1569,7 +1539,8 @@ static void d3d8_font_render_msg( if (!d3d) return; - video_driver_get_size(&width, &height); + width = d3d->vp.full_width; + height = d3d->vp.full_height; if (!width || !height) return; @@ -1781,21 +1752,18 @@ gfx_display_ctx_driver_t gfx_display_ctx_d3d8 = { static void d3d8_viewport_info(void *data, struct video_viewport *vp) { - unsigned width, height; d3d8_video_t *d3d = (d3d8_video_t*)data; if (!d3d || !vp) return; - video_driver_get_size(&width, &height); - vp->x = d3d->out_vp.X; vp->y = d3d->out_vp.Y; vp->width = d3d->out_vp.Width; vp->height = d3d->out_vp.Height; - vp->full_width = width; - vp->full_height = height; + vp->full_width = d3d->vp.full_width; + vp->full_height = d3d->vp.full_height; } static void d3d8_overlay_render(d3d8_video_t *d3d, @@ -2104,14 +2072,26 @@ static void d3d8_make_d3dpp(void *data, if (!windowed_enable) { #ifdef _XBOX + /* Xbox: query the actual display size, publish it to video_st + * and track it in d3d->vp.full_width/full_height so subsequent + * read sites (font_render_msg, viewport_info, etc.) can pull + * from the local field instead of locking video_st. */ unsigned width = 0; unsigned height = 0; d3d8_get_video_size(d3d, &width, &height); video_driver_set_size(width, height); + d3d->vp.full_width = width; + d3d->vp.full_height = height; + d3dpp->BackBufferWidth = width; + d3dpp->BackBufferHeight = height; +#else + /* Non-Xbox: by the time make_d3dpp runs, d3d8_init_internal + * has already published the size and written d3d->vp. + * full_width/full_height; read from there. */ + d3dpp->BackBufferWidth = d3d->vp.full_width; + d3dpp->BackBufferHeight = d3d->vp.full_height; #endif - video_driver_get_size(&d3dpp->BackBufferWidth, - &d3dpp->BackBufferHeight); } #ifdef _XBOX @@ -2193,7 +2173,8 @@ static void d3d8_calculate_rect(void *data, struct video_viewport vp; d3d8_video_t *d3d = (d3d8_video_t*)data; - video_driver_get_size(width, height); + *width = d3d->vp.full_width; + *height = d3d->vp.full_height; vp.full_width = *width; vp.full_height = *height; @@ -2258,7 +2239,6 @@ static void d3d8_set_viewport(void *data, static bool d3d8_initialize(d3d8_video_t *d3d, const video_info_t *info) { struct LinkInfo link_info; - unsigned width, height; unsigned i = 0; bool ret = true; settings_t *settings = config_get_ptr(); @@ -2307,9 +2287,10 @@ static bool d3d8_initialize(d3d8_video_t *d3d, const video_info_t *info) ) return false; - video_driver_get_size(&width, &height); + /* d3d->vp.full_* was written by the caller (d3d8_init_internal + * has already called set_size at this point). */ d3d8_set_viewport(d3d, - width, height, false, true); + d3d->vp.full_width, d3d->vp.full_height, false, true); font_driver_init_osd(d3d, info, false, @@ -2404,6 +2385,8 @@ static void d3d8_set_resize(d3d8_video_t *d3d, d3d->video_info.width = new_width; d3d->video_info.height = new_height; video_driver_set_size(new_width, new_height); + d3d->vp.full_width = new_width; + d3d->vp.full_height = new_height; } static bool d3d8_alive(void *data) @@ -2415,8 +2398,14 @@ static bool d3d8_alive(void *data) bool quit = false; bool resize = false; - /* Needed because some context drivers don't track their sizes */ - video_driver_get_size(&temp_width, &temp_height); + /* Read from local bookkeeping rather than video_st (which + * would acquire context_lock + display_lock). d3d->vp.full_* + * is written at every set_size call site in this driver, so + * it stays in sync with video_st->width/height as long as no + * other code path writes them. In practice nothing does -- + * see video_driver.c audit. */ + temp_width = d3d->vp.full_width; + temp_height = d3d->vp.full_height; win32_check_window(NULL, &quit, &resize, &temp_width, &temp_height); @@ -2433,7 +2422,11 @@ static bool d3d8_alive(void *data) ret = !quit; if (temp_width != 0 && temp_height != 0) + { video_driver_set_size(temp_width, temp_height); + d3d->vp.full_width = temp_width; + d3d->vp.full_height = temp_height; + } return ret; } @@ -2481,10 +2474,6 @@ static bool d3d8_init_internal(d3d8_video_t *d3d, HMONITOR hm_to_use; #endif struct video_shader_pass *pass = NULL; -#ifdef HAVE_WINDOW - unsigned win_width = 0; - unsigned win_height = 0; -#endif unsigned full_x = 0; unsigned full_y = 0; settings_t *settings = config_get_ptr(); @@ -2538,18 +2527,22 @@ static bool d3d8_init_internal(d3d8_video_t *d3d, unsigned new_width = info->fullscreen ? full_x : info->width; unsigned new_height = info->fullscreen ? full_y : info->height; video_driver_set_size(new_width, new_height); - } + d3d->vp.full_width = new_width; + d3d->vp.full_height = new_height; #ifdef HAVE_WINDOW - video_driver_get_size(&win_width, &win_height); - - if (!win32_set_video_mode(d3d, win_width, win_height, - info->fullscreen)) - { - RARCH_ERR("[D3D8] win32_set_video_mode failed.\n"); - return false; - } + /* Use new_width / new_height directly rather than reading + * them back via video_driver_get_size: nothing in the + * codebase writes video_st->width / height between the + * set_size above and this call except us. */ + if (!win32_set_video_mode(d3d, new_width, new_height, + info->fullscreen)) + { + RARCH_ERR("[D3D8] win32_set_video_mode failed.\n"); + return false; + } #endif + } memset(&d3d->shader, 0, sizeof(d3d->shader)); d3d->shader.passes = 1; diff --git a/gfx/drivers/d3d9cg.c b/gfx/drivers/d3d9cg.c index bd194f58c8a..47eb9f977a6 100644 --- a/gfx/drivers/d3d9cg.c +++ b/gfx/drivers/d3d9cg.c @@ -476,23 +476,6 @@ static const float d3d9_cg_tex_coords[8] = { 1, 0 }; -static INT32 gfx_display_prim_to_d3d9_cg_enum( - enum gfx_display_prim_type prim_type) -{ - switch (prim_type) - { - case GFX_DISPLAY_PRIM_TRIANGLES: - case GFX_DISPLAY_PRIM_TRIANGLESTRIP: - return D3DPT_TRIANGLESTRIP; - case GFX_DISPLAY_PRIM_NONE: - default: - break; - } - - /* TODO/FIXME - hack */ - return 0; -} - static void gfx_display_d3d9_cg_blend_begin(void *data) { d3d9_video_t *d3d = (d3d9_video_t*)data; @@ -672,7 +655,6 @@ static void gfx_display_d3d9_cg_draw(gfx_display_ctx_draw_t *draw, { unsigned i; LPDIRECT3DDEVICE9 dev; - D3DPRIMITIVETYPE type; bool has_vertex_data; unsigned start = 0; unsigned count = 0; @@ -1038,13 +1020,20 @@ static void gfx_display_d3d9_cg_draw(gfx_display_ctx_draw_t *draw, gfx_display_d3d9_cg_bind_texture(draw, d3d); - type = (D3DPRIMITIVETYPE)gfx_display_prim_to_d3d9_cg_enum(draw->prim_type); start = d3d->menu_display.offset; - count = draw->coords->vertices - - ((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP) - ? 2 : 0); - IDirect3DDevice9_DrawPrimitive(dev, type, start, count); + /* Menu draws use a triangle-strip layout. Harden against vertices < 3 + * (the count formula vertices - 2 would otherwise underflow the + * unsigned subtraction and pass a huge primitive count to the GPU -- + * see d3d8.c for the matching guard). */ + if (draw->coords->vertices < 3) + { + d3d->menu_display.offset += draw->coords->vertices; + return; + } + count = draw->coords->vertices - 2; + + IDirect3DDevice9_DrawPrimitive(dev, D3DPT_TRIANGLESTRIP, start, count); d3d->menu_display.offset += draw->coords->vertices; } @@ -1196,7 +1185,6 @@ static void gfx_display_d3d9_cg_draw_pipeline(gfx_display_ctx_draw_t *draw, blank_coords.vertices = 4; draw->coords = &blank_coords; - draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; IDirect3DDevice9_SetRenderState(d3d->dev, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); @@ -1489,7 +1477,8 @@ static void d3d9_cg_font_render_msg( if (!d3d || !font || !msg || !*msg) return; - video_driver_get_size(&width, &height); + width = d3d->vp.full_width; + height = d3d->vp.full_height; if (!width || !height) return; @@ -1657,8 +1646,8 @@ static void d3d9_cg_font_render_msg( float _inv_vp_w, _inv_vp_h; float _inv_tex_w, _inv_tex_h; const struct font_glyph *_glyph_q = NULL; - unsigned _rl_width = 0; - unsigned _rl_height = 0; + unsigned _rl_width = d3d->vp.full_width; + unsigned _rl_height = d3d->vp.full_height; int _rx, _ry; unsigned _vert_count = 0; Vertex *_verts = NULL; @@ -1668,7 +1657,6 @@ static void d3d9_cg_font_render_msg( float _rl_pos_y = drop_pos_y; D3DCOLOR _rl_color = color_dark; - video_driver_get_size(&_rl_width, &_rl_height); if (_rl_width && _rl_height) { _verts = d3d9_cg_font_get_scratch(font, _rl_msg_len * 6); @@ -1771,8 +1759,8 @@ static void d3d9_cg_font_render_msg( float _inv_vp_w, _inv_vp_h; float _inv_tex_w, _inv_tex_h; const struct font_glyph *_glyph_q = NULL; - unsigned _rl_width = 0; - unsigned _rl_height = 0; + unsigned _rl_width = d3d->vp.full_width; + unsigned _rl_height = d3d->vp.full_height; int _rx, _ry; unsigned _vert_count = 0; Vertex *_verts = NULL; @@ -1782,7 +1770,6 @@ static void d3d9_cg_font_render_msg( float _rl_pos_y = line_y; D3DCOLOR _rl_color = color; - video_driver_get_size(&_rl_width, &_rl_height); if (_rl_width && _rl_height) { _verts = d3d9_cg_font_get_scratch(font, _rl_msg_len * 6); @@ -3664,7 +3651,10 @@ static void d3d9_cg_set_viewport(void *data, int y = 0; struct video_viewport vp; - video_driver_get_size(&width, &height); + /* Width/height parameters are intentionally overwritten here: + * the caller's values are not used (pre-existing behaviour). */ + width = d3d->vp.full_width; + height = d3d->vp.full_height; vp.full_width = width; vp.full_height = height; @@ -3712,7 +3702,6 @@ static void d3d9_cg_set_viewport(void *data, static bool d3d9_cg_initialize(d3d9_video_t *d3d, const video_info_t *info) { - unsigned width, height; bool ret = true; settings_t *settings = config_get_ptr(); @@ -3747,9 +3736,10 @@ static bool d3d9_cg_initialize(d3d9_video_t *d3d, const video_info_t *info) return false; } - video_driver_get_size(&width, &height); + /* d3d->vp.full_* was written by the caller (d3d9_cg_init_internal + * has already called set_size at this point). */ d3d9_cg_set_viewport(d3d, - width, height, false, true); + d3d->vp.full_width, d3d->vp.full_height, false, true); font_driver_init_osd(d3d, info, false, @@ -3918,10 +3908,6 @@ static bool d3d9_cg_init_internal(d3d9_video_t *d3d, RECT mon_rect; MONITORINFOEX current_mon; HMONITOR hm_to_use; -#endif -#ifdef HAVE_WINDOW - unsigned win_width = 0; - unsigned win_height = 0; #endif unsigned full_x = 0; unsigned full_y = 0; @@ -3978,18 +3964,22 @@ static bool d3d9_cg_init_internal(d3d9_video_t *d3d, unsigned new_width = info->fullscreen ? full_x : info->width; unsigned new_height = info->fullscreen ? full_y : info->height; video_driver_set_size(new_width, new_height); - } + d3d->vp.full_width = new_width; + d3d->vp.full_height = new_height; #ifdef HAVE_WINDOW - video_driver_get_size(&win_width, &win_height); - - if (!win32_set_video_mode(d3d, win_width, win_height, - info->fullscreen)) - { - RARCH_ERR("[D3D9 Cg] win32_set_video_mode failed.\n"); - return false; - } + /* Use new_width / new_height directly rather than reading + * them back via video_driver_get_size: nothing in the + * codebase writes video_st->width / height between the + * set_size above and this call except us. */ + if (!win32_set_video_mode(d3d, new_width, new_height, + info->fullscreen)) + { + RARCH_ERR("[D3D9 Cg] win32_set_video_mode failed.\n"); + return false; + } #endif + } d3d->video_info = *info; @@ -4834,6 +4824,8 @@ static void d3d9_cg_set_resize(d3d9_video_t *d3d, d3d->video_info.width = new_width; d3d->video_info.height = new_height; video_driver_set_size(new_width, new_height); + d3d->vp.full_width = new_width; + d3d->vp.full_height = new_height; } static bool d3d9_cg_alive(void *data) @@ -4845,8 +4837,11 @@ static bool d3d9_cg_alive(void *data) bool resize = false; d3d9_video_t *d3d = (d3d9_video_t*)data; - /* Needed because some context drivers don't track their sizes */ - video_driver_get_size(&temp_width, &temp_height); + /* Read from local bookkeeping rather than video_st (which would + * acquire context_lock + display_lock). d3d->vp.full_* is + * written at every set_size call site in this driver. */ + temp_width = d3d->vp.full_width; + temp_height = d3d->vp.full_height; win32_check_window(NULL, &quit, &resize, &temp_width, &temp_height); @@ -4864,7 +4859,11 @@ static bool d3d9_cg_alive(void *data) if ( temp_width != 0 && temp_height != 0) + { video_driver_set_size(temp_width, temp_height); + d3d->vp.full_width = temp_width; + d3d->vp.full_height = temp_height; + } return ret; } @@ -4892,18 +4891,15 @@ void d3d9_cg_set_rotation(void *data, unsigned rot) void d3d9_cg_viewport_info(void *data, struct video_viewport *vp) { - unsigned width, height; d3d9_video_t *d3d = (d3d9_video_t*)data; - video_driver_get_size(&width, &height); - vp->x = d3d->out_vp.X; vp->y = d3d->out_vp.Y; vp->width = d3d->out_vp.Width; vp->height = d3d->out_vp.Height; - vp->full_width = width; - vp->full_height = height; + vp->full_width = d3d->vp.full_width; + vp->full_height = d3d->vp.full_height; } static INLINE bool d3d9_cg_device_get_render_target_data( @@ -4917,15 +4913,14 @@ static INLINE bool d3d9_cg_device_get_render_target_data( bool d3d9_cg_read_viewport(void *data, uint8_t *buffer, bool is_idle) { - unsigned width, height; D3DLOCKED_RECT rect; LPDIRECT3DSURFACE9 target = NULL; LPDIRECT3DSURFACE9 dest = NULL; bool ret = true; d3d9_video_t *d3d = (d3d9_video_t*)data; LPDIRECT3DDEVICE9 d3dr = d3d->dev; - - video_driver_get_size(&width, &height); + unsigned width = d3d->vp.full_width; + unsigned height = d3d->vp.full_height; if ( !SUCCEEDED(IDirect3DDevice9_GetRenderTarget(d3dr, 0, (LPDIRECT3DSURFACE9*)&target)) diff --git a/gfx/drivers/d3d9hlsl.c b/gfx/drivers/d3d9hlsl.c index 7bef5423ed2..139052d3839 100644 --- a/gfx/drivers/d3d9hlsl.c +++ b/gfx/drivers/d3d9hlsl.c @@ -709,23 +709,6 @@ static const float d3d9_hlsl_tex_coords[8] = { static LPDIRECT3DTEXTURE9 d3d9_hlsl_white_texture = NULL; -static INT32 gfx_display_prim_to_d3d9_hlsl_enum( - enum gfx_display_prim_type prim_type) -{ - switch (prim_type) - { - case GFX_DISPLAY_PRIM_TRIANGLES: - case GFX_DISPLAY_PRIM_TRIANGLESTRIP: - return D3DPT_TRIANGLESTRIP; - case GFX_DISPLAY_PRIM_NONE: - default: - break; - } - - /* TODO/FIXME - hack */ - return 0; -} - static void gfx_display_d3d9_hlsl_blend_begin(void *data) { d3d9_video_t *d3d = (d3d9_video_t*)data; @@ -777,7 +760,6 @@ static void gfx_display_d3d9_hlsl_draw(gfx_display_ctx_draw_t *draw, { unsigned i; LPDIRECT3DDEVICE9 dev; - D3DPRIMITIVETYPE type; bool has_vertex_data; unsigned start = 0; unsigned count = 0; @@ -1099,13 +1081,20 @@ static void gfx_display_d3d9_hlsl_draw(gfx_display_ctx_draw_t *draw, if (draw && draw->texture) gfx_display_d3d9_bind_texture(draw, d3d); - type = (D3DPRIMITIVETYPE)gfx_display_prim_to_d3d9_hlsl_enum(draw->prim_type); start = d3d->menu_display.offset; - count = draw->coords->vertices - - ((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP) - ? 2 : 0); - IDirect3DDevice9_DrawPrimitive(dev, type, start, count); + /* Menu draws use a triangle-strip layout. Harden against vertices < 3 + * (the count formula vertices - 2 would otherwise underflow the + * unsigned subtraction and pass a huge primitive count to the GPU -- + * see d3d8.c for the matching guard). */ + if (draw->coords->vertices < 3) + { + d3d->menu_display.offset += draw->coords->vertices; + return; + } + count = draw->coords->vertices - 2; + + IDirect3DDevice9_DrawPrimitive(dev, D3DPT_TRIANGLESTRIP, start, count); d3d->menu_display.offset += draw->coords->vertices; } @@ -1252,7 +1241,6 @@ static void gfx_display_d3d9_hlsl_draw_pipeline( * ca->coords.vertices (which ribbon needs at 8064). */ blank_coords.vertices = 4; draw->coords = &blank_coords; - draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; /* Set blend state for particle effects */ IDirect3DDevice9_SetRenderState(d3d->dev, @@ -1606,7 +1594,8 @@ static void d3d9_font_render_msg( if (!d3d) return; - video_driver_get_size(&width, &height); + width = d3d->vp.full_width; + height = d3d->vp.full_height; if (!width || !height) return; @@ -6901,7 +6890,10 @@ static void d3d9_hlsl_set_viewport(void *data, int y = 0; struct video_viewport vp; - video_driver_get_size(&width, &height); + /* Width/height parameters are intentionally overwritten here: + * the caller's values are not used (pre-existing behaviour). */ + width = d3d->vp.full_width; + height = d3d->vp.full_height; vp.full_width = width; vp.full_height = height; @@ -6963,7 +6955,6 @@ static void d3d9_hlsl_set_osd_msg(void *data, static bool d3d9_hlsl_initialize( d3d9_video_t *d3d, const video_info_t *info) { - unsigned width, height; bool ret = true; if (!d3d->d3d9) @@ -6998,9 +6989,10 @@ static bool d3d9_hlsl_initialize( return false; } - video_driver_get_size(&width, &height); + /* d3d->vp.full_* was written by the caller (d3d9_hlsl_init_internal + * has already called set_size at this point). */ d3d9_hlsl_set_viewport(d3d, - width, height, false, true); + d3d->vp.full_width, d3d->vp.full_height, false, true); font_driver_init_osd(d3d, info, false, @@ -7144,10 +7136,6 @@ static bool d3d9_hlsl_init_internal(d3d9_video_t *d3d, RECT mon_rect; MONITORINFOEX current_mon; HMONITOR hm_to_use; -#endif -#ifdef HAVE_WINDOW - unsigned win_width = 0; - unsigned win_height = 0; #endif unsigned full_x = 0; unsigned full_y = 0; @@ -7204,18 +7192,22 @@ static bool d3d9_hlsl_init_internal(d3d9_video_t *d3d, unsigned new_width = info->fullscreen ? full_x : info->width; unsigned new_height = info->fullscreen ? full_y : info->height; video_driver_set_size(new_width, new_height); - } + d3d->vp.full_width = new_width; + d3d->vp.full_height = new_height; #ifdef HAVE_WINDOW - video_driver_get_size(&win_width, &win_height); - - if (!win32_set_video_mode(d3d, win_width, win_height, - info->fullscreen)) - { - RARCH_ERR("[D3D9 HLSL] win32_set_video_mode failed.\n"); - return false; - } + /* Use new_width / new_height directly rather than reading + * them back via video_driver_get_size: nothing in the + * codebase writes video_st->width / height between the + * set_size above and this call except us. */ + if (!win32_set_video_mode(d3d, new_width, new_height, + info->fullscreen)) + { + RARCH_ERR("[D3D9 HLSL] win32_set_video_mode failed.\n"); + return false; + } #endif + } d3d->video_info = *info; @@ -7287,18 +7279,15 @@ static void *d3d9_hlsl_init(const video_info_t *info, static void d3d9_hlsl_viewport_info(void *data, struct video_viewport *vp) { - unsigned width, height; d3d9_video_t *d3d = (d3d9_video_t*)data; - video_driver_get_size(&width, &height); - vp->x = d3d->out_vp.X; vp->y = d3d->out_vp.Y; vp->width = d3d->out_vp.Width; vp->height = d3d->out_vp.Height; - vp->full_width = width; - vp->full_height = height; + vp->full_width = d3d->vp.full_width; + vp->full_height = d3d->vp.full_height; } #ifdef HAVE_OVERLAY @@ -8175,6 +8164,8 @@ static void d3d9_hlsl_set_resize(d3d9_video_t *d3d, d3d->video_info.width = new_width; d3d->video_info.height = new_height; video_driver_set_size(new_width, new_height); + d3d->vp.full_width = new_width; + d3d->vp.full_height = new_height; } static bool d3d9_hlsl_alive(void *data) @@ -8186,8 +8177,11 @@ static bool d3d9_hlsl_alive(void *data) bool resize = false; d3d9_video_t *d3d = (d3d9_video_t*)data; - /* Needed because some context drivers don't track their sizes */ - video_driver_get_size(&temp_width, &temp_height); + /* Read from local bookkeeping rather than video_st (which would + * acquire context_lock + display_lock). d3d->vp.full_* is + * written at every set_size call site in this driver. */ + temp_width = d3d->vp.full_width; + temp_height = d3d->vp.full_height; win32_check_window(NULL, &quit, &resize, &temp_width, &temp_height); @@ -8205,7 +8199,11 @@ static bool d3d9_hlsl_alive(void *data) if ( temp_width != 0 && temp_height != 0) + { video_driver_set_size(temp_width, temp_height); + d3d->vp.full_width = temp_width; + d3d->vp.full_height = temp_height; + } return ret; } @@ -8266,15 +8264,14 @@ static INLINE bool d3d9_hlsl_device_get_render_target_data( static bool d3d9_hlsl_read_viewport(void *data, uint8_t *buffer, bool is_idle) { - unsigned width, height; D3DLOCKED_RECT rect; LPDIRECT3DSURFACE9 target = NULL; LPDIRECT3DSURFACE9 dest = NULL; bool ret = true; d3d9_video_t *d3d = (d3d9_video_t*)data; LPDIRECT3DDEVICE9 d3dr = d3d->dev; - - video_driver_get_size(&width, &height); + unsigned width = d3d->vp.full_width; + unsigned height = d3d->vp.full_height; if ( !(d3dr && diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index bd24a6da2ec..d6bfce0b91d 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -571,8 +571,10 @@ static void *gdi_init(const video_info_t *video, if (temp_width != 0 && temp_height != 0) video_driver_set_size(temp_width, temp_height); - - video_driver_get_size(&temp_width, &temp_height); + else + video_driver_get_size(&temp_width, &temp_height); + gdi->full_width = temp_width; + gdi->full_height = temp_height; RARCH_LOG("[GDI] Using resolution %ux%u.\n", temp_width, temp_height); @@ -793,9 +795,13 @@ static bool gdi_alive(void *data) bool quit = false; bool resize = false; bool ret = false; + gdi_t *gdi = (gdi_t*)data; - /* Needed because some context drivers don't track their sizes */ - video_driver_get_size(&temp_width, &temp_height); + /* Read from local bookkeeping rather than video_st (which would + * acquire context_lock + display_lock). gdi->full_{width,height} + * is written at every set_size call site in this driver. */ + temp_width = gdi->full_width; + temp_height = gdi->full_height; win32_check_window(NULL, &quit, &resize, &temp_width, &temp_height); @@ -803,7 +809,11 @@ static bool gdi_alive(void *data) ret = !quit; if (temp_width != 0 && temp_height != 0) + { video_driver_set_size(temp_width, temp_height); + gdi->full_width = temp_width; + gdi->full_height = temp_height; + } return ret; } diff --git a/gfx/drivers/gl1.c b/gfx/drivers/gl1.c index c04258f8702..5c97b986554 100644 --- a/gfx/drivers/gl1.c +++ b/gfx/drivers/gl1.c @@ -273,23 +273,6 @@ static void *gfx_display_gl1_get_default_mvp(void *data) return &gl1->mvp_no_rot; } -static GLenum gfx_display_prim_to_gl1_enum( - enum gfx_display_prim_type type) -{ - switch (type) - { - case GFX_DISPLAY_PRIM_TRIANGLESTRIP: - return GL_TRIANGLE_STRIP; - case GFX_DISPLAY_PRIM_TRIANGLES: - return GL_TRIANGLES; - case GFX_DISPLAY_PRIM_NONE: - default: - break; - } - - return 0; -} - static void gfx_display_gl1_blend_begin(void *data) { glEnable(GL_BLEND); @@ -366,8 +349,8 @@ static void gfx_display_gl1_draw(gfx_display_ctx_draw_t *draw, glColorPointer(4, GL_FLOAT, 0, draw->coords->color); glTexCoordPointer(2, GL_FLOAT, 0, draw->coords->tex_coord); - glDrawArrays(gfx_display_prim_to_gl1_enum( - draw->prim_type), 0, draw->coords->vertices); + /* Menu draws use a triangle-strip layout. */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1285,8 +1268,10 @@ static void *gl1_init(const video_info_t *video, if (temp_width != 0 && temp_height != 0) video_driver_set_size(temp_width, temp_height); - - video_driver_get_size(&temp_width, &temp_height); + else + video_driver_get_size(&temp_width, &temp_height); + gl1->vp.full_width = temp_width; + gl1->vp.full_height = temp_height; RARCH_LOG("[GL1] Using resolution %ux%u.\n", temp_width, temp_height); @@ -2008,8 +1993,11 @@ static bool gl1_alive(void *data) bool ret = false; gl1_t *gl1 = (gl1_t*)data; - /* Needed because some context drivers don't track their sizes */ - video_driver_get_size(&temp_width, &temp_height); + /* Read from local bookkeeping rather than video_st (which would + * acquire context_lock + display_lock). gl1->vp.full_* is + * written at every set_size call site in this driver. */ + temp_width = gl1->vp.full_width; + temp_height = gl1->vp.full_height; gl1->ctx_driver->check_window(gl1->ctx_data, &quit, &resize, &temp_width, &temp_height); @@ -2020,7 +2008,11 @@ static bool gl1_alive(void *data) ret = !quit; if (temp_width != 0 && temp_height != 0) + { video_driver_set_size(temp_width, temp_height); + gl1->vp.full_width = temp_width; + gl1->vp.full_height = temp_height; + } return ret; } @@ -2098,19 +2090,17 @@ static void gl1_set_rotation(void *data, static void gl1_viewport_info(void *data, struct video_viewport *vp) { - unsigned width, height; unsigned top_y, top_dist; gl1_t *gl1 = (gl1_t*)data; - video_driver_get_size(&width, &height); - + /* gl1->vp carries full_width/full_height (written at every + * set_size call site), so the struct copy populates them + * directly without a video_driver_get_size round-trip. */ *vp = gl1->vp; - vp->full_width = width; - vp->full_height = height; /* Adjust as GL viewport is bottom-up. */ top_y = vp->y + vp->height; - top_dist = height - top_y; + top_dist = vp->full_height - top_y; vp->y = top_dist; } @@ -2135,16 +2125,13 @@ static bool gl1_read_viewport(void *data, uint8_t *buffer, bool is_idle) /* Clamp to the region glReadPixels actually wrote. * gl1_readback() clamps its read to * min(vp.{w,h}, video_{width,height}), where video_{width,height} - * come from video_info and ultimately video_driver_get_size(). + * come from the surface size kept in gl1->vp.full_*. * gl1->video_{width,height} holds the core's frame size, not the - * window size, so we re-query here to match. Not a hot path. */ - unsigned vd_w = 0; - unsigned vd_h = 0; - unsigned rb_w = 0; - unsigned rb_h = 0; - video_driver_get_size(&vd_w, &vd_h); - rb_w = (gl1->vp.width > vd_w) ? vd_w : gl1->vp.width; - rb_h = (gl1->vp.height > vd_h) ? vd_h : gl1->vp.height; + * window size, so we read the surface size from gl1->vp.full_*. */ + unsigned vd_w = gl1->vp.full_width; + unsigned vd_h = gl1->vp.full_height; + unsigned rb_w = (gl1->vp.width > vd_w) ? vd_w : gl1->vp.width; + unsigned rb_h = (gl1->vp.height > vd_h) ? vd_h : gl1->vp.height; video_frame_convert_rgba_to_bgr( (const void*)gl1->readback_buffer_screenshot, buffer, diff --git a/gfx/drivers/gl2.c b/gfx/drivers/gl2.c index 5efbaf260e8..464372cd81b 100644 --- a/gfx/drivers/gl2.c +++ b/gfx/drivers/gl2.c @@ -511,23 +511,6 @@ static void *gfx_display_gl2_get_default_mvp(void *data) return &gl->mvp_no_rot; } -static GLenum gfx_display_prim_to_gl_enum( - enum gfx_display_prim_type type) -{ - switch (type) - { - case GFX_DISPLAY_PRIM_TRIANGLESTRIP: - return GL_TRIANGLE_STRIP; - case GFX_DISPLAY_PRIM_TRIANGLES: - return GL_TRIANGLES; - case GFX_DISPLAY_PRIM_NONE: - default: - break; - } - - return 0; -} - static void gfx_display_gl2_blend_begin(void *data) { gl2_t *gl = (gl2_t*)data; @@ -650,8 +633,8 @@ static void gfx_display_gl2_draw(gfx_display_ctx_draw_t *draw, : (math_matrix_4x4*)&gl->mvp_no_rot); - glDrawArrays(gfx_display_prim_to_gl_enum( - draw->prim_type), 0, draw->coords->vertices); + /* Menu draws use a triangle-strip layout. */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices); gl->coords.color = gl->white_color_ptr; } @@ -4657,8 +4640,8 @@ static void *gl2_init(const video_info_t *video, if (temp_width != 0 && temp_height != 0) video_driver_set_size(temp_width, temp_height); - - video_driver_get_size(&temp_width, &temp_height); + else + video_driver_get_size(&temp_width, &temp_height); gl->video_width = temp_width; gl->video_height = temp_height; diff --git a/gfx/drivers/gl3.c b/gfx/drivers/gl3.c index c9229106ca3..35907e1108e 100644 --- a/gfx/drivers/gl3.c +++ b/gfx/drivers/gl3.c @@ -641,7 +641,6 @@ static void gfx_display_gl3_draw_pipeline( + 3 * sizeof(float), &yflip, sizeof(yflip)); draw->coords = &blank_coords; blank_coords.vertices = 4; - draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; break; } } @@ -651,23 +650,6 @@ static void gfx_display_gl3_draw_pipeline( #endif } -static GLenum gfx_display_prim_to_gl3_enum( - enum gfx_display_prim_type type) -{ - switch (type) - { - case GFX_DISPLAY_PRIM_TRIANGLESTRIP: - return GL_TRIANGLE_STRIP; - case GFX_DISPLAY_PRIM_TRIANGLES: - return GL_TRIANGLES; - case GFX_DISPLAY_PRIM_NONE: - default: - break; - } - - return 0; -} - static void gfx_display_gl3_draw(gfx_display_ctx_draw_t *draw, void *data, unsigned video_width, unsigned video_height) { @@ -695,8 +677,8 @@ static void gfx_display_gl3_draw(gfx_display_ctx_draw_t *draw, draw->matrix_data ? (math_matrix_4x4*)draw->matrix_data : (math_matrix_4x4*)&gl->mvp_no_rot); - glDrawArrays(gfx_display_prim_to_gl3_enum( - draw->prim_type), 0, draw->coords->vertices); + /* Menu draws use a triangle-strip layout. */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices); } #ifdef HAVE_SLANG else @@ -797,18 +779,9 @@ static void gfx_display_gl3_draw(gfx_display_ctx_draw_t *draw, glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(uintptr_t)0); - switch (draw->prim_type) - { - case GFX_DISPLAY_PRIM_TRIANGLESTRIP: - glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices); - break; - case GFX_DISPLAY_PRIM_TRIANGLES: - glDrawArrays(GL_TRIANGLES, 0, draw->coords->vertices); - break; - case GFX_DISPLAY_PRIM_NONE: - default: - break; - } + /* See the matching comment in the chain.active branch above: + * every caller passes TRIANGLESTRIP. */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, draw->coords->vertices); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); @@ -3025,7 +2998,8 @@ static void *gl3_init(const video_info_t *video, if (temp_width != 0 && temp_height != 0) video_driver_set_size(temp_width, temp_height); - video_driver_get_size(&temp_width, &temp_height); + else + video_driver_get_size(&temp_width, &temp_height); gl->video_width = temp_width; gl->video_height = temp_height; diff --git a/gfx/drivers/metal.m b/gfx/drivers/metal.m index 33ca2653636..89971c3dc86 100644 --- a/gfx/drivers/metal.m +++ b/gfx/drivers/metal.m @@ -2197,13 +2197,6 @@ - (void)clearScissorRect [_context resetScissorRect]; } -- (MTLPrimitiveType)_toPrimitiveType:(enum gfx_display_prim_type)prim -{ - if (prim == GFX_DISPLAY_PRIM_TRIANGLESTRIP) - return MTLPrimitiveTypeTriangleStrip; - return MTLPrimitiveTypeTriangle; -} - - (void)drawPipeline:(gfx_display_ctx_draw_t *)draw { static struct video_coords blank_coords; @@ -2234,7 +2227,6 @@ - (void)drawPipeline:(gfx_display_ctx_draw_t *)draw { draw->coords = &blank_coords; blank_coords.vertices = 4; - draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; break; } } @@ -2312,7 +2304,8 @@ - (void)draw:(gfx_display_ctx_draw_t *)draw [rce setVertexBytes:draw->backend_data length:draw->backend_data_size atIndex:BufferIndexUniforms]; [rce setVertexBuffer:range.buffer offset:range.offset atIndex:BufferIndexPositions]; [rce setFragmentBytes:draw->backend_data length:draw->backend_data_size atIndex:BufferIndexUniforms]; - [rce drawPrimitives:[self _toPrimitiveType:draw->prim_type] vertexStart:0 vertexCount:vertex_count]; + /* Menu draws use a triangle-strip layout. */ + [rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:vertex_count]; return; #endif default: diff --git a/gfx/drivers/network_gfx.c b/gfx/drivers/network_gfx.c index ccd44f45aa1..54a3e274123 100644 --- a/gfx/drivers/network_gfx.c +++ b/gfx/drivers/network_gfx.c @@ -343,17 +343,13 @@ static void network_gfx_set_nonblock_state(void *a, bool b, bool c, unsigned d) static bool network_gfx_alive(void *data) { - unsigned temp_width = 0; - unsigned temp_height = 0; - bool quit = false; - bool resize = false; - network_video_t *network = (network_video_t*)data; - - video_driver_get_size(&temp_width, &temp_height); - - if (temp_width != 0 && temp_height != 0) - video_driver_set_size(temp_width, temp_height); - + /* The video_driver_get_size + conditional set_size dance that + * used to live here was a copy-paste from d3d8_alive, where the + * intermediate win32_check_window call mutates the fetched + * size on window resize. The network driver has no equivalent + * windowing step, so the get/set was reading and writing back + * the same values -- a pure no-op. Drop it. */ + (void)data; return true; } diff --git a/gfx/drivers/sixel_gfx.c b/gfx/drivers/sixel_gfx.c index c7ad186bcf2..9364b2437af 100644 --- a/gfx/drivers/sixel_gfx.c +++ b/gfx/drivers/sixel_gfx.c @@ -502,18 +502,13 @@ static bool sixel_gfx_frame(void *data, const void *frame, static bool sixel_gfx_alive(void *data) { - unsigned temp_width = 0; - unsigned temp_height = 0; - bool quit = false; - bool resize = false; - sixel_t *sixel = (sixel_t*)data; - - /* Needed because some context drivers don't track their sizes */ - video_driver_get_size(&temp_width, &temp_height); - - if (temp_width != 0 && temp_height != 0) - video_driver_set_size(temp_width, temp_height); - + /* The video_driver_get_size + conditional set_size dance that + * used to live here was a copy-paste from d3d8_alive, where the + * intermediate win32_check_window call mutates the fetched + * size on window resize. sixel has no equivalent windowing + * step, so the get/set was reading and writing back the same + * values -- a pure no-op. Drop it. */ + (void)data; return true; } diff --git a/gfx/drivers/vg.c b/gfx/drivers/vg.c index c52160dff63..99cffe86db0 100644 --- a/gfx/drivers/vg.c +++ b/gfx/drivers/vg.c @@ -175,8 +175,6 @@ static void *vg_init(const video_info_t *video, win_width, win_height, video->fullscreen)) goto error; - video_driver_get_size(&temp_width, &temp_height); - temp_width = 0; temp_height = 0; mode_width = 0; @@ -197,8 +195,8 @@ static void *vg_init(const video_info_t *video, temp_width, temp_height); video_driver_set_size(temp_width, temp_height); } - - video_driver_get_size(&temp_width, &temp_height); + else + video_driver_get_size(&temp_width, &temp_height); vg->mScreenAspect = (float)temp_width / temp_height; diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index d933ba299f7..c9b99a1646c 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -215,10 +215,6 @@ struct vk_draw_triangles VkSampler sampler; /* ptr alignment */ size_t uniform_size; unsigned vertices; - /* When true, vertices are groups of 4 (quads) and will be - * drawn with the shared index buffer via vkCmdDrawIndexed. - * When false, vertices are drawn directly via vkCmdDraw. */ - bool indexed_quads; }; typedef struct vk @@ -298,9 +294,22 @@ typedef struct vk struct { - VkPipeline pipelines[9 * 2]; + /* Layout: every menu draw uses a triangle-strip topology, so this + * driver only keeps STRIP variants: + * [0] alpha_blend, no blend + * [1] alpha_blend, blend + * [2] ribbon + * [3] ribbon_simple + * [4] snow_simple + * [5] snow + * [6] bokeh + * [7] snowflake + * All entries are TRIANGLE_STRIP topology. The history of this + * array previously included parallel TRIANGLE_LIST variants in + * even slots; they were built at init and never used. */ + VkPipeline pipelines[8]; #ifdef VULKAN_HDR_SWAPCHAIN - VkPipeline pipelines_sdr[9 * 2]; /* SDR offscreen variants */ + VkPipeline pipelines_sdr[8]; /* SDR offscreen variants, same layout */ #endif struct vk_texture blank_texture; } display; @@ -945,29 +954,7 @@ static void vulkan_draw_triangles(vk_t *vk, const struct vk_draw_triangles *call vkCmdBindVertexBuffers(vk->cmd, 0, 1, &call->vbo->buffer, &call->vbo->offset); - /* Use indexed draw for quad-based geometry. - * Quads use 4 vertices each with the shared index buffer, - * saving 33% VBO bandwidth compared to 6 vertices per quad. */ - if (call->indexed_quads && vk->quad_ibo.buffer != VK_NULL_HANDLE) - { - unsigned num_quads = call->vertices / 4; - /* Guard against exceeding IBO capacity to prevent - * out-of-bounds index reads - * (VUID-vkCmdDrawIndexed-indexSize-00463). */ - if (num_quads <= vk->quad_ibo.num_quads) - { - unsigned index_count = num_quads * 6; - vkCmdBindIndexBuffer(vk->cmd, vk->quad_ibo.buffer, - 0, VK_INDEX_TYPE_UINT16); - vkCmdDrawIndexed(vk->cmd, index_count, 1, 0, 0, 0); - } - else - vkCmdDraw(vk->cmd, call->vertices, 1, 0, 0); - } - else - { - vkCmdDraw(vk->cmd, call->vertices, 1, 0, 0); - } + vkCmdDraw(vk->cmd, call->vertices, 1, 0, 0); } @@ -1774,23 +1761,27 @@ static const float *gfx_display_vk_get_default_tex_coords(void) } #ifdef HAVE_SHADERPIPELINE -static unsigned to_menu_pipeline( - enum gfx_display_prim_type type, unsigned pipeline) +static unsigned to_menu_pipeline(unsigned pipeline) { + /* The display pipeline array slots [2..7] hold the six menu + * shader pipelines (ribbon, ribbon_simple, snow_simple, snow, + * bokeh, snowflake) in that order. VIDEO_SHADER_MENU through + * VIDEO_SHADER_MENU_6 are consecutive descending #defines, so + * the mapping is a simple offset. */ switch (pipeline) { case VIDEO_SHADER_MENU: - return 6 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP); + return 2; case VIDEO_SHADER_MENU_2: - return 8 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP); + return 3; case VIDEO_SHADER_MENU_3: - return 10 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP); + return 4; case VIDEO_SHADER_MENU_4: - return 12 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP); + return 5; case VIDEO_SHADER_MENU_5: - return 14 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP); + return 6; case VIDEO_SHADER_MENU_6: - return 16 + (type == GFX_DISPLAY_PRIM_TRIANGLESTRIP); + return 7; default: break; } @@ -1873,7 +1864,6 @@ static void gfx_display_vk_draw_pipeline( + 3 * sizeof(float), &yflip, sizeof(yflip)); draw->coords = &blank_coords; blank_coords.vertices = 4; - draw->prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; break; } @@ -1987,7 +1977,7 @@ static void gfx_display_vk_draw(gfx_display_ctx_draw_t *draw, case VIDEO_SHADER_MENU_6: { struct vk_draw_triangles call; - unsigned idx = to_menu_pipeline(draw->prim_type, draw->pipeline_id); + unsigned idx = to_menu_pipeline(draw->pipeline_id); #ifdef VULKAN_HDR_SWAPCHAIN call.pipeline = (vk->flags & VK_FLAG_SDR_PIPELINE) @@ -2002,7 +1992,6 @@ static void gfx_display_vk_draw(gfx_display_ctx_draw_t *draw, call.uniform_size = draw->backend_data_size; call.vbo = ⦥ call.vertices = draw->coords->vertices; - call.indexed_quads = false; vulkan_draw_triangles(vk, &call); } @@ -2012,10 +2001,11 @@ static void gfx_display_vk_draw(gfx_display_ctx_draw_t *draw, default: { struct vk_draw_triangles call; + /* Slot 0 = no blend, slot 1 = blend. Both are TRIANGLE_STRIP + * (every menu draw is a tristrip; see the comment on + * display.pipelines for the layout). */ unsigned - disp_pipeline = - ((draw->prim_type == GFX_DISPLAY_PRIM_TRIANGLESTRIP) << 1) - | (((vk->flags & VK_FLAG_DISPLAY_BLEND) > 0) << 0); + disp_pipeline = ((vk->flags & VK_FLAG_DISPLAY_BLEND) > 0); #ifdef VULKAN_HDR_SWAPCHAIN call.pipeline = (vk->flags & VK_FLAG_SDR_PIPELINE) ? vk->display.pipelines_sdr[disp_pipeline] @@ -2034,7 +2024,6 @@ static void gfx_display_vk_draw(gfx_display_ctx_draw_t *draw, call.uniform_size = sizeof(math_matrix_4x4); call.vbo = ⦥ call.vertices = draw->coords->vertices; - call.indexed_quads = false; vulkan_draw_triangles(vk, &call); } @@ -2519,7 +2508,6 @@ static void vulkan_font_render_msg( * Vulkan commands directly we eliminate: * - packing/unpacking through struct vk_draw_triangles * - the generic vulkan_draw_triangles() indirection - * - the runtime branch on indexed_quads (always true for fonts) * - the null-check on texture->image (always valid for fonts) */ @@ -3499,13 +3487,12 @@ static void vulkan_init_pipelines(vk_t *vk) vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, 1, &pipe, NULL, &vk->pipelines.alpha_blend); - /* Build display pipelines. */ - for (i = 0; i < 4; i++) + /* Build display pipelines (STRIP topology only). + * [0]: blend off, [1]: blend on. */ + input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + for (i = 0; i < 2; i++) { - input_assembly.topology = i & 2 ? - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP : - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - blend_attachment.blendEnable = i & 1; + blend_attachment.blendEnable = i; vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, 1, &pipe, NULL, &vk->display.pipelines[i]); } @@ -3533,13 +3520,16 @@ static void vulkan_init_pipelines(vk_t *vk) vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, 1, &pipe, NULL, &vk->pipelines.hdr); - /* Build display hdr pipelines. */ - for (i = 4; i < 6; i++) - { - input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, - 1, &pipe, NULL, &vk->display.pipelines[i]); - } + /* The previous code built two additional display pipelines + * here (in old slots 4 and 5) using the hdr_frag shader. Both + * iterations of that loop produced identical pipeline objects + * (no varying state between them), and no consumer ever + * indexed slots 4 or 5 -- they were copy-paste residue from + * the SDR-side loop above and went unused even with HDR + * enabled. The dedicated `vk->pipelines.hdr` field built + * just above is the actual HDR composition pipeline; it is + * still used by vulkan_run_hdr_pipeline at the swapchain + * presentation path. */ vkDestroyShaderModule(vk->context->device, shader_stages[1].module, NULL); @@ -3572,10 +3562,13 @@ static void vulkan_init_pipelines(vk_t *vk) * readback_render_pass. */ pipe.renderPass = vk->render_pass; - /* Other menu pipelines. */ - for (i = 0; i < (int)ARRAY_SIZE(vk->display.pipelines) - 6; i++) + /* Other menu pipelines. Six STRIP-only variants populate + * slots [2..7]: ribbon, ribbon_simple, snow_simple, snow, + * bokeh, snowflake. See display.pipelines for layout. */ + input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + for (i = 0; i < 6; i++) { - switch (i >> 1) + switch (i) { case 0: module_info.codeSize = sizeof(pipeline_ribbon_vert); @@ -3587,28 +3580,10 @@ static void vulkan_init_pipelines(vk_t *vk) module_info.pCode = pipeline_ribbon_simple_vert; break; - case 2: - module_info.codeSize = sizeof(alpha_blend_vert); - module_info.pCode = alpha_blend_vert; - break; - - case 3: - module_info.codeSize = sizeof(alpha_blend_vert); - module_info.pCode = alpha_blend_vert; - break; - - case 4: - module_info.codeSize = sizeof(alpha_blend_vert); - module_info.pCode = alpha_blend_vert; - break; - - case 5: + default: module_info.codeSize = sizeof(alpha_blend_vert); module_info.pCode = alpha_blend_vert; break; - - default: - break; } shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; @@ -3616,7 +3591,7 @@ static void vulkan_init_pipelines(vk_t *vk) vkCreateShaderModule(vk->context->device, &module_info, NULL, &shader_stages[0].module); - switch (i >> 1) + switch (i) { case 0: module_info.codeSize = sizeof(pipeline_ribbon_frag); @@ -3657,7 +3632,7 @@ static void vulkan_init_pipelines(vk_t *vk) vkCreateShaderModule(vk->context->device, &module_info, NULL, &shader_stages[1].module); - switch (i >> 1) + switch (i) { case 0: case 1: @@ -3670,12 +3645,8 @@ static void vulkan_init_pipelines(vk_t *vk) break; } - input_assembly.topology = i & 1 ? - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP : - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, - 1, &pipe, NULL, &vk->display.pipelines[6 + i]); + 1, &pipe, NULL, &vk->display.pipelines[2 + i]); vkDestroyShaderModule(vk->context->device, shader_stages[0].module, NULL); vkDestroyShaderModule(vk->context->device, shader_stages[1].module, NULL); @@ -3731,16 +3702,15 @@ static void vulkan_init_pipelines(vk_t *vk) vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, 1, &pipe, NULL, &vk->pipelines.alpha_blend_sdr); - /* SDR display pipelines 0-3. + /* SDR display pipelines, slots [0..1]. STRIP-only, see the + * matching comment on the main display.pipelines build above. * Reuse the alpha_blend vertex shader (stages[0]) and * alpha_blend fragment shader (stages[1]) still alive * from just above. */ - for (i = 0; i < 4; i++) + input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + for (i = 0; i < 2; i++) { - input_assembly.topology = i & 2 ? - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP : - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - blend_attachment.blendEnable = i & 1; + blend_attachment.blendEnable = i; vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, 1, &pipe, NULL, &vk->display.pipelines_sdr[i]); } @@ -3749,10 +3719,12 @@ static void vulkan_init_pipelines(vk_t *vk) vkDestroyShaderModule(vk->context->device, shader_stages[0].module, NULL); vkDestroyShaderModule(vk->context->device, shader_stages[1].module, NULL); - /* SDR menu shader pipelines 6+ */ - for (i = 0; i < (int)ARRAY_SIZE(vk->display.pipelines) - 6; i++) + /* SDR menu shader pipelines, slots [2..7]. STRIP-only; + * mirror of the main display.pipelines build. */ + input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + for (i = 0; i < 6; i++) { - switch (i >> 1) + switch (i) { case 0: module_info.codeSize = sizeof(pipeline_ribbon_vert); @@ -3772,7 +3744,7 @@ static void vulkan_init_pipelines(vk_t *vk) vkCreateShaderModule(vk->context->device, &module_info, NULL, &shader_stages[0].module); - switch (i >> 1) + switch (i) { case 0: module_info.codeSize = sizeof(pipeline_ribbon_frag); @@ -3806,7 +3778,7 @@ static void vulkan_init_pipelines(vk_t *vk) vkCreateShaderModule(vk->context->device, &module_info, NULL, &shader_stages[1].module); - switch (i >> 1) + switch (i) { case 0: case 1: @@ -3819,12 +3791,8 @@ static void vulkan_init_pipelines(vk_t *vk) break; } - input_assembly.topology = i & 1 ? - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP : - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache, - 1, &pipe, NULL, &vk->display.pipelines_sdr[6 + i]); + 1, &pipe, NULL, &vk->display.pipelines_sdr[2 + i]); vkDestroyShaderModule(vk->context->device, shader_stages[0].module, NULL); vkDestroyShaderModule(vk->context->device, shader_stages[1].module, NULL); @@ -4987,7 +4955,8 @@ static void *vulkan_init(const video_info_t *video, if (temp_width != 0 && temp_height != 0) video_driver_set_size(temp_width, temp_height); - video_driver_get_size(&temp_width, &temp_height); + else + video_driver_get_size(&temp_width, &temp_height); vk->video_width = temp_width; vk->video_height = temp_height; vk->translate_x = 0.0; @@ -8148,12 +8117,14 @@ static void vulkan_render_overlay(vk_t *vk, unsigned width, { int idx = base + i; struct vk_texture *tex = &vk->overlay.images[idx]; + /* Slot [1] is alpha-blend, TRIANGLE_STRIP (the only + * topology this driver builds; see display.pipelines). */ #ifdef VULKAN_HDR_SWAPCHAIN VkPipeline pipeline = (vk->flags & VK_FLAG_SDR_PIPELINE) - ? vk->display.pipelines_sdr[3] - : vk->display.pipelines[3]; /* Strip with blend */ + ? vk->display.pipelines_sdr[1] + : vk->display.pipelines[1]; #else - VkPipeline pipeline = vk->display.pipelines[3]; /* Strip with blend */ + VkPipeline pipeline = vk->display.pipelines[1]; #endif if (tex->image) diff --git a/gfx/gfx_display.c b/gfx/gfx_display.c index 19200dcc541..d175f2db492 100644 --- a/gfx/gfx_display.c +++ b/gfx/gfx_display.c @@ -520,7 +520,6 @@ void gfx_display_draw_quad( draw.texture = (texture && *texture) ? *texture : gfx_white_texture; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; draw.scale_factor = 1.0f; draw.rotation = 0.0f; @@ -651,7 +650,6 @@ void gfx_display_draw_texture_slice( draw.height = height; draw.coords = &coords; draw.matrix_data = mymat; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; coords.color = (const float*)(color == NULL ? colors : color); @@ -914,7 +912,6 @@ void gfx_display_draw_cursor( draw.coords = &coords; draw.matrix_data = NULL; draw.texture = texture; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; draw.scale_factor = 1.0f; draw.rotation = 0.0f; diff --git a/gfx/gfx_display.h b/gfx/gfx_display.h index 0706f973d36..cafd9db61c4 100644 --- a/gfx/gfx_display.h +++ b/gfx/gfx_display.h @@ -83,13 +83,6 @@ enum menu_driver_id_type MENU_DRIVER_ID_XMB }; -enum gfx_display_prim_type -{ - GFX_DISPLAY_PRIM_NONE = 0, - GFX_DISPLAY_PRIM_TRIANGLESTRIP, - GFX_DISPLAY_PRIM_TRIANGLES -}; - enum gfx_display_driver_type { GFX_VIDEO_DRIVER_GENERIC = 0, @@ -165,7 +158,6 @@ struct gfx_display_ctx_draw float y; float rotation; float scale_factor; - enum gfx_display_prim_type prim_type; bool pipeline_active; }; diff --git a/gfx/gfx_thumbnail.c b/gfx/gfx_thumbnail.c index 624a7238652..e2562592dcf 100644 --- a/gfx/gfx_thumbnail.c +++ b/gfx/gfx_thumbnail.c @@ -1102,7 +1102,6 @@ void gfx_thumbnail_draw( draw.coords = &coords; draw.matrix_data = &mymat; draw.texture = thumb_texture; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; /* Set thumbnail alignment within bounding box */ diff --git a/gfx/gfx_widgets.c b/gfx/gfx_widgets.c index 2b7ff979e0f..62e2babcd9e 100644 --- a/gfx/gfx_widgets.c +++ b/gfx/gfx_widgets.c @@ -721,7 +721,6 @@ void gfx_widgets_draw_icon( draw.coords = &coords; draw.matrix_data = &mymat; draw.texture = texture; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; if (draw.height > 0 && draw.width > 0) diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 1aa731ef3f7..3f1989afda0 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -2634,7 +2634,6 @@ static void materialui_draw_icon( draw.coords = &coords; draw.matrix_data = mymat; draw.texture = texture; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; if (dispctx) @@ -3353,22 +3352,23 @@ static float materialui_get_scroll(materialui_handle_t *mui, gfx_display_t *p_disp) { size_t i; + unsigned height; materialui_node_t *node = NULL; struct menu_state *menu_st = menu_state_get_ptr(); menu_list_t *menu_list = menu_st->entries.list; file_list_t *list = MENU_LIST_GET_SELECTION(menu_list, 0); size_t selection = menu_st->selection_ptr; unsigned header_height = p_disp->header_height; - unsigned width = 0; - unsigned height = 0; float view_centre = 0.0f; float selection_centre = 0.0f; if (!mui || !list || !list->size) return 0; - /* Get current window size */ - video_driver_get_size(&width, &height); + /* Read cached size from mui rather than locking video_st via + * video_driver_get_size: mui->last_{width,height} is updated + * every frame in materialui_render. */ + height = mui->last_height; /* Get the vertical midpoint of the actual * list view - i.e. account for header + @@ -6202,7 +6202,6 @@ static void materialui_render_background( draw.height = video_height; draw.coords = NULL; draw.matrix_data = NULL; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.vertex = NULL; draw.tex_coord = NULL; draw.vertex_count = 4; @@ -10789,14 +10788,12 @@ static int materialui_pointer_down(void *userdata, if ( (mui->flags & MUI_FLAG_SCROLLBAR_ACTIVE) && (!(mui->flags & MUI_FLAG_SHOW_FULLSCREEN_THUMBNAILS))) { - unsigned width; - unsigned height; int drag_margin_horz; int drag_margin_vert; gfx_display_t *p_disp = disp_get_ptr(); unsigned header_height = p_disp->header_height; - - video_driver_get_size(&width, &height); + unsigned width = mui->last_width; + unsigned height = mui->last_height; /* Check whether pointer down event is within * vertical list region */ @@ -11030,6 +11027,10 @@ static int materialui_pointer_up(void *userdata, if (!mui) return -1; + /* Read cached size from mui rather than locking video_st via + * video_driver_get_size: mui->last_{width,height} is updated + * every frame in materialui_render. */ + /* All input is ignored if user was previously * dragging the scrollbar */ if (mui->flags & MUI_FLAG_SCROLLBAR_DRAGGED) @@ -11060,7 +11061,8 @@ static int materialui_pointer_up(void *userdata, return 0; } - video_driver_get_size(&width, &height); + width = mui->last_width; + height = mui->last_height; switch (gesture) { diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index bdcb1b443c1..024c59db267 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -3089,7 +3089,6 @@ static void ozone_draw_icon( draw.coords = &coords; draw.matrix_data = mymat; draw.texture = texture; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; if (draw.height > 0 && draw.width > 0) @@ -4751,7 +4750,7 @@ static void ozone_list_cache(void *data, ozone->flags &= ~OZONE_FLAG_IS_PLAYLIST_OLD; /* Deep copy visible elements */ - video_driver_get_size(NULL, &video_info_height); + video_info_height = ozone->last_height; y = ozone->dimensions.header_height + ozone->dimensions.entry_padding_vertical; entries_end = MENU_LIST_GET_SELECTION(menu_list, 0)->size; selection_buf = MENU_LIST_GET_SELECTION(menu_list, 0); @@ -4860,14 +4859,12 @@ static void ozone_sidebar_goto(ozone_handle_t *ozone, size_t new_selection) #endif }; - unsigned video_info_height; + unsigned video_info_height = ozone->last_height; struct gfx_animation_ctx_entry entry; uintptr_t tag = (uintptr_t)ozone; struct menu_state *menu_st = menu_state_get_ptr(); menu_input_t *menu_input = &menu_st->input_state; - video_driver_get_size(NULL, &video_info_height); - if (ozone->categories_selection_ptr != new_selection) { ozone->categories_active_idx_old = ozone->categories_selection_ptr; @@ -5605,7 +5602,7 @@ static void ozone_content_metadata_line( static void ozone_update_scroll(ozone_handle_t *ozone, bool allow_animation, ozone_node_t *node) { - unsigned video_info_height; + unsigned video_info_height = ozone->last_height; gfx_animation_ctx_entry_t entry; float new_scroll = 0, entries_middle; float bottom_boundary, current_selection_middle_onscreen; @@ -5615,8 +5612,6 @@ static void ozone_update_scroll(ozone_handle_t *ozone, file_list_t *selection_buf = MENU_LIST_GET_SELECTION(menu_list, 0); uintptr_t tag = (uintptr_t)selection_buf; - video_driver_get_size(NULL, &video_info_height); - if (!node) return; @@ -5702,8 +5697,8 @@ static void ozone_compute_entries_position(ozone_handle_t *ozone, { size_t i; /* Compute entries height and adjust scrolling if needed */ - unsigned video_info_height; - unsigned video_info_width; + unsigned video_info_height = ozone->last_height; + unsigned video_info_width = ozone->last_width; struct menu_state *menu_st = menu_state_get_ptr(); menu_list_t *menu_list = menu_st->entries.list; file_list_t *selection_buf = NULL; @@ -5729,8 +5724,6 @@ static void ozone_compute_entries_position(ozone_handle_t *ozone, if (!selection_buf->size) return; - video_driver_get_size(&video_info_width, &video_info_height); - if (menu_show_sublabels) sublabel_max_width = ozone_get_sublabel_max_width(ozone, video_info_width, entry_padding); @@ -5842,7 +5835,8 @@ static void ozone_draw_entries( size_t i; uint32_t alpha_uint32; float bottom_boundary; - unsigned video_info_height, video_info_width; + unsigned video_info_height = ozone->last_height; + unsigned video_info_width = ozone->last_width; float last_border_alpha = -1.0f; bool menu_show_sublabels = settings->bools.menu_show_sublabels; bool use_smooth_ticker = settings->bools.menu_ticker_smooth; @@ -5874,8 +5868,6 @@ static void ozone_draw_entries( float invert = (ozone->flags & OZONE_FLAG_FADE_DIRECTION) ? -1 : 1; float alpha_anim = old_list ? alpha : 1.0f - alpha; - video_driver_get_size(&video_info_width, &video_info_height); - bottom_boundary = video_info_height - ozone->dimensions.header_height - ozone->dimensions.footer_height; @@ -13304,8 +13296,9 @@ static int ozone_pointer_up(void *userdata, menu_entry_t *entry, unsigned action) { - unsigned int width, height; ozone_handle_t *ozone = (ozone_handle_t*)userdata; + unsigned int width = ozone->last_width; + unsigned int height = ozone->last_height; struct menu_state *menu_st = menu_state_get_ptr(); menu_input_t *menu_input = &menu_st->input_state; menu_list_t *menu_list = menu_st->entries.list; @@ -13335,8 +13328,6 @@ static int ozone_pointer_up(void *userdata, return 0; } - video_driver_get_size(&width, &height); - switch (gesture) { case MENU_INPUT_GESTURE_TAP: diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index ff34f03b487..bd6a2c63b57 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -519,6 +519,14 @@ typedef struct xmb_handle * Prevents use-after-free on textures/fonts during driver * reinit under threaded video. */ uint32_t context_generation; + + /* Surface size last seen by xmb_frame. Updated every frame + * from video_info->{width,height} so non-render code paths + * (selection_pointer_changed, list_open_new, list_switch_new, + * list_cache, pointer_up, layout) can read the size without + * locking video_st via video_driver_get_size. */ + unsigned last_width; + unsigned last_height; } xmb_handle_t; /* Constant color templates — safe to share across threads. @@ -1039,7 +1047,6 @@ static void xmb_draw_icon( draw.coords = &coords; draw.matrix_data = &mymat_tmp; draw.texture = texture; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; if (shadows_enable) @@ -1896,7 +1903,7 @@ static void xmb_selection_pointer_changed( threshold = xmb->icon_size * 10; menu_st->entries.begin = num; - video_driver_get_size(NULL, &height); + height = xmb->last_height; /* On cursor movement within a playlist, invalidate any in-flight * icon thumbnail requests (they're for the previous cursor position @@ -2082,14 +2089,13 @@ static void xmb_list_open_new(xmb_handle_t *xmb, bool savestate_thumbnail, file_list_t *list, int dir, size_t current) { - unsigned i, height; + unsigned i; + unsigned height = xmb->last_height; size_t skip = 0; int threshold = xmb->icon_size * 10; size_t end = list ? list->size : 0; struct menu_state *menu_st = menu_state_get_ptr(); - video_driver_get_size(NULL, &height); - for (i = 0; i < end; i++) { float ia; @@ -2270,7 +2276,8 @@ static void xmb_animation_list_alpha(xmb_handle_t *xmb, bool fade_in) static void xmb_list_switch_new(xmb_handle_t *xmb, file_list_t *list, int dir, size_t current) { - unsigned i, height; + unsigned i; + unsigned height = xmb->last_height; unsigned last = 0; unsigned first = 0; size_t end = 0; @@ -2281,7 +2288,6 @@ static void xmb_list_switch_new(xmb_handle_t *xmb, if (end > 0) last = (unsigned)(end - 1); - video_driver_get_size(NULL, &height); xmb_calculate_visible_range(xmb, height, end, (unsigned)current, &first, &last); for (i = 0; i < end; i++) @@ -6470,7 +6476,9 @@ static void xmb_init_scale_mod(float *scale_mod, float scale_value) static void xmb_layout(xmb_handle_t *xmb) { - unsigned width, height, i; + unsigned i; + unsigned width = xmb->last_width; + unsigned height = xmb->last_height; struct menu_state *menu_st = menu_state_get_ptr(); menu_list_t *menu_list = menu_st->entries.list; file_list_t *selection_buf = MENU_LIST_GET_SELECTION(menu_list, 0); @@ -6478,7 +6486,6 @@ static void xmb_layout(xmb_handle_t *xmb) unsigned current = (unsigned)selection; unsigned end = (unsigned)MENU_LIST_GET_SELECTION(menu_list, 0)->size; - video_driver_get_size(&width, &height); xmb_init_scale_mod(xmb->scale_mod, config_get_ptr()->floats.menu_scale_factor * 100.0f); if (xmb->use_ps3_layout) @@ -7566,7 +7573,6 @@ static void xmb_draw_bg( draw.vertex = NULL; draw.tex_coord = NULL; draw.vertex_count = 4; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; draw.pipeline_active = (menu_shader_pipeline == XMB_SHADER_PIPELINE_WALLPAPER) ? false : true; @@ -7675,7 +7681,6 @@ static void xmb_draw_dark_layer( draw.tex_coord = NULL; draw.vertex_count = 4; draw.texture = 0; - draw.prim_type = GFX_DISPLAY_PRIM_TRIANGLESTRIP; draw.pipeline_id = 0; draw.pipeline_active = false; @@ -8233,6 +8238,11 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) if (!xmb) return; + /* Cache the per-frame size on the handle so non-render paths + * can read it without locking video_st. */ + xmb->last_width = video_width; + xmb->last_height = video_height; + /* Snapshot context generation — if xmb_context_destroy() * runs on the main thread while we are mid-render on the * video thread, the generation will change and we must @@ -9484,6 +9494,11 @@ static void *xmb_init(void **userdata, bool video_is_threaded) return NULL; } + /* Initialise last_{width,height} from the snapshot taken + * above; xmb_frame will refresh these every render. */ + xmb->last_width = width; + xmb->last_height = height; + xmb_init_scale_mod(xmb->scale_mod, settings->floats.menu_scale_factor * 100.0f); *userdata = xmb; @@ -9760,8 +9775,7 @@ static void xmb_list_cache(void *data, enum menu_list_type type, if (xmb->allow_horizontal_animation) { unsigned first = 0, last = 0; - unsigned height = 0; - video_driver_get_size(NULL, &height); + unsigned height = xmb->last_height; /* FIXME: this shouldn't be happening at all */ if (selection >= selection_buf->size) @@ -10188,7 +10202,8 @@ static int xmb_pointer_up(void *userdata, return 0; } - video_driver_get_size(&width, &height); + width = xmb->last_width; + height = xmb->last_height; margin_top = (int16_t)xmb->margins_screen_top; margin_left = (int16_t)xmb->margins_screen_left; margin_right = (int16_t)((float)width - xmb->margins_screen_left); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 690fa44fcbf..e709cec8bea 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -8932,7 +8932,7 @@ static void general_write_handler(rarch_setting_t *setting) aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (float)custom_vp->width / custom_vp->height; /* Update Aspect Ratio (only useful for 1:1 PAR) */ - video_driver_set_aspect_ratio(); + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); } } break; diff --git a/pkg/apple/make-frameworks.sh b/pkg/apple/make-frameworks.sh index b40ddf7a3f4..1467f22be1b 100755 --- a/pkg/apple/make-frameworks.sh +++ b/pkg/apple/make-frameworks.sh @@ -114,6 +114,14 @@ MVK_PLATFORM_SUBDIR="${SWIFT_PLATFORM_TARGET_PREFIX}-$(echo $ARCHS_STANDARD_64_B if [ -d "${MOLTENVK_XCFRAMEWORK}/${MVK_PLATFORM_SUBDIR}/MoltenVK.framework" ] ; then echo copying moltenvk from "${MOLTENVK_XCFRAMEWORK}/${MVK_PLATFORM_SUBDIR}/MoltenVK.framework" cp -R "${MOLTENVK_XCFRAMEWORK}/${MVK_PLATFORM_SUBDIR}/MoltenVK.framework" "${OUTDIR}" + # tvOS App Store rejects arm64e; strip it from the fat MoltenVK binary + if [ "$PLATFORM_FAMILY_NAME" = "tvOS" -a "$APPSTORE_BUILD" = "1" ] ; then + MVK_BIN="${OUTDIR}/MoltenVK.framework/MoltenVK" + if lipo -info "$MVK_BIN" 2>/dev/null | grep -q arm64e ; then + echo "stripping arm64e from MoltenVK for tvOS App Store build" + lipo -remove arm64e "$MVK_BIN" -output "$MVK_BIN" + fi + fi codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${OUTDIR}/MoltenVK.framework" fi diff --git a/runloop.c b/runloop.c index f4970e1ffed..c8078db282f 100644 --- a/runloop.c +++ b/runloop.c @@ -2449,7 +2449,7 @@ bool runloop_environment_cb(unsigned cmd, void *data) RARCH_LOG("[Environ] Setting audio latency to %u ms.\n", audio_latency_new); command_event(CMD_EVENT_REINIT, &reinit_flags); - video_driver_set_aspect_ratio(); + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); /* Cannot continue recording with different * parameters. @@ -2688,7 +2688,7 @@ bool runloop_environment_cb(unsigned cmd, void *data) command_event(CMD_EVENT_REINIT, &reinit_flags); if (no_video_reinit) - video_driver_set_aspect_ratio(); + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); if (video_switch_refresh_rate) video_display_server_set_refresh_rate(refresh_rate); @@ -2919,7 +2919,7 @@ bool runloop_environment_cb(unsigned cmd, void *data) /* Forces recomputation of aspect ratios if * using core-dependent aspect ratios. */ - video_driver_set_aspect_ratio(); + command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL); /* Ignore frame delay target temporarily */ if (video_frame_delay_auto)