}
static void
+_wayland_tbm_client_queue_get_attach_bufs(struct wayland_tbm_surface_queue *queue_info,
+ int unused, tbm_surface_h *surfaces, int *count)
+{
+ struct wayland_tbm_buffer *buffer, *tmp;
+
+ *count = 0;
+
+ wl_list_for_each_safe(buffer, tmp, &queue_info->attach_bufs, link) {
+ if (unused && buffer->allocated) continue;
+
+ surfaces[*count] = buffer->tbm_surface;
+ *count = *count + 1;
+ }
+}
+
+static void
_wayland_tbm_client_queue_destroy_attach_bufs(struct wayland_tbm_surface_queue *queue_info)
{
struct wayland_tbm_buffer *buffer, *tmp;
}
}
- tbm_surface_internal_unref(buffer->tbm_surface);
wl_list_remove(&buffer->link);
free(buffer);
}
}
}
- tbm_surface_internal_unref(buffer->tbm_surface);
wl_list_remove(&buffer->link);
free(buffer);
}
{
struct wayland_tbm_surface_queue *queue_info =
(struct wayland_tbm_surface_queue *)data;
- struct wayland_tbm_buffer *buffer;
tbm_surface_h surface = NULL;
+ struct wayland_tbm_buffer *buffer;
+ int alloc = 0;
pthread_mutex_lock(&queue_info->lock);
if (_wayland_tbm_client_is_valid_attach_bufs(queue_info, buffer)) {
surface = buffer->tbm_surface;
/* ref.. pair of __wayland_tbm_client_surface_free_cb */
- tbm_surface_internal_ref(surface);
buffer->allocated = 1;
-#ifdef DEBUG_TRACE
+
WL_TBM_TRACE(" pid:%d wl_buffer:%p tbm_surface:%p ACTIVE", getpid(), buffer->wl_buffer, buffer->tbm_surface);
-#endif
+
} else {
- surface = tbm_surface_internal_create_with_flags(queue_info->width,
- queue_info->height,
- queue_info->format,
- queue_info->flag);
-#ifdef DEBUG_TRACE
- WL_TBM_TRACE(" pid:%d tbm_surface:%p invalid attach_bufs fallback", getpid(), surface);
-#endif
+ alloc = 1;
}
break;
}
}
} else {
+ alloc = 1;
+ }
+
+ pthread_mutex_unlock(&queue_info->lock);
+
+ if (surface) {
+ /* ref.. pair of __wayland_tbm_client_surface_free_cb */
+ tbm_surface_internal_ref(surface);
+ } else if (!surface && alloc) {
/* ref.. pair of __wayland_tbm_client_surface_free_cb */
surface = tbm_surface_internal_create_with_flags(queue_info->width,
queue_info->height,
queue_info->format,
queue_info->flag);
-#ifdef DEBUG_TRACE
WL_TBM_TRACE(" pid:%d tbm_surface:%p DEACTIVE", getpid(), surface);
-#endif
}
- pthread_mutex_unlock(&queue_info->lock);
-
return surface;
}
struct wayland_tbm_surface_queue *queue_info =
(struct wayland_tbm_surface_queue *)data;
struct wayland_tbm_buffer *buffer, *tmp;
+ int attached = 0;
pthread_mutex_lock(&queue_info->lock);
if (buffer->wl_buffer)
wl_tbm_queue_detach_buffer(queue_info->wl_tbm_queue, buffer->wl_buffer);
- tbm_surface_internal_unref(buffer->tbm_surface);
+ attached = 1;
wl_list_remove(&buffer->link);
free(buffer);
}
+ pthread_mutex_unlock(&queue_info->lock);
+
+ if (attached)
+ tbm_surface_internal_unref(surface);
+
/* unref.. pair of __wayland_tbm_client_surface_alloc_cb */
tbm_surface_internal_unref(surface);
-
- pthread_mutex_unlock(&queue_info->lock);
}
static void
{
struct wayland_tbm_surface_queue *queue_info =
(struct wayland_tbm_surface_queue *)data;
+ tbm_surface_queue_h tbm_queue = NULL;
+ tbm_surface_h *surfaces = NULL;
int flush = 0;
int need_flush = 0;
- tbm_surface_queue_h tbm_queue = NULL;
int queue_size = 0;
+ int count = 0;
+ int length = 0;
+ int i;
#ifdef DEBUG_TRACE
WL_TBM_TRACE(" pid:%d", getpid());
if (queue_info->active_flush) {
queue_info->active_flush = 0;
- /* flush the attached surfaces */
- _wayland_tbm_client_queue_destroy_unused_attach_bufs(queue_info, &flush);
- need_flush = 1;
+
+ length = wl_list_length(&queue_info->attach_bufs);
+ if (length) {
+ surfaces = (tbm_surface_h *)calloc(length, sizeof(tbm_surface_h));
+ if (!surfaces) {
+ WL_TBM_LOG_E("failed to alloc surfaces");
+ pthread_mutex_unlock(&queue_info->lock);
+ return;
+ }
+
+ _wayland_tbm_client_queue_get_attach_bufs(queue_info, 1, surfaces, &count);
+ /* flush the attached surfaces */
+ _wayland_tbm_client_queue_destroy_unused_attach_bufs(queue_info, &flush);
+ need_flush = 1;
+ }
}
tbm_queue = queue_info->tbm_queue;
pthread_mutex_unlock(&queue_info->lock);
+ if (surfaces) {
+ for (i = 0; i < count; i++)
+ tbm_surface_internal_unref(surfaces[i]);
+
+ free(surfaces);
+ }
+
if (need_flush)
tbm_surface_queue_set_size(tbm_queue, queue_size, flush);
}
{
struct wayland_tbm_surface_queue *queue_info =
(struct wayland_tbm_surface_queue *)data;
+ tbm_surface_h *surfaces = NULL;
+ int count = 0;
+ int length = 0;
+ int i;
#ifdef DEBUG_TRACE
WL_TBM_TRACE(" pid:%d", getpid());
#endif
pthread_mutex_lock(&queue_info->lock);
- /* remove the attach_bufs int the queue_info */
- _wayland_tbm_client_queue_destroy_attach_bufs(queue_info);
+ length = wl_list_length(&queue_info->attach_bufs);
+ if (length) {
+ surfaces = (tbm_surface_h *)calloc(length, sizeof(tbm_surface_h));
+ if (!surfaces) {
+ WL_TBM_LOG_E("failed to alloc surfaces");
+ pthread_mutex_unlock(&queue_info->lock);
+ return;
+ }
+
+ _wayland_tbm_client_queue_get_attach_bufs(queue_info, 0, surfaces, &count);
+ /* remove the attach_bufs int the queue_info */
+ _wayland_tbm_client_queue_destroy_attach_bufs(queue_info);
+ }
if (queue_info->wl_tbm_queue)
wl_tbm_queue_destroy(queue_info->wl_tbm_queue);
pthread_mutex_unlock(&queue_info->lock);
pthread_mutex_destroy(&queue_info->lock);
free(queue_info);
+
+ if (surfaces) {
+ for (i = 0; i < count; i++)
+ tbm_surface_internal_unref(surfaces[i]);
+
+ free(surfaces);
+ }
}
static void