#include "tbm_bufmgr_int.h"
#include "list.h"
+#define FREE_QUEUE 1
+#define DUTY_QUEUE 2
+#define NODE_LIST 4
+
+#define DEBUG 0
+
+#if DEBUG
+#define TBM_TRACE() TBM_LOG("[TRACE] %s:%d surface:%p\n", __FUNCTION__, __LINE__, surface_queue)
+#define TBM_LOCK() TBM_LOG("[LOCK] %s:%d surface:%p\n", __FUNCTION__, __LINE__, surface_queue)
+#define TBM_UNLOCK() TBM_LOG("[UNLOCK] %s:%d surface:%p\n", __FUNCTION__, __LINE__, surface_queue)
+#else
+#define TBM_TRACE()
+#define TBM_LOCK()
+#define TBM_UNLOCK()
+#endif
+
typedef struct {
struct list_head head;
-
struct list_head tail;
int count;
tbm_surface_h surface;
struct list_head item_link;
+ struct list_head link;
} queue_node;
+typedef struct _tbm_surface_queue_interface {
+ void (*init)(tbm_surface_queue_h queue);
+ void (*reset)(tbm_surface_queue_h queue);
+ void (*destroy)(tbm_surface_queue_h queue);
+ void (*need_attach)(tbm_surface_queue_h queue);
+
+ void (*enqueue)(tbm_surface_queue_h queue, tbm_surface_h surface);
+ void (*release)(tbm_surface_queue_h queue, tbm_surface_h surface);
+ void (*dequeue)(tbm_surface_queue_h queue);
+ void (*acquire)(tbm_surface_queue_h queue);
+}tbm_surface_queue_interface;
+
struct _tbm_surface_queue {
int width;
int height;
int format;
- int size;
- int flags;
queue free_queue;
- queue duty_queue;
- queue_node **node_list;
+ queue dirty_queue;
+ struct list_head list;
tbm_surface_queue_notify_cb destroy_cb;
void *destroy_cb_data;
pthread_mutex_t lock;
pthread_cond_t free_cond;
- pthread_cond_t duty_cond;
+ pthread_cond_t dirty_cond;
+
+ const tbm_surface_queue_interface *impl;
+ void *impl_data;
};
static queue_node *_queue_node_create(void)
{
if (node->surface)
tbm_surface_destroy(node->surface);
+
LIST_DEL(&node->item_link);
+ LIST_DEL(&node->link);
free(node);
}
return node;
}
-static int _queue_node_exist_in_queue(queue * queue, queue_node * node)
+static queue_node* _queue_get_node(tbm_surface_queue_h surface_queue, int type, tbm_surface_h surface, int *out_type)
{
- queue_node *search_node = NULL;
- queue_node *temp = NULL;
+ queue_node *node = NULL;
+ queue_node *tmp = NULL;
+
+ if (type == 0)
+ type = FREE_QUEUE | DUTY_QUEUE | NODE_LIST;
+ if (out_type)
+ *out_type = 0;
+
+ if (type & FREE_QUEUE)
+ {
+ LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
+ if (node->surface == surface)
+ {
+ if (out_type) *out_type = FREE_QUEUE;
+ return node;
+ }
+ }
+ }
- if (!_queue_is_empty(queue)) {
- LIST_FOR_EACH_ENTRY_SAFE(search_node, temp, &queue->head, item_link) {
- if (search_node == node)
- return 1;
+ if (type & DUTY_QUEUE)
+ {
+ LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->dirty_queue.head, item_link) {
+ if (node->surface == surface)
+ {
+ if (out_type) *out_type = DUTY_QUEUE;
+ return node;
+ }
}
}
- return 0;
+ if (type & NODE_LIST)
+ {
+ LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
+ if (node->surface == surface)
+ {
+ if (out_type) *out_type = NODE_LIST;
+ return node;
+ }
+ }
+ }
+
+ return NULL;
}
static void _queue_init(queue * queue)
queue->count = 0;
}
-tbm_surface_queue_error_e tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
+void _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
{
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
+ queue_node *node = NULL;
- int i;
+ node = _queue_node_create();
+ TBM_RETURN_IF_FAIL(node != NULL);
- pthread_mutex_lock(&surface_queue->lock);
+ tbm_surface_internal_ref(surface);
+ node->surface = surface;
- for (i = 0; i < surface_queue->size; i++) {
- if (surface_queue->node_list[i]->surface == surface)
- break;
- }
+ LIST_ADDTAIL(&node->link, &surface_queue->list);
+ _queue_node_push_back(&surface_queue->free_queue, node);
+}
- if (i == surface_queue->size) {
- TBM_LOG("Can't find the surface in queue\n");
- pthread_mutex_unlock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
- }
+void _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
+{
+ queue_node *node = NULL;
+ int queue_type;
- if (_queue_node_exist_in_queue(&surface_queue->duty_queue, surface_queue->node_list[i])) {
- TBM_LOG("Surface exist in queue\n");
- pthread_mutex_unlock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
- }
+ node = _queue_get_node(surface_queue, 0, surface, &queue_type);
+ if (node)
+ _queue_node_delete(node);
+}
+
+void _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue, tbm_surface_h surface, int push_back)
+{
+ queue_node *node = NULL;
+ int queue_type;
+
+ node = _queue_get_node(surface_queue, 0, surface, &queue_type);
+ TBM_RETURN_IF_FAIL(node != NULL);
+ TBM_RETURN_IF_FAIL(queue_type == NODE_LIST);
+
+ if (push_back)
+ _queue_node_push_back(&surface_queue->dirty_queue, node);
+ else
+ _queue_node_push_front(&surface_queue->dirty_queue, node);
+}
+
+void _tbm_surface_queue_release(tbm_surface_queue_h surface_queue, tbm_surface_h surface, int push_back)
+{
+ queue_node *node = NULL;
+ int queue_type;
+
+ node = _queue_get_node(surface_queue, 0, surface, &queue_type);
+ TBM_RETURN_IF_FAIL(node != NULL);
+ TBM_RETURN_IF_FAIL(queue_type == NODE_LIST);
+
+ if (push_back)
+ _queue_node_push_back(&surface_queue->free_queue, node);
+ else
+ _queue_node_push_front(&surface_queue->free_queue, node);
+}
+
+void _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
+ int width, int height, int format,
+ const tbm_surface_queue_interface* impl, void *data)
+{
+ TBM_RETURN_IF_FAIL(surface_queue != NULL);
+ TBM_RETURN_IF_FAIL(impl != NULL);
+
+ memset(surface_queue, 0x00, sizeof(struct _tbm_surface_queue));
+
+ pthread_mutex_init(&surface_queue->lock, NULL);
+ pthread_cond_init(&surface_queue->free_cond, NULL);
+ pthread_cond_init(&surface_queue->dirty_cond, NULL);
+
+ surface_queue->width = width;
+ surface_queue->height = height;
+ surface_queue->format = format;
+ surface_queue->impl = impl;
+ surface_queue->impl_data = data;
+
+ _queue_init(&surface_queue->free_queue);
+ _queue_init(&surface_queue->dirty_queue);
+ LIST_INITHEAD(&surface_queue->list);
+
+ if (surface_queue->impl && surface_queue->impl->init)
+ surface_queue->impl->init(surface_queue);
+}
+
+tbm_surface_queue_error_e tbm_surface_queue_set_destroy_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, void *data)
+{
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+
+ pthread_mutex_lock(&surface_queue->lock);
- _queue_node_push_back(&surface_queue->duty_queue, surface_queue->node_list[i]);
+ surface_queue->destroy_cb = destroy_cb;
+ surface_queue->destroy_cb_data = data;
pthread_mutex_unlock(&surface_queue->lock);
- pthread_cond_signal(&surface_queue->duty_cond);
- if (surface_queue->acquirable_cb)
- surface_queue->acquirable_cb(surface_queue, surface_queue->acquirable_cb_data);
+ return TBM_SURFACE_QUEUE_ERROR_NONE;
+}
+
+tbm_surface_queue_error_e tbm_surface_queue_set_dequeuable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_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->dequeuable_cb = dequeuable_cb;
+ surface_queue->dequeuable_cb_data = data;
+
+ pthread_mutex_unlock(&surface_queue->lock);
return TBM_SURFACE_QUEUE_ERROR_NONE;
}
-tbm_surface_queue_error_e tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue, tbm_surface_h * surface)
+tbm_surface_queue_error_e tbm_surface_queue_set_acquirable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, void *data)
{
TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
- TBM_RETURN_VAL_IF_FAIL(surface_queue->free_queue.count > 0, TBM_SURFACE_QUEUE_ERROR_EMPTY);
pthread_mutex_lock(&surface_queue->lock);
- if (_queue_is_empty(&surface_queue->free_queue)) {
- TBM_LOG("Surface queue is empty\n");
- pthread_mutex_unlock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_EMPTY;
- }
+ surface_queue->acquirable_cb = acquirable_cb;
+ surface_queue->acquirable_cb_data = data;
- queue_node *node = NULL;
+ pthread_mutex_unlock(&surface_queue->lock);
- node = _queue_node_pop_front(&surface_queue->free_queue);
- if (node == NULL) {
- TBM_LOG("_queue_node_pop_front is failed\n");
- pthread_mutex_unlock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
- }
+ return TBM_SURFACE_QUEUE_ERROR_NONE;
+}
- if (!node->surface) {
- tbm_surface_h surface = tbm_surface_internal_create_with_flags(surface_queue->width,
- surface_queue->height,
- surface_queue->format,
- surface_queue->flags);
- if (surface == NULL) {
- TBM_LOG("tbm surface create failed");
- pthread_mutex_unlock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_SURFACE_ALLOC_FAILED;
- }
- node->surface = surface;
- }
+int tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
+{
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
- *surface = node->surface;
+ return surface_queue->width;
+}
+
+int tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
+{
+ return surface_queue->height;
+}
+
+int tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
+{
+ return surface_queue->format;
+}
+
+tbm_surface_queue_error_e tbm_surface_queue_set_reset_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_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->reset_cb = reset_cb;
+ surface_queue->reset_cb_data = data;
pthread_mutex_unlock(&surface_queue->lock);
return TBM_SURFACE_QUEUE_ERROR_NONE;
}
-tbm_surface_queue_error_e tbm_surface_queue_release(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
+
+tbm_surface_queue_error_e tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
{
+ queue_node *node = NULL;
+ int queue_type;
+
TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
pthread_mutex_lock(&surface_queue->lock);
- int i;
- for (i = 0; i < surface_queue->size; i++) {
- if (surface_queue->node_list[i]->surface == surface)
- break;
- }
- if (i == surface_queue->size) {
- TBM_LOG("Can't find the surface in queue\n");
+ node = _queue_get_node(surface_queue, 0, surface, &queue_type);
+ if (node == NULL || queue_type != NODE_LIST)
+ {
+ TBM_LOG("tbm_surface_queue_enqueue::Surface exist in free_queue or dirty_queue node:%p, queue:%d\n", node, queue_type);
pthread_mutex_unlock(&surface_queue->lock);
return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
}
- if (_queue_node_exist_in_queue(&surface_queue->free_queue, surface_queue->node_list[i])) {
- TBM_LOG("Surface exist in queue\n");
- pthread_mutex_unlock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
- }
-
- _queue_node_push_front(&surface_queue->free_queue, surface_queue->node_list[i]);
+ if (surface_queue->impl && surface_queue->impl->enqueue)
+ surface_queue->impl->enqueue(surface_queue, surface);
+ else
+ _queue_node_push_back(&surface_queue->dirty_queue, node);
pthread_mutex_unlock(&surface_queue->lock);
- pthread_cond_signal(&surface_queue->free_cond);
+ pthread_cond_signal(&surface_queue->dirty_cond);
- if (surface_queue->dequeuable_cb)
- surface_queue->dequeuable_cb(surface_queue, surface_queue->dequeuable_cb_data);
+ if (!_queue_is_empty(&surface_queue->dirty_queue) && surface_queue->acquirable_cb)
+ surface_queue->acquirable_cb(surface_queue, surface_queue->acquirable_cb_data);
return TBM_SURFACE_QUEUE_ERROR_NONE;
}
-tbm_surface_queue_error_e tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue, tbm_surface_h * surface)
+tbm_surface_queue_error_e tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue, tbm_surface_h * surface)
{
+ queue_node *node = NULL;
+
TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
- TBM_RETURN_VAL_IF_FAIL(surface_queue->duty_queue.count > 0, TBM_SURFACE_QUEUE_ERROR_EMPTY);
+ TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
pthread_mutex_lock(&surface_queue->lock);
- if (_queue_is_empty(&surface_queue->duty_queue)) {
- TBM_LOG("Surface queue is empty\n");
- pthread_mutex_unlock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_EMPTY;
- }
+ if (surface_queue->impl && surface_queue->impl->dequeue)
+ surface_queue->impl->dequeue(surface_queue);
- queue_node *node = NULL;
+ if (_queue_is_empty(&surface_queue->free_queue)) {
+ if (surface_queue->impl && surface_queue->impl->need_attach)
+ surface_queue->impl->need_attach(surface_queue);
- node = _queue_node_pop_front(&surface_queue->duty_queue);
- if (node == NULL) {
- TBM_LOG("_queue_node_pop_front failed\n");
+ if (_queue_is_empty(&surface_queue->free_queue)) {
+ pthread_mutex_unlock(&surface_queue->lock);
+ return TBM_SURFACE_QUEUE_ERROR_EMPTY;
+ }
+ }
+
+ node = _queue_node_pop_front(&surface_queue->free_queue);
+ if (node == NULL || node->surface == NULL) {
+ TBM_LOG("_queue_node_pop_front is failed\n");
pthread_mutex_unlock(&surface_queue->lock);
return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
}
pthread_mutex_lock(&surface_queue->lock);
if (_queue_is_empty(&surface_queue->free_queue)) {
+ if (surface_queue->impl && surface_queue->impl->need_attach)
+ surface_queue->impl->need_attach(surface_queue);
+ }
+
+ if (_queue_is_empty(&surface_queue->free_queue)) {
if (wait) {
pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
pthread_mutex_unlock(&surface_queue->lock);
}
pthread_mutex_unlock(&surface_queue->lock);
+
return 1;
}
-int tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
+tbm_surface_queue_error_e tbm_surface_queue_release(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
{
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
+ queue_node *node = NULL;
+ int queue_type;
- pthread_mutex_lock(&surface_queue->lock);
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+ TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
- if (_queue_is_empty(&surface_queue->duty_queue)) {
- if (wait) {
- pthread_cond_wait(&surface_queue->duty_cond, &surface_queue->lock);
- pthread_mutex_unlock(&surface_queue->lock);
- return 1;
- }
+ pthread_mutex_lock(&surface_queue->lock);
+ node = _queue_get_node(surface_queue, 0, surface, &queue_type);
+ if (node == NULL || queue_type != NODE_LIST)
+ {
+ TBM_LOG("tbm_surface_queue_release::Surface exist in free_queue or dirty_queue node:%p, queue:%d\n", node, queue_type);
pthread_mutex_unlock(&surface_queue->lock);
- return 0;
+ return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
}
+ if (surface_queue->impl && surface_queue->impl->release)
+ surface_queue->impl->release(surface_queue, surface);
+ else
+ _queue_node_push_front(&surface_queue->free_queue, node);
+
pthread_mutex_unlock(&surface_queue->lock);
+ pthread_cond_signal(&surface_queue->free_cond);
- return 1;
+ if (!_queue_is_empty(&surface_queue->free_queue) && surface_queue->dequeuable_cb)
+ surface_queue->dequeuable_cb(surface_queue, surface_queue->dequeuable_cb_data);
+
+ return TBM_SURFACE_QUEUE_ERROR_NONE;
}
-tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width, int height, int format, int flags)
+tbm_surface_queue_error_e tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue, tbm_surface_h * surface)
{
- TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
- TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
- TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
- TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
+ queue_node *node = NULL;
- int i, j;
- tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1, sizeof(struct _tbm_surface_queue));
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+ TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
- pthread_mutex_init(&surface_queue->lock, NULL);
- pthread_cond_init(&surface_queue->free_cond, NULL);
- pthread_cond_init(&surface_queue->duty_cond, NULL);
+ pthread_mutex_lock(&surface_queue->lock);
- surface_queue->width = width;
- surface_queue->height = height;
- surface_queue->format = format;
- surface_queue->flags = flags;
- surface_queue->size = queue_size;
- surface_queue->node_list = (queue_node **) calloc(queue_size, sizeof(queue_node *));
- if (!surface_queue->node_list) {
- TBM_LOG("surface node list alloc failed");
- pthread_mutex_destroy(&surface_queue->lock);
- free(surface_queue);
- return NULL;
+ if (surface_queue->impl && surface_queue->impl->acquire)
+ surface_queue->impl->acquire(surface_queue);
+
+ if (_queue_is_empty(&surface_queue->dirty_queue)) {
+ pthread_mutex_unlock(&surface_queue->lock);
+ return TBM_SURFACE_QUEUE_ERROR_EMPTY;
}
- _queue_init(&surface_queue->free_queue);
- _queue_init(&surface_queue->duty_queue);
+ node = _queue_node_pop_front(&surface_queue->dirty_queue);
+ if (node == NULL) {
+ TBM_LOG("_queue_node_pop_front failed\n");
+ pthread_mutex_unlock(&surface_queue->lock);
+ return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
+ }
- for (i = 0; i < queue_size; i++) {
- queue_node *node = _queue_node_create();
- if (node == NULL) {
- TBM_LOG("surface node create failed");
- goto fail;
- }
+ *surface = node->surface;
- surface_queue->node_list[i] = node;
- _queue_node_push_back(&surface_queue->free_queue, node);
- }
+ pthread_mutex_unlock(&surface_queue->lock);
- return surface_queue;
+ return TBM_SURFACE_QUEUE_ERROR_NONE;
+}
- fail:
- for (j = 0; j < i; j++)
- _queue_node_delete(surface_queue->node_list[j]);
+int tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
+{
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
- free(surface_queue->node_list);
- pthread_mutex_destroy(&surface_queue->lock);
- free(surface_queue);
+ pthread_mutex_lock(&surface_queue->lock);
- return NULL;
+ if (_queue_is_empty(&surface_queue->dirty_queue)) {
+ if (wait) {
+ pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
+ pthread_mutex_unlock(&surface_queue->lock);
+ return 1;
+ }
+
+ pthread_mutex_unlock(&surface_queue->lock);
+ return 0;
+ }
+
+ pthread_mutex_unlock(&surface_queue->lock);
+
+ return 1;
}
void tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
{
+ queue_node *node = NULL, *tmp = NULL;
+
TBM_RETURN_IF_FAIL(surface_queue != NULL);
if (surface_queue->destroy_cb)
surface_queue->destroy_cb(surface_queue, surface_queue->destroy_cb_data);
- int i;
+ if (surface_queue->impl && surface_queue->impl->destroy)
+ surface_queue->impl->destroy(surface_queue);
- for (i = 0; i < surface_queue->size; i++)
- _queue_node_delete(surface_queue->node_list[i]);
+ LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
+ _queue_node_delete(node);
+ }
- free(surface_queue->node_list);
pthread_mutex_destroy(&surface_queue->lock);
free(surface_queue);
}
-tbm_surface_queue_error_e tbm_surface_queue_set_destroy_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, void *data)
+tbm_surface_queue_error_e tbm_surface_queue_reset(tbm_surface_queue_h surface_queue, int width, int height, int format)
{
TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
- pthread_mutex_lock(&surface_queue->lock);
+ queue_node *node = NULL, *tmp = NULL;
- surface_queue->destroy_cb = destroy_cb;
- surface_queue->destroy_cb_data = data;
+ if (width == surface_queue->width && height == surface_queue->height && format == surface_queue->format)
+ return TBM_SURFACE_QUEUE_ERROR_NONE;
- pthread_mutex_unlock(&surface_queue->lock);
+ pthread_mutex_lock(&surface_queue->lock);
- return TBM_SURFACE_QUEUE_ERROR_NONE;
-}
+ surface_queue->width = width;
+ surface_queue->height = height;
+ surface_queue->format = format;
-tbm_surface_queue_error_e tbm_surface_queue_set_dequeuable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, void *data)
-{
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+ /* Destory surface and Push to free_queue */
+ LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
+ {
+ _queue_node_delete(node);
+ }
- pthread_mutex_lock(&surface_queue->lock);
+ /* Reset queue */
+ _queue_init(&surface_queue->free_queue);
+ _queue_init(&surface_queue->dirty_queue);
+ LIST_INITHEAD(&surface_queue->list);
- surface_queue->dequeuable_cb = dequeuable_cb;
- surface_queue->dequeuable_cb_data = data;
+ if (surface_queue->impl && surface_queue->impl->reset)
+ surface_queue->impl->reset(surface_queue);
pthread_mutex_unlock(&surface_queue->lock);
+ pthread_cond_signal(&surface_queue->free_cond);
+
+ if (surface_queue->reset_cb)
+ surface_queue->reset_cb(surface_queue, surface_queue->reset_cb_data);
return TBM_SURFACE_QUEUE_ERROR_NONE;
}
-tbm_surface_queue_error_e tbm_surface_queue_set_acquirable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, void *data)
+typedef struct
{
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
-
- pthread_mutex_lock(&surface_queue->lock);
-
- surface_queue->acquirable_cb = acquirable_cb;
- surface_queue->acquirable_cb_data = data;
-
- pthread_mutex_unlock(&surface_queue->lock);
+ int queue_size;
+ int num_attached;
+ int flags;
+}tbm_queue_default;
- return TBM_SURFACE_QUEUE_ERROR_NONE;
+static void __tbm_queue_default_init(tbm_surface_queue_h surface_queue)
+{
}
-int tbm_surface_queue_get_queue_size(tbm_surface_queue_h surface_queue)
+static void __tbm_queue_default_reset(tbm_surface_queue_h surface_queue)
{
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
+ tbm_queue_default* data = surface_queue->impl_data;
+ data->num_attached = 0;
+}
- return surface_queue->size;
+static void __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
+{
+ free(surface_queue->impl_data);
}
-int tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
+static void __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
{
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
+ tbm_queue_default* data = surface_queue->impl_data;
+ tbm_surface_h surface;
- return surface_queue->width;
+ 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);
+ _tbm_surface_queue_attach(surface_queue, surface);
+ tbm_surface_internal_unref(surface);
+ data->num_attached++;
}
-int tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
+static void __tbm_queue_default_enqueue(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
{
- return surface_queue->height;
+ /* Push to back of dirty_queue */
+ _tbm_surface_queue_enqueue(surface_queue, surface, 1);
}
-int tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
+static void __tbm_queue_default_release(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
{
- return surface_queue->format;
+ /* Push to front of free_queue */
+ _tbm_surface_queue_release(surface_queue, surface, 0);
}
-tbm_surface_queue_error_e tbm_surface_queue_reset(tbm_surface_queue_h surface_queue, int width, int height, int format)
+static void __tbm_queue_default_dequeue(tbm_surface_queue_h surface_queue)
{
- TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
-
- int i;
- queue_node *node = NULL;
+ /*NOOP*/
+}
- if (width == surface_queue->width && height == surface_queue->height && format == surface_queue->format)
- return TBM_SURFACE_QUEUE_ERROR_NONE;
+static void __tbm_queue_default_acquire(tbm_surface_queue_h surface_queue)
+{
+ /*NOOP*/
+}
- pthread_mutex_lock(&surface_queue->lock);
+static const tbm_surface_queue_interface tbm_queue_default_impl =
+{
+ __tbm_queue_default_init,
+ __tbm_queue_default_reset,
+ __tbm_queue_default_destroy,
+ __tbm_queue_default_need_attach,
+ __tbm_queue_default_enqueue,
+ __tbm_queue_default_release,
+ __tbm_queue_default_dequeue,
+ __tbm_queue_default_acquire
+};
- surface_queue->width = width;
- surface_queue->height = height;
- surface_queue->format = format;
+tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width, int height, int format, int flags)
+{
+ TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
+ TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
+ TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
+ TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
- /* Reset queue */
- _queue_init(&surface_queue->free_queue);
- _queue_init(&surface_queue->duty_queue);
-
- /* Destory surface and Push to free_queue */
- for (i = 0; i < surface_queue->size; i++) {
- node = surface_queue->node_list[i];
- if (node->surface) {
- tbm_surface_destroy(node->surface);
- node->surface = NULL;
- }
+ tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1, sizeof(struct _tbm_surface_queue));
+ TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
- _queue_node_push_back(&surface_queue->free_queue, node);
+ tbm_queue_default *data = (tbm_queue_default *) calloc(1, sizeof(tbm_queue_default));
+ if (data == NULL)
+ {
+ free(surface_queue);
+ return NULL;
}
- pthread_mutex_unlock(&surface_queue->lock);
- pthread_cond_signal(&surface_queue->free_cond);
-
- if (surface_queue->reset_cb)
- surface_queue->reset_cb(surface_queue, surface_queue->reset_cb_data);
+ data->queue_size = queue_size;
+ data->flags = flags;
+ _tbm_surface_queue_init(surface_queue,
+ width, height, format,
+ &tbm_queue_default_impl, data);
- return TBM_SURFACE_QUEUE_ERROR_NONE;
+ return surface_queue;
}
-tbm_surface_queue_error_e tbm_surface_queue_set_reset_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_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->reset_cb = reset_cb;
- surface_queue->reset_cb_data = data;
-
- pthread_mutex_unlock(&surface_queue->lock);
-
- return TBM_SURFACE_QUEUE_ERROR_NONE;
-}