From b1ee4393972b6ad50b60c9cab3d3f5b0ac5f0022 Mon Sep 17 00:00:00 2001 From: Sung-jae Park Date: Sat, 23 Feb 2013 08:59:16 +0000 Subject: [PATCH] Update the H/W buffer support API Change-Id: I6ab8efbc7ce0f8a4d98c4696d2cf227d3c50ce2f --- include/livebox.h | 120 ++++++++++++++++++++------- packaging/liblivebox.spec | 3 +- src/livebox.c | 205 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 295 insertions(+), 33 deletions(-) diff --git a/include/livebox.h b/include/livebox.h index aaba16d..d815dec 100644 --- a/include/livebox.h +++ b/include/livebox.h @@ -157,65 +157,127 @@ extern char *livebox_util_nl2br(const char *str); * This enumeration value should be sync'd with provider */ enum buffer_event { - BUFFER_EVENT_ENTER, /*!< */ - BUFFER_EVENT_LEAVE, /*!< */ - BUFFER_EVENT_DOWN, /*!< */ - BUFFER_EVENT_MOVE, /*!< */ - BUFFER_EVENT_UP, /*!< */ + BUFFER_EVENT_ENTER, /*!< Mouse cursor enter */ + BUFFER_EVENT_LEAVE, /*!< Mouse cursor leave */ + BUFFER_EVENT_DOWN, /*!< Mouse down */ + BUFFER_EVENT_MOVE, /*!< Mouse move */ + BUFFER_EVENT_UP, /*!< Mouse up */ + + BUFFER_EVENT_KEY_DOWN, /*!< Key down */ + BUFFER_EVENT_KEY_UP, /*!< Key up */ }; #endif /*! - * \brief - * \param[in] filename - * \param[in] width - * \param[in] height - * \param[in] handler - * \param[in] data - * \return handler + * \brief Acquire a buffer for PD or LB, Currently, we only supporting the PD. + * \param[in] id Id of a livebox instance + * \param[in] is_pd 1 for PD or 0 for livebox + * \param[in] width Width + * \param[in] height Height + * \param[in] handler Event handling callback + * \param[in] data user data for event handling callback + * \return handler Buffer handle */ -extern struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data); +extern struct livebox_buffer *livebox_acquire_buffer(const char *id, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data); /*! - * \param[in] filename - * \return pixmap ID + * \brief Acquire the ID of pixmap resource + * Only if the provider uses pixmap for providing render buffer. + * \param[in] handle Buffer handle + * \return pixmap ID if succeed or 0lu + * \see livebox_acquire_buffer */ extern unsigned long livebox_pixmap_id(struct livebox_buffer *handle); /*! * \brief - * \param[in] handle + * \param[in] handle Buffer handle * \return int + * \see livebox_acquire_buffer */ extern int livebox_release_buffer(struct livebox_buffer *handle); /*! - * \brief - * \param[in] handle - * \return void* buffer + * \brief Get the address of S/W render buffer. + * If you try to use this, after create_hw_buffer, you will get NULL + * \param[in] handle Buffer handle + * \return void* address of the render buffer + * \see livebox_unref_buffer */ extern void *livebox_ref_buffer(struct livebox_buffer *handle); /*! - * \brief - * \param[in] buffer - * \return int + * \brief Release the S/W render buffer. + * \param[in] void* Address of render buffer + * \return int 0 if succeed or errno < 0 + * \see livebox_ref_buffer */ extern int livebox_unref_buffer(void *buffer); /*! - * \brief - * \param[in] handler - * \return int + * \brief Sync the updated buffer + * This is only needed for non-H/W accelerated buffer + * \param[in] handler Buffer handle + * \return int 0 if succeed or errno < 0 + * \see livebox_acquire_buffer */ extern int livebox_sync_buffer(struct livebox_buffer *handle); /*! - * \brief - * \param[in] filename - * \return int + * \brief Request schedule the update operation to a provider. + * \param[in] id Livebox Id + * \return int 0 if succeed or errno < 0 + */ +extern int livebox_request_update(const char *id); + +/*! + * \brief Checking wether the livebox support H/W acceleration or not. + * \param[in] handle Buffer handle. + * \return 1 if support or 0 + * \see livebox_acquire_buffer + */ +extern int livebox_support_hw_buffer(struct livebox_buffer *handle); + +/*! + * \brief Create the H/W accelerated buffer. + * \param[in] handle Buffer handle + * \return 0 if succeed to create it or errno < 0 + * \see livebox_support_hw_buffer + */ +extern int livebox_create_hw_buffer(struct livebox_buffer *handle); + +/*! + * \brief Destroy the H/W accelerated buffer. + * \param[in] handle Buffer handle + * \return 0 if succeed to destroy it or errno < 0 + * \see livebox_create_hw_buffer + */ +extern int livebox_destroy_hw_buffer(struct livebox_buffer *handle); + +/*! + * \brief Get the address of accelerated H/W buffer + * \param[in] handle Buffer handle + * \return void + * \see livebox_create_hw_buffer + */ +extern void *livebox_buffer_hw_buffer(struct livebox_buffer *handle); + +/*! + * \brief Pre-processing for rendering content. + * This is only needed for accessing H/W accelerated buffer. + * \param[in] handle Buffer handle + * \return 0 if succeed or errno < 0 + * \see livebox_support_hw_buffer + */ +extern int livebox_buffer_pre_render(struct livebox_buffer *handle); + +/*! + * \brief Post-processing for rendering content. + * \param[in] handle Buffer handle + * \return 0 if succeed or errno < 0 + * \see livebox_support_hw_buffer */ -extern int livebox_request_update(const char *filename); +extern int livebox_buffer_post_render(struct livebox_buffer *handle); #ifdef __cplusplus } diff --git a/packaging/liblivebox.spec b/packaging/liblivebox.spec index 685d274..1a69865 100644 --- a/packaging/liblivebox.spec +++ b/packaging/liblivebox.spec @@ -1,6 +1,6 @@ Name: liblivebox Summary: Library for the development of a livebox -Version: 0.1.14 +Version: 0.1.15 Release: 1 Group: main/app License: Flora License @@ -9,6 +9,7 @@ BuildRequires: cmake, gettext-tools, coreutils BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(livebox-service) BuildRequires: pkgconfig(provider) +BuildRequires: pkgconfig(elementary) %description Livebox development library diff --git a/src/livebox.c b/src/livebox.c index 87e4aa1..487011d 100644 --- a/src/livebox.c +++ b/src/livebox.c @@ -61,6 +61,11 @@ struct livebox_desc { struct dlist *block_list; }; +struct livebox_buffer_data { + int is_pd; + int accelerated; +}; + EAPI const int DONE = 0x00; EAPI const int OUTPUT_UPDATED = 0x02; EAPI const int USE_NET = 0x04; @@ -455,6 +460,7 @@ EAPI int livebox_desc_del_block(struct livebox_desc *handle, int idx) EAPI struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data) { + struct livebox_buffer_data *user_data; const char *pkgname; struct livebox_buffer *handle; char *uri; @@ -465,10 +471,19 @@ EAPI struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_ return NULL; } + user_data = calloc(1, sizeof(*user_data)); + if (!user_data) { + ErrPrint("Heap: %s\n", strerror(errno)); + return NULL; + } + + user_data->is_pd = is_pd; + uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1; uri = malloc(uri_len); if (!uri) { ErrPrint("Heap: %s\n", strerror(errno)); + free(user_data); return NULL; } @@ -476,6 +491,7 @@ EAPI struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_ pkgname = livebox_find_pkgname(uri); if (!pkgname) { ErrPrint("Invalid Request\n"); + free(user_data); free(uri); return NULL; } @@ -483,6 +499,8 @@ EAPI struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_ handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), handler, data); DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle); free(uri); + + (void)provider_buffer_set_user_data(handle, user_data); return handle; } @@ -517,20 +535,39 @@ EAPI unsigned long livebox_pixmap_id(struct livebox_buffer *handle) EAPI int livebox_release_buffer(struct livebox_buffer *handle) { + struct livebox_buffer_data *user_data; + if (!handle) return -EINVAL; + user_data = provider_buffer_user_data(handle); + if (user_data) { + free(user_data); + provider_buffer_set_user_data(handle, NULL); + } + DbgPrint("Release buffer\n"); return provider_buffer_release(handle); } EAPI void *livebox_ref_buffer(struct livebox_buffer *handle) { + struct livebox_buffer_data *user_data; void *data; int w, h, size; int ret; + if (!handle) - return -EINVAL; + return NULL; + + user_data = provider_buffer_user_data(handle); + if (!user_data) + return NULL; + + if (user_data->accelerated) { + DbgPrint("H/W accelerated buffer is allocated\n"); + return NULL; + } ret = provider_buffer_get_size(handle, &w, &h, &size); @@ -555,22 +592,184 @@ EAPI int livebox_unref_buffer(void *buffer) EAPI int livebox_sync_buffer(struct livebox_buffer *handle) { + struct livebox_buffer_data *user_data; const char *pkgname; const char *id; if (!handle) return -EINVAL; + user_data = provider_buffer_user_data(handle); + if (!user_data) { + ErrPrint("Invalid buffer\n"); + return -EINVAL; + } + + if (user_data->accelerated) { + DbgPrint("H/W Buffer allocated. skip the sync buffer\n"); + return 0; + } + pkgname = provider_buffer_pkgname(handle); + if (!pkgname) { + ErrPrint("Invalid buffer handler\n"); + return -EINVAL; + } + id = provider_buffer_id(handle); - if (!pkgname || !id) { + if (!id) { ErrPrint("Invalid buffer handler\n"); return -EINVAL; } DbgPrint("Sync buffer\n"); provider_buffer_sync(handle); - provider_send_desc_updated(pkgname, id, NULL); + + if (user_data->is_pd) { + if (provider_send_desc_updated(pkgname, id, NULL) < 0) + ErrPrint("Failed to send PD updated (%s)\n", id); + } else { + int w; + int h; + int pixel_size; + + if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) + ErrPrint("Failed to get size (%s)\n", id); + + if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) + ErrPrint("Failed to send updated (%s)\n", id); + } + return 0; +} + +EAPI int livebox_support_hw_buffer(struct livebox_buffer *handle) +{ + if (!handle) + return -EINVAL; + + return provider_buffer_pixmap_is_support_hw(handle); +} + +EAPI int livebox_create_hw_buffer(struct livebox_buffer *handle) +{ + struct livebox_buffer_data *user_data; + int ret; + + if (!handle) + return -EINVAL; + + user_data = provider_buffer_user_data(handle); + if (!user_data) + return -EINVAL; + + if (user_data->accelerated) + return -EALREADY; + + ret = provider_buffer_pixmap_create_hw(handle); + user_data->accelerated = (ret == 0); + return ret; +} + +EAPI int livebox_destroy_hw_buffer(struct livebox_buffer *handle) +{ + struct livebox_buffer_data *user_data; + if (!handle) + return -EINVAL; + + user_data = provider_buffer_user_data(handle); + if (!user_data || !user_data->accelerated) + return -EINVAL; + + user_data->accelerated = 0; + + return provider_buffer_pixmap_destroy_hw(handle); +} + +EAPI void *livebox_buffer_hw_buffer(struct livebox_buffer *handle) +{ + struct livebox_buffer_data *user_data; + + if (!handle) + return NULL; + + user_data = provider_buffer_user_data(handle); + if (!user_data || !user_data->accelerated) + return -EINVAL; + + return provider_buffer_pixmap_hw_addr(handle); +} + +EAPI int livebox_buffer_pre_render(struct livebox_buffer *handle) +{ + struct livebox_buffer_data *user_data; + + if (!handle) + return -EINVAL; + + user_data = provider_buffer_user_data(handle); + if (!user_data) + return -EINVAL; + + if (!user_data->accelerated) + return 0; + + /*! + * \note + * Do preprocessing for accessing the H/W render buffer + */ + return provider_buffer_pre_render(handle); +} + +EAPI int livebox_buffer_post_render(struct livebox_buffer *handle) +{ + int ret; + const char *pkgname; + const char *id; + struct livebox_buffer_data *user_data; + + if (!handle) + return -EINVAL; + + user_data = provider_buffer_user_data(handle); + if (!user_data) + return -EINVAL; + + if (!user_data->accelerated) + return 0; + + pkgname = provider_buffer_pkgname(handle); + if (!pkgname) { + ErrPrint("Invalid buffer handle\n"); + return -EINVAL; + } + + id = provider_buffer_id(handle); + if (!id) { + ErrPrint("Invalid buffer handler\n"); + return -EINVAL; + } + + ret = provider_buffer_post_render(handle); + if (ret < 0) { + ErrPrint("Failed to post render processing\n"); + return ret; + } + + if (user_data->is_pd == 1) { + if (provider_send_desc_updated(pkgname, id, NULL) < 0) + ErrPrint("Failed to send PD updated (%s)\n", id); + } else { + int w; + int h; + int pixel_size; + + if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) + ErrPrint("Failed to get size (%s)\n", id); + + if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) + ErrPrint("Failed to send updated (%s)\n", id); + } + return 0; } -- 2.7.4