struct wayland_tbm_client *wl_tbm_client;
struct tizen_surface_shm *tss; /* used for surface buffer_flush */
struct wp_presentation *presentation;
- tpl_list_t *presentation_feedbacks;
struct zwp_linux_explicit_synchronization_v1 *explicit_sync;
tpl_bool_t use_explicit_sync;
struct {
tpl_list_t *fence_waiting_sources; /* Trace fence_wait_source from ENQUEUE to fence signaled */
tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */
tpl_list_t *render_done_fences; /* for attaching to twe_thread with fences passed by enqueue */
+ tpl_list_t *presentation_feedbacks; /* for tracing presentation feedbacks */
tbm_surface_h draw_done_buffer; /* for MAILBOX mode */
int render_done_cnt;
int fd;
} commit_sync;
- tbm_fd presentation_sync_timeline;
- int presentation_sync_timestamp;
- int presentation_sync_ts_backup;
- int presentation_sync_req_cnt;
- GMutex pst_mutex;
+ struct {
+ GMutex mutex;
+ int fd;
+ } presentation_sync;
GMutex surf_mutex;
int acquire_fence_fd;
int commit_sync_fd;
+
+ struct wp_presentation_feedback *presentation_feedback;
+ int presentation_sync_fd;
+
};
struct _twe_fence_wait_source {
_twe_display_print_err(disp_source, "dispatch_queue_pending");
}
- if (disp_source->presentation && disp_source->presentation_feedbacks)
- __tpl_list_free(disp_source->presentation_feedbacks, (tpl_free_func_t)free);
-
wl_event_queue_destroy(disp_source->ev_queue);
g_mutex_unlock(&disp_source->wl_event_mutex);
TPL_DISPLAY_PRESENT_MODE_FIFO;
_twe_display_wayland_init(source);
- source->presentation_feedbacks = NULL;
-
- if (source->presentation)
- source->presentation_feedbacks = __tpl_list_alloc();
-
source->disp_del_source = _twe_del_source_init(ctx, source);
source->disp_del_source->destroy_target_source_func
= _twe_thread_wl_disp_source_destroy;
struct tizen_private *tizen_private = (struct tizen_private *)private;
twe_wl_surf_source *surf_source = NULL;
- tbm_fd presentation_sync_fd = -1;
+ int presentation_sync_fd = -1;
surf_source = (twe_wl_surf_source *)tizen_private->data;
if (!surf_source) {
return -1;
}
- if (surf_source->presentation_sync_timeline != -1) {
- char name[32];
- snprintf(name, 32, "p_sync_timeline:%d",
- surf_source->presentation_sync_timeline);
-
- g_mutex_lock(&surf_source->pst_mutex);
-
- surf_source->presentation_sync_timestamp++;
-
- presentation_sync_fd = tbm_sync_fence_create(surf_source->presentation_sync_timeline,
- name,
- surf_source->presentation_sync_timestamp);
- TPL_DEBUG("[PRESENTATION_SYNC] surf_source(%p) timeline(%d) timestamp(%d) sync_fence(%d)",
- surf_source, surf_source->presentation_sync_timeline, surf_source->presentation_sync_timestamp,
- presentation_sync_fd);
+ g_mutex_lock(&surf_source->presentation_sync.mutex);
+ if (surf_source->presentation_sync.fd != -1) {
+ presentation_sync_fd = dup(surf_source->presentation_sync.fd);
+ TRACE_MARK("[ONLY_DUP] presentation_sync_fd(%d) dup(%d)",
+ surf_source->presentation_sync.fd, presentation_sync_fd);
+ TPL_DEBUG("[DUP_PRESENTATION_SYNC] surf_source(%p) presentation_sync_fd(%d) dup(%d)",
+ surf_source, surf_source->presentation_sync.fd, presentation_sync_fd);
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
+ return presentation_sync_fd;
+ }
- TRACE_ASYNC_BEGIN(surf_source->presentation_sync_timestamp, "[PRESENTATION]");
+ surf_source->presentation_sync.fd = eventfd(0, EFD_CLOEXEC);
+ if (surf_source->presentation_sync.fd == -1) {
+ TPL_ERR("Failed to create presentation_sync_fd. twe_surface(%p)", surf_source);
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
+ return -1;
+ }
- surf_source->presentation_sync_req_cnt++;
+ presentation_sync_fd = dup(surf_source->presentation_sync.fd);
+ TRACE_MARK("[CREATE] presentation_sync_fd(%d) dup(%d)",
+ surf_source->presentation_sync.fd, presentation_sync_fd);
+ TPL_DEBUG("[CREATE_PRESENTATION_SYNC] surf_source(%p) presentation_sync_fd(%d) dup(%d)",
+ surf_source, surf_source->presentation_sync.fd, presentation_sync_fd);
- g_mutex_unlock(&surf_source->pst_mutex);
- return presentation_sync_fd;
- }
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
- return -1;
+ return presentation_sync_fd;
}
static int
return -1;
}
- if (surf_source->presentation_sync_timeline == -1) {
- TPL_ERR("There is no timeline for any sync fd in surf_source(%p)", surf_source);
- return -1;
- }
-
merged_fd = tbm_sync_fence_merge(NULL, sync_fd1, sync_fd2);
TPL_DEBUG("[FENCE_MERGE] surf_source(%p) fence1(%d) + fence2(%d) = merged(%d)",
if (buf_info->commit_sync_fd != -1) {
int ret = _write_to_eventfd(buf_info->commit_sync_fd);
if (ret == -1)
- TPL_ERR("Failed to send commit_sync signal to fd(%d)", buf_info->commit_sync_fd);
+ TPL_ERR("Failed to send commit_sync signal to fd(%d)",
+ buf_info->commit_sync_fd);
close(buf_info->commit_sync_fd);
buf_info->commit_sync_fd = -1;
}
+ if (buf_info->presentation_sync_fd != -1) {
+ int ret = _write_to_eventfd(buf_info->presentation_sync_fd);
+ if (ret == -1)
+ TPL_ERR("Failed to send presentation_sync signal to fd(%d)",
+ buf_info->presentation_sync_fd);
+ close(buf_info->presentation_sync_fd);
+ buf_info->presentation_sync_fd = -1;
+
+ if (buf_info->presentation_feedback)
+ wp_presentation_feedback_destroy(buf_info->presentation_feedback);
+ buf_info->presentation_feedback = NULL;
+ }
+
if (buf_info->sync_timeline != -1) {
close(buf_info->sync_timeline);
buf_info->sync_timeline = -1;
buf_info->acquire_fence_fd = -1;
buf_info->commit_sync_fd = -1;
+ buf_info->presentation_sync_fd = -1;
+ buf_info->presentation_feedback = NULL;
+
if (surf_source->in_use_buffers) {
g_mutex_lock(&surf_source->surf_mutex);
__tpl_list_push_back(surf_source->in_use_buffers,
buf_info->release_fence_fd = -1;
buf_info->acquire_fence_fd = -1;
buf_info->commit_sync_fd = -1;
+ buf_info->presentation_sync_fd = -1;
+ buf_info->presentation_feedback = NULL;
+
wl_buffer_add_listener((void *)buf_info->wl_buffer,
&wl_buffer_release_listener, tbm_surface);
TRACE_ASYNC_BEGIN(buf_info->commit_sync_fd, "[COMMIT_SYNC] bo(%d)",
tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
g_mutex_unlock(&surf_source->commit_sync.mutex);
+
+ g_mutex_lock(&surf_source->presentation_sync.mutex);
+ buf_info->presentation_sync_fd = surf_source->presentation_sync.fd;
+ surf_source->presentation_sync.fd = -1;
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
}
if (surf_source->in_use_buffers) {
TPL_IGNORE(seq_lo);
TPL_IGNORE(flags);
- struct feedback_info *feedback_info = (struct feedback_info *)data;
- twe_wl_surf_source *surf_source = feedback_info->surf_source;
- twe_wl_disp_source *disp_source = surf_source->disp_source;
-
- g_mutex_lock(&surf_source->pst_mutex);
+ tbm_surface_h tbm_surface = (tbm_surface_h)data;
+ twe_wl_buffer_info *buf_info = NULL;
+ twe_wl_surf_source *surf_source = NULL;
- TPL_DEBUG("[FEEDBACK][PRESENTED] surf_source(%p) wl_surface(%p)",
- surf_source, surf_source->surf);
+ tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+ (void **)&buf_info);
+ if (!buf_info) {
+ TPL_ERR("Failed to get twe_wl_buffer_info from tbm_surface(%p)",
+ tbm_surface);
+ return;
+ }
- if (surf_source->presentation_sync_timeline != -1 &&
- surf_source->presentation_sync_req_cnt > 0) {
+ surf_source = buf_info->surf_source;
- surf_source->presentation_sync_ts_backup++;
- surf_source->presentation_sync_req_cnt--;
+ g_mutex_lock(&surf_source->presentation_sync.mutex);
- TRACE_ASYNC_END(surf_source->presentation_sync_ts_backup, "[PRESENTATION]");
+ TPL_DEBUG("[FEEDBACK][PRESENTED] surf_source(%p) tbm_surface(%p) bo(%d)",
+ surf_source, tbm_surface,
+ tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
- TPL_DEBUG("[PRESENTATION][INC] surf_source(%p) timeline(%d) timestamp(%d)",
- surf_source, surf_source->presentation_sync_timeline,
- surf_source->presentation_sync_ts_backup);
- if (!tbm_sync_timeline_inc(surf_source->presentation_sync_timeline, 1)) {
- TPL_ERR("Failed to increase timeline(%d)",
- surf_source->presentation_sync_timeline);
+ if (buf_info->presentation_sync_fd != -1) {
+ int ret = _write_to_eventfd(buf_info->presentation_sync_fd);
+ if (ret == -1) {
+ TPL_ERR("Failed to send presentation_sync signal to fd(%d)",
+ buf_info->presentation_sync_fd);
}
+
+ TRACE_ASYNC_END(buf_info->presentation_sync_fd,
+ "[PRESENTATION_SYNC] bo(%d)",
+ tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
+
+ close(buf_info->presentation_sync_fd);
+ buf_info->presentation_sync_fd = -1;
}
- if (presentation_feedback)
- wp_presentation_feedback_destroy(presentation_feedback);
+ if (buf_info->presentation_feedback)
+ wp_presentation_feedback_destroy(buf_info->presentation_feedback);
+
+ buf_info->presentation_feedback = NULL;
- __tpl_list_remove_data(disp_source->presentation_feedbacks, feedback_info,
- TPL_FIRST, (tpl_free_func_t)free);
+ __tpl_list_remove_data(surf_source->presentation_feedbacks, tbm_surface,
+ TPL_FIRST, NULL);
- g_mutex_unlock(&surf_source->pst_mutex);
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
}
static void
__cb_presentation_feedback_discarded(void *data,
struct wp_presentation_feedback *presentation_feedback)
{
- struct feedback_info *feedback_info = (struct feedback_info *)data;
- twe_wl_surf_source *surf_source = feedback_info->surf_source;
- twe_wl_disp_source *disp_source = surf_source->disp_source;
-
- g_mutex_lock(&surf_source->pst_mutex);
+ tbm_surface_h tbm_surface = (tbm_surface_h)data;
+ twe_wl_buffer_info *buf_info = NULL;
+ twe_wl_surf_source *surf_source = NULL;
- TPL_DEBUG("[FEEDBACK][DISCARDED] surf_source(%p) wl_surface(%p)",
- surf_source, surf_source->surf);
+ tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+ (void **)&buf_info);
+ if (!buf_info) {
+ TPL_ERR("Failed to get twe_wl_buffer_info from tbm_surface(%p)",
+ tbm_surface);
+ return;
+ }
- if (surf_source->presentation_sync_timeline != -1 &&
- surf_source->presentation_sync_req_cnt > 0) {
+ surf_source = buf_info->surf_source;
- surf_source->presentation_sync_ts_backup++;
- surf_source->presentation_sync_req_cnt--;
+ g_mutex_lock(&surf_source->presentation_sync.mutex);
- TRACE_ASYNC_END(surf_source->presentation_sync_ts_backup, "[PRESENTATION]");
+ TPL_DEBUG("[FEEDBACK][DISCARDED] surf_source(%p) tbm_surface(%p) bo(%d)",
+ surf_source, tbm_surface,
+ tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
- TPL_DEBUG("[PRESENTATION][INC] surf_source(%p) timeline(%d) timestamp(%d)",
- surf_source, surf_source->presentation_sync_timeline,
- surf_source->presentation_sync_ts_backup);
- if (!tbm_sync_timeline_inc(surf_source->presentation_sync_timeline, 1)) {
- TPL_ERR("Failed to increase timeline(%d)",
- surf_source->presentation_sync_timeline);
+ if (buf_info->presentation_sync_fd != -1) {
+ int ret = _write_to_eventfd(buf_info->presentation_sync_fd);
+ if (ret == -1) {
+ TPL_ERR("Failed to send presentation_sync signal to fd(%d)",
+ buf_info->presentation_sync_fd);
}
+
+ TRACE_ASYNC_END(buf_info->presentation_sync_fd,
+ "[PRESENTATION_SYNC] bo(%d)",
+ tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
+
+ close(buf_info->presentation_sync_fd);
+ buf_info->presentation_sync_fd = -1;
}
- if (presentation_feedback)
- wp_presentation_feedback_destroy(presentation_feedback);
+ if (buf_info->presentation_feedback)
+ wp_presentation_feedback_destroy(buf_info->presentation_feedback);
- if (disp_source->presentation_feedbacks)
- __tpl_list_remove_data(disp_source->presentation_feedbacks, feedback_info,
- TPL_FIRST, (tpl_free_func_t)free);
+ buf_info->presentation_feedback = NULL;
- g_mutex_unlock(&surf_source->pst_mutex);
+ __tpl_list_remove_data(surf_source->presentation_feedbacks, tbm_surface,
+ TPL_FIRST, NULL);
+
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
}
static const struct wp_presentation_feedback_listener feedback_listener = {
version = wl_proxy_get_version((struct wl_proxy *)wl_surface);
- g_mutex_lock(&surf_source->pst_mutex);
- if (disp_source->presentation &&
- surf_source->presentation_sync_req_cnt > 0) {
- struct feedback_info *feedback_info =
- (struct feedback_info *)calloc(1, sizeof(struct feedback_info));
- if (feedback_info) {
- feedback_info->feedback = wp_presentation_feedback(disp_source->presentation,
- wl_surface);
- feedback_info->surf_source = surf_source;
- wp_presentation_feedback_add_listener(feedback_info->feedback,
- &feedback_listener, feedback_info);
- if (disp_source->presentation_feedbacks)
- __tpl_list_push_back(disp_source->presentation_feedbacks,
- (void *)feedback_info);
- }
+ g_mutex_lock(&surf_source->presentation_sync.mutex);
+ if (disp_source->presentation && buf_info->presentation_sync_fd != -1) {
+ buf_info->presentation_feedback =
+ wp_presentation_feedback(disp_source->presentation,
+ wl_surface);
+ wp_presentation_feedback_add_listener(buf_info->presentation_feedback,
+ &feedback_listener, tbm_surface);
+ __tpl_list_push_back(surf_source->presentation_feedbacks, tbm_surface);
+ TRACE_ASYNC_BEGIN(buf_info->presentation_sync_fd,
+ "[PRESENTATION_SYNC] bo(%d)",
+ tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
}
- g_mutex_unlock(&surf_source->pst_mutex);
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
if (buf_info->w_rotated == TPL_TRUE) {
wayland_tbm_client_set_buffer_transform(
g_mutex_lock(&surf_source->surf_mutex);
- if (disp_source->presentation && disp_source->presentation_feedbacks) {
- int num_feedbacks = __tpl_list_get_count(disp_source->presentation_feedbacks);
- while (num_feedbacks) {
- struct feedback_info *feedback_info = __tpl_list_pop_front(disp_source->presentation_feedbacks, NULL);
- if (feedback_info && surf_source == feedback_info->surf_source) {
- wp_presentation_feedback_destroy(feedback_info->feedback);
- feedback_info->feedback = NULL;
- feedback_info->surf_source = NULL;
-
- free(feedback_info);
- } else {
- __tpl_list_push_back(disp_source->presentation_feedbacks, feedback_info);
+ g_mutex_lock(&surf_source->presentation_sync.mutex);
+ if (disp_source->presentation && surf_source->presentation_feedbacks) {
+ while (!__tpl_list_is_empty(surf_source->presentation_feedbacks)) {
+ tbm_surface_h tbm_surface =
+ __tpl_list_pop_front(surf_source->presentation_feedbacks, NULL);
+ if (tbm_surface_internal_is_valid(tbm_surface)) {
+ twe_wl_buffer_info *buf_info = NULL;
+ tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+ (void **)&buf_info);
+ if (buf_info && buf_info->presentation_sync_fd != -1 &&
+ buf_info->presentation_feedback) {
+
+ _write_to_eventfd(buf_info->presentation_sync_fd);
+ close(buf_info->presentation_sync_fd);
+ buf_info->presentation_sync_fd = -1;
+
+ wp_presentation_feedback_destroy(buf_info->presentation_feedback);
+ buf_info->presentation_feedback = NULL;
+ }
}
-
- num_feedbacks--;
}
}
+ if (surf_source->presentation_sync.fd != -1) {
+ _write_to_eventfd(surf_source->presentation_sync.fd);
+ close(surf_source->presentation_sync.fd);
+ surf_source->presentation_sync.fd = -1;
+ }
+ g_mutex_unlock(&surf_source->presentation_sync.mutex);
+ g_mutex_clear(&surf_source->presentation_sync.mutex);
+
if (surf_source->in_use_buffers) {
__tpl_list_free(surf_source->in_use_buffers,
(tpl_free_func_t)__cb_buffer_remove_from_list);
surf_source->surf = NULL;
}
- if (surf_source->presentation_sync_timeline >= 0) {
- close(surf_source->presentation_sync_timeline);
- surf_source->presentation_sync_timeline = -1;
- }
-
g_mutex_lock(&surf_source->commit_sync.mutex);
g_mutex_unlock(&surf_source->commit_sync.mutex);
g_mutex_clear(&surf_source->commit_sync.mutex);
source->commit_sync.fd = -1;
g_mutex_init(&source->commit_sync.mutex);
- source->presentation_sync_timeline = tbm_sync_timeline_create();
- source->presentation_sync_timestamp = 0;
- source->presentation_sync_ts_backup = 0;
- source->presentation_sync_req_cnt = 0;
+ source->presentation_sync.fd = -1;
+ g_mutex_init(&source->presentation_sync.mutex);
+ if (disp_source->presentation)
+ source->presentation_feedbacks = __tpl_list_alloc();
+ else
+ source->presentation_feedbacks = NULL;
if (!disp_source->is_vulkan_dpy) {
struct wl_egl_window *wl_egl_window =
g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop));
g_mutex_init(&source->surf_mutex);
- g_mutex_init(&source->pst_mutex);
g_mutex_init(&source->free_queue_mutex);
g_cond_init(&source->free_queue_cond);