VIDEO/DISPMANX: Fixed segfault when loading new core and content from RGUI

This commit is contained in:
vanfanel 2016-06-15 14:28:13 +02:00
parent 8adda6e822
commit 03dd7d4b51

View File

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