mirror of
https://github.com/libretro/RetroArch
synced 2025-04-07 13:23:32 +00:00
Fix performance issue with max_swapchain_images
This fixes a performance problem introduced in my last commit when max_swapchain_images == 3. In my last commit I incorrectly stated the 3rd buffer was not being used, after doing some additional testing I realized I was mistaken, it can indeed be used due to the used page tracking. Reverting that portion of my previous commit.
This commit is contained in:
parent
6e51153387
commit
858e15b837
@ -209,7 +209,6 @@ static void dispmanx_surface_free(struct dispmanx_video *_dispvars,
|
|||||||
slock_lock(_dispvars->pending_mutex);
|
slock_lock(_dispvars->pending_mutex);
|
||||||
if (_dispvars->pageflip_pending > 0)
|
if (_dispvars->pageflip_pending > 0)
|
||||||
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
|
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
|
||||||
|
|
||||||
slock_unlock(_dispvars->pending_mutex);
|
slock_unlock(_dispvars->pending_mutex);
|
||||||
|
|
||||||
for (i = 0; i < surface->numpages; i++)
|
for (i = 0; i < surface->numpages; i++)
|
||||||
@ -321,22 +320,19 @@ static void dispmanx_surface_update_async(const void *frame, struct dispmanx_sur
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void dispmanx_surface_update(struct dispmanx_video *_dispvars, const void *frame,
|
static void dispmanx_surface_update(struct dispmanx_video *_dispvars, const void *frame,
|
||||||
struct dispmanx_surface *surface, video_frame_info_t *video_info)
|
struct dispmanx_surface *surface)
|
||||||
{
|
{
|
||||||
/* Frame blitting */
|
/* Frame blitting */
|
||||||
vc_dispmanx_resource_write_data(surface->next_page->resource, surface->pixformat,
|
vc_dispmanx_resource_write_data(surface->next_page->resource, surface->pixformat,
|
||||||
surface->pitch, (void*)frame, &(surface->bmp_rect));
|
surface->pitch, (void*)frame, &(surface->bmp_rect));
|
||||||
|
|
||||||
/* Dispmanx doesn't support more than 1 pending frame flip, if we're "triple" buffering,
|
/* Dispmanx doesn't support more than one pending pageflip. Doing so would overwrite
|
||||||
* then wait at the last possible moment for any outstanding vsync to finish. */
|
* the page in the callback function, so we would be always freeing the same page. */
|
||||||
if (video_info->max_swapchain_images >= 3)
|
slock_lock(_dispvars->pending_mutex);
|
||||||
{
|
if (_dispvars->pageflip_pending > 0)
|
||||||
slock_lock(_dispvars->pending_mutex);
|
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
|
||||||
if (_dispvars->pageflip_pending > 0)
|
slock_unlock(_dispvars->pending_mutex);
|
||||||
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
|
|
||||||
slock_unlock(_dispvars->pending_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Issue a page flip that will be done at the next vsync. */
|
/* Issue a page flip that will be done at the next vsync. */
|
||||||
_dispvars->update = vc_dispmanx_update_start(0);
|
_dispvars->update = vc_dispmanx_update_start(0);
|
||||||
|
|
||||||
@ -350,17 +346,7 @@ static void dispmanx_surface_update(struct dispmanx_video *_dispvars, const void
|
|||||||
vc_dispmanx_update_submit(_dispvars->update,
|
vc_dispmanx_update_submit(_dispvars->update,
|
||||||
dispmanx_vsync_callback, (void*)(surface->next_page));
|
dispmanx_vsync_callback, (void*)(surface->next_page));
|
||||||
|
|
||||||
/* If we are "double" buffering, wait immediately after the flip for the vsync
|
/* This may block waiting on a new page when max_swapchain_images <= 2 */
|
||||||
* before continuing */
|
|
||||||
if (video_info->max_swapchain_images <= 2)
|
|
||||||
{
|
|
||||||
slock_lock(_dispvars->pending_mutex);
|
|
||||||
if (_dispvars->pageflip_pending > 0)
|
|
||||||
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
|
|
||||||
slock_unlock(_dispvars->pending_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* At this point, there will always be a free page available */
|
|
||||||
surface->next_page = dispmanx_get_free_page(_dispvars, surface);
|
surface->next_page = dispmanx_get_free_page(_dispvars, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,7 +469,7 @@ static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width,
|
|||||||
_dispvars->rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565,
|
_dispvars->rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565,
|
||||||
255,
|
255,
|
||||||
_dispvars->aspect_ratio,
|
_dispvars->aspect_ratio,
|
||||||
2,
|
video_info->max_swapchain_images,
|
||||||
0,
|
0,
|
||||||
&_dispvars->main_surface);
|
&_dispvars->main_surface);
|
||||||
|
|
||||||
@ -498,7 +484,7 @@ static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Update main surface: locate free page, blit and flip. */
|
/* Update main surface: locate free page, blit and flip. */
|
||||||
dispmanx_surface_update(_dispvars, frame, _dispvars->main_surface, video_info);
|
dispmanx_surface_update(_dispvars, frame, _dispvars->main_surface);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user