const tbm_surface_queue_interface *impl;
void *impl_data;
+
+ //For external buffer allocation
+ tbm_surface_alloc_cb alloc_cb;
+ tbm_surface_free_cb free_cb;
+ void *alloc_cb_data;
};
static queue_node *
static void
_queue_node_delete(queue_node *node)
{
- if (node->surface)
- tbm_surface_destroy(node->surface);
-
LIST_DEL(&node->item_link);
LIST_DEL(&node->link);
free(node);
}
static void
+_queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
+{
+ if (node->surface) {
+ if (surface_queue->free_cb) {
+ surface_queue->free_cb(surface_queue,
+ surface_queue->alloc_cb_data,
+ node->surface);
+ } else {
+ tbm_surface_destroy(node->surface);
+ }
+ }
+
+ _queue_node_delete(node);
+}
+
+static void
_queue_init(queue *queue)
{
LIST_INITHEAD(&queue->head);
node = _queue_get_node(surface_queue, 0, surface, &queue_type);
if (node)
- _queue_node_delete(node);
+ _queue_delete_node(surface_queue, node);
}
void
return TBM_SURFACE_QUEUE_ERROR_NONE;
}
+tbm_surface_queue_error_e
+tbm_surface_queue_set_alloc_cb(
+ tbm_surface_queue_h surface_queue,
+ tbm_surface_alloc_cb alloc_cb,
+ tbm_surface_free_cb free_cb,
+ void *data)
+{
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL,
+ TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+
+ pthread_mutex_lock(&surface_queue->lock);
+
+ surface_queue->alloc_cb = alloc_cb;
+ surface_queue->free_cb = free_cb;
+ surface_queue->alloc_cb_data = data;
+
+ pthread_mutex_unlock(&surface_queue->lock);
+
+ return TBM_SURFACE_QUEUE_ERROR_NONE;
+}
+
int
tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
{
surface_queue->impl->destroy(surface_queue);
LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
- _queue_node_delete(node);
+ _queue_delete_node(surface_queue, node);
}
_notify_remove_all(&surface_queue->destory_noti);
/* Destory surface and Push to free_queue */
LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
- _queue_node_delete(node);
+ _queue_delete_node(surface_queue, node);
}
/* Reset queue */
return TBM_SURFACE_QUEUE_ERROR_NONE;
}
+tbm_surface_queue_error_e
+tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
+{
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL,
+ TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+
+ queue_node *node = NULL, *tmp = NULL;
+
+ pthread_mutex_lock(&surface_queue->lock);
+
+ /* Destory surface and Push to free_queue */
+ LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
+ _queue_delete_node(surface_queue, node);
+ }
+
+ /* Reset queue */
+ _queue_init(&surface_queue->free_queue);
+ _queue_init(&surface_queue->dirty_queue);
+ LIST_INITHEAD(&surface_queue->list);
+
+ if (surface_queue->impl && surface_queue->impl->reset)
+ surface_queue->impl->reset(surface_queue);
+
+ _notify_emit(surface_queue, &surface_queue->reset_noti);
+ if (surface_queue->reset_cb)
+ surface_queue->reset_cb(surface_queue, surface_queue->reset_cb_data);
+
+ pthread_mutex_unlock(&surface_queue->lock);
+ pthread_cond_signal(&surface_queue->free_cond);
+
+ return TBM_SURFACE_QUEUE_ERROR_NONE;
+}
+
typedef struct {
int queue_size;
int num_attached;
if (data->queue_size == data->num_attached)
return;
- surface = tbm_surface_internal_create_with_flags(surface_queue->width,
- surface_queue->height,
- surface_queue->format,
- data->flags);
- TBM_RETURN_IF_FAIL(surface != NULL);
+ if (surface_queue->alloc_cb) {
+ surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
+ TBM_RETURN_IF_FAIL(surface != NULL);
+ tbm_surface_internal_ref(surface);
+ } else {
+ surface = tbm_surface_internal_create_with_flags(surface_queue->width,
+ surface_queue->height,
+ surface_queue->format,
+ data->flags);
+ TBM_RETURN_IF_FAIL(surface != NULL);
+ }
+
_tbm_surface_queue_attach(surface_queue, surface);
tbm_surface_internal_unref(surface);
data->num_attached++;
if (data->queue_size == data->num_attached)
return;
- surface = tbm_surface_internal_create_with_flags(surface_queue->width,
- surface_queue->height,
- surface_queue->format,
- data->flags);
- TBM_RETURN_IF_FAIL(surface != NULL);
+ if (surface_queue->alloc_cb) {
+ surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
+ TBM_RETURN_IF_FAIL(surface != NULL);
+ tbm_surface_internal_ref(surface);
+ } else {
+ surface = tbm_surface_internal_create_with_flags(surface_queue->width,
+ surface_queue->height,
+ surface_queue->format,
+ data->flags);
+ TBM_RETURN_IF_FAIL(surface != NULL);
+ }
+
_tbm_surface_queue_attach(surface_queue, surface);
tbm_surface_internal_unref(surface);
data->num_attached++;
typedef void (*tbm_surface_queue_notify_cb) (tbm_surface_queue_h surface_queue,
void *data);
+typedef tbm_surface_h (*tbm_surface_alloc_cb) (tbm_surface_queue_h surface_queue,
+ void *data);
+
+typedef void (*tbm_surface_free_cb) (tbm_surface_queue_h surface_queue,
+ void *data, tbm_surface_h surface);
+
#ifdef __cplusplus
extern "C" {
#endif
tbm_surface_queue_error_e tbm_surface_queue_reset(
tbm_surface_queue_h surface_queue, int width, int height, int format);
+tbm_surface_queue_error_e tbm_surface_queue_flush(tbm_surface_queue_h surface_queue);
+
tbm_surface_queue_error_e tbm_surface_queue_add_reset_cb(
tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
void *data);
tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
void *data);
+tbm_surface_queue_error_e tbm_surface_queue_set_alloc_cb(
+ tbm_surface_queue_h surface_queue,
+ tbm_surface_alloc_cb alloc_cb,
+ tbm_surface_free_cb free_cb,
+ void *data);
+
/*The functions of queue factory*/
tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width,
int height, int format, int flags);