tbm_bo bo;
tpl_bool_t w_rotated; /* TRUE if need to call wayland_tbm_client_set_buffer_transform */
tpl_bool_t rotated; /* TRUE if need to call wl_surface_set_buffer_transform */
- tpl_bool_t reset; /* TRUE if queue reseted by external */
tpl_bool_t is_new; /* for frontbuffer mode */
tpl_bool_t need_to_release; /* for checking need release */
struct wl_proxy *wl_proxy; /* wl_buffer proxy */
__cb_client_window_set_frontbuffer_mode(struct wl_egl_window *wl_egl_window,
void *private, int set);
-static TPL_INLINE void
-__tpl_wayland_egl_buffer_set_reset_flag(tpl_list_t *tracking_list)
-{
- tpl_list_node_t *node = __tpl_list_get_front_node(tracking_list);
-
- while (node) {
- tbm_surface_h tbm_surface =
- (tbm_surface_h)__tpl_list_node_get_data(node);
-
- if (tbm_surface) {
- tpl_wayland_egl_buffer_t *wayland_egl_buffer =
- __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface);
-
- if (wayland_egl_buffer)
- wayland_egl_buffer->reset = TPL_TRUE;
- }
-
- node = __tpl_list_node_next(node);
- }
-}
-
static void
__cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h surface_queue,
void *data)
wayland_egl_surface->reset = TPL_TRUE;
- /* Set the reset flag of the buffers which attached but not released to TPL_TRUE. */
- __tpl_wayland_egl_buffer_set_reset_flag(wayland_egl_surface->attached_buffers);
-
- /* Set the reset flag of the buffers which dequeued but not enqueued to TPL_TRUE. */
- __tpl_wayland_egl_buffer_set_reset_flag(wayland_egl_surface->dequeued_buffers);
-
TPL_OBJECT_UNLOCK(&wayland_egl_surface->base);
if (surface->reset_cb)
goto queue_create_fail;
}
+ if (tbm_surface_queue_set_modes(wayland_egl_surface->tbm_queue,
+ TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) !=
+ TBM_SURFACE_QUEUE_ERROR_NONE) {
+ TPL_ERR("Failed to set queue mode to tbm_surface_queue(%p)",
+ wayland_egl_surface->tbm_queue);
+ goto guarantee_mode_set_fail;
+ }
+
/* Set reset_callback to tbm_queue */
if (tbm_surface_queue_add_reset_cb(wayland_egl_surface->tbm_queue,
__cb_tbm_surface_queue_reset_callback,
tbm_surface_queue_remove_reset_cb(wayland_egl_surface->tbm_queue,
__cb_tbm_surface_queue_reset_callback,
(void *)surface);
+guarantee_mode_set_fail:
add_reset_cb_fail:
tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue);
+ wayland_egl_surface->tbm_queue = NULL;
queue_create_fail:
__tpl_list_free(wayland_egl_surface->attached_buffers, NULL);
alloc_dequeue_buffers_fail:
lock_res = pthread_mutex_lock(&wayland_egl_display->wl_event_mutex);
wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy,
wayland_egl_display->wl_tbm_event_queue);
+ /* When surface is destroyed, unreference tbm_surface which tracked by
+ * the list of attached_buffers in order to free the created resources.
+ * (tpl_wayland_egl_buffer_t or wl_buffer) */
+ if (wayland_egl_surface->attached_buffers) {
+ TPL_OBJECT_LOCK(&wayland_egl_surface->base);
+ while (!__tpl_list_is_empty(wayland_egl_surface->attached_buffers)) {
+ tbm_surface_queue_error_e tsq_err;
+ tbm_surface_h tbm_surface =
+ __tpl_list_pop_front(wayland_egl_surface->attached_buffers, NULL);
+ TRACE_ASYNC_END((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d",
+ tbm_bo_export(tbm_surface_internal_get_bo(
+ tbm_surface, 0)));
+ tbm_surface_internal_unref(tbm_surface);
+ tsq_err = tbm_surface_queue_release(wayland_egl_surface->tbm_queue, tbm_surface);
+ if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE)
+ TPL_ERR("Failed to release. tbm_surface(%p) tsq_err(%d)",
+ tbm_surface, tsq_err);
+ }
+
+ __tpl_list_free(wayland_egl_surface->attached_buffers, NULL);
+ wayland_egl_surface->attached_buffers = NULL;
+ TPL_OBJECT_UNLOCK(&wayland_egl_surface->base);
+ }
+
if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex);
TPL_LOG_B("WL_EGL",
wayland_egl_surface->tbm_queue = NULL;
}
- /* When surface is destroyed, unreference tbm_surface which tracked by
- * the list of attached_buffers in order to free the created resources.
- * (tpl_wayland_egl_buffer_t or wl_buffer) */
- if (wayland_egl_surface->attached_buffers) {
- TPL_OBJECT_LOCK(&wayland_egl_surface->base);
- while (!__tpl_list_is_empty(wayland_egl_surface->attached_buffers)) {
- tbm_surface_h tbm_surface =
- __tpl_list_pop_front(wayland_egl_surface->attached_buffers, NULL);
- tbm_surface_internal_unref(tbm_surface);
- }
-
- __tpl_list_free(wayland_egl_surface->attached_buffers, NULL);
- wayland_egl_surface->attached_buffers = NULL;
- TPL_OBJECT_UNLOCK(&wayland_egl_surface->base);
- }
-
/* the list of dequeued_buffers just does deletion */
if (wayland_egl_surface->dequeued_buffers) {
TPL_OBJECT_LOCK(&wayland_egl_surface->base);
TPL_OBJECT_UNLOCK(&wayland_egl_surface->base);
}
- if (wayland_egl_buffer->reset) {
- /*
- * When tbm_surface_queue being reset for receiving
- * scan-out buffer or resized buffer
- * tbm_surface_queue_enqueue will return error.
- * This error condition leads to skip frame.
- *
- * tbm_surface received from argument this function,
- * may be rendered done. So this tbm_surface is better to do
- * commit forcibly without handling queue in order to prevent
- * frame skipping.
- */
- __tpl_wayland_egl_surface_commit(surface, tbm_surface,
- num_rects, rects);
- return TPL_ERROR_NONE;
- }
-
tsq_err = tbm_surface_queue_enqueue(wayland_egl_surface->tbm_queue,
tbm_surface);
- if (tsq_err == TBM_SURFACE_QUEUE_ERROR_NONE) {
- /*
- * If tbm_surface_queue has not been reset, tbm_surface_queue_enqueue
- * will return ERROR_NONE. Otherwise, queue has been reset
- * this tbm_surface may have only one ref_count. So we need to
- * unreference this tbm_surface after getting ERROR_NONE result from
- * tbm_surface_queue_enqueue in order to prevent destruction.
- */
- tbm_surface_internal_unref(tbm_surface);
- } else {
- /*
- * If tbm_surface is valid but it is not tracked by tbm_surface_queue,
- * tbm_surface_queue_enqueue will return below value.
- * TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE
- * It means tbm_surface_queue has been reset before client try
- * to enqueue this tbm_surface.
- * We should commit this buffer to display to assure the latest frame.
- *
- * In enlightenment(E20) of TIZEN platform, depending on
- * some situation(Activate, Deactivate), the compositor may or may not
- * display the last forcibly commited buffer in this way.
- *
- * In this situation, the compositor's display policy may vary from
- * server to server.
- */
- if (tsq_err == TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE) {
- __tpl_wayland_egl_surface_commit(surface, tbm_surface,
- num_rects, rects);
- return TPL_ERROR_NONE;
- }
-
- TPL_ERR("Failed to enqeueue tbm_surface(%p). | tsq_err = %d",
- tbm_surface, tsq_err);
+ if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) {
+ TPL_ERR("Failed to enqueue tbm_surface(%p) to tbm_queue(%p) | tsq_err = %d",
+ tbm_surface, wayland_egl_surface->tbm_queue, tsq_err);
return TPL_ERROR_INVALID_OPERATION;
}
- if (tsq_err == TBM_SURFACE_QUEUE_ERROR_NONE &&
- wayland_egl_buffer->reset == TPL_TRUE) {
- wayland_egl_buffer->reset = TPL_FALSE;
- }
-
tsq_err = tbm_surface_queue_acquire(wayland_egl_surface->tbm_queue,
&tbm_surface);
- if (tsq_err == TBM_SURFACE_QUEUE_ERROR_NONE) {
- tbm_surface_internal_ref(tbm_surface);
- } else {
- TPL_ERR("Failed to acquire tbm_surface(%p). | tsq_err = %d",
- tbm_surface, tsq_err);
+ if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) {
+ TPL_ERR("Failed to acquire tbm_surface(%p) from tbm_queue(%p). | tsq_err = %d",
+ tbm_surface, wayland_egl_surface->tbm_queue, tsq_err);
return TPL_ERROR_INVALID_OPERATION;
}
tbm_surface_h tbm_surface)
{
tpl_wayland_egl_surface_t *wayland_egl_surface = NULL;
+ tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE;
wayland_egl_surface = (tpl_wayland_egl_surface_t *)surface->backend.data;
if (!wayland_egl_surface) {
tbm_surface_internal_unref(tbm_surface);
+ tsq_err = tbm_surface_queue_cancel_dequeue(wayland_egl_surface->tbm_queue,
+ tbm_surface);
+ if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) {
+ TPL_ERR("Failed to cancel dequeue tbm_surface(%p) to tbm_queue(%p)",
+ tbm_surface, wayland_egl_surface->tbm_queue);
+ return TPL_ERROR_INVALID_OPERATION;
+ }
+
TPL_LOG_B("WL_EGL", "[CANCEL BUFFER] tpl_surface(%p) tbm_surface(%p)",
surface, tbm_surface);
wayland_egl_buffer->rotated = TPL_FALSE;
}
- wayland_egl_buffer->reset = TPL_FALSE;
-
if (wayland_egl_surface->is_activated != is_activated)
wayland_egl_buffer->is_new = TPL_TRUE;
if (!wayland_egl_buffer) {
TPL_ERR("Mem alloc for wayland_egl_buffer failed!");
tbm_surface_internal_unref(tbm_surface);
+ tbm_surface_queue_cancel_dequeue(wayland_egl_surface->tbm_queue, tbm_surface);
if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex);
return NULL;
}
if (!wl_proxy) {
TPL_ERR("Failed to create TBM client buffer!");
tbm_surface_internal_unref(tbm_surface);
+ tbm_surface_queue_cancel_dequeue(wayland_egl_surface->tbm_queue, tbm_surface);
free(wayland_egl_buffer);
if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex);
return NULL;
wayland_egl_buffer->rotated = TPL_FALSE;
}
- /* reset flag is to check whether it is the buffer before
- * tbm_surface_queue is reset or not. */
- wayland_egl_buffer->reset = TPL_FALSE;
-
/* 'is_new' flag is to check wheter it is a new buffer need to commit
* in frontbuffer mode. */
wayland_egl_buffer->is_new = TPL_TRUE;
if (wayland_egl_surface->attached_buffers) {
TPL_OBJECT_LOCK(&wayland_egl_surface->base);
while (!__tpl_list_is_empty(wayland_egl_surface->attached_buffers)) {
+ tbm_surface_queue_error_e tsq_err;
tbm_surface_h tbm_surface =
__tpl_list_pop_front(wayland_egl_surface->attached_buffers, NULL);
+ TRACE_ASYNC_END((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d",
+ tbm_bo_export(tbm_surface_internal_get_bo(
+ tbm_surface, 0)));
tbm_surface_internal_unref(tbm_surface);
+ tsq_err = tbm_surface_queue_release(wayland_egl_surface->tbm_queue, tbm_surface);
+ if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE)
+ TPL_ERR("Failed to release. tbm_surface(%p) tsq_err(%d)",
+ tbm_surface, tsq_err);
}
TPL_OBJECT_UNLOCK(&wayland_egl_surface->base);
}