From 0fd4792cc70eb58f73b6d68566fe7d9f1eace5a4 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Tue, 10 Sep 2019 16:15:40 +0900 Subject: [PATCH] PUI: add manual render set/get APIs and move ani get/set/update APIs to PUI from PUI ani Change-Id: Iba9993f6bd35327ebb853b2b0d47d23710fa6f35 Signed-off-by: Sung-Jin Park --- backends/default_backend.c | 16 +++ backends/default_backend.h | 3 + include/PUI.h | 18 ++++ include/PUI_backend.h | 1 + include/PUI_common.h | 6 ++ src/PUI.c | 237 +++++++++++++++++++++++++++++++++++++++++++++ src/PUI_ani.c | 189 ++++++++---------------------------- src/PUI_internal.h | 1 + 8 files changed, 325 insertions(+), 146 deletions(-) diff --git a/backends/default_backend.c b/backends/default_backend.c index 8ed95cf..ddd4463 100644 --- a/backends/default_backend.c +++ b/backends/default_backend.c @@ -385,6 +385,20 @@ _create_ani_collection(void) return e; } +pui_bool +_geometry_get(int *width, int *height) +{ + if (!width || !height) + return 0; + + if (width) + *width = DEFAULT_BACKEND_GEOM_WIDTH; + if (height) + *height = DEFAULT_BACKEND_GEOM_HEIGHT; + + return 1; +} + pui_int_error _is_ani_supported(pui_id id) { @@ -598,6 +612,7 @@ pui_default_backend_init(void) } backend_data->create_ani_collection = _create_ani_collection; + backend_data->geometry_get = _geometry_get; backend_data->ani_create = _ani_create; backend_data->ani_destroy = _ani_destroy; @@ -652,6 +667,7 @@ pui_default_backend_deinit(pui_backend_module_data *backend_data) } backend_data->create_ani_collection = NULL; + backend_data->geometry_get = NULL; backend_data->ani_create = NULL; backend_data->ani_destroy = NULL; diff --git a/backends/default_backend.h b/backends/default_backend.h index 84210fc..b7b7047 100644 --- a/backends/default_backend.h +++ b/backends/default_backend.h @@ -38,6 +38,9 @@ #define ANI_COLLECTION_DIR "/usr/share/pui/" #define MAX_STR 1024 +#define DEFAULT_BACKEND_GEOM_WIDTH 12 +#define DEFAULT_BACKEND_GEOM_HEIGHT 1 + #ifndef PI #define PI 3.1415926545 #endif diff --git a/include/PUI.h b/include/PUI.h index 159f65c..38e8aa9 100644 --- a/include/PUI.h +++ b/include/PUI.h @@ -83,6 +83,24 @@ pui_ani_get_cmd(pui_ani_h ani_h); PUI_API int pui_ani_get_repeat(pui_ani_h ani_h); +PUI_API pui_ani_control_buffer * +pui_display_get_buffer(pui_h handle); + +PUI_API pui_error +pui_display_set_buffer(pui_h handle, pui_ani_control_buffer *buffer); + +PUI_API pui_error +pui_display_update(pui_h handle); + +PUI_API pui_error +pui_display_manual_render_set(pui_h handle, pui_bool set); + +PUI_API pui_bool +pui_display_manual_render_get(pui_h handle); + +PUI_API pui_bool +pui_display_geometry_get(pui_h handle, int *width, int *height); + #ifdef __cplusplus } #endif diff --git a/include/PUI_backend.h b/include/PUI_backend.h index d1e9210..6dc84f0 100644 --- a/include/PUI_backend.h +++ b/include/PUI_backend.h @@ -66,6 +66,7 @@ struct _pui_backend_module_data void *data; pui_int_error (*create_ani_collection)(void); + pui_bool (*geometry_get)(int *width, int *height); pui_backend_ani_data *(*ani_create)(pui_id id); void (*ani_destroy)(pui_backend_ani_data *ani_data); diff --git a/include/PUI_common.h b/include/PUI_common.h index eb587be..b5c5738 100644 --- a/include/PUI_common.h +++ b/include/PUI_common.h @@ -32,6 +32,11 @@ typedef enum { PUI_ERROR_INVALID_ANI_CMD, PUI_ERROR_INVALID_ANI_REPEAT, PUI_ERROR_INTERNAL, + PUI_ERROR_INVALID_HANDLE, + PUI_ERROR_INVALID_SURFACE, + PUI_ERROR_INVALID_BUFFER, + PUI_ERROR_MANUAL_RENDER_ENABLED, + PUI_ERROR_UNABLE_SET_MANUAL_RENDER, } pui_error; typedef enum { @@ -60,6 +65,7 @@ typedef enum { PUI_INT_ERROR_NO_ANI_AVAILABLE, PUI_INT_ERROR_BACKEND_FUNC_ERROR, PUI_INT_ERROR_INVALID_RESOURCES, + PUI_INT_ERROR_UNKNOWN, } pui_int_error; typedef unsigned int pui_bool; diff --git a/src/PUI.c b/src/PUI.c index ac47204..f7fa28e 100644 --- a/src/PUI.c +++ b/src/PUI.c @@ -45,6 +45,9 @@ int PUI_EVENT_ANI_PAUSED = 0; int PUI_EVENT_ANI_READY_TO_START = 0; int PUI_EVENT_ANI_READY_TO_RESUME = 0; +static int KEY_WL_BUFFER = 0xabcdbeaf; +static int KEY_CLIENT = 0xdcbabeaf; + pui_error_string pui_error_to_string(pui_error e) { @@ -68,6 +71,14 @@ pui_error_to_string(pui_error e) str = "PUI_Internal_Error"; break; + case PUI_ERROR_MANUAL_RENDER_ENABLED: + str = "PUI_Manual_Render_Enabled"; + break; + + case PUI_ERROR_UNABLE_SET_MANUAL_RENDER: + str = "PUI_Unable_To_Set_Manual_Render"; + break; + default: str = "PUI_Unknown_Error"; } @@ -75,6 +86,225 @@ pui_error_to_string(pui_error e) return str; } +static void +_buffer_release(void *data, struct wl_buffer *buffer) +{ + tbm_surface_h surface = (tbm_surface_h)data; + pui_h handle; + + tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_CLIENT, (void **)&handle); + tbm_surface_queue_release(handle->tbm_queue, surface); + + pui_info("[UPDATE] release wl_buffer:%p, surface:%p\n", buffer, surface); +} + +static const struct wl_buffer_listener buffer_listener = { + _buffer_release +}; + +pui_ani_control_buffer * +pui_display_get_buffer(pui_h handle) +{ + tbm_surface_error_e ret; + tbm_surface_h surface; + pui_ani_control_buffer *buffer = NULL; + + if (!handle) + { + pui_err("Error : PUI_INT_ERROR_INVALID_HANDLE\n"); + return NULL; + } + + if (handle->current_surface) + { + pui_warn("Current_surface is not used !\n"); + } + + if (!tbm_surface_queue_can_dequeue(handle->tbm_queue, 0)) + { + pui_err("[UPDATE] Cannot dequeue (error : PUI_ERROR_INTERNAL)\n"); + return NULL; + } + + ret = tbm_surface_queue_dequeue(handle->tbm_queue, &surface); + + if (ret != TBM_SURFACE_ERROR_NONE) + { + pui_err("[UPDATE] dequeue err:%d\n", ret); + return NULL; + } + + tbm_surface_map(surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &handle->current_sinfo); + + handle->current_surface = surface; + buffer = (pui_ani_control_buffer *)&(handle->current_sinfo.planes[0]); + + return buffer; +} + +pui_error +pui_display_set_buffer(pui_h handle, pui_ani_control_buffer *buffer) +{ + if (!handle) + { + pui_err("Error : PUI_ERROR_INVALID_HANDLE\n"); + return PUI_ERROR_INVALID_HANDLE; + } + + if (!handle->current_surface) + { + pui_err("Current_surface is not valid !\n"); + return PUI_ERROR_INVALID_SURFACE; + } + + if (!buffer || !buffer->ptr || !buffer->size) + return PUI_ERROR_INVALID_BUFFER; + + handle->is_buffer_set = 1; + + return PUI_ERROR_NONE; +} + +pui_error +pui_display_update(pui_h handle) +{ + tbm_surface_h surface; + tbm_surface_error_e ret; + struct wl_buffer *wl_buffer = NULL; + + if (!handle) + { + pui_err("Error : PUI_ERROR_INVALID_HANDLE\n"); + return PUI_ERROR_INVALID_HANDLE; + } + + if (!handle->current_surface) + return PUI_ERROR_INVALID_SURFACE; + + if (!handle->is_buffer_set) + { + pui_err("Buffer is not set !\n"); + return PUI_ERROR_INVALID_BUFFER; + } + + surface = handle->current_surface; + handle->current_surface = NULL; + + tbm_surface_unmap(surface); + + ret = tbm_surface_queue_enqueue(handle->tbm_queue, surface); + + if (ret != TBM_SURFACE_ERROR_NONE) + { + pui_err("[UPDATE] enqueue err:%d\n", ret); + return PUI_ERROR_INVALID_SURFACE; + } + + ret = tbm_surface_queue_acquire(handle->tbm_queue, &surface); + + if (ret != TBM_SURFACE_ERROR_NONE) + { + pui_err("[UPDATE] acquire err:%d\n", ret); + return PUI_ERROR_INVALID_SURFACE; + } + + if (!tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_WL_BUFFER, (void **)&wl_buffer)) { + wl_buffer = wayland_tbm_client_create_buffer(handle->wl_tbm_client, surface); + + if (!wl_buffer) + { + pui_err("[UPDATE] failed to create wl_buffer tbm_surface:%p\n", surface); + return PUI_ERROR_INVALID_BUFFER; + } + + wl_buffer_add_listener(wl_buffer, &buffer_listener, surface); + + tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_WL_BUFFER, NULL); + tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_WL_BUFFER, wl_buffer); + tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_CLIENT, NULL); + tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_CLIENT, handle); + } + + if (!wl_buffer) + { + pui_err("[UPDATE] dequeue err:%d\n", ret); + return PUI_ERROR_INVALID_BUFFER; + } + + ecore_wl2_window_buffer_attach(handle->win, wl_buffer, 0, 0, 0); + ecore_wl2_window_damage(handle->win, NULL, 0); + ecore_wl2_window_commit(handle->win, EINA_TRUE); + + pui_info("[UPDATE] commit wl_buffer:%p, surface:%p\n", wl_buffer, surface); + + handle->is_buffer_set = 0; + + return PUI_ERROR_NONE; +} + +pui_error +pui_display_manual_render_set(pui_h handle, pui_bool set) +{ + pui_ani_h ani_h = NULL; + + if (!handle) + { + pui_err("Error : PUI_ERROR_INVALID_HANDLE\n"); + return PUI_ERROR_INVALID_HANDLE; + } + + ani_h = handle->current_ani_h; + + if (ani_h) + { + if (pui_ani_status_get(ani_h->ani) == PUI_ANI_STATUS_RUNNING || + pui_ani_status_get(ani_h->ani) == PUI_ANI_STATUS_PAUSED) + { + pui_err("Please stop the current animation.\n"); + return PUI_ERROR_UNABLE_SET_MANUAL_RENDER; + } + } + + handle->manual_render = !!set; + + return PUI_ERROR_NONE; +} + +pui_bool +pui_display_manual_render_get(pui_h handle) +{ + if (!handle) + { + pui_err("Error : PUI_ERROR_INVALID_HANDLE\n"); + return 0; + } + + return handle->manual_render; +} + +pui_bool +pui_display_geometry_get(pui_h handle, int *width, int *height) +{ + if (!width || !height) + return 0; + + *width = 0; + *height = 0; + + if (!pui_module || !pui_module->backend_module_data) { + pui_err("pui module data is not loaded\n"); + return 0; + } + + if (!pui_module->backend_module_data->geometry_get) + { + pui_err("Backend doesn't have geometry_get() !\n"); + return 0; + } + + return pui_module->backend_module_data->geometry_get(width, height); +} + pui_h pui_create(Ecore_Wl2_Window *win) { @@ -107,6 +337,7 @@ pui_create(Ecore_Wl2_Window *win) handle->wl_tbm_client = wl_tbm_client; handle->ani_handles = NULL; handle->current_ani_h = NULL; + handle->manual_render = 0; handle->backend_module_data = pui_module->backend_module_data; handle->tbm_queue = wayland_tbm_client_create_surface_queue(handle->wl_tbm_client, @@ -262,6 +493,12 @@ _pui_load_backend_collect_animations(void) return; } + if (!pui_module->backend_module_data->create_ani_collection) + { + pui_err("Backend doesn't have create_ani_collection() !\n"); + return; + } + ret = pui_module->backend_module_data->create_ani_collection(); if (ret != PUI_INT_ERROR_NONE) { pui_err("Failed to collect animations data (%s)\n", diff --git a/src/PUI_ani.c b/src/PUI_ani.c index 9ef7c0f..e733987 100644 --- a/src/PUI_ani.c +++ b/src/PUI_ani.c @@ -28,8 +28,36 @@ #include "PUI.h" #include -static int KEY_WL_BUFFER = 0xabcdbeaf; -static int KEY_CLIENT = 0xdcbabeaf; +pui_int_error +_pui_ani_error_to_int_error(pui_error e) +{ + pui_int_error ei; + + switch (e) + { + case PUI_ERROR_NONE: + ei = PUI_INT_ERROR_NONE; + break; + + case PUI_ERROR_INVALID_HANDLE: + ei = PUI_INT_ERROR_INVALID_HANDLE; + break; + + case PUI_ERROR_INVALID_SURFACE: + ei = PUI_INT_ERROR_INVALID_SURFACE; + break; + + case PUI_ERROR_INVALID_BUFFER: + ei = PUI_INT_ERROR_INVALID_BUFFER; + break; + + default: + ei = PUI_INT_ERROR_UNKNOWN; + break; + } + + return ei; +} static void _pui_ani_cb_frame_done(Ecore_Wl2_Window *win, uint32_t timestamp EINA_UNUSED, void *data) @@ -44,28 +72,10 @@ _pui_ani_cb_frame_done(Ecore_Wl2_Window *win, uint32_t timestamp EINA_UNUSED, vo return; } -static void -_buffer_release(void *data, struct wl_buffer *buffer) -{ - tbm_surface_h surface = (tbm_surface_h)data; - pui_h handle; - - tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_CLIENT, (void **)&handle); - tbm_surface_queue_release(handle->tbm_queue, surface); - - pui_info("[UPDATE] release wl_buffer:%p, surface:%p\n", buffer, surface); -} - -static const struct wl_buffer_listener buffer_listener = { - _buffer_release -}; - pui_ani_control_buffer * pui_ani_get_buffer(pui_ani_h ani_h) { pui_h handle = NULL; - tbm_surface_error_e ret; - tbm_surface_h surface; pui_ani_control_buffer *buffer = NULL; if (!ani_h) @@ -75,36 +85,7 @@ pui_ani_get_buffer(pui_ani_h ani_h) } handle = ani_h->pui_handle; - - if (!handle) - { - pui_err("Error : PUI_INT_ERROR_INVALID_HANDLE\n"); - return NULL; - } - - if (handle->current_surface) - { - pui_warn("Current_surface is not used !\n"); - } - - if (!tbm_surface_queue_can_dequeue(handle->tbm_queue, 0)) - { - pui_err("[UPDATE] Cannot dequeue (error : PUI_ERROR_INTERNAL)\n"); - return NULL; - } - - ret = tbm_surface_queue_dequeue(handle->tbm_queue, &surface); - - if (ret != TBM_SURFACE_ERROR_NONE) - { - pui_err("[UPDATE] dequeue err:%d\n", ret); - return NULL; - } - - tbm_surface_map(surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &handle->current_sinfo); - - handle->current_surface = surface; - buffer = (pui_ani_control_buffer *)&(handle->current_sinfo.planes[0]); + buffer = pui_display_get_buffer(handle); return buffer; } @@ -112,43 +93,19 @@ pui_ani_get_buffer(pui_ani_h ani_h) pui_int_error pui_ani_set_buffer(pui_ani_h ani_h, pui_ani_control_buffer *buffer) { + pui_error e = PUI_ERROR_NONE; pui_h handle = NULL; - if (!ani_h) - { - pui_err("Invalid ani handle !\n"); - return PUI_INT_ERROR_INVALID_HANDLE; - } - handle = ani_h->pui_handle; + e = pui_display_set_buffer(handle, buffer); - if (!handle) - { - pui_err("Error : PUI_INT_ERROR_INVALID_HANDLE\n"); - return PUI_INT_ERROR_INVALID_HANDLE; - } - - if (!handle->current_surface) - { - pui_err("Current_surface is not valid !\n"); - return PUI_INT_ERROR_INVALID_SURFACE; - } - - if (!buffer || !buffer->ptr || !buffer->size) - return PUI_INT_ERROR_INVALID_BUFFER; - - handle->is_buffer_set = 1; - - return PUI_INT_ERROR_NONE; + return _pui_ani_error_to_int_error(e); } pui_int_error pui_ani_update(pui_ani_h ani_h) { - tbm_surface_h surface; - tbm_surface_error_e ret; - struct wl_buffer *wl_buffer = NULL; - + pui_error e = PUI_ERROR_NONE; pui_h handle = NULL; if (!ani_h) @@ -158,75 +115,9 @@ pui_ani_update(pui_ani_h ani_h) } handle = ani_h->pui_handle; + e = pui_display_update(handle); - if (!handle) - { - pui_err("Error : PUI_INT_ERROR_INVALID_HANDLE\n"); - return PUI_INT_ERROR_INVALID_HANDLE; - } - - if (!handle->current_surface) - return PUI_INT_ERROR_INVALID_SURFACE; - - if (!handle->is_buffer_set) - { - pui_err("Buffer is not set !\n"); - return PUI_INT_ERROR_INVALID_BUFFER; - } - - surface = handle->current_surface; - handle->current_surface = NULL; - - tbm_surface_unmap(surface); - - ret = tbm_surface_queue_enqueue(handle->tbm_queue, surface); - - if (ret != TBM_SURFACE_ERROR_NONE) - { - pui_err("[UPDATE] enqueue err:%d\n", ret); - return PUI_INT_ERROR_INVALID_SURFACE; - } - - ret = tbm_surface_queue_acquire(handle->tbm_queue, &surface); - - if (ret != TBM_SURFACE_ERROR_NONE) - { - pui_err("[UPDATE] acquire err:%d\n", ret); - return PUI_INT_ERROR_INVALID_SURFACE; - } - - if (!tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_WL_BUFFER, (void **)&wl_buffer)) { - wl_buffer = wayland_tbm_client_create_buffer(handle->wl_tbm_client, surface); - - if (!wl_buffer) - { - pui_err("[UPDATE] failed to create wl_buffer tbm_surface:%p\n", surface); - return PUI_INT_ERROR_INVALID_BUFFER; - } - - wl_buffer_add_listener(wl_buffer, &buffer_listener, surface); - - tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_WL_BUFFER, NULL); - tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_WL_BUFFER, wl_buffer); - tbm_surface_internal_add_user_data(surface, (unsigned long)&KEY_CLIENT, NULL); - tbm_surface_internal_set_user_data(surface, (unsigned long)&KEY_CLIENT, handle); - } - - if (!wl_buffer) - { - pui_err("[UPDATE] dequeue err:%d\n", ret); - return PUI_INT_ERROR_INVALID_BUFFER; - } - - ecore_wl2_window_buffer_attach(handle->win, wl_buffer, 0, 0, 0); - ecore_wl2_window_damage(handle->win, NULL, 0); - ecore_wl2_window_commit(handle->win, EINA_TRUE); - - pui_info("[UPDATE] commit wl_buffer:%p, surface:%p\n", wl_buffer, surface); - - handle->is_buffer_set = 0; - - return PUI_INT_ERROR_NONE; + return _pui_ani_error_to_int_error(e); } static Eina_Bool @@ -489,6 +380,12 @@ _pui_ani_control_with_force(pui_ani_h ani_h, pui_ani_cmd cmd, int repeat, pui_bo if (cmd == PUI_ANI_CMD_START) { + if (handle->manual_render) + { + pui_err("Manual render has been set ! Unable to start animation.\n"); + return PUI_ERROR_MANUAL_RENDER_ENABLED; + } + if (handle->current_ani_h && handle->current_ani_h != ani_h) { pui_ani_t *current_ani = handle->current_ani_h->ani; diff --git a/src/PUI_internal.h b/src/PUI_internal.h index 2f4b7aa..06be182 100644 --- a/src/PUI_internal.h +++ b/src/PUI_internal.h @@ -84,6 +84,7 @@ struct _pui tbm_surface_info_s current_sinfo; tbm_surface_h current_surface; int is_buffer_set; + pui_bool manual_render; Eina_List *ani_handles; -- 2.7.4