@@ -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