mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Reimplement 'fix ozone issues on mali400 gpu. as a bonus, fixes #5378'
by BringerethOfLight
This commit is contained in:
parent
320d22f5b8
commit
5dc11fcd31
@ -26,6 +26,48 @@
|
||||
|
||||
#include "../menu_driver.h"
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
static int scx0, scx1, scy0, scy1;
|
||||
|
||||
/* This array contains problematic GPU drivers
|
||||
* that have problems when we draw outside the
|
||||
* bounds of the framebuffer */
|
||||
static const struct {
|
||||
const char *str;
|
||||
int len;
|
||||
} scissor_device_strings[] = {
|
||||
{ "ARM Mali-4xx", 10 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void scissor_set_rectangle(
|
||||
int x0, int x1, int y0, int y1, int sc)
|
||||
{
|
||||
const int dx = sc ? 10 : 2;
|
||||
const int dy = dx;
|
||||
scx0 = x0 + dx;
|
||||
scx1 = x1 - dx;
|
||||
scy0 = y0 + dy;
|
||||
scy1 = y1 - dy;
|
||||
}
|
||||
|
||||
static bool scissor_is_outside_rectangle(
|
||||
int x0, int x1, int y0, int y1)
|
||||
{
|
||||
if (x1 < scx0)
|
||||
return true;
|
||||
if (scx1 < x0)
|
||||
return true;
|
||||
if (y1 < scy0)
|
||||
return true;
|
||||
if (scy1 < y0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MALI_BUG
|
||||
#endif
|
||||
|
||||
static const GLfloat gl_vertexes[] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
@ -100,6 +142,63 @@ static void menu_display_gl_viewport(menu_display_ctx_draw_t *draw,
|
||||
glViewport(draw->x, draw->y, draw->width, draw->height);
|
||||
}
|
||||
|
||||
#ifdef MALI_BUG
|
||||
static bool
|
||||
menu_display_gl_discard_draw_rectangle(menu_display_ctx_draw_t *draw,
|
||||
video_frame_info_t *video_info
|
||||
)
|
||||
{
|
||||
static bool mali_4xx_detected = false;
|
||||
static bool scissor_inited = false;
|
||||
|
||||
if (!scissor_inited)
|
||||
{
|
||||
unsigned i;
|
||||
const char *gpu_device_string = NULL;
|
||||
scissor_inited = true;
|
||||
|
||||
if ((scx0 + scx1 + scy0 + scy1) == 0)
|
||||
scissor_set_rectangle(0,
|
||||
video_info->width - 1,
|
||||
0,
|
||||
video_info->height - 1,
|
||||
0);
|
||||
|
||||
/* TODO/FIXME - This might be thread unsafe in the long run -
|
||||
* preferably call this once outside of the menu display driver
|
||||
* and then just pass this string as a parameter */
|
||||
gpu_device_string = video_driver_get_gpu_device_string();
|
||||
|
||||
if (gpu_device_string)
|
||||
{
|
||||
for (i = 0; scissor_device_strings[i].len; ++i)
|
||||
{
|
||||
if (strncmp(gpu_device_string,
|
||||
scissor_device_strings[i].str,
|
||||
scissor_device_strings[i].len) == 0)
|
||||
{
|
||||
mali_4xx_detected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* discards not only out-of-bounds scissoring,
|
||||
* but also out-of-view draws.
|
||||
*
|
||||
* This is intentional.
|
||||
*/
|
||||
if (mali_4xx_detected &&
|
||||
scissor_is_outside_rectangle(
|
||||
draw->x, draw->x + draw->width - 1,
|
||||
draw->y, draw->y + draw->height - 1))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void menu_display_gl_draw(menu_display_ctx_draw_t *draw,
|
||||
video_frame_info_t *video_info)
|
||||
{
|
||||
@ -108,6 +207,15 @@ static void menu_display_gl_draw(menu_display_ctx_draw_t *draw,
|
||||
if (!gl || !draw)
|
||||
return;
|
||||
|
||||
#ifdef MALI_BUG
|
||||
if (menu_display_gl_discard_draw_rectangle(draw, video_info))
|
||||
{
|
||||
/*RARCH_WARN("[Menu]: discarded draw rect: %.4i %.4i %.4i %.4i\n",
|
||||
(int)draw->x, (int)draw->y, (int)draw->width, (int)draw->height);*/
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!draw->coords->vertex)
|
||||
draw->coords->vertex = menu_display_gl_get_default_vertices();
|
||||
if (!draw->coords->tex_coord)
|
||||
@ -243,12 +351,18 @@ static void menu_display_gl_scissor_begin(
|
||||
{
|
||||
glScissor(x, video_info->height - y - height, width, height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#ifdef MALI_BUG
|
||||
scissor_set_rectangle(x, x + width - 1, y, y + height - 1, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void menu_display_gl_scissor_end(video_frame_info_t *video_info)
|
||||
{
|
||||
glScissor(0, 0, video_info->width, video_info->height);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
#ifdef MALI_BUG
|
||||
scissor_set_rectangle(0, video_info->width - 1, 0, video_info->height - 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
menu_display_ctx_driver_t menu_display_ctx_gl = {
|
||||
|
@ -504,7 +504,26 @@ void menu_display_blend_end(video_frame_info_t *video_info)
|
||||
void menu_display_scissor_begin(video_frame_info_t *video_info, int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
if (menu_disp && menu_disp->scissor_begin)
|
||||
{
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (y >= menu_display_framebuf_height)
|
||||
return;
|
||||
if (x >= menu_display_framebuf_width)
|
||||
return;
|
||||
if ((y + height) > menu_display_framebuf_height)
|
||||
height = menu_display_framebuf_height - y;
|
||||
if ((x + width) > menu_display_framebuf_width)
|
||||
width = menu_display_framebuf_width - x;
|
||||
if (height <= 0)
|
||||
return;
|
||||
if (width <= 0)
|
||||
return;
|
||||
|
||||
menu_disp->scissor_begin(video_info, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/* End scissoring operation */
|
||||
@ -790,9 +809,10 @@ void menu_display_draw(menu_display_ctx_draw_t *draw,
|
||||
if (!menu_disp || !draw || !menu_disp->draw)
|
||||
return;
|
||||
|
||||
/* TODO - edge case */
|
||||
if (draw->height <= 0)
|
||||
draw->height = 1;
|
||||
return;
|
||||
if (draw->width <= 0)
|
||||
return;
|
||||
|
||||
menu_disp->draw(draw, video_info);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user