PUI: increase tbm_surface_queue size (2->3)
[platform/core/uifw/libpui.git] / src / PUI.c
1 /*
2  * Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25
26 #include "PUI_internal.h"
27 #include "PUI_backend.h"
28 #include "PUI.h"
29
30 #include <wayland-tbm-client.h>
31 #include <tbm_surface_internal.h>
32 #include <stdio.h>
33 #include <dlfcn.h>
34
35 #ifndef PUI_MODULE_DIR
36 #define PUI_MODULE_DIR "/usr/lib"
37 #endif
38
39 static int _pui_init_count = 0;
40 static pui_module_data *pui_module = NULL;
41
42 int PUI_EVENT_ANI_STARTED = 0;
43 int PUI_EVENT_ANI_STOPPED = 0;
44 int PUI_EVENT_ANI_PAUSED = 0;
45 int PUI_EVENT_ANI_READY_TO_START = 0;
46 int PUI_EVENT_ANI_READY_TO_RESUME = 0;
47
48 pui_error_string
49 pui_error_to_string(pui_error e)
50 {
51         pui_error_string str = NULL;
52
53         switch (e)
54         {
55                 case PUI_ERROR_NONE:
56                         str = "PUI_No_Error";
57                         break;
58
59                 case PUI_ERROR_INVALID_ANI_HANDLE:
60                         str = "PUI_Invalid_Animation_Handle";
61                         break;
62
63                 case PUI_ERROR_INVALID_ANI_CMD:
64                         str = "PUI_Invalid_Animation_Command";
65                         break;
66
67                 case PUI_ERROR_INTERNAL:
68                         str = "PUI_Internal_Error";
69                         break;
70
71                 default:
72                         str = "PUI_Unknown_Error";
73         }
74
75         return str;
76 }
77
78 pui_h
79 pui_create(Ecore_Wl2_Window *win)
80 {
81         pui_h handle = NULL;
82         Ecore_Wl2_Display *ewd = ecore_wl2_window_display_get(win);
83         struct wayland_tbm_client *wl_tbm_client = NULL;
84
85         if (!win || !ewd)
86         {
87                 pui_err("Invalid window or display !\n");
88                 return NULL;
89         }
90
91         wl_tbm_client = wayland_tbm_client_init(ecore_wl2_display_get(ewd));
92
93         if (!wl_tbm_client)
94         {
95                 pui_err("Failed to init wayland_tbm_client !\n");
96                 return NULL;
97         }
98
99         handle = (pui_h)calloc(1, sizeof(pui));
100
101         if (!handle)
102                 return NULL;
103
104         handle->win = win;
105         handle->ewd = ewd;
106         handle->visibility = 0;
107         handle->wl_tbm_client = wl_tbm_client;
108         handle->ani_handles = NULL;
109         handle->current_ani_h = NULL;
110         handle->backend_module_data = pui_module->backend_module_data;
111
112         handle->tbm_queue = wayland_tbm_client_create_surface_queue(handle->wl_tbm_client,
113                                                                 ecore_wl2_window_surface_get(handle->win),
114                                                                 3, 100, 100, TBM_FORMAT_ABGR8888);
115
116         if (!handle->tbm_queue)
117         {
118                 pui_err("Failed to create a surface queue !");
119                 goto err;
120         }
121
122         return handle;
123
124 err:
125         pui_destroy(handle);
126
127         return NULL;
128 }
129
130 void
131 pui_destroy(pui_h handle)
132 {
133         pui_ani_h ani_h = NULL;
134
135         if (!handle)
136                 return;
137
138         EINA_LIST_FREE(handle->ani_handles, ani_h)
139         {
140                 pui_ani_destroy(ani_h);
141                 free(ani_h);
142         }
143
144         if (handle->tbm_queue)
145         {
146                 tbm_surface_queue_destroy(handle->tbm_queue);
147         }
148
149         if (handle->wl_tbm_client)
150         {
151                 wayland_tbm_client_deinit(handle->wl_tbm_client);
152                 handle->wl_tbm_client = NULL;
153         }
154
155         free(handle);
156 }
157
158 #define PREFIX_LIB    "libpui-"
159 #define SUFFIX_LIB    ".so"
160 #define DEFAULT_LIB   PREFIX_LIB"default-backend"SUFFIX_LIB
161
162 static void
163 _pui_load_backend_module(void)
164 {
165         //char path[PATH_MAX] = {0, };
166         void *module_info = NULL;
167         pui_backend_module *backend_module_info = NULL;
168         int backend_module_major, backend_module_minor;
169         int pui_backend_major, pui_backend_minor;
170
171         pui_backend_module_data *backend_module_data = NULL;
172
173
174         module_info = dlopen(DEFAULT_LIB, RTLD_LAZY);
175
176         if (!module_info)
177         {
178                 pui_err("Failed to dlopen(error:%s, path:%s) !\n", dlerror(), DEFAULT_LIB);
179                 return;
180         }
181
182         backend_module_info = dlsym(module_info, "pui_backend_module_info");
183
184         if (!backend_module_info) {
185                 pui_err("Backend module(%s) doesn't have pui_backend_module_info !\n", DEFAULT_LIB);
186                 goto err;
187         }
188
189         pui_backend_major = PUI_BACKEND_GET_ABI_MAJOR(PUI_BACKEND_AB_VERSION_LAST);
190         pui_backend_minor = PUI_BACKEND_GET_ABI_MINOR(PUI_BACKEND_AB_VERSION_LAST);
191
192         backend_module_major = PUI_BACKEND_GET_ABI_MAJOR(backend_module_info->abi_version);
193         backend_module_minor = PUI_BACKEND_GET_ABI_MINOR(backend_module_info->abi_version);
194
195         if (backend_module_major > pui_backend_major) {
196                 pui_err("PUI backend module ABI major ver(%d) is newer than the PUI's ver(%d)\n",
197                         backend_module_major, pui_backend_major);
198                 goto err;
199         } else if (backend_module_minor > pui_backend_minor) {
200                 pui_err("PUI backend module ABI minor ver(%d) is newer than the PUI's ver(%d)\n",
201                         backend_module_minor, pui_backend_minor);
202                 goto err;
203         }
204
205         if (!backend_module_info->backend_init || !backend_module_info->backend_deinit)
206         {
207                 pui_err("Backend module doesn't have backend_init/backend_deinit function !\n");
208                 goto err;
209         }
210
211         backend_module_data = backend_module_info->backend_init();
212
213         if (!backend_module_data)
214         {
215                 pui_err("Failed to init module (%s) !\n", DEFAULT_LIB);
216                 goto err;
217         }
218
219         pui_module->module_info = module_info;
220         pui_module->backend_module_info = backend_module_info;
221         pui_module->backend_module_data = backend_module_data;
222
223         return;
224
225 err:
226         if (backend_module_info && backend_module_info->backend_init)
227                 backend_module_info->backend_deinit(backend_module_data);
228
229         if (module_info)
230                 dlclose(module_info);
231
232         return;
233 }
234
235 static void
236 _pui_unload_backend_module(void)
237 {
238         if (!pui_module)
239         {
240                 pui_err("Invalid pui module !\n");
241                 return;
242         }
243
244         if (pui_module->backend_module_info)
245         {
246                 pui_module->backend_module_info->backend_deinit(pui_module->backend_module_data);
247                 pui_module->backend_module_data = NULL;
248                 pui_module->backend_module_info = NULL;
249         }
250
251         if (pui_module->module_info)
252                 dlclose(pui_module->module_info);
253 }
254
255 static void
256 _pui_load_backend_collect_animations(void)
257 {
258         pui_int_error ret;
259
260         if (!pui_module || !pui_module->backend_module_data) {
261                 pui_err("pui module data is not loaded\n");
262                 return;
263         }
264
265         ret = pui_module->backend_module_data->create_ani_collection();
266         if (ret != PUI_INT_ERROR_NONE) {
267                 pui_err("Failed to collect animations data (%s)\n",
268                         pui_error_to_string(ret));
269         }
270 }
271
272 static void
273 _pui_load(void)
274 {
275         _pui_load_backend_module();
276         _pui_load_backend_collect_animations();
277 }
278
279 static void
280 _pui_unload(void)
281 {
282         _pui_unload_backend_module();
283 }
284
285 static void
286 _pui_event_init(void)
287 {
288         PUI_EVENT_ANI_STARTED = ecore_event_type_new();
289         PUI_EVENT_ANI_STOPPED = ecore_event_type_new();
290         PUI_EVENT_ANI_PAUSED = ecore_event_type_new();
291         PUI_EVENT_ANI_READY_TO_START = ecore_event_type_new();
292         PUI_EVENT_ANI_READY_TO_RESUME = ecore_event_type_new();
293 }
294
295 static void
296 _pui_event_shutdown(void)
297 {
298         ecore_event_type_flush(PUI_EVENT_ANI_STARTED,
299                                         PUI_EVENT_ANI_STOPPED,
300                                         PUI_EVENT_ANI_PAUSED,
301                                         PUI_EVENT_ANI_READY_TO_START,
302                                         PUI_EVENT_ANI_READY_TO_RESUME);
303
304         PUI_EVENT_ANI_STARTED = -1;
305         PUI_EVENT_ANI_STOPPED = -1;
306         PUI_EVENT_ANI_PAUSED = -1;
307         PUI_EVENT_ANI_READY_TO_START = -1;
308         PUI_EVENT_ANI_READY_TO_RESUME = -1;
309 }
310
311 int
312 pui_init(void)
313 {
314         if (++_pui_init_count != 1)
315           return _pui_init_count;
316
317         if (pui_module)
318         {
319                 pui_err("Invalid calling of pui_init() !\n");
320                 goto error;
321         }
322
323         pui_module = (pui_module_data *)calloc(1, sizeof(pui_module_data));
324
325         if (!pui_module)
326         {
327                 pui_err("Failed to allocate memory for pui module data !\n");
328                 goto error;
329         }
330
331         //TODO
332         ecore_wl2_init();
333
334         _pui_event_init();
335
336         _pui_load();
337
338         return _pui_init_count;
339
340 error:
341         return --_pui_init_count;
342 }
343
344 int
345 pui_shutdown(void)
346 {
347         if (_pui_init_count <= 0)
348         {
349                 pui_err("Invalid pui init count : %d\n", _pui_init_count);
350                 _pui_init_count = 0;
351                 return 0;
352         }
353
354         if (!pui_module)
355         {
356                 pui_err("Invalid pui module data !\n");
357                 return _pui_init_count;
358         }
359
360         _pui_init_count--;
361
362         //TODO
363         _pui_unload();
364
365         _pui_event_shutdown();
366
367         ecore_wl2_shutdown();
368
369         free(pui_module);
370
371         return _pui_init_count;
372 }
373