#### Ecore_Buffer
build_ecore_buffer_x11_dri2="no"
build_ecore_buffer_x11_dri3="no"
+build_ecore_buffer_tbm="no"
EFL_LIB_START_OPTIONAL([Ecore_Buffer], [test "${want_ecore_buffer}" = "yes"])
### Checks for libraries
EFL_INTERNAL_DEPEND_PKG([ECORE_BUFFER], [eina])
build_ecore_buffer_x11_dri3="yes"
AC_DEFINE(BUILD_ECORE_BUFFER_X11_DRI3, 1, [Support for X11_DRI3 Backend in Ecore_Buffer])
fi
+
+PKG_CHECK_MODULES([TBM], [libtbm >= "1.1.0"],
+ [have_tbm="yes"],
+ [have_tbm="no"])
+
+if test "x${have_tbm}" = "xyes" ; then
+ build_ecore_buffer_tbm="yes"
+ AC_DEFINE(BUILD_ECORE_BUFFER_TBM, 1, [Support for TBM Backend in Ecore_Buffer])
+fi
+
EFL_EVAL_PKGS([ECORE_BUFFER])
EFL_ADD_FEATURE([ECORE_BUFFER], [shm], ["yes"])
EFL_ADD_FEATURE([ECORE_BUFFER], [x11_dri2], [${build_ecore_buffer_x11_dri2}])
EFL_ADD_FEATURE([ECORE_BUFFER], [x11_dri3], [${build_ecore_buffer_x11_dri3}])
+EFL_ADD_FEATURE([ECORE_BUFFER], [tbm], [${build_ecore_buffer_tbm}])
EFL_LIB_END_OPTIONAL([Ecore_Buffer])
AM_CONDITIONAL([BUILD_ECORE_BUFFER_X11_DRI2], [test "${build_ecore_buffer_x11_dri2}" = "xyes"])
AM_CONDITIONAL([BUILD_ECORE_BUFFER_X11_DRI3], [test "${build_ecore_buffer_x11_dri3}" = "xyes"])
+AM_CONDITIONAL([BUILD_ECORE_BUFFER_TBM], [test "${build_ecore_buffer_tbm}" = "yes"])
#### End of Ecore_Buffer
modules_ecore_buffer_x11_dri3_module_la_LIBTOOLFLAGS = --tag=disable-static
endif
+if BUILD_ECORE_BUFFER_TBM
+ecorebuffertbmdir = $(libdir)/ecore_buffer/modules/tbm/$(MODULE_ARCH)
+ecorebuffertbm_LTLIBRARIES = modules/ecore_buffer/tbm/module.la
+
+modules_ecore_buffer_tbm_module_la_SOURCES = \
+ modules/ecore_buffer/tbm/ecore_buffer_tbm.c
+modules_ecore_buffer_tbm_module_la_CPPFLAGS = \
+ -I$(top_builddir)/src/lib/efl \
+ @ECORE_BUFFER_CFLAGS@ \
+ @TBM_CFLAGS@ \
+ -I$(top_srcdir)/src/modules/ecore_buffer/tbm
+modules_ecore_buffer_tbm_module_la_LIBADD = \
+ @ECORE_BUFFER_LIBS@ \
+ @USE_ECORE_BUFFER_INTERNAL_LIBS@ \
+ @TBM_LIBS@
+modules_ecore_buffer_tbm_module_la_DEPENDENCIES = \
+ @USE_ECORE_X_INTERNAL_LIBS@ \
+ @USE_ECORE_BUFFER_INTERNAL_LIBS@
+modules_ecore_buffer_tbm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
+modules_ecore_buffer_tbm_module_la_LIBTOOLFLAGS = --tag=disable-static
+endif
+
endif
};
/**
+ * @typedef Ecore_Buffer_Plane
+ * Types for plane information.
+ * @since 1.15
+ */
+typedef struct _Ecore_Buffer_Plane Ecore_Buffer_Plane;
+
+/**
+ * @typedef Ecore_Buffer_Info
+ * Types for buffer information.
+ * @since 1.15
+ */
+typedef struct _Ecore_Buffer_Info Ecore_Buffer_Info;
+
+/**
+ * @brief Definition for the maximum number of Ecore_Buffer's plane.
+ * @since 1.15
+ */
+#define ECORE_BUFFER_PLANE_MAX 4
+
+/**
+ * @brief Definition for the Ecore_Buffer plane struct.
+ * @since 1.15
+ */
+struct _Ecore_Buffer_Plane
+{
+ int size;
+ int offset;
+ int stride;
+};
+
+/**
+ * @brief Definition for the Ecore_Buffer information struct.
+ * @since 1.15
+ */
+struct _Ecore_Buffer_Info
+{
+ int width;
+ int height;
+ int bpp;
+ int size;
+ Ecore_Buffer_Format format;
+
+ int num_planes;
+ Ecore_Buffer_Plane planes[ECORE_BUFFER_PLANE_MAX];
+ Ecore_Pixmap pixmap;
+};
+
+/**
* @struct _Ecore_Buffer_Backend
* @brief Structure used when initializing Ecore Buffer Backend. This structure
* is mainly used by modules implementing the Ecore Buffer Backend interface.
int width, int height,
Ecore_Buffer_Format format,
unsigned int flags); /**< Newly allocate memory for buffer */
+ Ecore_Buffer_Data (*buffer_alloc_with_tbm_surface)(Ecore_Buffer_Module_Data bmdata,
+ void *tbm_surface,
+ int *ret_w, int *ret_h,
+ Ecore_Buffer_Format *ret_format,
+ unsigned int flags); /**< Create Ecore_Buffer from existed tbm_surface handle. */
+ Eina_Bool (*buffer_info_get)(Ecore_Buffer_Module_Data bmdata,
+ Ecore_Buffer_Data bdata,
+ Ecore_Buffer_Info *info);
void (*buffer_free)(Ecore_Buffer_Module_Data bmdata,
Ecore_Buffer_Data bdata); /**< Free allocated memory */
Ecore_Export_Type (*buffer_export)(Ecore_Buffer_Module_Data bmdata,
Ecore_Buffer_Data bdata, int *id); /**< Get the id or fd of Ecore_Buffer for exporting it */
Ecore_Buffer_Data (*buffer_import)(Ecore_Buffer_Module_Data bmdata,
- int w, int h,
- Ecore_Buffer_Format format,
+ Ecore_Buffer_Info *info,
Ecore_Export_Type type,
int export_id,
unsigned int flags); /**< Import and create Ecore_Buffer from id or fd */
- void *(*data_get)(Ecore_Buffer_Module_Data bmdata,
- Ecore_Buffer_Data bdata);
Ecore_Pixmap (*pixmap_get)(Ecore_Buffer_Module_Data bmdata,
Ecore_Buffer_Data bdata); /**< Get the pixmap handle */
void *(*tbm_surface_get)(Ecore_Buffer_Module_Data bmdata,
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
*
* @see ecore_buffer_shutdown()
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Eina_Bool ecore_buffer_init(void);
/**
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
*
* @see ecore_buffer_init()
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Eina_Bool ecore_buffer_shutdown(void);
/**
* @param[in] be The backend
*
* @return @c EINA_TRUE if backend has been correctly registered, @c EINA_FALSE otherwise.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Eina_Bool ecore_buffer_register(Ecore_Buffer_Backend *be);
/**
* @since 1.15
*
* @param[in] be The backend
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_unregister(Ecore_Buffer_Backend *be);
/**
* @param[in] flags Flags for Ecore_Buffer
*
* @return Newly allocated Ecore_Buffer instance, NULL otherwise.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Buffer *ecore_buffer_new(const char *engine, unsigned int width, unsigned int height, Ecore_Buffer_Format format, unsigned int flags);
/**
* @since 1.15
*
* @param[in] buf The Ecore_Buffer to free
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_free(Ecore_Buffer *buf);
/**
* @p func to be called whenever @p buf is freed.
*
* @see ecore_buffer_free_callback_remove()
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_free_callback_add(Ecore_Buffer *buf, Ecore_Buffer_Cb func, void *data);
/**
* @param[in] data A pointer to the user data to remove
*
* @see ecore_buffer_free_callback_add()
- */
-EAPI void ecore_buffer_free_callback_remove(Ecore_Buffer *buf, Ecore_Buffer_Cb func, void *data);
-/**
- * @brief Get a pointer to the raw data of the given Ecore_Buffer.
*
- * @param[in] buf The Ecore_Buffer.
- *
- * @return The pointer of raw data.
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
-EAPI void *ecore_buffer_data_get(Ecore_Buffer *buf);
+EAPI void ecore_buffer_free_callback_remove(Ecore_Buffer *buf, Ecore_Buffer_Cb func, void *data);
/**
* @brief Returns the Pixmap of given Ecore_Buffer.
*
* @param[in] buf The Ecore_Buffer
*
* @return The Pixmap instance, @c 0 otherwise.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Pixmap ecore_buffer_pixmap_get(Ecore_Buffer *buf);
/**
*
* The tbm surface handle will be used for the API of libtbm.
* The API is described in tbm_surface.h in libtbm.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void *ecore_buffer_tbm_surface_get(Ecore_Buffer *buf);
/**
* @param[out] height Where to return the height value. May be @c NULL.
*
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Eina_Bool ecore_buffer_size_get(Ecore_Buffer *buf, unsigned int *width, unsigned int *height);
/**
* @return The format of given Ecore_Buffer.
*
* Return value can be one of those pre-defined value such as ECORE_BUFFER_FORMAT_XRGB8888.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Buffer_Format ecore_buffer_format_get(Ecore_Buffer *buf);
/**
* @return The flags of given Ecore_Buffer.
*
* NOTE: Not Defined yet.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI unsigned int ecore_buffer_flags_get(Ecore_Buffer *buf);
* Set up the connection of Buffer Queue daemon, and Init Ecore_Buffer_Queue libraries.
*
* @see ecore_buffer_queue_shutdown()
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
-EAPI int ecore_buffer_queue_init(void);
+EAPI int ecore_buffer_queue_init(void);
/**
* @brief Shuts down the Ecore_Buffer_Queue system.
*
* @since 1.15
*
- * @return How many times the lib has been initialized.
* This closes the connection of Buffer Queue daemon, and Shut down Ecore_Buffer_Queue libraries.
*
+ * @return How many times the lib has been initialized.
+ *
* @see ecore_buffer_queue_init()
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI int ecore_buffer_queue_shutdown(void);
* @param[in] h Height of buffer recommended to provider.
*
* @return Ecore_Buffer_Consumer instance or @c NULL if creation failed.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Buffer_Consumer *ecore_buffer_consumer_new(const char *name, int32_t queue_size, int32_t w, int32_t h);
/**
* @param[in] consumer The Ecore_Buffer_Consumer to free
*
* This frees up any memory used by the Ecore_Buffer_Consumer.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_consumer_free(Ecore_Buffer_Consumer *consumer);
/**
*
* Consumer can store Ecore_Buffer submitted by Provider as much as size of queue
* which is passed as a argument of ecore_buffer_consumer_new().
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Buffer *ecore_buffer_consumer_buffer_dequeue(Ecore_Buffer_Consumer *consumer);
/**
* By doing release, Ecore_Buffer will be used by provider again,
* or freed internally if Ecore_Buffer is not necessary anymore.
* If not, the resource of Ecore_Buffer is continually owned by consumer until released.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Eina_Bool ecore_buffer_consumer_buffer_release(Ecore_Buffer_Consumer *consumer, Ecore_Buffer *buffer);
/**
* @param[in] consumer The Ecore_Buffer_Consumer to query
*
* @return @c EINA_TRUE means queue is empty, @c EINA_FALSE otherwise.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Eina_Bool ecore_buffer_consumer_queue_is_empty(Ecore_Buffer_Consumer *consumer);
/**
*
* A call to this function will set a callback on an Ecore_Buffer_Consumer, causing
* @p func to be called whenever @p consumer is connected with provider.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_consumer_provider_add_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Provider_Add_Cb func, void *data);
/**
*
* A call to this function will set a callback on an Ecore_Buffer_Consumer, causing
* @p func to be called whenever @p consumer is disconnected with provider.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_consumer_provider_del_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Provider_Del_Cb func, void *data);
/**
* @p func to be called whenever @p consumer has received buffer submitted from provider.
*
* You may success acquire Ecore_Buffer after this callback called.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_consumer_buffer_enqueued_cb_set(Ecore_Buffer_Consumer *consumer, Ecore_Buffer_Consumer_Enqueue_Cb func, void *data);
* @param[in] name The name of Buffer_Queue.
*
* @return Ecore_Buffer_Provider instance or @c NULL if creation failed.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Buffer_Provider *ecore_buffer_provider_new(const char *name);
/**
* @param[in] provider The Ecore_Buffer_Provider to free
*
* This frees up any memory used by the Ecore_Buffer_Provider.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_provider_free(Ecore_Buffer_Provider *provider);
/**
* so, You may create new Ecore_Buffer, and then just enqueue the Ecore_Buffer.
*
* @see ecore_buffer_new(), ecore_buffer_provider_buffer_enqueue()
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Buffer_Return ecore_buffer_provider_buffer_acquire(Ecore_Buffer_Provider *provider, Ecore_Buffer **ret_buf);
/**
* and new Ecore_Buffer after received return value of ECORE_BUFFER_RETURN_NEED_ALLOC by ecore_buffer_provider_buffer_acquire().
*
* @see ecore_buffer_new(), ecore_buffer_provider_buffer_dequeue()
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Eina_Bool ecore_buffer_provider_buffer_enqueue(Ecore_Buffer_Provider *provider, Ecore_Buffer *buffer);
/**
* so, You may create new Ecore_Buffer, and then just enqueue the Ecore_Buffer.
*
* @return @c EINA_TRUE means queue is empty, @c EINA_FALSE otherwise.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI Ecore_Buffer_Return ecore_buffer_provider_buffer_acquirable_check(Ecore_Buffer_Provider *provider);
/**
*
* A call to this function will set a callback on an Ecore_Buffer_Provider, causing
* @p func to be called whenever @p provider is connected with consumer.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_provider_consumer_add_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Consumer_Add_Cb func, void *data);
/**
*
* A call to this function will set a callback on an Ecore_Buffer_Provider, causing
* @p func to be called whenever @p provider is disconnected with consumer.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_provider_consumer_del_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Consumer_Del_Cb func, void *data);
/**
* @p func to be called whenever @p provider has received Ecore_Buffer released from provider.
*
* You may success dequeue the Ecore_Buffer after this callback called.
+ *
+ * @if MOBILE @since_tizen 2.4
+ * @elseif WEARABLE @since_tizen 3.0
+ * @endif
*/
EAPI void ecore_buffer_provider_buffer_released_cb_set(Ecore_Buffer_Provider *provider, Ecore_Buffer_Provider_Enqueue_Cb func, void *data);
static const struct wl_message bq_consumer_requests[] = {
{ "release_buffer", "o", types + 10 },
+ { "destroy", "2", types + 0 },
};
static const struct wl_message bq_consumer_events[] = {
};
WL_EXPORT const struct wl_interface bq_consumer_interface = {
- "bq_consumer", 1,
- 1, bq_consumer_requests,
+ "bq_consumer", 2,
+ 2, bq_consumer_requests,
7, bq_consumer_events,
};
{ "set_buffer_fd", "ohiiiiii", types + 50 },
{ "detach_buffer", "o", types + 58 },
{ "enqueue_buffer", "ou", types + 59 },
+ { "destroy", "2", types + 0 },
};
static const struct wl_message bq_provider_events[] = {
};
WL_EXPORT const struct wl_interface bq_provider_interface = {
- "bq_provider", 1,
- 5, bq_provider_requests,
+ "bq_provider", 2,
+ 6, bq_provider_requests,
3, bq_provider_events,
};
+static const struct wl_message bq_buffer_requests[] = {
+ { "destroy", "2", types + 0 },
+};
+
WL_EXPORT const struct wl_interface bq_buffer_interface = {
- "bq_buffer", 1,
- 0, NULL,
+ "bq_buffer", 2,
+ 1, bq_buffer_requests,
0, NULL,
};
struct wl_client;
struct wl_resource;
-struct bq_mgr;
+struct bq_buffer;
struct bq_consumer;
+struct bq_mgr;
struct bq_provider;
-struct bq_buffer;
extern const struct wl_interface bq_mgr_interface;
extern const struct wl_interface bq_consumer_interface;
#define BQ_MGR_CREATE_CONSUMER 0
#define BQ_MGR_CREATE_PROVIDER 1
+#define BQ_MGR_CREATE_CONSUMER_SINCE_VERSION 1
+#define BQ_MGR_CREATE_PROVIDER_SINCE_VERSION 1
+
static inline void
bq_mgr_set_user_data(struct bq_mgr *bq_mgr, void *user_data)
{
return wl_proxy_get_user_data((struct wl_proxy *) bq_mgr);
}
+static inline uint32_t
+bq_mgr_get_version(struct bq_mgr *bq_mgr)
+{
+ return wl_proxy_get_version((struct wl_proxy *) bq_mgr);
+}
+
static inline void
bq_mgr_destroy(struct bq_mgr *bq_mgr)
{
}
#define BQ_CONSUMER_RELEASE_BUFFER 0
+#define BQ_CONSUMER_DESTROY 1
+
+#define BQ_CONSUMER_RELEASE_BUFFER_SINCE_VERSION 1
+#define BQ_CONSUMER_DESTROY_SINCE_VERSION 2
static inline void
bq_consumer_set_user_data(struct bq_consumer *bq_consumer, void *user_data)
return wl_proxy_get_user_data((struct wl_proxy *) bq_consumer);
}
-static inline void
-bq_consumer_destroy(struct bq_consumer *bq_consumer)
+static inline uint32_t
+bq_consumer_get_version(struct bq_consumer *bq_consumer)
{
- wl_proxy_destroy((struct wl_proxy *) bq_consumer);
+ return wl_proxy_get_version((struct wl_proxy *) bq_consumer);
}
static inline void
BQ_CONSUMER_RELEASE_BUFFER, buffer);
}
+static inline void
+bq_consumer_destroy(struct bq_consumer *bq_consumer)
+{
+ wl_proxy_marshal((struct wl_proxy *) bq_consumer,
+ BQ_CONSUMER_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) bq_consumer);
+}
+
#ifndef BQ_PROVIDER_ERROR_ENUM
#define BQ_PROVIDER_ERROR_ENUM
enum bq_provider_error {
#define BQ_PROVIDER_SET_BUFFER_FD 2
#define BQ_PROVIDER_DETACH_BUFFER 3
#define BQ_PROVIDER_ENQUEUE_BUFFER 4
+#define BQ_PROVIDER_DESTROY 5
+
+#define BQ_PROVIDER_ATTACH_BUFFER_SINCE_VERSION 1
+#define BQ_PROVIDER_SET_BUFFER_ID_SINCE_VERSION 1
+#define BQ_PROVIDER_SET_BUFFER_FD_SINCE_VERSION 1
+#define BQ_PROVIDER_DETACH_BUFFER_SINCE_VERSION 1
+#define BQ_PROVIDER_ENQUEUE_BUFFER_SINCE_VERSION 1
+#define BQ_PROVIDER_DESTROY_SINCE_VERSION 2
static inline void
bq_provider_set_user_data(struct bq_provider *bq_provider, void *user_data)
return wl_proxy_get_user_data((struct wl_proxy *) bq_provider);
}
-static inline void
-bq_provider_destroy(struct bq_provider *bq_provider)
+static inline uint32_t
+bq_provider_get_version(struct bq_provider *bq_provider)
{
- wl_proxy_destroy((struct wl_proxy *) bq_provider);
+ return wl_proxy_get_version((struct wl_proxy *) bq_provider);
}
static inline struct bq_buffer *
}
static inline void
+bq_provider_destroy(struct bq_provider *bq_provider)
+{
+ wl_proxy_marshal((struct wl_proxy *) bq_provider,
+ BQ_PROVIDER_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) bq_provider);
+}
+
+#define BQ_BUFFER_DESTROY 0
+
+#define BQ_BUFFER_DESTROY_SINCE_VERSION 2
+
+static inline void
bq_buffer_set_user_data(struct bq_buffer *bq_buffer, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) bq_buffer, user_data);
return wl_proxy_get_user_data((struct wl_proxy *) bq_buffer);
}
+static inline uint32_t
+bq_buffer_get_version(struct bq_buffer *bq_buffer)
+{
+ return wl_proxy_get_version((struct wl_proxy *) bq_buffer);
+}
+
static inline void
bq_buffer_destroy(struct bq_buffer *bq_buffer)
{
+ wl_proxy_marshal((struct wl_proxy *) bq_buffer,
+ BQ_BUFFER_DESTROY);
+
wl_proxy_destroy((struct wl_proxy *) bq_buffer);
}
struct _Ecore_Buffer_Module
{
- Ecore_Buffer_Backend *be;
- Ecore_Buffer_Module_Data data;
+ Ecore_Buffer_Backend *be;
+ Ecore_Buffer_Module_Data data;
};
struct _Ecore_Buffer
{
- unsigned int width;
- unsigned int height;
- int format;
unsigned int flags;
+ Ecore_Buffer_Info info;
Ecore_Buffer_Data buffer_data;
Ecore_Buffer_Module *bm;
else
bm = eina_hash_find(_backends, backend_name);
- if ((!bm) || (!bm->be))
+ if ((!bm) || (!bm->be) || (!bm->be->init))
return NULL;
- if (bm->be->init)
+ if (!bm->data)
bm->data = bm->be->init(NULL, NULL);
return bm;
return NULL;
}
+ if (bm->be->buffer_info_get)
+ bm->be->buffer_info_get(bm->data, bo_data, &bo->info);
+ else
+ {
+ bo->info.width = width;
+ bo->info.height = height;
+ bo->info.format = format;
+ }
+
+ bo->bm = bm;
+ bo->flags = flags;
+ bo->buffer_data = bo_data;
+
+ return bo;
+}
+
+EAPI Ecore_Buffer *
+ecore_buffer_new_with_tbm_surface(const char *engine, void *tbm_surface, unsigned int flags)
+{
+ Ecore_Buffer_Module *bm;
+ Ecore_Buffer *bo;
+ int w = 0, h = 0;
+ Ecore_Buffer_Format format = 0;
+ void *bo_data;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
+
+ bm = _ecore_buffer_get_backend(engine);
+ if (!bm)
+ {
+ ERR("Failed to get Backend: %s", engine);
+ return NULL;
+ }
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(bm->be, NULL);
+
+ if (!bm->be->buffer_alloc_with_tbm_surface)
+ {
+ ERR("Not supported create buffer with tbm_surface");
+ return NULL;
+ }
+
+ bo = calloc(1, sizeof(Ecore_Buffer));
+ if (!bo)
+ return NULL;
+
+ bo_data = bm->be->buffer_alloc_with_tbm_surface(bm->data, tbm_surface,
+ &w, &h, &format, flags);
+ if (!bo_data)
+ {
+ free(bo);
+ return NULL;
+ }
+
+ if (bm->be->buffer_info_get)
+ bm->be->buffer_info_get(bm->data, bo_data, &bo->info);
+ else
+ {
+ bo->info.width = w;
+ bo->info.height = h;
+ bo->info.format = format;
+ }
+
bo->bm = bm;
- bo->width = width;
- bo->height = height;
- bo->format = format;
bo->flags = flags;
bo->buffer_data = bo_data;
free(buf);
}
-EAPI void *
-ecore_buffer_data_get(Ecore_Buffer *buf)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(buf, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(buf->bm->be, NULL);
-
- if (!buf->bm->be->data_get)
- return NULL;
-
- return buf->bm->be->data_get(buf->bm->data, buf->buffer_data);
-}
-
EAPI Ecore_Pixmap
ecore_buffer_pixmap_get(Ecore_Buffer *buf)
{
{
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, EINA_FALSE);
- if (width) *width = buf->width;
- if (height) *height = buf->height;
+ if (width) *width = buf->info.width;
+ if (height) *height = buf->info.height;
return EINA_TRUE;
}
{
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
- return buf->format;
+ return buf->info.format;
}
EAPI unsigned int
}
Ecore_Buffer *
-_ecore_buffer_import(const char *engine, int width, int height, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags)
+_ecore_buffer_import(const char *engine, Ecore_Buffer_Info *info, Ecore_Export_Type type, int export_id, unsigned int flags)
{
Ecore_Buffer_Module *bm;
Ecore_Buffer *bo;
if (!bo)
return NULL;
- bo_data = bm->be->buffer_import(bm->data, width, height, format, type, export_id, flags);
+ bo_data = bm->be->buffer_import(bm->data, info, type, export_id, flags);
if (!bo_data)
{
free(bo);
return NULL;
}
+ memcpy(&bo->info, info, sizeof(*info));
+
bo->bm = bm;
- bo->width = width;
- bo->height = height;
- bo->format = format;
bo->flags = flags;
bo->buffer_data = bo_data;
return bo;
}
+
+Eina_Bool
+_ecore_buffer_info_get(Ecore_Buffer *buf, Ecore_Buffer_Info *info)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(buf, EINA_FALSE);
+
+ if (info)
+ memcpy(info, &buf->info, sizeof(*info));
+
+ return EINA_TRUE;
+}
return EINA_FALSE;
}
- if (!(_connection->display = wl_display_connect(name)))
+ if (!(_connection->display = wl_display_connect(NULL)))
{
- ERR("Failed to connect to Queue Server");
- goto err_connect;
+ if (!(_connection->display = wl_display_connect(name)))
+ {
+ ERR("Failed to connect to Queue Server");
+ goto err_connect;
+ }
}
_connection->fd = wl_display_get_fd(_connection->display);
static void _ecore_buffer_consumer_cb_buffer_detached(void *data, struct bq_consumer *bq_consumer, struct bq_buffer *id);
static void _ecore_buffer_consumer_cb_add_buffer(void *data, struct bq_consumer *bq_consumer, struct bq_buffer *buffer, uint32_t serial);
static void _ecore_buffer_consumer_cb_buffer_free(Ecore_Buffer *buf, void *data);
-static Eina_Bool _ecore_buffer_consumer_buffer_import(Ecore_Buffer_Consumer *consumer, Shared_Buffer *sb, int32_t seed, Ecore_Export_Type export_type);
+static Eina_Bool _ecore_buffer_consumer_buffer_import(Ecore_Buffer_Consumer *consumer, Shared_Buffer *sb, int32_t seed, Ecore_Export_Type export_type, Ecore_Buffer_Info *info);
struct bq_consumer_listener _ecore_buffer_consumer_listener =
{
_ecore_buffer_con_init_wait();
- consumer = calloc(1, sizeof(Ecore_Buffer_Consumer));
+ consumer = calloc(sizeof(Ecore_Buffer_Consumer), 1);
if (!consumer)
return NULL;
return consumer;
}
+static void
+_consumer_shared_buffer_free(Ecore_Buffer_Consumer *consumer)
+{
+ Eina_List *clone, *shared_buffers, *l;
+ Shared_Buffer *sb;
+
+ if (!consumer->ebq)
+ return;
+
+ shared_buffers = _ecore_buffer_queue_shared_buffer_list_get(consumer->ebq);
+ clone = eina_list_clone(shared_buffers);
+
+ EINA_LIST_FOREACH(clone, l, sb)
+ ecore_buffer_free(_shared_buffer_buffer_get(sb));
+
+ eina_list_free(clone);
+}
+
EAPI void
ecore_buffer_consumer_free(Ecore_Buffer_Consumer *consumer)
{
DBG("Consumer Free");
+ _consumer_shared_buffer_free(consumer);
+
if (consumer->ebq)
_ecore_buffer_queue_free(consumer->ebq);
// This should not happen.
if (_shared_buffer_state_get(sb) != SHARED_BUFFER_STATE_ENQUEUE)
{
- ERR("Unknown error occurred - Not on Enqueued State: buffer %p, state %s",
+ ERR("Unknown error occured - Not on Enqueued State: buffer %p, state %s",
sb, _shared_buffer_state_string_get(sb));
return NULL;
}
_ecore_buffer_consumer_cb_provider_disconnected(void *data, struct bq_consumer *bq_consumer EINA_UNUSED)
{
Ecore_Buffer_Consumer *consumer = data;
- Eina_List *clone, *shared_buffers, *l;
- Shared_Buffer *sb;
EINA_SAFETY_ON_NULL_RETURN(consumer);
CALLBACK_CALL(consumer, provider_del);
- shared_buffers = _ecore_buffer_queue_shared_buffer_list_get(consumer->ebq);
- clone = eina_list_clone(shared_buffers);
-
- EINA_LIST_FOREACH(clone, l, sb)
- ecore_buffer_free(_shared_buffer_buffer_get(sb));
-
- eina_list_free(clone);
+ _consumer_shared_buffer_free(consumer);
}
static void
_shared_buffer_free(sb);
}
+#define INFO_SET(I, PIX) \
+ I.planes[0].offset = offset0; \
+ I.planes[0].stride = stride0; \
+ I.planes[1].offset = offset1; \
+ I.planes[1].stride = stride1; \
+ I.planes[2].offset = offset2; \
+ I.planes[2].stride = stride2; \
+ I.pixmap = PIX
static void
-_ecore_buffer_consumer_cb_buffer_id_set(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *buffer, int32_t id, int32_t offset0 EINA_UNUSED, int32_t stride0 EINA_UNUSED, int32_t offset1 EINA_UNUSED, int32_t stride1 EINA_UNUSED, int32_t offset2 EINA_UNUSED, int32_t stride2 EINA_UNUSED)
+_ecore_buffer_consumer_cb_buffer_id_set(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *buffer, int32_t id, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
{
Ecore_Buffer_Consumer *consumer = data;
Shared_Buffer *sb = bq_buffer_get_user_data(buffer);
+ Ecore_Buffer_Info info;
EINA_SAFETY_ON_NULL_RETURN(consumer);
EINA_SAFETY_ON_NULL_RETURN(sb);
- if (_ecore_buffer_consumer_buffer_import(consumer, sb, id, EXPORT_TYPE_ID))
+ INFO_SET(info, 0);
+
+ if (_ecore_buffer_consumer_buffer_import(consumer, sb, id, EXPORT_TYPE_ID, &info))
bq_buffer_set_user_data(buffer, sb);
else
ERR("Failed to import buffer - buffer resource %p", buffer);
}
static void
-_ecore_buffer_consumer_cb_buffer_fd_set(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *buffer, int32_t fd, int32_t offset0 EINA_UNUSED, int32_t stride0 EINA_UNUSED, int32_t offset1 EINA_UNUSED, int32_t stride1 EINA_UNUSED, int32_t offset2 EINA_UNUSED, int32_t stride2 EINA_UNUSED)
+_ecore_buffer_consumer_cb_buffer_fd_set(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *buffer, int32_t fd, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
{
Ecore_Buffer_Consumer *consumer = data;
Shared_Buffer *sb = bq_buffer_get_user_data(buffer);
+ Ecore_Buffer_Info info;
EINA_SAFETY_ON_NULL_RETURN(consumer);
EINA_SAFETY_ON_NULL_RETURN(sb);
- if (_ecore_buffer_consumer_buffer_import(consumer, sb, fd, EXPORT_TYPE_FD))
+ INFO_SET(info, 0);
+
+ if (_ecore_buffer_consumer_buffer_import(consumer, sb, fd, EXPORT_TYPE_FD, &info))
bq_buffer_set_user_data(buffer, sb);
else
ERR("Failed to import buffer - buffer resource %p", buffer);
}
+#undef INFO_SET
static void
_ecore_buffer_consumer_cb_buffer_detached(void *data, struct bq_consumer *bq_consumer EINA_UNUSED, struct bq_buffer *id)
if (!sb)
{
- ERR("Unknown Error occurred - maybe this buffer is not shared yet");
+ ERR("Unknown Error occured - maybe this buffer is not shared yet");
return;
}
if ((state != SHARED_BUFFER_STATE_IMPORT) &&
(state != SHARED_BUFFER_STATE_RELEASE))
{
- ERR("Unknown Error occurred - Could not enqueued this state of buffer: buffer %p, state %s",
+ ERR("Unknown Error occured - Could not enqueued this state of buffer: buffer %p, state %s",
sb, _shared_buffer_state_string_get(sb));
return;
}
}
static Eina_Bool
-_ecore_buffer_consumer_buffer_import(Ecore_Buffer_Consumer *consumer, Shared_Buffer *sb, int32_t seed, Ecore_Export_Type export_type)
+_ecore_buffer_consumer_buffer_import(Ecore_Buffer_Consumer *consumer, Shared_Buffer *sb, int32_t seed, Ecore_Export_Type export_type, Ecore_Buffer_Info *info)
{
Ecore_Buffer *buffer;
const char *engine = NULL;
return EINA_FALSE;
}
- if (!(buffer = _ecore_buffer_import(engine, w, h, format, export_type, seed, flags)))
+ info->width = w;
+ info->height = h;
+ info->format = format;
+
+ if (!(buffer = _ecore_buffer_import(engine, info, export_type, seed, flags)))
{
ERR("Failed to Import Buffer - size (%dx%d), foramt %d, seed %d, export_type %d",
w, h, format, seed, export_type);
/* NOTE: if Ecore_Export_Type as a return value is EXPORT_TYPE_FD,
* then caller should close the fd after using it. */
Ecore_Export_Type _ecore_buffer_export(Ecore_Buffer *buf, int *id);
-Ecore_Buffer *_ecore_buffer_import(const char *engine, int width, int height, Ecore_Buffer_Format format, Ecore_Export_Type type, int export_id, unsigned int flags);
+Ecore_Buffer *_ecore_buffer_import(const char *engine, Ecore_Buffer_Info *info, Ecore_Export_Type type, int export_id, unsigned int flags);
+Eina_Bool _ecore_buffer_info_get(Ecore_Buffer *buf, Ecore_Buffer_Info *info);
#endif /* _ECORE_BUFFER_PRIVATE_H_ */
_ecore_buffer_provider_shared_buffer_new(Ecore_Buffer_Provider *provider, Ecore_Buffer *buffer)
{
Shared_Buffer *sb;
+ Ecore_Export_Type export_type;
+ Ecore_Buffer_Info info;
+ Eina_Bool res;
struct bq_buffer *buf_resource;
unsigned int w = 0, h = 0, format = 0;
- Ecore_Export_Type export_type;
int export_id;
const char *engine;
unsigned int flags;
+ int offset[3] = {0,}, stride[3] = {0,};
+ int i;
EINA_SAFETY_ON_NULL_RETURN_VAL(provider, NULL);
return NULL;
}
- ecore_buffer_size_get(buffer, &w, &h);
- format = ecore_buffer_format_get(buffer);
- export_type = _ecore_buffer_export(buffer, &export_id);
engine = _ecore_buffer_engine_name_get(buffer);
flags = ecore_buffer_flags_get(buffer);
+ res = _ecore_buffer_info_get(buffer, &info);
+ if (res)
+ {
+ int count;
+ w = info.width;
+ h = info.height;
+ format = info.format;
+ /* FIXME info.num_planes may be 4 */
+ count = info.num_planes < 4 ? info.num_planes : 3;
+ for (i = 0; i < count; i++)
+ {
+ offset[i] = info.planes[i].offset;
+ stride[i] = info.planes[i].stride;
+ }
+ }
+ else
+ {
+ ecore_buffer_size_get(buffer, &w, &h);
+ format = ecore_buffer_format_get(buffer);
+ }
+
buf_resource = bq_provider_attach_buffer(provider->resource, engine, w, h, format, flags);
if (!buf_resource)
{
return NULL;
}
+ export_type = _ecore_buffer_export(buffer, &export_id);
switch (export_type)
{
case EXPORT_TYPE_ID:
- bq_provider_set_buffer_id(provider->resource, buf_resource,
- export_id, 0, 0, 0, 0, 0, 0);
+ bq_provider_set_buffer_id(provider->resource,
+ buf_resource,
+ export_id,
+ offset[0], stride[0],
+ offset[1], stride[1],
+ offset[2], stride[2]);
break;
case EXPORT_TYPE_FD:
- bq_provider_set_buffer_fd(provider->resource, buf_resource,
- export_id, 0, 0, 0, 0, 0, 0);
+ bq_provider_set_buffer_fd(provider->resource,
+ buf_resource,
+ export_id,
+ offset[0], stride[0],
+ offset[1], stride[1],
+ offset[2], stride[2]);
close(export_id);
break;
default:
static void
_ecore_buffer_provider_shared_buffer_free(Ecore_Buffer_Provider *provider, Shared_Buffer *sb)
{
- struct bq_buffer *buf_resource;
+ struct bq_buffer *buf_resource = _shared_buffer_resource_get(sb);
EINA_SAFETY_ON_NULL_RETURN(provider);
EINA_SAFETY_ON_NULL_RETURN(sb);
+ if (!provider->ebq)
+ return;
+
buf_resource = _shared_buffer_resource_get(sb);
if (!buf_resource)
return;
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Ecore.h>
+
+#include <tbm_bufmgr.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+
+#include <Ecore_Buffer.h>
+#include "ecore_buffer_private.h"
+
+typedef struct _Ecore_Buffer_Module_Tbm_Data Ecore_Buffer_Module_Tbm_Data;
+typedef struct _Ecore_Buffer_Tbm_Data Ecore_Buffer_Tbm_Data;
+
+struct _Ecore_Buffer_Module_Tbm_Data {
+ tbm_bufmgr tbm_mgr;
+};
+
+struct _Ecore_Buffer_Tbm_Data {
+ void *tbm_surface;
+ int w;
+ int h;
+ int stride;
+ unsigned int flags;
+ Ecore_Buffer_Format format;
+ Eina_Bool is_imported;
+};
+
+static int
+_buf_get_num_planes(Ecore_Buffer_Format format)
+{
+ int num_planes = 0;
+
+ switch (format)
+ {
+ case ECORE_BUFFER_FORMAT_C8:
+ case ECORE_BUFFER_FORMAT_RGB332:
+ case ECORE_BUFFER_FORMAT_BGR233:
+ case ECORE_BUFFER_FORMAT_XRGB4444:
+ case ECORE_BUFFER_FORMAT_XBGR4444:
+ case ECORE_BUFFER_FORMAT_RGBX4444:
+ case ECORE_BUFFER_FORMAT_BGRX4444:
+ case ECORE_BUFFER_FORMAT_ARGB4444:
+ case ECORE_BUFFER_FORMAT_ABGR4444:
+ case ECORE_BUFFER_FORMAT_RGBA4444:
+ case ECORE_BUFFER_FORMAT_BGRA4444:
+ case ECORE_BUFFER_FORMAT_XRGB1555:
+ case ECORE_BUFFER_FORMAT_XBGR1555:
+ case ECORE_BUFFER_FORMAT_RGBX5551:
+ case ECORE_BUFFER_FORMAT_BGRX5551:
+ case ECORE_BUFFER_FORMAT_ARGB1555:
+ case ECORE_BUFFER_FORMAT_ABGR1555:
+ case ECORE_BUFFER_FORMAT_RGBA5551:
+ case ECORE_BUFFER_FORMAT_BGRA5551:
+ case ECORE_BUFFER_FORMAT_RGB565:
+ case ECORE_BUFFER_FORMAT_BGR565:
+ case ECORE_BUFFER_FORMAT_RGB888:
+ case ECORE_BUFFER_FORMAT_BGR888:
+ case ECORE_BUFFER_FORMAT_XRGB8888:
+ case ECORE_BUFFER_FORMAT_XBGR8888:
+ case ECORE_BUFFER_FORMAT_RGBX8888:
+ case ECORE_BUFFER_FORMAT_BGRX8888:
+ case ECORE_BUFFER_FORMAT_ARGB8888:
+ case ECORE_BUFFER_FORMAT_ABGR8888:
+ case ECORE_BUFFER_FORMAT_RGBA8888:
+ case ECORE_BUFFER_FORMAT_BGRA8888:
+ case ECORE_BUFFER_FORMAT_XRGB2101010:
+ case ECORE_BUFFER_FORMAT_XBGR2101010:
+ case ECORE_BUFFER_FORMAT_RGBX1010102:
+ case ECORE_BUFFER_FORMAT_BGRX1010102:
+ case ECORE_BUFFER_FORMAT_ARGB2101010:
+ case ECORE_BUFFER_FORMAT_ABGR2101010:
+ case ECORE_BUFFER_FORMAT_RGBA1010102:
+ case ECORE_BUFFER_FORMAT_BGRA1010102:
+ case ECORE_BUFFER_FORMAT_YUYV:
+ case ECORE_BUFFER_FORMAT_YVYU:
+ case ECORE_BUFFER_FORMAT_UYVY:
+ case ECORE_BUFFER_FORMAT_VYUY:
+ case ECORE_BUFFER_FORMAT_AYUV:
+ num_planes = 1;
+ break;
+ case ECORE_BUFFER_FORMAT_NV12:
+ case ECORE_BUFFER_FORMAT_NV21:
+ case ECORE_BUFFER_FORMAT_NV16:
+ case ECORE_BUFFER_FORMAT_NV61:
+ num_planes = 2;
+ break;
+ case ECORE_BUFFER_FORMAT_YUV410:
+ case ECORE_BUFFER_FORMAT_YVU410:
+ case ECORE_BUFFER_FORMAT_YUV411:
+ case ECORE_BUFFER_FORMAT_YVU411:
+ case ECORE_BUFFER_FORMAT_YUV420:
+ case ECORE_BUFFER_FORMAT_YVU420:
+ case ECORE_BUFFER_FORMAT_YUV422:
+ case ECORE_BUFFER_FORMAT_YVU422:
+ case ECORE_BUFFER_FORMAT_YUV444:
+ case ECORE_BUFFER_FORMAT_YVU444:
+ num_planes = 3;
+ break;
+
+ default:
+ break;
+ }
+
+ return num_planes;
+}
+
+static int
+_buf_get_bpp(Ecore_Buffer_Format format)
+{
+ int bpp = 0;
+
+ switch (format)
+ {
+ case ECORE_BUFFER_FORMAT_C8:
+ case ECORE_BUFFER_FORMAT_RGB332:
+ case ECORE_BUFFER_FORMAT_BGR233:
+ bpp = 8;
+ break;
+ case ECORE_BUFFER_FORMAT_XRGB4444:
+ case ECORE_BUFFER_FORMAT_XBGR4444:
+ case ECORE_BUFFER_FORMAT_RGBX4444:
+ case ECORE_BUFFER_FORMAT_BGRX4444:
+ case ECORE_BUFFER_FORMAT_ARGB4444:
+ case ECORE_BUFFER_FORMAT_ABGR4444:
+ case ECORE_BUFFER_FORMAT_RGBA4444:
+ case ECORE_BUFFER_FORMAT_BGRA4444:
+ case ECORE_BUFFER_FORMAT_XRGB1555:
+ case ECORE_BUFFER_FORMAT_XBGR1555:
+ case ECORE_BUFFER_FORMAT_RGBX5551:
+ case ECORE_BUFFER_FORMAT_BGRX5551:
+ case ECORE_BUFFER_FORMAT_ARGB1555:
+ case ECORE_BUFFER_FORMAT_ABGR1555:
+ case ECORE_BUFFER_FORMAT_RGBA5551:
+ case ECORE_BUFFER_FORMAT_BGRA5551:
+ case ECORE_BUFFER_FORMAT_RGB565:
+ case ECORE_BUFFER_FORMAT_BGR565:
+ bpp = 16;
+ break;
+ case ECORE_BUFFER_FORMAT_RGB888:
+ case ECORE_BUFFER_FORMAT_BGR888:
+ bpp = 24;
+ break;
+ case ECORE_BUFFER_FORMAT_XRGB8888:
+ case ECORE_BUFFER_FORMAT_XBGR8888:
+ case ECORE_BUFFER_FORMAT_RGBX8888:
+ case ECORE_BUFFER_FORMAT_BGRX8888:
+ case ECORE_BUFFER_FORMAT_ARGB8888:
+ case ECORE_BUFFER_FORMAT_ABGR8888:
+ case ECORE_BUFFER_FORMAT_RGBA8888:
+ case ECORE_BUFFER_FORMAT_BGRA8888:
+ case ECORE_BUFFER_FORMAT_XRGB2101010:
+ case ECORE_BUFFER_FORMAT_XBGR2101010:
+ case ECORE_BUFFER_FORMAT_RGBX1010102:
+ case ECORE_BUFFER_FORMAT_BGRX1010102:
+ case ECORE_BUFFER_FORMAT_ARGB2101010:
+ case ECORE_BUFFER_FORMAT_ABGR2101010:
+ case ECORE_BUFFER_FORMAT_RGBA1010102:
+ case ECORE_BUFFER_FORMAT_BGRA1010102:
+ case ECORE_BUFFER_FORMAT_YUYV:
+ case ECORE_BUFFER_FORMAT_YVYU:
+ case ECORE_BUFFER_FORMAT_UYVY:
+ case ECORE_BUFFER_FORMAT_VYUY:
+ case ECORE_BUFFER_FORMAT_AYUV:
+ bpp = 32;
+ break;
+ case ECORE_BUFFER_FORMAT_NV12:
+ case ECORE_BUFFER_FORMAT_NV21:
+ bpp = 12;
+ break;
+ case ECORE_BUFFER_FORMAT_NV16:
+ case ECORE_BUFFER_FORMAT_NV61:
+ bpp = 16;
+ break;
+ case ECORE_BUFFER_FORMAT_YUV410:
+ case ECORE_BUFFER_FORMAT_YVU410:
+ bpp = 9;
+ break;
+ case ECORE_BUFFER_FORMAT_YUV411:
+ case ECORE_BUFFER_FORMAT_YVU411:
+ case ECORE_BUFFER_FORMAT_YUV420:
+ case ECORE_BUFFER_FORMAT_YVU420:
+ bpp = 12;
+ break;
+ case ECORE_BUFFER_FORMAT_YUV422:
+ case ECORE_BUFFER_FORMAT_YVU422:
+ bpp = 16;
+ break;
+ case ECORE_BUFFER_FORMAT_YUV444:
+ case ECORE_BUFFER_FORMAT_YVU444:
+ bpp = 24;
+ break;
+ default :
+ break;
+ }
+
+ return bpp;
+}
+
+static Ecore_Buffer_Module_Data
+_ecore_buffer_tbm_init(const char *context EINA_UNUSED, const char *options EINA_UNUSED)
+{
+ Ecore_Buffer_Module_Tbm_Data *mdata = NULL;
+
+ mdata = calloc(sizeof(Ecore_Buffer_Module_Tbm_Data), 1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(mdata, NULL);
+
+ mdata->tbm_mgr = tbm_bufmgr_init(-1);
+ if (!mdata->tbm_mgr)
+ {
+ free(mdata);
+ return NULL;
+ }
+
+ return mdata;
+}
+
+static void
+_ecore_buffer_tbm_shutdown(Ecore_Buffer_Module_Data bmdata)
+{
+ Ecore_Buffer_Module_Tbm_Data *bm = bmdata;
+
+ if (!bm) return;
+
+ if (bm->tbm_mgr)
+ tbm_bufmgr_deinit(bm->tbm_mgr);
+
+ free(bm);
+}
+
+static Ecore_Buffer_Data
+_ecore_buffer_tbm_buffer_alloc(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, int width, int height, Ecore_Buffer_Format format, unsigned int flags)
+{
+ Ecore_Buffer_Tbm_Data *buf;
+
+ /* invalid size */
+ if ((width < 1) || (height < 1))
+ return NULL;
+
+ buf = calloc(1, sizeof(Ecore_Buffer_Tbm_Data));
+ if (!buf)
+ return NULL;
+
+ buf->w = width;
+ buf->h = height;
+ buf->flags = flags;
+ buf->format = format;
+ buf->is_imported = EINA_FALSE;
+ buf->tbm_surface = tbm_surface_create(width, height, (tbm_format)format);
+ if (!buf->tbm_surface)
+ {
+ free(buf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+static Ecore_Buffer_Data
+_ecore_buffer_tbm_buffer_alloc_with_tbm_surface(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, void *tbm_surface, int *ret_w, int *ret_h, Ecore_Buffer_Format *ret_format, unsigned int flags)
+{
+ Ecore_Buffer_Tbm_Data *buf;
+
+ buf = calloc(1, sizeof(Ecore_Buffer_Tbm_Data));
+ if (!buf)
+ return NULL;
+
+ buf->w = tbm_surface_get_width(tbm_surface);
+ buf->h = tbm_surface_get_height(tbm_surface);
+ buf->format = tbm_surface_get_format(tbm_surface);
+ buf->flags = flags;
+ buf->is_imported = EINA_FALSE;
+ buf->tbm_surface = tbm_surface;
+ tbm_surface_internal_ref(tbm_surface);
+
+ if (ret_w) *ret_w = buf->w;
+ if (ret_h) *ret_h = buf->h;
+ if (ret_format) *ret_format = buf->format;
+
+ return buf;
+}
+
+static Eina_Bool
+_ecore_buffer_tbm_buffer_info_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, Ecore_Buffer_Info *info)
+{
+ Ecore_Buffer_Tbm_Data *buf = bdata;
+ tbm_surface_info_s tinfo;
+ int i, res;
+
+ if (!buf->tbm_surface)
+ return EINA_FALSE;
+
+ res = tbm_surface_get_info(buf->tbm_surface, &tinfo);
+ if (res != TBM_SURFACE_ERROR_NONE)
+ return EINA_FALSE;
+
+ if (info)
+ {
+ info->width = tinfo.width;
+ info->height = tinfo.height;
+ info->format = tinfo.format;
+ info->bpp = tinfo.bpp;
+ info->size = tinfo.size;
+ info->num_planes = tinfo.num_planes;
+ info->pixmap = 0;
+
+ for (i = 0; i < (int)tinfo.num_planes; i++)
+ {
+ info->planes[i].size = tinfo.planes[i].size;
+ info->planes[i].offset = tinfo.planes[i].offset;
+ info->planes[i].stride = tinfo.planes[i].stride;
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+static void
+_ecore_buffer_tbm_buffer_free(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
+{
+ Ecore_Buffer_Tbm_Data *buf = bdata;
+
+ if (!buf) return;
+
+ if (buf->tbm_surface)
+ {
+ tbm_surface_destroy(buf->tbm_surface);
+ buf->tbm_surface = NULL;
+ }
+
+ free(buf);
+}
+
+static Ecore_Export_Type
+_ecore_buffer_tbm_buffer_export(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata, int *id)
+{
+ Ecore_Buffer_Tbm_Data *buf = bdata;
+ tbm_bo bo;
+
+ if (!buf) return EXPORT_TYPE_INVALID;
+
+ if (tbm_surface_internal_get_num_bos(buf->tbm_surface) != 1)
+ return EXPORT_TYPE_INVALID;
+
+ bo = tbm_surface_internal_get_bo(buf->tbm_surface, 0);
+
+ if (id) *id = tbm_bo_export_fd(bo);
+
+ return EXPORT_TYPE_FD;
+}
+
+static Ecore_Buffer_Data
+_ecore_buffer_tbm_buffer_import(Ecore_Buffer_Module_Data bmdata, Ecore_Buffer_Info *einfo, Ecore_Export_Type type, int export_id, unsigned int flags)
+{
+ Ecore_Buffer_Module_Tbm_Data *bm = bmdata;
+ Ecore_Buffer_Tbm_Data *buf;
+ tbm_bo bo;
+ tbm_surface_info_s tinfo;
+ int i;
+
+ if (type != EXPORT_TYPE_FD) return NULL;
+ if (export_id < 1) return NULL;
+
+ buf = calloc(1, sizeof(Ecore_Buffer_Tbm_Data));
+ if (!buf)
+ return NULL;
+
+ buf->w = einfo->width;
+ buf->h = einfo->height;
+ buf->stride = einfo->planes[0].stride;
+ buf->format = einfo->format;
+ buf->flags = flags;
+ buf->is_imported = EINA_TRUE;
+
+ bo = tbm_bo_import_fd(bm->tbm_mgr, export_id);
+ if (!bo)
+ {
+ free(buf);
+ return NULL;
+ }
+
+ tinfo.width = einfo->width;
+ tinfo.height = einfo->height;
+ tinfo.format = einfo->format;
+ tinfo.bpp = _buf_get_bpp(einfo->format);
+ tinfo.size = einfo->height * einfo->planes[0].stride;
+ tinfo.num_planes = (uint32_t)_buf_get_num_planes(einfo->format);
+ for ( i = 0 ; i < (int)tinfo.num_planes ; i++)
+ {
+ tinfo.planes[i].size = einfo->height * einfo->planes[i].stride;
+ tinfo.planes[i].stride = einfo->planes[i].stride;
+ tinfo.planes[i].offset = einfo->planes[i].offset;
+ }
+
+ buf->tbm_surface = tbm_surface_internal_create_with_bos(&tinfo, &bo, 1);
+ if (!buf->tbm_surface)
+ {
+ tbm_bo_unref(bo);
+ free(buf);
+ return NULL;
+ }
+
+ tbm_bo_unref(bo);
+
+ return buf;
+}
+
+static void *
+_ecore_buffer_tbm_tbm_bo_get(Ecore_Buffer_Module_Data bmdata EINA_UNUSED, Ecore_Buffer_Data bdata)
+{
+ Ecore_Buffer_Tbm_Data *buf = bdata;
+
+ if (!buf) return NULL;
+
+ return buf->tbm_surface;
+}
+
+static Ecore_Buffer_Backend _ecore_buffer_tbm_backend = {
+ "tbm",
+ &_ecore_buffer_tbm_init,
+ &_ecore_buffer_tbm_shutdown,
+ &_ecore_buffer_tbm_buffer_alloc,
+ &_ecore_buffer_tbm_buffer_alloc_with_tbm_surface,
+ &_ecore_buffer_tbm_buffer_info_get,
+ &_ecore_buffer_tbm_buffer_free,
+ &_ecore_buffer_tbm_buffer_export,
+ &_ecore_buffer_tbm_buffer_import,
+ NULL,
+ &_ecore_buffer_tbm_tbm_bo_get,
+};
+
+Eina_Bool tbm_init(void)
+{
+ return ecore_buffer_register(&_ecore_buffer_tbm_backend);
+}
+
+void tbm_shutdown(void)
+{
+ ecore_buffer_unregister(&_ecore_buffer_tbm_backend);
+}
+
+EINA_MODULE_INIT(tbm_init);
+EINA_MODULE_SHUTDOWN(tbm_shutdown);