Change max_swapchain=2 implementation to actually working code.

This commit is contained in:
vanfanel 2017-10-18 12:06:58 +00:00
parent 65ef37706c
commit d9ec2267f7

View File

@ -24,6 +24,7 @@
#include <VG/openvg.h>
#include <bcm_host.h>
#include <rthreads/rthreads.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@ -59,6 +60,12 @@ typedef struct
egl_ctx_data_t egl;
#endif
EGL_DISPMANX_WINDOW_T native_window;
DISPMANX_DISPLAY_HANDLE_T dispman_display;
/* For vsync wait after eglSwapBuffers when max_swapchain < 3 */
scond_t *vsync_condition;
slock_t *vsync_condition_mutex;
bool vsync_callback_set;
bool resize;
unsigned fb_width, fb_height;
@ -134,6 +141,15 @@ static void gfx_ctx_vc_get_video_size(void *data,
}
}
static void dispmanx_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data)
{
vc_ctx_data_t *vc = (vc_ctx_data_t*)data;
slock_lock(vc->vsync_condition_mutex);
scond_signal(vc->vsync_condition);
slock_unlock(vc->vsync_condition_mutex);
}
static void gfx_ctx_vc_destroy(void *data);
static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver)
@ -235,6 +251,7 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver)
}
dispman_display = vc_dispmanx_display_open(0 /* LCD */);
vc->dispman_display = dispman_display;
vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);
dispman_update = vc_dispmanx_update_start(0);
@ -281,6 +298,16 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver)
goto error;
#endif
/* For vsync after eglSwapBuffers when max_swapchain < 3 */
vc->vsync_condition = scond_new();
vc->vsync_condition_mutex = slock_new();
vc->vsync_callback_set = false;
if (video_info->max_swapchain_images <= 2) {
/* Start sending vsync callbacks so we can wait for vsync after eglSwapBuffers */
vc_dispmanx_vsync_callback(vc->dispman_display, dispmanx_vsync_callback, (void*)vc);
vc->vsync_callback_set = true;
}
return vc;
error:
@ -291,7 +318,6 @@ error:
static void gfx_ctx_vc_set_swap_interval(void *data, unsigned swap_interval)
{
vc_ctx_data_t *vc = (vc_ctx_data_t*)data;
#ifdef HAVE_EGL
egl_set_swap_interval(&vc->egl, swap_interval);
#endif
@ -305,18 +331,18 @@ static bool gfx_ctx_vc_set_video_mode(void *data,
vc_ctx_data_t *vc = (vc_ctx_data_t*)data;
#ifdef HAVE_EGL
if (g_egl_inited)
return false;
frontend_driver_install_signal_handler();
gfx_ctx_vc_set_swap_interval(&vc->egl, vc->egl.interval);
/* If we set this env variable, Broadcom's EGL implementation will block
* on vsync with a double buffer when we call eglSwapBuffers. Less input lag! */
if (video_info->max_swapchain_images <= 2)
/*if (video_info->max_swapchain_images <= 2)
setenv("V3D_DOUBLE_BUFFER", "1", 1);
else
setenv("V3D_DOUBLE_BUFFER", "0", 1);
setenv("V3D_DOUBLE_BUFFER", "0", 1);*/
gfx_ctx_vc_set_swap_interval(&vc->egl, vc->egl.interval);
@ -436,6 +462,10 @@ static void gfx_ctx_vc_destroy(void *data)
vc->eglBuffer[i] = NULL;
vc->vgimage[i] = 0;
}
/* Destroy mutexes and conditions. */
slock_free(vc->vsync_condition_mutex);
scond_free(vc->vsync_condition);
}
static void gfx_ctx_vc_input_driver(void *data,
@ -593,9 +623,26 @@ error:
static void gfx_ctx_vc_swap_buffers(void *data, void *data2)
{
vc_ctx_data_t *vc = (vc_ctx_data_t*)data;
video_frame_info_t *video_info = (video_frame_info_t*)data2;
#ifdef HAVE_EGL
egl_swap_buffers(&vc->egl);
/* Wait for vsync immediately if we don't wait egl_swap_buffers to triple-buffer */
if (video_info->max_swapchain_images <= 2) {
/* We DON'T wait to wait without callback function ready! */
if(!vc->vsync_callback_set) {
vc_dispmanx_vsync_callback(vc->dispman_display, dispmanx_vsync_callback, (void*)vc);
vc->vsync_callback_set = true;
}
slock_lock(vc->vsync_condition_mutex);
scond_wait(vc->vsync_condition, vc->vsync_condition_mutex);
slock_unlock(vc->vsync_condition_mutex);
}
else if (vc->vsync_callback_set) {
/* Stop generating vsync callbacks from now on */
vc_dispmanx_vsync_callback(vc->dispman_display, NULL, NULL);
}
#endif
}