Fixed a memory allocation error and simplified surface resource freeing functions.
This commit is contained in:
parent
437c9bb593
commit
98e6522f3f
|
@ -32,9 +32,9 @@
|
||||||
* core and other for menu, each one backed by a dispmanx
|
* core and other for menu, each one backed by a dispmanx
|
||||||
* element and a set of buffers (resources in dispmanx terms). */
|
* element and a set of buffers (resources in dispmanx terms). */
|
||||||
enum dispmanx_surface_type {
|
enum dispmanx_surface_type {
|
||||||
MAIN_SURFACE,
|
MAIN_SURFACE, /* Always first surface */
|
||||||
MENU_SURFACE,
|
MENU_SURFACE,
|
||||||
BACK_SURFACE
|
BACK_SURFACE /* Always last surface */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dispmanx_page
|
struct dispmanx_page
|
||||||
|
@ -78,6 +78,9 @@ struct dispmanx_surface
|
||||||
|
|
||||||
/* External aspect for scaling */
|
/* External aspect for scaling */
|
||||||
float aspect;
|
float aspect;
|
||||||
|
|
||||||
|
/* Has the surface been setup already? */
|
||||||
|
bool setup;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dispmanx_video
|
struct dispmanx_video
|
||||||
|
@ -110,8 +113,6 @@ struct dispmanx_video
|
||||||
|
|
||||||
/* Menu */
|
/* Menu */
|
||||||
bool menu_active;
|
bool menu_active;
|
||||||
|
|
||||||
unsigned int numsurfaces;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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. */
|
||||||
|
@ -178,21 +179,24 @@ static void dispmanx_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data)
|
||||||
slock_unlock(page->dispvars->pending_mutex);
|
slock_unlock(page->dispvars->pending_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispmanx_surface_free_resources(void *data, struct dispmanx_surface *surface)
|
static void dispmanx_surface_free(void *data, struct dispmanx_surface *surface)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct dispmanx_video *_dispvars = data;
|
struct dispmanx_video *_dispvars = data;
|
||||||
|
|
||||||
_dispvars->update = vc_dispmanx_update_start(0);
|
|
||||||
|
|
||||||
for (i = 0; i < surface->numpages; i++) {
|
for (i = 0; i < surface->numpages; i++) {
|
||||||
if (surface->pages[i].resource != 0){
|
vc_dispmanx_resource_delete(surface->pages[i].resource);
|
||||||
vc_dispmanx_resource_delete(surface->pages[i].resource);
|
surface->pages[i].used = false;
|
||||||
}
|
slock_free(surface->pages[i].page_used_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(surface->pages);
|
||||||
|
|
||||||
|
_dispvars->update = vc_dispmanx_update_start(0);
|
||||||
vc_dispmanx_element_remove(_dispvars->update, surface->element);
|
vc_dispmanx_element_remove(_dispvars->update, surface->element);
|
||||||
vc_dispmanx_update_submit_sync(_dispvars->update);
|
vc_dispmanx_update_submit_sync(_dispvars->update);
|
||||||
|
|
||||||
|
surface->setup = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dispmanx_surface_setup(void *data, int width, int height, int pitch, float aspect,
|
static bool dispmanx_surface_setup(void *data, int width, int height, int pitch, float aspect,
|
||||||
|
@ -201,6 +205,15 @@ static bool dispmanx_surface_setup(void *data, int width, int height, int pitch,
|
||||||
struct dispmanx_video *_dispvars = data;
|
struct dispmanx_video *_dispvars = data;
|
||||||
int i, dst_width, dst_height, dst_xpos, dst_ypos;
|
int i, dst_width, dst_height, dst_xpos, dst_ypos;
|
||||||
|
|
||||||
|
/* Allocate memory for all the pages in each surface
|
||||||
|
* and initialize variables inside each page's struct. */
|
||||||
|
surface->pages = calloc(surface->numpages, sizeof(struct dispmanx_page));
|
||||||
|
for (i = 0; i < surface->numpages; i++) {
|
||||||
|
surface->pages[i].used = false;
|
||||||
|
surface->pages[i].dispvars = _dispvars;
|
||||||
|
surface->pages[i].page_used_mutex = slock_new();
|
||||||
|
}
|
||||||
|
|
||||||
/* Internal frame dimensions. Pitch is total pitch including info
|
/* Internal frame dimensions. Pitch is total pitch including info
|
||||||
* between scanlines */
|
* between scanlines */
|
||||||
surface->width = width;
|
surface->width = width;
|
||||||
|
@ -244,6 +257,8 @@ static bool dispmanx_surface_setup(void *data, int width, int height, int pitch,
|
||||||
|
|
||||||
vc_dispmanx_update_submit_sync(_dispvars->update);
|
vc_dispmanx_update_submit_sync(_dispvars->update);
|
||||||
|
|
||||||
|
surface->setup = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,14 +290,9 @@ static void dispmanx_surface_init(void *data,
|
||||||
surface->alpha.opacity = alpha;
|
surface->alpha.opacity = alpha;
|
||||||
surface->alpha.mask = 0;
|
surface->alpha.mask = 0;
|
||||||
|
|
||||||
/* Allocate memory for all the pages in each surface
|
/* This will be true when we have allocated mem for the pages and
|
||||||
* and initialize variables inside each page's struct. */
|
* created their element, resources, etc.. */
|
||||||
surface->pages = calloc(surface->numpages, sizeof(struct dispmanx_surface));
|
surface->setup = false;
|
||||||
for (i = 0; i < surface->numpages; i++) {
|
|
||||||
surface->pages[i].used = false;
|
|
||||||
surface->pages[i].dispvars = _dispvars;
|
|
||||||
surface->pages[i].page_used_mutex = slock_new();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispmanx_surface_update(void *data, const void *frame, struct dispmanx_surface *surface)
|
static void dispmanx_surface_update(void *data, const void *frame, struct dispmanx_surface *surface)
|
||||||
|
@ -351,8 +361,6 @@ static void *dispmanx_gfx_init(const video_info_t *video,
|
||||||
graphics_get_display_size(_dispvars->display, &_dispvars->dispmanx_width, &_dispvars->dispmanx_height);
|
graphics_get_display_size(_dispvars->display, &_dispvars->dispmanx_width, &_dispvars->dispmanx_height);
|
||||||
|
|
||||||
/* Setup surface parameters */
|
/* Setup surface parameters */
|
||||||
_dispvars->numsurfaces = 3;
|
|
||||||
|
|
||||||
_dispvars->vc_image_ptr = 0;
|
_dispvars->vc_image_ptr = 0;
|
||||||
_dispvars->pageflip_pending = 0;
|
_dispvars->pageflip_pending = 0;
|
||||||
_dispvars->current_page = NULL;
|
_dispvars->current_page = NULL;
|
||||||
|
@ -389,8 +397,9 @@ static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width,
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
return true;
|
return true;
|
||||||
|
if (_dispvars->surfaces[MAIN_SURFACE].setup)
|
||||||
|
dispmanx_surface_free(_dispvars, &_dispvars->surfaces[MAIN_SURFACE]);
|
||||||
|
|
||||||
dispmanx_surface_free_resources(_dispvars, &_dispvars->surfaces[MAIN_SURFACE]);
|
|
||||||
float aspect = video_driver_get_aspect_ratio();
|
float aspect = video_driver_get_aspect_ratio();
|
||||||
/* Reconfiguring internal dimensions of the main surface is needed. */
|
/* Reconfiguring internal dimensions of the main surface is needed. */
|
||||||
dispmanx_surface_setup(_dispvars, width, height, pitch, aspect, &_dispvars->surfaces[MAIN_SURFACE]);
|
dispmanx_surface_setup(_dispvars, width, height, pitch, aspect, &_dispvars->surfaces[MAIN_SURFACE]);
|
||||||
|
@ -414,7 +423,7 @@ static void dispmanx_set_texture_enable(void *data, bool state, bool full_screen
|
||||||
|
|
||||||
/* If it was active but it's not anymore... */
|
/* If it was active but it's not anymore... */
|
||||||
if (!state && _dispvars->menu_active) {
|
if (!state && _dispvars->menu_active) {
|
||||||
dispmanx_surface_free_resources(_dispvars, &_dispvars->surfaces[MENU_SURFACE]);
|
dispmanx_surface_free(_dispvars, &_dispvars->surfaces[MENU_SURFACE]);
|
||||||
/* This is needed so we enter thru surface_setup on
|
/* This is needed so we enter thru surface_setup on
|
||||||
* set_texture_frame() next time menu is active. */
|
* set_texture_frame() next time menu is active. */
|
||||||
_dispvars->surfaces[MENU_SURFACE].width = 0;
|
_dispvars->surfaces[MENU_SURFACE].width = 0;
|
||||||
|
@ -541,11 +550,11 @@ static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx)
|
||||||
float aspect = aspectratio_lut[aspect_ratio_idx].value;
|
float aspect = aspectratio_lut[aspect_ratio_idx].value;
|
||||||
|
|
||||||
surface = &_dispvars->surfaces[MAIN_SURFACE];
|
surface = &_dispvars->surfaces[MAIN_SURFACE];
|
||||||
dispmanx_surface_free_resources(_dispvars, surface);
|
dispmanx_surface_free(_dispvars, surface);
|
||||||
dispmanx_surface_setup(_dispvars, surface->width, surface->height, surface->pitch, aspect, surface);
|
dispmanx_surface_setup(_dispvars, surface->width, surface->height, surface->pitch, aspect, surface);
|
||||||
|
|
||||||
surface = &_dispvars->surfaces[MENU_SURFACE];
|
surface = &_dispvars->surfaces[MENU_SURFACE];
|
||||||
dispmanx_surface_free_resources(_dispvars, surface);
|
dispmanx_surface_free(_dispvars, surface);
|
||||||
dispmanx_surface_setup(_dispvars, surface->width, surface->height, surface->pitch, aspect, surface);
|
dispmanx_surface_setup(_dispvars, surface->width, surface->height, surface->pitch, aspect, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,27 +584,16 @@ static void dispmanx_gfx_get_poke_interface(void *data,
|
||||||
*iface = &dispmanx_poke_interface;
|
*iface = &dispmanx_poke_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispmanx_surface_free_pages (struct dispmanx_surface *surface)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < surface->numpages; i++) {
|
|
||||||
surface->pages[i].used = false;
|
|
||||||
slock_free(surface->pages[i].page_used_mutex);
|
|
||||||
}
|
|
||||||
free(surface->pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dispmanx_gfx_free(void *data)
|
static void dispmanx_gfx_free(void *data)
|
||||||
{
|
{
|
||||||
struct dispmanx_video *_dispvars = data;
|
struct dispmanx_video *_dispvars = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
dispmanx_surface_free_resources(_dispvars, &_dispvars->surfaces[MENU_SURFACE]);
|
for (i = MAIN_SURFACE; i <= BACK_SURFACE; i++) {
|
||||||
dispmanx_surface_free_resources(_dispvars, &_dispvars->surfaces[MAIN_SURFACE]);
|
if (_dispvars->surfaces[i].setup) {
|
||||||
dispmanx_surface_free_resources(_dispvars, &_dispvars->surfaces[BACK_SURFACE]);
|
dispmanx_surface_free(_dispvars, &_dispvars->surfaces[i]);
|
||||||
|
}
|
||||||
dispmanx_surface_free_pages(&_dispvars->surfaces[MAIN_SURFACE]);
|
}
|
||||||
dispmanx_surface_free_pages(&_dispvars->surfaces[MENU_SURFACE]);
|
|
||||||
dispmanx_surface_free_pages(&_dispvars->surfaces[BACK_SURFACE]);
|
|
||||||
|
|
||||||
/* Close display and deinitialize. */
|
/* Close display and deinitialize. */
|
||||||
vc_dispmanx_display_close(_dispvars->display);
|
vc_dispmanx_display_close(_dispvars->display);
|
||||||
|
|
Loading…
Reference in New Issue