mirror of
https://github.com/libretro/RetroArch
synced 2025-03-25 16:44:01 +00:00
VIDEO/DISPMANX: Fixed segfault when loading new core and content from RGUI
This commit is contained in:
parent
8adda6e822
commit
03dd7d4b51
@ -118,7 +118,7 @@ struct dispmanx_video
|
|||||||
int menu_pitch;
|
int menu_pitch;
|
||||||
/* Both main and menu surfaces are going to have the same aspect,
|
/* Both main and menu surfaces are going to have the same aspect,
|
||||||
* so we keep it here for future reference. */
|
* so we keep it here for future reference. */
|
||||||
float aspect;
|
float aspect_ratio;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* If no free page is available when called, wait for a page flip. */
|
/* If no free page is available when called, wait for a page flip. */
|
||||||
@ -378,7 +378,7 @@ static void *dispmanx_gfx_init(const video_info_t *video,
|
|||||||
* call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame()
|
* call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame()
|
||||||
* and we don't want the main surface to be setup in set_aspect()
|
* and we don't want the main surface to be setup in set_aspect()
|
||||||
* before we get to gfx_frame(). */
|
* before we get to gfx_frame(). */
|
||||||
_dispvars->aspect = video_driver_get_aspect_ratio();
|
_dispvars->aspect_ratio = video_driver_get_aspect_ratio();
|
||||||
|
|
||||||
/* Initialize the rest of the mutexes and conditions. */
|
/* Initialize the rest of the mutexes and conditions. */
|
||||||
_dispvars->vsync_condition = scond_new();
|
_dispvars->vsync_condition = scond_new();
|
||||||
@ -404,21 +404,24 @@ static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width,
|
|||||||
unsigned height, uint64_t frame_count, unsigned pitch, const char *msg)
|
unsigned height, uint64_t frame_count, unsigned pitch, const char *msg)
|
||||||
{
|
{
|
||||||
struct dispmanx_video *_dispvars = data;
|
struct dispmanx_video *_dispvars = data;
|
||||||
|
float aspect = video_driver_get_aspect_ratio();
|
||||||
|
|
||||||
if (width != _dispvars->core_width || height != _dispvars->core_height)
|
if (width != _dispvars->core_width || height != _dispvars->core_height || _dispvars->aspect_ratio != aspect)
|
||||||
{
|
{
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
_dispvars->core_width = width;
|
_dispvars->core_width = width;
|
||||||
_dispvars->core_height = height;
|
_dispvars->core_height = height;
|
||||||
_dispvars->core_pitch = pitch;
|
_dispvars->core_pitch = pitch;
|
||||||
|
_dispvars->aspect_ratio = aspect;
|
||||||
|
|
||||||
if (_dispvars->main_surface != NULL)
|
if (_dispvars->main_surface != NULL)
|
||||||
dispmanx_surface_free(_dispvars, &_dispvars->main_surface);
|
dispmanx_surface_free(_dispvars, &_dispvars->main_surface);
|
||||||
|
|
||||||
/* We need to recreate the main surface. */
|
/* Internal resolution or ratio has changed, so we need
|
||||||
|
* to recreate the main surface. */
|
||||||
dispmanx_surface_setup(_dispvars,
|
dispmanx_surface_setup(_dispvars,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@ -426,10 +429,16 @@ static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width,
|
|||||||
_dispvars->rgb32 ? 32 : 16,
|
_dispvars->rgb32 ? 32 : 16,
|
||||||
_dispvars->rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565,
|
_dispvars->rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565,
|
||||||
255,
|
255,
|
||||||
_dispvars->aspect,
|
_dispvars->aspect_ratio,
|
||||||
3,
|
3,
|
||||||
0,
|
0,
|
||||||
&_dispvars->main_surface);
|
&_dispvars->main_surface);
|
||||||
|
|
||||||
|
/* We need to recreate the menu surface too, if it exists already, so we
|
||||||
|
* free it and let dispmanx_set_texture_frame() recreate it as it detects it's NULL.*/
|
||||||
|
if (_dispvars->menu_active && _dispvars->menu_surface) {
|
||||||
|
dispmanx_surface_free(_dispvars, &_dispvars->menu_surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dispvars->menu_active)
|
if (_dispvars->menu_active)
|
||||||
@ -462,7 +471,7 @@ static void dispmanx_set_texture_frame(void *data, const void *frame, bool rgb32
|
|||||||
if (!_dispvars->menu_active)
|
if (!_dispvars->menu_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If menu is active in this frame but out menu surface is NULL, we allocate a new one.*/
|
/* If menu is active in this frame but our menu surface is NULL, we allocate a new one.*/
|
||||||
if (_dispvars->menu_surface == NULL)
|
if (_dispvars->menu_surface == NULL)
|
||||||
{
|
{
|
||||||
_dispvars->menu_width = width;
|
_dispvars->menu_width = width;
|
||||||
@ -473,10 +482,10 @@ static void dispmanx_set_texture_frame(void *data, const void *frame, bool rgb32
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
_dispvars->menu_pitch,
|
_dispvars->menu_pitch,
|
||||||
rgb32 ? 32 : 16,
|
16,
|
||||||
VC_IMAGE_RGBA16,
|
VC_IMAGE_RGBA16,
|
||||||
210,
|
210,
|
||||||
_dispvars->aspect,
|
_dispvars->aspect_ratio,
|
||||||
3,
|
3,
|
||||||
0,
|
0,
|
||||||
&_dispvars->menu_surface);
|
&_dispvars->menu_surface);
|
||||||
@ -562,45 +571,32 @@ static bool dispmanx_gfx_read_viewport(void *data, uint8_t *buffer)
|
|||||||
|
|
||||||
static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx)
|
static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx)
|
||||||
{
|
{
|
||||||
struct dispmanx_video *_dispvars = data;
|
/* Due to RetroArch setting the data pointer to NULL internally
|
||||||
/* Here we obtain the new aspect ratio. */
|
* on core change, data is going to be NULL here after we load
|
||||||
float new_aspect = aspectratio_lut[aspect_ratio_idx].value;
|
* a new core from the GUI, so we can't count on accessing it
|
||||||
if (_dispvars->aspect != new_aspect)
|
* to store the aspect ratio we are going to use, so we tell RA
|
||||||
{
|
* to keep track of the new aspect ratio and we get it in gfx_frame()
|
||||||
_dispvars->aspect = new_aspect;
|
* with video_driver_get_aspect_ratio() to find out if it has changed. */
|
||||||
if (_dispvars->main_surface != NULL)
|
|
||||||
dispmanx_surface_free(_dispvars, &_dispvars->main_surface);
|
switch (aspect_ratio_idx)
|
||||||
|
{
|
||||||
|
case ASPECT_RATIO_SQUARE:
|
||||||
|
video_driver_set_viewport_square_pixel();
|
||||||
|
break;
|
||||||
|
|
||||||
dispmanx_surface_setup(_dispvars,
|
case ASPECT_RATIO_CORE:
|
||||||
_dispvars->core_width,
|
video_driver_set_viewport_core();
|
||||||
_dispvars->core_height,
|
break;
|
||||||
_dispvars->core_pitch,
|
|
||||||
_dispvars->rgb32 ? 32 : 16,
|
|
||||||
_dispvars->rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565,
|
|
||||||
255,
|
|
||||||
_dispvars->aspect,
|
|
||||||
3,
|
|
||||||
0,
|
|
||||||
&_dispvars->main_surface);
|
|
||||||
|
|
||||||
if (_dispvars->menu_active)
|
case ASPECT_RATIO_CONFIG:
|
||||||
{
|
video_driver_set_viewport_config();
|
||||||
if (_dispvars->menu_surface != NULL)
|
break;
|
||||||
dispmanx_surface_free(_dispvars, &_dispvars->menu_surface);
|
|
||||||
|
|
||||||
dispmanx_surface_setup(_dispvars,
|
default:
|
||||||
_dispvars->menu_width,
|
break;
|
||||||
_dispvars->menu_height,
|
|
||||||
_dispvars->menu_pitch,
|
|
||||||
16,
|
|
||||||
VC_IMAGE_RGBA16,
|
|
||||||
210,
|
|
||||||
_dispvars->aspect,
|
|
||||||
3,
|
|
||||||
0,
|
|
||||||
&_dispvars->menu_surface);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
video_driver_set_aspect_ratio_value(aspectratio_lut[aspect_ratio_idx].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const video_poke_interface_t dispmanx_poke_interface = {
|
static const video_poke_interface_t dispmanx_poke_interface = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user