typedef struct _twe_wl_buffer_info twe_wl_buffer_info;
typedef struct _twe_tdm_source twe_tdm_source;
typedef struct _twe_del_source twe_del_source;
-typedef struct _vk_sync_draw_source twe_sync_draw_source;
struct _twe_thread_context {
GThread *twe_thread;
/* for waiting draw done */
tpl_bool_t use_sync_fence;
- /* Temporary sub worker thread */
- GThread *vk_sub_thread;
- GMainLoop *vk_sub_loop;
- GMutex sub_thread_mutex;
- GCond sub_thread_cond;
- int draw_done_count;
-
int post_interval;
};
tbm_fd sync_fd;
tpl_bool_t is_vk_image;
- /* for waiting draw done */
- twe_sync_draw_source *sync_draw_source;
-
tbm_surface_h tbm_surface;
twe_wl_surf_source *surf_source;
unsigned int serial;
};
-struct _vk_sync_draw_source {
- GSource gsource;
- gpointer tag;
- int event_fd;
- int draw_done_signal_fd;
- tbm_fd draw_fence_fd;
- tbm_surface_h tbm_surface;
- twe_wl_buffer_info *buf_info;
-};
-
static twe_thread_context *_twe_ctx;
static twe_tdm_source *
_twe_thread_tdm_source_create(void);
buf_info->need_to_commit = TPL_TRUE;
buf_info->draw_done = TPL_FALSE;
buf_info->tbm_surface = tbm_surface;
- buf_info->sync_draw_source = NULL;
buf_info->sync_fd = -1;
buf_info->sync_timeline = -1;
buf_info->is_vk_image = surf_source->disp_source->is_vulkan_dpy;
* to commit or pending, depending on whether vblank_done
* after acquire as much as possible. */
while (tbm_surface_queue_can_acquire(surf_source->tbm_queue, 0)) {
- /* If its backend is vulkan, it should be checked with draw_done_count.
- * Because vulkan surface's [enqueue] doesn't mean render done state */
- if (disp_source->is_vulkan_dpy && surf_source->draw_done_count <= 0)
- return;
tsq_err = tbm_surface_queue_acquire(surf_source->tbm_queue, &tbm_surface);
if (!tbm_surface || tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) {
tbm_surface,
tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
- surf_source->draw_done_count--;
-
switch (surf_source->swapchain_properties.present_mode) {
case TPL_DISPLAY_PRESENT_MODE_IMMEDIATE:
_twe_thread_wl_vk_surface_commit(surf_source, tbm_surface);
TPL_ERR("Failed to read from event_fd(%d)",
surf_source->event_fd);
- if (surf_source->disp_source->is_vulkan_dpy &&
- surf_source->use_sync_fence) {
- g_mutex_lock(&surf_source->sub_thread_mutex);
- _twe_thread_wl_surface_acquire_and_commit(surf_source);
- g_mutex_unlock(&surf_source->sub_thread_mutex);
- } else {
- _twe_thread_wl_surface_acquire_and_commit(surf_source);
- }
+ _twe_thread_wl_surface_acquire_and_commit(surf_source);
+
} else {
TPL_ERR("eventfd(%d) cannot wake up with other condition. cond(%d)",
surf_source->event_fd, cond);
g_source_unref(&surf_source->gsource);
}
-static gpointer
-_vk_sub_thread_loop(gpointer data)
-{
- twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data;
-
- g_mutex_lock(&surf_source->sub_thread_mutex);
- /* Do nothing */
- TPL_DEBUG("vk_sub_thread(%p) vk_sub_loop(%p) run",
- surf_source->vk_sub_thread, surf_source->vk_sub_loop);
- g_cond_signal(&surf_source->sub_thread_cond);
- g_mutex_unlock(&surf_source->sub_thread_mutex);
-
- g_main_loop_run(surf_source->vk_sub_loop);
-
- return surf_source->vk_sub_thread;
-}
-
twe_surface_h
twe_surface_add(twe_thread* thread,
twe_display_h twe_display,
source->vblank_waiting_buffers = NULL;
source->draw_done_buffer = NULL;
- source->vk_sub_loop = NULL;
- source->vk_sub_thread = NULL;
- source->draw_done_count = 0;
-
source->set_serial_is_used = TPL_FALSE;
source->serial = 0;
{
twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface;
twe_wl_disp_source *disp_source = NULL;
- GMainContext *context;
tbm_bufmgr bufmgr = NULL;
unsigned int capability;
"[SWAPCHAIN_CREATE][2/2] w(%d) h(%d) f(%d) p(%d) b_cnt(%d)",
width, height, format, present_mode, buffer_count);
- /* TODO : Below lines about sub_thread will be deleted.
- * It is temporary code for sync_drawing. */
-
- g_mutex_init(&surf_source->sub_thread_mutex);
- g_cond_init(&surf_source->sub_thread_cond);
-
- context = g_main_context_new();
- surf_source->vk_sub_loop = g_main_loop_new(context, FALSE);
-
- g_main_context_unref(context);
- g_mutex_lock(&surf_source->sub_thread_mutex);
- surf_source->vk_sub_thread = g_thread_new("twe_sub_thread", _vk_sub_thread_loop,
- surf_source);
- g_cond_wait(&surf_source->sub_thread_cond, &surf_source->sub_thread_mutex);
- g_mutex_unlock(&surf_source->sub_thread_mutex);
-
return TPL_ERROR_NONE;
}
TPL_LOG_T(BACKEND, "[SWAPCHAIN_DESTROY] twe_surface(%p) tbm_queue(%p)",
twe_surface, surf_source->tbm_queue);
- while (surf_source->vk_sub_loop &&
- !g_main_loop_is_running(surf_source->vk_sub_loop)) {
- /* Do nothing */
- }
-
- if (surf_source->vk_sub_thread) {
- TPL_DEBUG("vk_sub_thread(%p) exit.", surf_source->vk_sub_thread);
- g_mutex_lock(&surf_source->sub_thread_mutex);
-
- g_main_loop_quit(surf_source->vk_sub_loop);
- /* Waiting for all drawing buffers. */
- g_thread_join(surf_source->vk_sub_thread);
- g_main_loop_unref(surf_source->vk_sub_loop);
-
- g_mutex_unlock(&surf_source->sub_thread_mutex);
-
- surf_source->vk_sub_thread = NULL;
- surf_source->vk_sub_loop = NULL;
-
- g_mutex_clear(&surf_source->sub_thread_mutex);
- g_cond_clear(&surf_source->sub_thread_cond);
- }
-
/* Waiting for vblank to commit all draw done buffers.*/
while (surf_source->vblank_waiting_buffers &&
!__tpl_list_is_empty(surf_source->vblank_waiting_buffers)) {
g_mutex_unlock(&surf_source->surf_mutex);
}
-static gboolean
-_twe_thread_sync_draw_source_dispatch(GSource *source, GSourceFunc cb, gpointer data)
-{
- twe_sync_draw_source *sync_draw_source = (twe_sync_draw_source *)source;
- GIOCondition cond;
-
- if (g_source_is_destroyed(source)) {
- TPL_ERR("del_source(%p) already destroyed.", source);
- return G_SOURCE_REMOVE;
- }
-
- cond = g_source_query_unix_fd(source, sync_draw_source->tag);
-
- if (cond & G_IO_IN) {
- ssize_t s;
- uint64_t u;
- int ret;
- uint64_t value = 1;
- tbm_surface_h tbm_surface = sync_draw_source->tbm_surface;
- twe_wl_surf_source *surf_source = sync_draw_source->buf_info->surf_source;
-
- tbm_surface_internal_ref(tbm_surface);
-
- s = read(sync_draw_source->event_fd, &u, sizeof(uint64_t));
- if (s != sizeof(uint64_t))
- TPL_ERR("Failed to read from event_fd(%d)",
- sync_draw_source->event_fd);
-
- TRACE_BEGIN("Fence waiting. BO(%d)",
- tbm_bo_export(
- tbm_surface_internal_get_bo(tbm_surface, 0)));
- /* Below API is blocking call.
- * It is waiting for drawing complete in GPU. */
- if (tbm_sync_fence_wait(sync_draw_source->draw_fence_fd, -1) != 1) {
- char buf[1024];
- strerror_r(errno, buf, sizeof(buf));
- TPL_ERR("Failed to wait sync fence(%d). | error: %d(%s)",
- sync_draw_source->draw_fence_fd, errno, buf);
- }
-
- g_mutex_lock(&surf_source->sub_thread_mutex);
- surf_source->draw_done_count++;
- g_mutex_unlock(&surf_source->sub_thread_mutex);
-
- /* Draw done */
- /* Send event to twe_wl_surf_source */
- ret = write(sync_draw_source->draw_done_signal_fd,
- &value, sizeof(uint64_t));
- if (ret == -1) {
- TPL_ERR("failed to send acquirable event. tbm_surface(%p)",
- tbm_surface);
- }
- TRACE_END();
-
- tbm_surface_internal_unref(tbm_surface);
- }
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-_twe_thread_sync_draw_source_finalize(GSource *source)
-{
- twe_sync_draw_source *sync_draw_source = (twe_sync_draw_source *)source;
- twe_wl_buffer_info *buf_info = sync_draw_source->buf_info;
-
- TPL_LOG_T(BACKEND, "gsource(%p) event_fd(%d)",
- source, sync_draw_source->event_fd);
-
- close(sync_draw_source->event_fd);
- close(sync_draw_source->draw_fence_fd);
-
- buf_info->sync_draw_source = NULL;
- sync_draw_source->draw_fence_fd = -1;
- sync_draw_source->tag = NULL;
- sync_draw_source->event_fd = -1;
- sync_draw_source->draw_done_signal_fd = -1;
- sync_draw_source->buf_info = NULL;
- sync_draw_source->tbm_surface = NULL;
-}
-
-static GSourceFuncs _twe_sync_draw_source_funcs = {
- .prepare = NULL,
- .check = NULL,
- .dispatch = _twe_thread_sync_draw_source_dispatch,
- .finalize = _twe_thread_sync_draw_source_finalize,
-};
-
-static twe_sync_draw_source *
-_twe_sync_draw_source_attach(twe_wl_surf_source *surf_source,
- twe_wl_buffer_info *buf_info,
- tbm_fd sync_fd)
-{
- twe_sync_draw_source *source = NULL;
-
- if (!surf_source->vk_sub_thread || !surf_source->vk_sub_loop) {
- TPL_ERR("Invalid parameter. vk_sub_thread is not initialized.");
- return NULL;
- }
-
- if (!buf_info) {
- TPL_ERR("Invalid parameter. buf_info is NULL");
- return NULL;
- }
-
- source = (twe_sync_draw_source *)g_source_new(&_twe_sync_draw_source_funcs,
- sizeof(twe_sync_draw_source));
- if (!source) {
- TPL_ERR("[THREAD] Failed to create GSource");
- return NULL;
- }
-
- source->event_fd = eventfd(0, EFD_CLOEXEC);
- if (source->event_fd < 0) {
- TPL_ERR("[THREAD] Failed to create eventfd. errno(%d)", errno);
- g_source_unref(&source->gsource);
- return NULL;
- }
-
- source->tag = g_source_add_unix_fd(&source->gsource,
- source->event_fd,
- G_IO_IN);
- source->draw_done_signal_fd = surf_source->event_fd;
- source->draw_fence_fd = sync_fd;
- source->buf_info = buf_info;
- source->tbm_surface = buf_info->tbm_surface;
-
- g_source_attach(&source->gsource, g_main_loop_get_context(surf_source->vk_sub_loop));
- g_source_unref(&source->gsource);
-
- return source;
-}
-
tpl_result_t
twe_surface_set_sync_fd(twe_surface_h twe_surface,
tbm_surface_h tbm_surface, tbm_fd sync_fd)
{
- twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface;
- twe_wl_buffer_info *buf_info = NULL;
- twe_sync_draw_source *sync_draw_source = NULL;
- int ret;
- uint64_t value = 1;
-
- tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
- (void **)&buf_info);
- if (!buf_info) {
- TPL_ERR("wl_buffer_info is not existed in tbm_surface(%p)",
- tbm_surface);
- surf_source->use_sync_fence = TPL_FALSE;
- return TPL_ERROR_INVALID_OPERATION;
- }
-
- sync_draw_source = _twe_sync_draw_source_attach(surf_source,
- buf_info, sync_fd);
- if (!sync_draw_source) {
- TPL_ERR("Failed to create and attach sync_draw_source.");
- surf_source->use_sync_fence = TPL_FALSE;
- return TPL_ERROR_INVALID_OPERATION;
- }
-
- /* Draw done */
- /* Send event to twe_wl_surf_source */
- ret = write(sync_draw_source->event_fd,
- &value, sizeof(uint64_t));
- if (ret == -1) {
- TPL_ERR("failed to send event to wait sync_fd(%d). twe_wl_surf_source(%p)",
- sync_fd, surf_source);
- g_source_remove_unix_fd(&sync_draw_source->gsource,
- sync_draw_source->tag);
- g_source_destroy(&sync_draw_source->gsource);
- surf_source->use_sync_fence = TPL_FALSE;
- return TPL_ERROR_INVALID_OPERATION;
- }
-
- surf_source->use_sync_fence = TPL_TRUE;
+ TPL_IGNORE(twe_surface);
+ TPL_IGNORE(tbm_surface);
+ TPL_IGNORE(sync_fd);
return TPL_ERROR_NONE;
}