From 8569ee79bc111f8eb1f92eb2fa2c038c6a90ef6d Mon Sep 17 00:00:00 2001 From: Stuart Carnie Date: Tue, 6 Nov 2018 07:51:40 -0700 Subject: [PATCH] feat(metal): Add scissor rect support This is required for correct rendering of the ozone menu --- gfx/common/metal/Context.h | 3 +++ gfx/common/metal/Context.m | 11 +++++++++++ gfx/common/metal/MenuDisplay.h | 2 ++ gfx/common/metal/MenuDisplay.m | 22 +++++++++++++++++++++- menu/drivers_display/menu_display_metal.m | 23 +++++++++++++++++++++-- 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/gfx/common/metal/Context.h b/gfx/common/metal/Context.h index 7e8e7eab7c..5068df92a2 100644 --- a/gfx/common/metal/Context.h +++ b/gfx/common/metal/Context.h @@ -61,6 +61,9 @@ typedef struct /*! @brief resets the viewport for the main render encoder to the drawable size */ - (void)resetRenderViewport; +/*! @brief resets the scissor rect for the main render encoder to the drawable size */ +- (void)resetScissorRect; + /*! @brief draws a quad at the specified position (normalized coordinates) using the main render encoder */ - (void)drawQuadX:(float)x y:(float)y w:(float)w h:(float)h r:(float)r g:(float)g b:(float)b a:(float)a; diff --git a/gfx/common/metal/Context.m b/gfx/common/metal/Context.m index 00ca54e3f4..69d1c059f6 100644 --- a/gfx/common/metal/Context.m +++ b/gfx/common/metal/Context.m @@ -565,6 +565,17 @@ [self.rce setViewport:vp]; } +- (void)resetScissorRect +{ + MTLScissorRect sr = { + .x = 0, + .y = 0, + .width = _viewport.full_width, + .height = _viewport.full_height, + }; + [self.rce setScissorRect:sr]; +} + - (void)drawQuadX:(float)x y:(float)y w:(float)w h:(float)h r:(float)r g:(float)g b:(float)b a:(float)a { diff --git a/gfx/common/metal/MenuDisplay.h b/gfx/common/metal/MenuDisplay.h index 12d5bbd6fd..734e6489d0 100644 --- a/gfx/common/metal/MenuDisplay.h +++ b/gfx/common/metal/MenuDisplay.h @@ -14,6 +14,8 @@ - (instancetype)initWithContext:(Context *)context; - (void)drawPipeline:(menu_display_ctx_draw_t *)draw video:(video_frame_info_t *)video; - (void)draw:(menu_display_ctx_draw_t *)draw video:(video_frame_info_t *)video; +- (void)setScissorRect:(MTLScissorRect)rect; +- (void)clearScissorRect; #pragma mark - static methods diff --git a/gfx/common/metal/MenuDisplay.m b/gfx/common/metal/MenuDisplay.m index cde9edc265..c5ad4e3c52 100644 --- a/gfx/common/metal/MenuDisplay.m +++ b/gfx/common/metal/MenuDisplay.m @@ -14,8 +14,10 @@ { Context *_context; MTLClearColor _clearColor; - bool _clearNextRender; + MTLScissorRect _scissorRect; + BOOL _useScissorRect; Uniforms _uniforms; + bool _clearNextRender; } - (instancetype)initWithContext:(Context *)context @@ -25,6 +27,7 @@ _context = context; _clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0); _uniforms.projectionMatrix = matrix_proj_ortho(0, 1, 0, 1); + _useScissorRect = NO; } return self; } @@ -73,6 +76,19 @@ return _clearColor; } +- (void)setScissorRect:(MTLScissorRect)rect +{ + _scissorRect = rect; + _useScissorRect = YES; +} + +- (void)clearScissorRect +{ + _useScissorRect = NO; + [_context resetScissorRect]; +} + + - (MTLPrimitiveType)_toPrimitiveType:(enum menu_display_prim_type)prim { switch (prim) @@ -181,6 +197,10 @@ }; [rce setViewport:vp]; + if (_useScissorRect) { + [rce setScissorRect:_scissorRect]; + } + switch (draw->pipeline.id) { #if HAVE_SHADERPIPELINE diff --git a/menu/drivers_display/menu_display_metal.m b/menu/drivers_display/menu_display_metal.m index 237a04191b..1d7d4430a0 100644 --- a/menu/drivers_display/menu_display_metal.m +++ b/menu/drivers_display/menu_display_metal.m @@ -88,6 +88,25 @@ static void menu_display_metal_viewport(menu_display_ctx_draw_t *draw, { } +static void menu_display_metal_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height) +{ + MetalDriver *md = GET_DRIVER(video_info); + if (!md) + return; + + MTLScissorRect r = {.x = (NSUInteger)x, .y = (NSUInteger)y, .width = width, .height = height}; + [md.display setScissorRect:r]; +} + +static void menu_display_metal_scissor_end(video_frame_info_t *video_info) +{ + MetalDriver *md = GET_DRIVER(video_info); + if (!md) + return; + + [md.display clearScissorRect]; +} + static void menu_display_metal_restore_clear_color(void) { // nothing to do @@ -135,7 +154,7 @@ menu_display_ctx_driver_t menu_display_ctx_metal = { .type = MENU_VIDEO_DRIVER_METAL, .ident = "menu_display_metal", .handles_transform = NO, - .scissor_begin = NULL, - .scissor_end = NULL + .scissor_begin = menu_display_metal_scissor_begin, + .scissor_end = menu_display_metal_scissor_end };