#define wl_egl_buffer(ptr) *wl_egl_buffer = (tpl_wl_egl_buffer_t *)ptr;
#define tizen_private(ptr) *tizen_private = (struct tizen_private *)ptr;
+#define rightmost_zero(x) (~(x) & ((x) + 1))
+
struct _tpl_wl_egl_display {
tpl_gsource *disp_source;
tpl_gthread *thread;
ACQUIRABLE = 2,
FORCE_FLUSH = 4,
QUEUE_RESIZE = 8,
+ BUFFERS_FINALIZE = 16,
} surf_message;
struct _tpl_wl_egl_surface {
tpl_list_t *buffers;
int buffer_cnt; /* the number of using wl_egl_buffers */
tpl_gmutex_rec buffers_mutex;
+ int in_use;
tpl_list_t *presentation_feedbacks; /* for tracing presentation feedbacks */
int fd;
} presentation_sync;
+ struct {
+ tpl_gmutex mutex;
+ tpl_gcond cond;
+ int condition; /* store status of buffers in each bit */
+ } status_sync;
+
tpl_gmutex surf_mutex;
tpl_gcond surf_cond;
surf_message sent_message;
tpl_bool_t is_activated;
+ tpl_bool_t is_finalized;
tpl_bool_t reset; /* TRUE if queue reseted by external */
tpl_bool_t need_to_enqueue;
tpl_bool_t prerotation_capability;
buffer_status status; /* for tracing buffer status */
double changed_time; /* the time when buffer status changed */
+ /* creation order between same tpl_wl_egl_surface */
+ int order;
+
/* for damage region */
int num_rects;
int *rects;
_update_buffer_status(tpl_wl_egl_buffer_t *wl_egl_buffer, buffer_status status)
{
double current_time = _get_current_time();
+ tpl_wl_egl_surface_t wl_egl_surface(wl_egl_buffer->wl_egl_surface);
+ int *condition = &wl_egl_surface->status_sync.condition;
+ tpl_bool_t is_removable = TPL_FALSE;
+ tpl_gmutex_lock(&wl_egl_surface->status_sync.mutex);
switch (status)
{
case CREATED:
+ case CANCELED:
case RELEASED:
+ is_removable = TPL_TRUE;
case DEQUEUED:
/* do nothing */
break;
break;
}
+ if (is_removable)
+ *condition &= ~wl_egl_buffer->order;
+ else
+ *condition |= wl_egl_buffer->order;
+
wl_egl_buffer->status = status;
wl_egl_buffer->changed_time = current_time;
+
+ tpl_gmutex_unlock(&wl_egl_surface->status_sync.mutex);
}
static void
wl_egl_surface->reset = TPL_FALSE;
wl_egl_surface->is_activated = TPL_FALSE;
+ wl_egl_surface->is_finalized = TPL_FALSE;
wl_egl_surface->need_to_enqueue = TPL_TRUE;
+ wl_egl_surface->need_force_release = TPL_FALSE;
wl_egl_surface->prerotation_capability = TPL_FALSE;
wl_egl_surface->vblank_done = TPL_TRUE;
wl_egl_surface->serial_updated = TPL_FALSE;
wl_egl_surface->commit_sync.fd = -1;
wl_egl_surface->presentation_sync.fd = -1;
+ wl_egl_surface->status_sync.condition = 0;
wl_egl_surface->sent_message = NONE_MESSAGE;
wl_egl_surface->buffers = __tpl_list_alloc();
+ wl_egl_surface->in_use = 0;
{
struct tizen_private *tizen_private = wl_egl_tizen_get_tizen_private(wl_egl_window);
tpl_gmutex_init(&wl_egl_surface->commit_sync.mutex);
tpl_gmutex_init(&wl_egl_surface->presentation_sync.mutex);
+ tpl_gmutex_init(&wl_egl_surface->status_sync.mutex);
+ tpl_gcond_init(&wl_egl_surface->status_sync.cond);
+
tpl_gmutex_rec_init(&wl_egl_surface->buffers_mutex);
tpl_gmutex_init(&wl_egl_surface->surf_mutex);
tpl_gmutex_clear(&wl_egl_surface->presentation_sync.mutex);
tpl_gmutex_clear(&wl_egl_surface->perf_trace.mutex);
+ tpl_gcond_clear(&wl_egl_surface->status_sync.cond);
+ tpl_gmutex_clear(&wl_egl_surface->status_sync.mutex);
+
tpl_gcond_clear(&wl_egl_surface->surf_cond);
tpl_gmutex_clear(&wl_egl_surface->surf_mutex);
wl_egl_buffer->bo_name = _get_tbm_surface_bo_name(tbm_surface);
wl_egl_buffer->wl_egl_surface = wl_egl_surface;
- _update_buffer_status(wl_egl_buffer, CREATED);
-
wl_egl_buffer->acquire_fence_fd = -1;
wl_egl_buffer->commit_sync_fd = -1;
wl_egl_buffer->presentation_sync_fd = -1;
tpl_gmutex_init(&wl_egl_buffer->mutex);
tpl_gmutex_rec_lock(&wl_egl_surface->buffers_mutex);
+ wl_egl_buffer->order = rightmost_zero(wl_egl_surface->in_use);
+ wl_egl_surface->in_use |= wl_egl_buffer->order;
__tpl_list_push_back(wl_egl_surface->buffers, (void *)wl_egl_buffer);
tpl_gmutex_rec_unlock(&wl_egl_surface->buffers_mutex);
+ _update_buffer_status(wl_egl_buffer, CREATED);
+
TPL_INFO("[WL_EGL_BUFFER_CREATE]",
"wl_egl_surface(%p) wl_egl_buffer(%p) tbm_surface(%p) bo(%d)",
wl_egl_surface, wl_egl_buffer, tbm_surface,
wl_egl_buffer->tbm_surface, wl_egl_buffer->bo_name);
tpl_gmutex_rec_lock(&wl_egl_surface->buffers_mutex);
+ wl_egl_surface->in_use &= ~wl_egl_buffer->order;
if (wl_egl_surface->buffers) {
__tpl_list_remove_data(wl_egl_surface->buffers, (void *)wl_egl_buffer,
TPL_FIRST, NULL);