Skip to content

Commit 7d6477b

Browse files
committed
gfx/d3d8: Wire up gfx_widgets_frame() in the frame function
The d3d8 backend's widgets_enabled hook was added in 5f23e85 to advertise widget support to the rest of RA, on the assumption (per the comment that landed alongside it) that widgets would "work transparently" once gfx_display was implemented. They didn't — d3d8_frame was missing the actual gfx_widgets_frame() call that every other consumer-facing video backend (d3d9/d3d10/d3d11/d3d12, gl1/gl2/gl3, vulkan, etc.) makes once per frame. Returning true from widgets_enabled tells RA to route runtime indicators — fast-forward, rewind, pause, FPS counter, achievement popups, load-progress bars, status text — into the widget queue (gfx_widgets_status_text + the per-widget animation state) instead of falling back to the runloop_msg → font_driver_render_msg path (see gfx/video_driver.c:4742). With no gfx_widgets_frame call, that state was assembled every frame but never rendered, so e.g. holding the fast-forward key produced no on-screen indicator. The fallback OSD msg path still rendered runloop_msg toasts when an overlay wasn't masking them, which is what made the regression look overlay-conditional in practice. Add the missing pieces: - Include gfx/gfx_widgets.h behind HAVE_GFX_WIDGETS, matching the d3d10/d3d9hlsl pattern. - Capture widgets_active from video_info at frame entry. - Between the overlay block and the OSD msg block, prepare the same device state the menu render path uses (reset menu_display.offset, bind the menu vertex buffer, full-screen viewport, ALPHABLENDENABLE re-enabled — d3d8_overlay_render disables it on the way out, defensive FVF) and call gfx_widgets_frame(video_info). No outer BeginScene/EndScene wrap is needed: gfx_display_d3d8_draw and d3d8_font_render_line both wrap their own scene around each DrawPrimitiveUP, matching the per-draw scene convention used throughout the rest of the d3d8 menu path. Also fix the comment on d3d8_gfx_widgets_enabled — the previous text claimed widgets worked transparently, which was wrong; it now documents what advertising support actually triggers in RA.
1 parent 1dff13b commit 7d6477b

1 file changed

Lines changed: 56 additions & 6 deletions

File tree

gfx/drivers/d3d8.c

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868

6969
#include "../font_driver.h"
7070
#include "../gfx_display.h"
71+
#ifdef HAVE_GFX_WIDGETS
72+
#include "../gfx_widgets.h"
73+
#endif
7174

7275
#include "../../core.h"
7376
#include "../../retroarch.h"
@@ -2843,6 +2846,9 @@ static bool d3d8_frame(void *data, const void *frame,
28432846
const char *stat_text = video_info->stat_text;
28442847
bool statistics_show = video_info->statistics_show;
28452848
unsigned black_frame_insertion = video_info->black_frame_insertion;
2849+
#ifdef HAVE_GFX_WIDGETS
2850+
bool widgets_active = video_info->widgets_active;
2851+
#endif
28462852
#ifdef HAVE_MENU
28472853
bool menu_is_alive = (video_info->menu_st_flags & MENU_ST_FLAG_ALIVE) ? true : false;
28482854
#endif
@@ -2931,6 +2937,46 @@ static bool d3d8_frame(void *data, const void *frame,
29312937
}
29322938
#endif
29332939

2940+
#ifdef HAVE_GFX_WIDGETS
2941+
/* Widget overlay (notifications, FPS counter, fast-forward
2942+
* indicator, achievement popups, load-progress bars, etc.).
2943+
*
2944+
* Widgets are drawn in screen-space using the same gfx_display
2945+
* ctx the menu uses, so all the prep here mirrors the
2946+
* pre-menu_driver_frame setup above:
2947+
* - reset menu_display.offset (gfx_display_d3d8_draw streams
2948+
* vertices into a ring at this offset)
2949+
* - bind the menu_display vertex buffer
2950+
* - full-screen viewport (widgets are positioned in screen
2951+
* pixels, not in the game viewport)
2952+
* - alpha blend on so semi-transparent widget panels
2953+
* composite over the framebuffer (overlay_render disables
2954+
* alpha blending on the way out, so we re-enable it here)
2955+
* - FVF reset defensively in case the overlay or renderchain
2956+
* left a different format bound
2957+
*
2958+
* gfx_widgets_frame ultimately calls gfx_display_d3d8_draw and
2959+
* d3d8_font_render_line, both of which wrap their own
2960+
* BeginScene/EndScene around each DrawPrimitiveUP, so we
2961+
* deliberately don't add an outer scene-wrap here. */
2962+
if (widgets_active)
2963+
{
2964+
d3d->menu_display.offset = 0;
2965+
IDirect3DDevice8_SetStreamSource(d3d->dev,
2966+
0, d3d->menu_display.buffer, sizeof(Vertex));
2967+
IDirect3DDevice8_SetViewport(d3d->dev, (D3DVIEWPORT8*)&screen_vp);
2968+
IDirect3DDevice8_SetRenderState(d3d->dev,
2969+
D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2970+
IDirect3DDevice8_SetRenderState(d3d->dev,
2971+
D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2972+
IDirect3DDevice8_SetRenderState(d3d->dev,
2973+
D3DRS_ALPHABLENDENABLE, TRUE);
2974+
IDirect3DDevice8_SetVertexShader(d3d->dev,
2975+
D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE);
2976+
gfx_widgets_frame(video_info);
2977+
}
2978+
#endif
2979+
29342980
if (msg && *msg)
29352981
{
29362982
IDirect3DDevice8_SetViewport(d3d->dev, (D3DVIEWPORT8*)&screen_vp);
@@ -3216,12 +3262,16 @@ static bool d3d8_has_windowed(void *data) { return true; }
32163262
#endif
32173263

32183264
#ifdef HAVE_GFX_WIDGETS
3219-
/* The gfx_widgets layer (notifications, achievement popups,
3220-
* load-progress indicators, etc.) is built on top of the same
3221-
* gfx_display_ctx that the menu uses, so once gfx_display is
3222-
* implemented the widgets only need a non-NULL hook returning
3223-
* true to be enabled. d3d8 has the full gfx_display path now,
3224-
* so widgets work transparently. */
3265+
/* Required hook: gfx_widgets initialises only on backends that
3266+
* advertise support via this callback. When it returns true RA
3267+
* routes things like the fast-forward indicator, FPS counter,
3268+
* achievement popups and load-progress bars to the widget layer
3269+
* (gfx_widgets_status_text + gfx_widgets_frame), bypassing the
3270+
* runloop-msg → font_driver_render_msg fallback that would
3271+
* otherwise fire for text-only notifications. d3d8_frame calls
3272+
* gfx_widgets_frame each frame after the overlay block, so all
3273+
* the widget rendering (which goes through gfx_display_d3d8_draw
3274+
* + d3d8_font_render_line) is wired up. */
32253275
static bool d3d8_gfx_widgets_enabled(void *data)
32263276
{
32273277
(void)data;

0 commit comments

Comments
 (0)