Skip to content

Commit 5298e70

Browse files
committed
Metal: inline single-call helpers in render path
Fold the following private methods into their callers: MetalDriver: -_beginFrame, -_drawCore, -_drawMenu:, -_renderMessage:data: → -renderFrame:data:width:height:frameCount:pitch:msg:info: FrameView: -_convertFormat → -drawWithContext: -_initHistory → -_updateHistory TexturedView: -_convertFormat → -drawWithContext: Each of these had exactly one caller and existed only as a name for a short block of code. Inlining them removes a layer of indirection and, as a side effect, cleans up some duplicated work the function boundaries were hiding: - _context.rce is now fetched once per frame instead of three times (was refetched in _drawCore, _drawMenu:, and the inline overlay block). - menu_is_alive is computed once instead of twice per frame. - video_frame_info_t* no longer crosses a method boundary just to read MENU_ST_FLAG_ALIVE. setViewportWidth:height:forceFull:allowRotate: and MetalMenu's -updateFrame: are kept as-is; both are entry points for C trampolines (metal_set_viewport, metal_raster_thread). No functional change.
1 parent 371f419 commit 5298e70

1 file changed

Lines changed: 113 additions & 157 deletions

File tree

gfx/drivers/metal.m

Lines changed: 113 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ - (CGRect)frame
15041504
return _frame;
15051505
}
15061506

1507-
- (void)_convertFormat
1507+
- (void)drawWithContext:(Context *)ctx
15081508
{
15091509
if ( _format == RPixelFormatBGRA8Unorm
15101510
|| _format == RPixelFormatBGRX8Unorm)
@@ -1517,11 +1517,6 @@ - (void)_convertFormat
15171517
_srcDirty = NO;
15181518
}
15191519

1520-
- (void)drawWithContext:(Context *)ctx
1521-
{
1522-
[self _convertFormat];
1523-
}
1524-
15251520
- (void)drawWithEncoder:(id<MTLRenderCommandEncoder>)rce
15261521
{
15271522
[rce setVertexBytes:&_v length:sizeof(_v) atIndex:BufferIndexPositions];
@@ -2468,8 +2463,18 @@ - (bool)renderFrame:(const void *)frame
24682463
@autoreleasepool
24692464
{
24702465
bool statistics_show = video_info->statistics_show;
2466+
bool menu_is_alive = (video_info->menu_st_flags & MENU_ST_FLAG_ALIVE) ? true : false;
2467+
id<MTLRenderCommandEncoder> rce;
24712468

2472-
[self _beginFrame];
2469+
/* Begin frame: re-evaluate viewport, push to context if it changed,
2470+
* then begin the command buffer / render pass. */
2471+
{
2472+
video_viewport_t vp = *_viewport;
2473+
video_driver_update_viewport(_viewport, NO, _keepAspect, YES);
2474+
if (memcmp(&vp, _viewport, sizeof(vp)) != 0)
2475+
_context.viewport = _viewport;
2476+
[_context begin];
2477+
}
24732478

24742479
_frameView.frameCount = frameCount;
24752480
if (frame && width && height)
@@ -2478,12 +2483,46 @@ - (bool)renderFrame:(const void *)frame
24782483
[_frameView updateFrame:frame pitch:pitch];
24792484
}
24802485

2481-
[self _drawCore];
2482-
[self _drawMenu:video_info];
2486+
rce = _context.rce;
24832487

2484-
#ifdef HAVE_OVERLAY
2485-
id<MTLRenderCommandEncoder> rce = _context.rce;
2488+
/* Draw core: back buffer + optional encoder pass. */
2489+
[_frameView drawWithContext:_context];
2490+
if ((_frameView.drawState & ViewDrawStateEncoder) != 0)
2491+
{
2492+
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
2493+
[rce setRenderPipelineState:_t_pipelineStateNoAlpha];
2494+
if (_frameView.filter == RTextureFilterNearest)
2495+
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
2496+
else
2497+
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
2498+
[_frameView drawWithEncoder:rce];
2499+
}
24862500

2501+
/* Draw menu: textured menu frame if present, otherwise delegate to
2502+
* the menu driver for widget-based menus. */
2503+
if (_menu.enabled)
2504+
{
2505+
if (_menu.hasFrame)
2506+
{
2507+
[_menu.view drawWithContext:_context];
2508+
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
2509+
[rce setRenderPipelineState:_t_pipelineState];
2510+
if (_menu.view.filter == RTextureFilterNearest)
2511+
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
2512+
else
2513+
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
2514+
[_menu.view drawWithEncoder:rce];
2515+
}
2516+
#if defined(HAVE_MENU)
2517+
else
2518+
{
2519+
[_context resetRenderViewport:kFullscreenViewport];
2520+
menu_driver_frame(menu_is_alive, video_info);
2521+
}
2522+
#endif
2523+
}
2524+
2525+
#ifdef HAVE_OVERLAY
24872526
if (_overlay.enabled)
24882527
{
24892528
[_context resetRenderViewport:_overlay.fullscreen ? kFullscreenViewport : kVideoViewport];
@@ -2495,135 +2534,61 @@ - (bool)renderFrame:(const void *)frame
24952534
#endif
24962535

24972536
/* Only show statistics when menu is not visible and content is running */
2498-
if (statistics_show && frame && width && height)
2537+
if (statistics_show && frame && width && height && !menu_is_alive)
24992538
{
2500-
bool menu_is_alive = (video_info->menu_st_flags & MENU_ST_FLAG_ALIVE) ? true : false;
2501-
if (!menu_is_alive)
2502-
{
2503-
struct font_params *osd_params = (struct font_params *)&video_info->osd_stat_params;
2504-
2505-
if (osd_params)
2506-
font_driver_render_msg(data, video_info->stat_text, osd_params, NULL);
2507-
}
2539+
struct font_params *osd_params = (struct font_params *)&video_info->osd_stat_params;
2540+
if (osd_params)
2541+
font_driver_render_msg(data, video_info->stat_text, osd_params, NULL);
25082542
}
25092543

25102544
#ifdef HAVE_GFX_WIDGETS
25112545
if (video_info->widgets_active)
25122546
gfx_widgets_frame(video_info);
25132547
#endif
25142548

2549+
/* Render on-screen message: optional background quad + text. */
25152550
if (msg && *msg)
2516-
[self _renderMessage:msg data:data];
2517-
[self _endFrame];
2518-
}
2519-
2520-
return YES;
2521-
}
2522-
2523-
- (void)_renderMessage:(const char *)msg
2524-
data:(void*)data
2525-
{
2526-
settings_t *settings = config_get_ptr();
2527-
bool msg_bgcolor_enable = settings->bools.video_msg_bgcolor_enable;
2528-
2529-
if (msg_bgcolor_enable)
2530-
{
2531-
float r, g, b, a;
2532-
int msg_width =
2533-
font_driver_get_message_width(NULL,
2534-
msg, strlen(msg), 1.0f);
2535-
float font_size = settings->floats.video_font_size;
2536-
unsigned bgcolor_red
2537-
= settings->uints.video_msg_bgcolor_red;
2538-
unsigned bgcolor_green
2539-
= settings->uints.video_msg_bgcolor_green;
2540-
unsigned bgcolor_blue
2541-
= settings->uints.video_msg_bgcolor_blue;
2542-
float bgcolor_opacity = settings->floats.video_msg_bgcolor_opacity;
2543-
float x = settings->floats.video_msg_pos_x;
2544-
float y = 1.0f - settings->floats.video_msg_pos_y;
2545-
float width = msg_width / (float)_viewport->full_width;
2546-
float height = font_size / (float)_viewport->full_height;
2547-
2548-
float x2 = 0.005f; /* extend background around text */
2549-
float y2 = 0.005f;
2550-
2551-
y -= height;
2552-
2553-
x -= x2;
2554-
y -= y2;
2555-
width += x2;
2556-
height += y2;
2557-
2558-
r = bgcolor_red / 255.0f;
2559-
g = bgcolor_green / 255.0f;
2560-
b = bgcolor_blue / 255.0f;
2561-
a = bgcolor_opacity;
2562-
2563-
[_context resetRenderViewport:kFullscreenViewport];
2564-
[_context drawQuadX:x y:y w:width h:height r:r g:g b:b a:a];
2565-
}
2566-
2567-
font_driver_render_msg(data, msg, NULL, NULL);
2568-
}
2569-
2570-
- (void)_beginFrame
2571-
{
2572-
video_viewport_t vp = *_viewport;
2573-
video_driver_update_viewport(_viewport, NO, _keepAspect, YES);
2574-
2575-
if (memcmp(&vp, _viewport, sizeof(vp)) != 0)
2576-
_context.viewport = _viewport;
2577-
2578-
[_context begin];
2579-
}
2551+
{
2552+
settings_t *settings = config_get_ptr();
2553+
bool msg_bgcolor_enable = settings->bools.video_msg_bgcolor_enable;
25802554

2581-
- (void)_drawCore
2582-
{
2583-
id<MTLRenderCommandEncoder> rce = _context.rce;
2555+
if (msg_bgcolor_enable)
2556+
{
2557+
int msg_width = font_driver_get_message_width(NULL,
2558+
msg, strlen(msg), 1.0f);
2559+
float font_size = settings->floats.video_font_size;
2560+
unsigned bgcolor_red = settings->uints.video_msg_bgcolor_red;
2561+
unsigned bgcolor_green= settings->uints.video_msg_bgcolor_green;
2562+
unsigned bgcolor_blue = settings->uints.video_msg_bgcolor_blue;
2563+
float bgcolor_opacity = settings->floats.video_msg_bgcolor_opacity;
2564+
float x = settings->floats.video_msg_pos_x;
2565+
float y = 1.0f - settings->floats.video_msg_pos_y;
2566+
float width_n = msg_width / (float)_viewport->full_width;
2567+
float height_n = font_size / (float)_viewport->full_height;
2568+
float x2 = 0.005f; /* extend background around text */
2569+
float y2 = 0.005f;
2570+
float r = bgcolor_red / 255.0f;
2571+
float g = bgcolor_green / 255.0f;
2572+
float b = bgcolor_blue / 255.0f;
2573+
float a = bgcolor_opacity;
2574+
2575+
y -= height_n;
2576+
x -= x2;
2577+
y -= y2;
2578+
width_n += x2;
2579+
height_n += y2;
2580+
2581+
[_context resetRenderViewport:kFullscreenViewport];
2582+
[_context drawQuadX:x y:y w:width_n h:height_n r:r g:g b:b a:a];
2583+
}
25842584

2585-
/* draw back buffer */
2586-
[_frameView drawWithContext:_context];
2585+
font_driver_render_msg(data, msg, NULL, NULL);
2586+
}
25872587

2588-
if ((_frameView.drawState & ViewDrawStateEncoder) != 0)
2589-
{
2590-
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
2591-
[rce setRenderPipelineState:_t_pipelineStateNoAlpha];
2592-
if (_frameView.filter == RTextureFilterNearest)
2593-
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
2594-
else
2595-
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
2596-
[_frameView drawWithEncoder:rce];
2588+
[self _endFrame];
25972589
}
2598-
}
2599-
2600-
- (void)_drawMenu:(video_frame_info_t *)video_info
2601-
{
2602-
bool menu_is_alive = (video_info->menu_st_flags & MENU_ST_FLAG_ALIVE) ? true : false;
2603-
2604-
if (!_menu.enabled)
2605-
return;
26062590

2607-
id<MTLRenderCommandEncoder> rce = _context.rce;
2608-
2609-
if (_menu.hasFrame)
2610-
{
2611-
[_menu.view drawWithContext:_context];
2612-
[rce setVertexBytes:_context.uniforms length:sizeof(*_context.uniforms) atIndex:BufferIndexUniforms];
2613-
[rce setRenderPipelineState:_t_pipelineState];
2614-
if (_menu.view.filter == RTextureFilterNearest)
2615-
[rce setFragmentSamplerState:_samplerStateNearest atIndex:SamplerIndexDraw];
2616-
else
2617-
[rce setFragmentSamplerState:_samplerStateLinear atIndex:SamplerIndexDraw];
2618-
[_menu.view drawWithEncoder:rce];
2619-
}
2620-
#if defined(HAVE_MENU)
2621-
else
2622-
{
2623-
[_context resetRenderViewport:kFullscreenViewport];
2624-
menu_driver_frame(menu_is_alive, video_info);
2625-
}
2626-
#endif
2591+
return YES;
26272592
}
26282593

26292594
- (void)_endFrame { [_context end]; }
@@ -2921,27 +2886,27 @@ - (void)setFrame:(CGRect)frame
29212886

29222887
- (CGRect)frame { return _frame; }
29232888

2924-
- (void)_convertFormat
2925-
{
2926-
if ( _format == RPixelFormatBGRA8Unorm
2927-
|| _format == RPixelFormatBGRX8Unorm)
2928-
return;
2929-
2930-
if (!_srcDirty)
2931-
return;
2932-
2933-
[_context convertFormat:_format from:_src to:_texture];
2934-
_srcDirty = NO;
2935-
}
2936-
29372889
- (void)_updateHistory
29382890
{
29392891
if (_shader)
29402892
{
29412893
if (_shader->history_size)
29422894
{
29432895
if (init_history)
2944-
[self _initHistory];
2896+
{
2897+
int i;
2898+
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
2899+
width:(NSUInteger)_size.width
2900+
height:(NSUInteger)_size.height
2901+
mipmapped:false];
2902+
td.usage = MTLTextureUsageShaderRead
2903+
| MTLTextureUsageShaderWrite
2904+
| MTLTextureUsageRenderTarget;
2905+
2906+
for (i = 0; i < _shader->history_size + 1; i++)
2907+
[self _initTexture:&_engine.frame.texture[i] withDescriptor:td];
2908+
init_history = NO;
2909+
}
29452910
else
29462911
{
29472912
int k;
@@ -3033,22 +2998,6 @@ - (void)_initTexture:(texture_t *)t withDescriptor:(MTLTextureDescriptor *)td
30332998
t->size_data.w = 1.0f / td.height;
30342999
}
30353000

3036-
- (void)_initHistory
3037-
{
3038-
int i;
3039-
MTLTextureDescriptor *td = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
3040-
width:(NSUInteger)_size.width
3041-
height:(NSUInteger)_size.height
3042-
mipmapped:false];
3043-
td.usage = MTLTextureUsageShaderRead
3044-
| MTLTextureUsageShaderWrite
3045-
| MTLTextureUsageRenderTarget;
3046-
3047-
for (i = 0; i < _shader->history_size + 1; i++)
3048-
[self _initTexture:&_engine.frame.texture[i] withDescriptor:td];
3049-
init_history = NO;
3050-
}
3051-
30523001
- (void)drawWithEncoder:(id<MTLRenderCommandEncoder>)rce
30533002
{
30543003
if (_texture)
@@ -3064,7 +3013,14 @@ - (void)drawWithContext:(Context *)ctx
30643013
{
30653014
int i;
30663015
_texture = _engine.frame.texture[0].view;
3067-
[self _convertFormat];
3016+
3017+
if ( (_format != RPixelFormatBGRA8Unorm)
3018+
&& (_format != RPixelFormatBGRX8Unorm)
3019+
&& _srcDirty)
3020+
{
3021+
[_context convertFormat:_format from:_src to:_texture];
3022+
_srcDirty = NO;
3023+
}
30683024

30693025
if (!_shader || _shader->passes == 0)
30703026
return;

0 commit comments

Comments
 (0)