typedef struct _twe_del_source twe_del_source;
struct _twe_thread_context {
- int ref_cnt;
-
GThread *twe_thread;
GMainLoop *twe_loop;
+ int ref_cnt;
+
twe_tdm_source *tdm_source;
GMutex thread_mutex;
GThread *fence_waiting_thread;
+ /* for checking draw done */
tpl_bool_t draw_done;
tbm_fd draw_done_fence;
+
+ /* for checking released from display server */
tbm_fd sync_timeline;
unsigned int sync_timestamp;
__cb_tbm_queue_acquirable_callback(tbm_surface_queue_h surface_queue,
void *data)
{
- twe_wl_surf_source *source = (twe_wl_surf_source *)data;
+ twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data;
uint64_t value = 1;
int ret;
- ret = write(source->event_fd, &value, sizeof(uint64_t));
+ if (surf_source->disp_source->is_vulkan_dpy)
+ return;
+
+ ret = write(surf_source->event_fd, &value, sizeof(uint64_t));
if (ret == -1) {
TPL_ERR("failed to send acquirable event. twe_wl_surf_source(%p)",
- source);
+ surf_source);
return;
}
}
{
tbm_surface_h tbm_surface = NULL;
tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE;
+ twe_wl_buffer_info *buf_info = NULL;
TPL_OBJECT_LOCK(&surf_source->obj);
tbm_surface_internal_ref(tbm_surface);
+ tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+ (void **)&buf_info);
+ if (buf_info && buf_info->fence_waiting_thread) {
+ g_thread_join(buf_info->fence_waiting_thread);
+ buf_info->fence_waiting_thread = NULL;
+ }
+
TPL_LOG_T("WL_EGL", "[ACQ] tbm_surface(%p) bo(%d)",
tbm_surface,
tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
TPL_OBJECT_UNLOCK(&surf_source->obj);
}
+static gpointer
+_twe_sync_fence_waiting(gpointer data)
+{
+ twe_wl_buffer_info *buf_info = (twe_wl_buffer_info *)data;
+ twe_wl_surf_source *surf_source = buf_info->surf_source;
+ uint64_t value = 1;
+ int ret;
+
+ if (buf_info->draw_done_fence == -1)
+ return data;
+
+ TRACE_BEGIN("Fence waiting. BO(%d)",
+ tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
+ /* non worker thread mode */
+ /* TODO: set max wait time */
+ if (tbm_sync_fence_wait(buf_info->draw_done_fence, -1) != 1) {
+ char buf[1024];
+ strerror_r(errno, buf, sizeof(buf));
+ TPL_ERR("Failed to wait sync fence. | error: %d(%s)", errno, buf);
+ }
+ TRACE_END();
+
+ close(buf_info->draw_done_fence);
+ buf_info->draw_done_fence = -1;
+ buf_info->draw_done = TPL_TRUE;
+
+ ret = write(surf_source->event_fd, &value, sizeof(uint64_t));
+ if (ret == -1) {
+ TPL_ERR("failed to send acquirable event. twe_wl_surf_source(%p)",
+ surf_source);
+ }
+
+ return data;
+}
+
+tpl_result_t
+twe_surface_set_sync_fd(tbm_surface_h tbm_surface, tbm_fd sync_fd)
+{
+ twe_wl_buffer_info *buf_info = NULL;
+
+ 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);
+ return TPL_ERROR_INVALID_OPERATION;
+ }
+
+ if (sync_fd == -1) {
+ TPL_WARN("It will be managed with async mode.");
+ }
+
+ if (buf_info->fence_waiting_thread) {
+ g_thread_join(buf_info->fence_waiting_thread);
+ buf_info->fence_waiting_thread = NULL;
+ }
+
+ if (buf_info->draw_done_fence != -1) {
+ close(buf_info->draw_done_fence);
+ buf_info->draw_done_fence = -1;
+ }
+
+ buf_info->draw_done_fence = sync_fd;
+
+ buf_info->fence_waiting_thread = g_thread_new("fence_waiting_thread",
+ _twe_sync_fence_waiting,
+ buf_info);
+
+ return TPL_ERROR_NONE;
+}
+
tpl_result_t
twe_check_native_handle_is_wl_display(tpl_handle_t display)
{