typedef struct _tpl_wl_egl_display tpl_wl_egl_display_t;
typedef struct _tpl_wl_egl_surface tpl_wl_egl_surface_t;
typedef struct _tpl_wl_egl_buffer tpl_wl_egl_buffer_t;
+typedef struct _surface_vblank tpl_surface_vblank_t;
struct _tpl_wl_egl_display {
tpl_gsource *disp_source;
struct wayland_tbm_client *wl_tbm_client;
int last_error; /* errno of the last wl_display error*/
- tpl_bool_t wl_initialized;
- tpl_bool_t tdm_initialized;
-
- tdm_client *tdm_client;
- tpl_gsource *tdm_source;
- int tdm_display_fd;
+ tpl_bool_t wl_initialized;
tpl_bool_t use_wait_vblank;
tpl_bool_t use_explicit_sync;
tpl_bool_t prepared;
+ struct {
+ tdm_client *tdm_client;
+ tpl_gsource *tdm_source;
+ int tdm_display_fd;
+ tpl_bool_t tdm_initialized;
+ } tdm;
+
struct tizen_surface_shm *tss; /* used for surface buffer_flush */
struct wp_presentation *presentation; /* for presentation feedback */
struct zwp_linux_explicit_synchronization_v1 *explicit_sync; /* for explicit fence sync */
struct zwp_linux_surface_synchronization_v1 *surface_sync; /* for explicit fence sync */
struct tizen_surface_shm_flusher *tss_flusher; /* used for surface buffer_flush */
- tdm_client_vblank *vblank;
+ tpl_surface_vblank_t *vblank;
/* surface information */
int render_done_cnt;
int buffer_cnt; /* the number of using wl_egl_buffers */
tpl_gmutex buffers_mutex;
- tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */
tpl_list_t *presentation_feedbacks; /* for tracing presentation feedbacks */
struct {
tpl_bool_t set_serial_is_used;
};
+struct _surface_vblank {
+ tdm_client_vblank *tdm_vblank;
+ tpl_wl_egl_surface_t *wl_egl_surface;
+ tpl_list_t *waiting_buffers; /* for FIFO/FIFO_RELAXED modes */
+};
+
typedef enum buffer_status {
RELEASED = 0, // 0
DEQUEUED, // 1
return TPL_FALSE;
}
- tdm_err = tdm_client_handle_events(wl_egl_display->tdm_client);
+ tdm_err = tdm_client_handle_events(wl_egl_display->tdm.tdm_client);
/* If an error occurs in tdm_client_handle_events, it cannot be recovered.
* When tdm_source is no longer available due to an unexpected situation,
tpl_gsource_destroy(gsource, TPL_FALSE);
- wl_egl_display->tdm_source = NULL;
+ wl_egl_display->tdm.tdm_source = NULL;
return TPL_FALSE;
}
TPL_LOG_T("WL_EGL",
"tdm_destroy| wl_egl_display(%p) tdm_client(%p) tpl_gsource(%p)",
- wl_egl_display, wl_egl_display->tdm_client, gsource);
+ wl_egl_display, wl_egl_display->tdm.tdm_client, gsource);
- if (wl_egl_display->tdm_client) {
- tdm_client_destroy(wl_egl_display->tdm_client);
- wl_egl_display->tdm_client = NULL;
- wl_egl_display->tdm_display_fd = -1;
+ if (wl_egl_display->tdm.tdm_client) {
+ tdm_client_destroy(wl_egl_display->tdm.tdm_client);
+ wl_egl_display->tdm.tdm_client = NULL;
+ wl_egl_display->tdm.tdm_display_fd = -1;
+ wl_egl_display->tdm.tdm_source = NULL;
}
- wl_egl_display->tdm_initialized = TPL_FALSE;
+ wl_egl_display->tdm.tdm_initialized = TPL_FALSE;
}
static tpl_gsource_functions tdm_funcs = {
return TPL_ERROR_INVALID_OPERATION;
}
- wl_egl_display->tdm_display_fd = tdm_display_fd;
- wl_egl_display->tdm_client = tdm_client;
- wl_egl_display->tdm_source = NULL;
- wl_egl_display->tdm_initialized = TPL_TRUE;
+ wl_egl_display->tdm.tdm_display_fd = tdm_display_fd;
+ wl_egl_display->tdm.tdm_client = tdm_client;
+ wl_egl_display->tdm.tdm_source = NULL;
+ wl_egl_display->tdm.tdm_initialized = TPL_TRUE;
TPL_INFO("[TDM_CLIENT_INIT]",
"wl_egl_display(%p) tdm_client(%p) tdm_display_fd(%d)",
wl_egl_display, wl_egl_display->wl_display);
}
- if (_thread_tdm_init(wl_egl_display) != TPL_ERROR_NONE) {
+ if (wl_egl_display->use_wait_vblank &&
+ _thread_tdm_init(wl_egl_display) != TPL_ERROR_NONE) {
TPL_WARN("Failed to initialize tdm-client. TPL_WAIT_VLANK:DISABLED");
}
display->backend.data = wl_egl_display;
display->bufmgr_fd = -1;
- wl_egl_display->tdm_initialized = TPL_FALSE;
+ wl_egl_display->tdm.tdm_initialized = TPL_FALSE;
+ wl_egl_display->tdm.tdm_client = NULL;
+ wl_egl_display->tdm.tdm_display_fd = -1;
+ wl_egl_display->tdm.tdm_source = NULL;
+
wl_egl_display->wl_initialized = TPL_FALSE;
wl_egl_display->ev_queue = NULL;
goto free_display;
}
- wl_egl_display->tdm_source = tpl_gsource_create(wl_egl_display->thread,
- (void *)wl_egl_display,
- wl_egl_display->tdm_display_fd,
- &tdm_funcs, SOURCE_TYPE_NORMAL);
- if (!wl_egl_display->tdm_source) {
- TPL_ERR("Failed to create tdm_gsource\n");
- goto free_display;
+ if (wl_egl_display->use_wait_vblank &&
+ wl_egl_display->tdm.tdm_initialized) {
+ wl_egl_display->tdm.tdm_source = tpl_gsource_create(wl_egl_display->thread,
+ (void *)wl_egl_display,
+ wl_egl_display->tdm.tdm_display_fd,
+ &tdm_funcs, SOURCE_TYPE_NORMAL);
+ if (!wl_egl_display->tdm.tdm_source) {
+ TPL_ERR("Failed to create tdm_gsource\n");
+ goto free_display;
+ }
}
+ wl_egl_display->use_wait_vblank = (wl_egl_display->tdm.tdm_initialized &&
+ (wl_egl_display->tdm.tdm_source != NULL));
+
TPL_INFO("[DISPLAY_INIT]",
"wl_egl_display(%p) tpl_gthread(%p) wl_display(%p)",
wl_egl_display,
free_display:
if (wl_egl_display->thread) {
- if (wl_egl_display->tdm_source)
- tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE);
+ if (wl_egl_display->tdm.tdm_source)
+ tpl_gsource_destroy(wl_egl_display->tdm.tdm_source, TPL_TRUE);
if (wl_egl_display->disp_source)
tpl_gsource_destroy(wl_egl_display->disp_source, TPL_TRUE);
wl_egl_display->thread,
wl_egl_display->wl_display);
- if (wl_egl_display->tdm_source && wl_egl_display->tdm_initialized) {
- tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE);
- wl_egl_display->tdm_source = NULL;
+ if (wl_egl_display->tdm.tdm_source && wl_egl_display->tdm.tdm_initialized) {
+ tpl_gsource_destroy(wl_egl_display->tdm.tdm_source, TPL_TRUE);
+ wl_egl_display->tdm.tdm_source = NULL;
}
if (wl_egl_display->disp_source) {
wl_egl_surface->presentation_sync.fd = -1;
}
- if (wl_egl_surface->vblank_waiting_buffers) {
- __tpl_list_free(wl_egl_surface->vblank_waiting_buffers, NULL);
- wl_egl_surface->vblank_waiting_buffers = NULL;
+ if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) {
+ __tpl_list_free(wl_egl_surface->vblank->waiting_buffers, NULL);
+ wl_egl_surface->vblank->waiting_buffers = NULL;
}
tpl_gmutex_unlock(&wl_egl_surface->presentation_sync.mutex);
}
if (wl_egl_surface->vblank) {
+ tpl_surface_vblank_t *vblank = wl_egl_surface->vblank;
TPL_INFO("[VBLANK_DESTROY]",
- "wl_egl_surface(%p) vblank(%p)",
- wl_egl_surface, wl_egl_surface->vblank);
- tdm_client_vblank_destroy(wl_egl_surface->vblank);
+ "wl_egl_surface(%p) surface_vblank(%p) tdm_vblank(%p)",
+ wl_egl_surface, vblank,
+ vblank->tdm_vblank);
+ tdm_client_vblank_destroy(vblank->tdm_vblank);
+ vblank->tdm_vblank = NULL;
+ vblank->wl_egl_surface = NULL;
+ free(vblank);
+
wl_egl_surface->vblank = NULL;
}
static tdm_client_vblank*
_thread_create_tdm_client_vblank(tdm_client *tdm_client)
{
- tdm_client_vblank *vblank = NULL;
+ tdm_client_vblank *tdm_vblank = NULL;
tdm_client_output *tdm_output = NULL;
tdm_error tdm_err = TDM_ERROR_NONE;
return NULL;
}
- vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err);
- if (!vblank || tdm_err != TDM_ERROR_NONE) {
- TPL_ERR("Failed to create vblank. tdm_err(%d)", tdm_err);
+ tdm_vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err);
+ if (!tdm_vblank || tdm_err != TDM_ERROR_NONE) {
+ TPL_ERR("Failed to create tdm_vblank. tdm_err(%d)", tdm_err);
return NULL;
}
- tdm_client_vblank_set_enable_fake(vblank, 1);
- tdm_client_vblank_set_sync(vblank, 0);
+ tdm_client_vblank_set_enable_fake(tdm_vblank, 1);
+ tdm_client_vblank_set_sync(tdm_vblank, 0);
- return vblank;
+ return tdm_vblank;
}
static void
_thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface)
{
tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display;
+ tpl_surface_vblank_t *vblank = NULL;
wl_egl_surface->tbm_queue = _thread_create_tbm_queue(
wl_egl_surface,
CLIENT_QUEUE_SIZE,
wl_egl_surface->format);
- wl_egl_surface->vblank = _thread_create_tdm_client_vblank(
- wl_egl_display->tdm_client);
- if (wl_egl_surface->vblank) {
- TPL_INFO("[VBLANK_INIT]",
- "wl_egl_surface(%p) tdm_client(%p) vblank(%p)",
- wl_egl_surface, wl_egl_display->tdm_client,
- wl_egl_surface->vblank);
+ if (wl_egl_display->use_wait_vblank) {
+ vblank = (tpl_surface_vblank_t *)calloc(1, sizeof(tpl_surface_vblank_t));
+ if (vblank) {
+ vblank->tdm_vblank = _thread_create_tdm_client_vblank(
+ wl_egl_display->tdm.tdm_client);
+ if (!vblank->tdm_vblank) {
+ TPL_ERR("Failed to create tdm_vblank from tdm_client(%p)",
+ wl_egl_display->tdm.tdm_client);
+ free(vblank);
+ vblank = NULL;
+ } else {
+ vblank->waiting_buffers = __tpl_list_alloc();
+ vblank->wl_egl_surface = wl_egl_surface;
+
+ TPL_INFO("[VBLANK_INIT]",
+ "wl_egl_surface(%p) tdm_client(%p) tdm_vblank(%p)",
+ wl_egl_surface, wl_egl_display->tdm.tdm_client,
+ vblank->tdm_vblank);
+ }
+ }
}
+ wl_egl_surface->vblank = vblank;
+
if (wl_egl_display->tss) {
wl_egl_surface->tss_flusher =
tizen_surface_shm_get_flusher(wl_egl_display->tss,
}
}
- wl_egl_surface->vblank_waiting_buffers = __tpl_list_alloc();
wl_egl_surface->presentation_feedbacks = __tpl_list_alloc();
}
tpl_wl_egl_buffer_t *wl_egl_buffer =
(tpl_wl_egl_buffer_t *)tpl_gsource_get_data(gsource);
tpl_wl_egl_surface_t *wl_egl_surface = wl_egl_buffer->wl_egl_surface;
- tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display;
tbm_surface_h tbm_surface = wl_egl_buffer->tbm_surface;
wl_egl_surface->render_done_cnt++;
tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
- if (!wl_egl_display->use_wait_vblank || wl_egl_surface->vblank_done)
+ if (wl_egl_surface->vblank == NULL || wl_egl_surface->vblank_done)
_thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
else
- __tpl_list_push_back(wl_egl_surface->vblank_waiting_buffers,
+ __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers,
wl_egl_buffer);
tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
}
if (ready_to_commit) {
- if (!wl_egl_display->use_wait_vblank || wl_egl_surface->vblank_done)
+ if (wl_egl_surface->vblank == NULL || wl_egl_surface->vblank_done)
ready_to_commit = TPL_TRUE;
else {
wl_egl_buffer->status = WAITING_VBLANK;
- __tpl_list_push_back(wl_egl_surface->vblank_waiting_buffers, wl_egl_buffer);
+ __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers, wl_egl_buffer);
ready_to_commit = TPL_FALSE;
}
}
tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
wl_egl_buffer = (tpl_wl_egl_buffer_t *)__tpl_list_pop_front(
- wl_egl_surface->vblank_waiting_buffers,
+ wl_egl_surface->vblank->waiting_buffers,
NULL);
if (wl_egl_buffer)
_thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
_thread_surface_vblank_wait(tpl_wl_egl_surface_t *wl_egl_surface)
{
tdm_error tdm_err = TDM_ERROR_NONE;
- tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display;
+ tpl_surface_vblank_t *vblank = wl_egl_surface->vblank;
- if (wl_egl_surface->vblank == NULL) {
- wl_egl_surface->vblank =
- _thread_create_tdm_client_vblank(wl_egl_display->tdm_client);
- if (!wl_egl_surface->vblank) {
- TPL_WARN("Failed to create vblank. wl_egl_surface(%p)",
- wl_egl_surface);
- return TPL_ERROR_OUT_OF_MEMORY;
- }
- }
-
- tdm_err = tdm_client_vblank_wait(wl_egl_surface->vblank,
+ tdm_err = tdm_client_vblank_wait(vblank->tdm_vblank,
wl_egl_surface->post_interval,
__cb_tdm_client_vblank,
(void *)wl_egl_surface);
wl_egl_buffer, wl_egl_buffer->wl_buffer, wl_egl_buffer->tbm_surface,
wl_egl_buffer->bo_name);
- if (wl_egl_display->use_wait_vblank &&
+ if (wl_egl_surface->vblank != NULL &&
_thread_surface_vblank_wait(wl_egl_surface) != TPL_ERROR_NONE)
TPL_ERR("Failed to set wait vblank.");