8f5fcdada6bf268ccd9906ffca7cda9266e81dc4
[platform/core/uifw/libtdm.git] / src / tdm_hwc_window.c
1 /**************************************************************************
2  *
3  * libtdm
4  *
5  * Copyright 2018 Samsung Electronics co., Ltd. All Rights Reserved.
6  *
7  * Contact: SooChan Lim <sc1.lim@samsung.com>,
8  *          Boram Park <boram1288.park@samsung.com>,
9  *          Changyeon Lee <cyeon.lee@samsung.com>,
10  *          Sangjin Lee <lsj119@samsung.com>
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the
14  * "Software"), to deal in the Software without restriction, including
15  * without limitation the rights to use, copy, modify, merge, publish,
16  * distribute, sub license, and/or sell copies of the Software, and to
17  * permit persons to whom the Software is furnished to do so, subject to
18  * the following conditions:
19  *
20  * The above copyright notice and this permission notice (including the
21  * next paragraph) shall be included in all copies or substantial portions
22  * of the Software.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
27  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
28  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31  *
32 **************************************************************************/
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include "tdm_private.h"
39
40 /* LCOV_EXCL_START */
41
42 #define COUNT_MAX   10
43
44 #define HWC_WINDOW_FUNC_ENTRY() \
45         tdm_private_display *private_display; \
46         tdm_private_output *private_output; \
47         tdm_private_hwc *private_hwc; \
48         tdm_private_hwc_window *private_hwc_window; \
49         tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50         TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); \
51         private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
52         private_hwc = private_hwc_window->private_hwc; \
53         TDM_RETURN_VAL_IF_FAIL(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER); \
54         private_output = private_hwc->private_output; \
55         TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); \
56         private_display = private_output->private_display
57
58 #define HWC_WINDOW_FUNC_ENTRY_ERROR() \
59         tdm_private_display *private_display; \
60         tdm_private_output *private_output; \
61         tdm_private_hwc *private_hwc; \
62         tdm_private_hwc_window *private_hwc_window; \
63         tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
64         TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
65         private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
66         private_hwc = private_hwc_window->private_hwc; \
67         TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
68         private_output = private_hwc->private_output; \
69         TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
70         private_display = private_output->private_display
71
72 #define HWC_WINDOW_FUNC_ENTRY_VOID_RETURN() \
73         tdm_private_display *private_display; \
74         tdm_private_output *private_output; \
75         tdm_private_hwc *private_hwc; \
76         tdm_private_hwc_window *private_hwc_window; \
77         tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
78         TDM_RETURN_IF_FAIL(hwc_window != NULL); \
79         private_hwc_window = (tdm_private_hwc_window*)hwc_window; \
80         private_hwc = private_hwc_window->private_hwc; \
81         TDM_RETURN_IF_FAIL(private_hwc != NULL); \
82         private_output = private_hwc->private_output; \
83         TDM_RETURN_IF_FAIL(private_output != NULL); \
84         private_display = private_output->private_display
85
86
87 INTERN tdm_hwc_window *
88 tdm_hwc_window_create_internal(tdm_private_hwc *private_hwc, tdm_error *error)
89 {
90         tdm_private_output *private_output = private_hwc->private_output;
91         tdm_private_module *private_module = private_output->private_module;
92         tdm_func_hwc *func_hwc = &private_module->func_hwc;
93         tdm_private_hwc_window *private_hwc_window = NULL;
94         tdm_hwc_window *hwc_window_backend = NULL;
95         tdm_error ret = TDM_ERROR_NONE;
96
97         TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
98
99         if (!func_hwc->hwc_create_window) {
100                 /* LCOV_EXCL_START */
101                 if (error)
102                         *error = TDM_ERROR_BAD_MODULE;
103                 return NULL;
104                 /* LCOV_EXCL_STOP */
105         }
106
107         private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
108         if (!private_hwc_window) {
109                 /* LCOV_EXCL_START */
110                 TDM_ERR("failed: alloc memory");
111                 if (error)
112                         *error = TDM_ERROR_OUT_OF_MEMORY;
113                 return NULL;
114                 /* LCOV_EXCL_STOP */
115         }
116
117         hwc_window_backend = func_hwc->hwc_create_window(private_hwc->hwc_backend, &ret);
118         if (ret != TDM_ERROR_NONE) {
119                 free(private_hwc_window);
120                 if (error)
121                         *error = ret;
122                 return NULL;
123         }
124
125         LIST_ADD(&private_hwc_window->link, &private_hwc->hwc_window_list);
126
127         private_hwc_window->private_hwc = private_hwc;
128         private_hwc_window->hwc_window_backend = hwc_window_backend;
129
130         TDM_DBG("hwc_window(%p) create", private_hwc_window);
131
132         if (error)
133                 *error = TDM_ERROR_NONE;
134
135         return private_hwc_window;
136 }
137
138 INTERN void
139 tdm_hwc_window_destroy_internal(tdm_private_hwc_window *private_hwc_window)
140 {
141         tdm_private_output *private_output;
142         tdm_private_module *private_module;
143         tdm_private_hwc *private_hwc;
144         tdm_func_hwc_window *func_hwc_window;
145
146         TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
147
148         if (!private_hwc_window)
149                 return;
150
151         private_hwc = private_hwc_window->private_hwc;
152         private_output = private_hwc->private_output;
153         private_module = private_output->private_module;
154         func_hwc_window = &private_module->func_hwc_window;
155
156         LIST_DEL(&private_hwc_window->link);
157
158         func_hwc_window = &private_module->func_hwc_window;
159         func_hwc_window->hwc_window_destroy(private_hwc_window->hwc_window_backend);
160
161         free(private_hwc_window);
162 }
163
164 EXTERN void
165 tdm_hwc_window_destroy(tdm_hwc_window *hwc_window)
166 {
167         tdm_private_display *private_display;
168         tdm_private_output *private_output;
169         tdm_private_hwc *private_hwc;
170         tdm_private_hwc_window *private_hwc_window;
171
172         if (!hwc_window)
173                 return;
174
175         private_hwc_window = (tdm_private_hwc_window *)hwc_window;
176         private_hwc = private_hwc_window->private_hwc;
177         private_output = private_hwc->private_output;
178         private_display = private_output->private_display;
179
180         _pthread_mutex_lock(&private_display->lock);
181
182         tdm_hwc_window_destroy_internal(hwc_window);
183
184         _pthread_mutex_unlock(&private_display->lock);
185 }
186
187 EXTERN tbm_surface_queue_h
188 tdm_hwc_window_acquire_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
189 {
190         tdm_private_module *private_module;
191         tdm_func_hwc_window *func_hwc_window = NULL;
192         tbm_surface_queue_h queue = NULL;
193
194         HWC_WINDOW_FUNC_ENTRY_ERROR();
195
196         _pthread_mutex_lock(&private_display->lock);
197
198         private_module = private_output->private_module;
199         func_hwc_window = &private_module->func_hwc_window;
200
201         if (!func_hwc_window->hwc_window_acquire_buffer_queue) {
202                 /* LCOV_EXCL_START */
203                 _pthread_mutex_unlock(&private_display->lock);
204                 TDM_WRN("not implemented!!");
205                 if (error)
206                         *error = TDM_ERROR_NOT_IMPLEMENTED;
207                 return NULL;
208         }
209
210         queue = func_hwc_window->hwc_window_acquire_buffer_queue(private_hwc_window->hwc_window_backend, error);
211
212         _pthread_mutex_unlock(&private_display->lock);
213
214         return queue;
215 }
216
217 EXTERN void
218 tdm_hwc_window_release_buffer_queue(tdm_hwc_window *hwc_window, tbm_surface_queue_h queue)
219 {
220         tdm_private_module *private_module;
221         tdm_func_hwc_window *func_hwc_window = NULL;
222         tdm_private_display *private_display;
223         tdm_private_output *private_output;
224         tdm_private_hwc *private_hwc;
225         tdm_private_hwc_window *private_hwc_window;
226
227         if (!hwc_window)
228                 return;
229
230         private_hwc_window = (tdm_private_hwc_window *)hwc_window;
231         private_hwc = private_hwc_window->private_hwc;
232         private_output = private_hwc->private_output;
233         private_display = private_output->private_display;
234
235         TDM_RETURN_IF_FAIL(queue != NULL);
236
237         _pthread_mutex_lock(&private_display->lock);
238
239         private_module = private_output->private_module;
240         func_hwc_window = &private_module->func_hwc_window;
241
242         if (!func_hwc_window->hwc_window_release_buffer_queue) {
243                 _pthread_mutex_unlock(&private_display->lock);
244                 TDM_WRN("not implemented!!");
245                 return;
246         }
247
248         func_hwc_window->hwc_window_release_buffer_queue(private_hwc_window->hwc_window_backend, queue);
249
250         _pthread_mutex_unlock(&private_display->lock);
251
252         return;
253 }
254
255 EXTERN tdm_error
256 tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
257                                                                         tdm_hwc_window_composition composition_type)
258 {
259         tdm_private_module *private_module;
260         tdm_func_hwc_window *func_hwc_window = NULL;
261
262         HWC_WINDOW_FUNC_ENTRY();
263         TDM_RETURN_VAL_IF_FAIL(composition_type >= TDM_HWC_WIN_COMPOSITION_NONE, TDM_ERROR_INVALID_PARAMETER);
264         TDM_RETURN_VAL_IF_FAIL(composition_type <= TDM_HWC_WIN_COMPOSITION_VIDEO, TDM_ERROR_INVALID_PARAMETER);
265
266         _pthread_mutex_lock(&private_display->lock);
267
268         private_module = private_output->private_module;
269         func_hwc_window = &private_module->func_hwc_window;
270
271         if (!func_hwc_window->hwc_window_set_composition_type) {
272                 _pthread_mutex_unlock(&private_display->lock);
273                 TDM_WRN("not implemented!!");
274                 return TDM_ERROR_NOT_IMPLEMENTED;
275         }
276
277         ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
278
279         _pthread_mutex_unlock(&private_display->lock);
280
281         return ret;
282 }
283
284 EXTERN tdm_error
285 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
286 {
287         tdm_private_module *private_module;
288         tdm_func_hwc_window *func_hwc_window = NULL;
289
290         HWC_WINDOW_FUNC_ENTRY();
291         if (damage.num_rects > 0)
292                 TDM_RETURN_VAL_IF_FAIL(damage.rects != NULL, TDM_ERROR_INVALID_PARAMETER);
293
294         _pthread_mutex_lock(&private_display->lock);
295
296         private_module = private_output->private_module;
297         func_hwc_window = &private_module->func_hwc_window;
298
299         if (!func_hwc_window->hwc_window_set_buffer_damage) {
300                 _pthread_mutex_unlock(&private_display->lock);
301                 TDM_WRN("not implemented!!");
302                 return TDM_ERROR_NOT_IMPLEMENTED;
303         }
304
305         ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
306
307         _pthread_mutex_unlock(&private_display->lock);
308
309         return ret;
310 }
311
312
313 EXTERN tdm_error
314 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
315 {
316         tdm_private_module *private_module;
317         tdm_func_hwc_window *func_hwc_window = NULL;
318         char fmtstr[128];
319
320         HWC_WINDOW_FUNC_ENTRY();
321
322         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
323
324         _pthread_mutex_lock(&private_display->lock);
325
326         private_module = private_output->private_module;
327         func_hwc_window = &private_module->func_hwc_window;
328
329         if (!func_hwc_window->hwc_window_set_info) {
330                 _pthread_mutex_unlock(&private_display->lock);
331                 TDM_WRN("not implemented!!");
332                 return TDM_ERROR_NOT_IMPLEMENTED;
333         }
334
335         if (info->src_config.format)
336                 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
337         else
338                 snprintf(fmtstr, 128, "NONE");
339
340         TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
341                          private_hwc_window, info->src_config.size.h, info->src_config.size.v,
342                          info->src_config.pos.x, info->src_config.pos.y,
343                          info->src_config.pos.w, info->src_config.pos.h,
344                          fmtstr,
345                          info->dst_pos.x, info->dst_pos.y,
346                          info->dst_pos.w, info->dst_pos.h,
347                          info->transform);
348
349         ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
350
351         _pthread_mutex_unlock(&private_display->lock);
352
353         return ret;
354 }
355
356 EXTERN tdm_error
357 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
358 {
359         tdm_private_module *private_module;
360         tdm_func_hwc_window *func_hwc_window;
361
362         HWC_WINDOW_FUNC_ENTRY();
363
364         _pthread_mutex_lock(&private_display->lock);
365
366         if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
367                 char str[TDM_PATH_LEN];
368                 static int i;
369                 snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++);
370                 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
371         }
372
373         private_module = private_output->private_module;
374         func_hwc_window = &private_module->func_hwc_window;
375
376         if (!func_hwc_window->hwc_window_set_buffer) {
377                 _pthread_mutex_unlock(&private_display->lock);
378                 TDM_WRN("not implemented!!");
379                 return TDM_ERROR_NOT_IMPLEMENTED;
380         }
381
382         ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
383
384         _pthread_mutex_unlock(&private_display->lock);
385
386         return ret;
387 }
388
389 EXTERN tdm_error
390 tdm_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
391 {
392         tdm_private_module *private_module;
393         tdm_func_hwc_window *func_hwc_window = NULL;
394
395         HWC_WINDOW_FUNC_ENTRY();
396
397         TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
398
399         _pthread_mutex_lock(&private_display->lock);
400
401         private_module = private_output->private_module;
402         func_hwc_window = &private_module->func_hwc_window;
403
404         if (!func_hwc_window->hwc_window_get_property) {
405                 /* LCOV_EXCL_START */
406                 _pthread_mutex_unlock(&private_display->lock);
407                 TDM_WRN("not implemented!!");
408                 return TDM_ERROR_NOT_IMPLEMENTED;
409         }
410
411         ret = func_hwc_window->hwc_window_get_property(private_hwc_window->hwc_window_backend, id, value);
412
413         _pthread_mutex_unlock(&private_display->lock);
414
415         return ret;
416 }
417
418 EXTERN tdm_error
419 tdm_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
420 {
421         tdm_private_module *private_module;
422         tdm_func_hwc_window *func_hwc_window = NULL;
423
424         HWC_WINDOW_FUNC_ENTRY();
425
426         _pthread_mutex_lock(&private_display->lock);
427
428         private_module = private_output->private_module;
429         func_hwc_window = &private_module->func_hwc_window;
430
431         if (!func_hwc_window->hwc_window_set_property) {
432                 /* LCOV_EXCL_START */
433                 _pthread_mutex_unlock(&private_display->lock);
434                 TDM_WRN("not implemented!!");
435                 return TDM_ERROR_NOT_IMPLEMENTED;
436         }
437
438         ret = func_hwc_window->hwc_window_set_property(private_hwc_window->hwc_window_backend, id, value);
439
440         _pthread_mutex_unlock(&private_display->lock);
441
442         return ret;
443 }
444
445 EXTERN tdm_error
446 tdm_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints)
447 {
448         tdm_private_module *private_module;
449         tdm_func_hwc_window *func_hwc_window = NULL;
450
451         HWC_WINDOW_FUNC_ENTRY();
452
453         _pthread_mutex_lock(&private_display->lock);
454
455         private_module = private_output->private_module;
456         func_hwc_window = &private_module->func_hwc_window;
457
458         if (!func_hwc_window->hwc_window_get_constraints) {
459                 _pthread_mutex_unlock(&private_display->lock);
460                 TDM_WRN("not implemented!!");
461                 return TDM_ERROR_NOT_IMPLEMENTED;
462         }
463
464         ret = func_hwc_window->hwc_window_get_constraints(private_hwc_window->hwc_window_backend, constraints);
465
466         _pthread_mutex_unlock(&private_display->lock);
467
468         return ret;
469 }
470
471 EXTERN tdm_error
472 tdm_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name)
473 {
474         tdm_private_module *private_module;
475         tdm_func_hwc_window *func_hwc_window = NULL;
476
477         HWC_WINDOW_FUNC_ENTRY();
478
479         _pthread_mutex_lock(&private_display->lock);
480
481         private_module = private_output->private_module;
482         func_hwc_window = &private_module->func_hwc_window;
483
484         if (!func_hwc_window->hwc_window_get_constraints) {
485                 _pthread_mutex_unlock(&private_display->lock);
486                 TDM_WRN("not implemented!!");
487                 return TDM_ERROR_NOT_IMPLEMENTED;
488         }
489
490         ret = func_hwc_window->hwc_window_set_name(private_hwc_window->hwc_window_backend, name);
491
492         _pthread_mutex_unlock(&private_display->lock);
493
494         return ret;
495 }
496
497 tdm_error
498 tdm_hwc_window_set_cursor_image(tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr)
499 {
500         tdm_private_module *private_module;
501         tdm_func_hwc_window *func_hwc_window = NULL;
502
503         HWC_WINDOW_FUNC_ENTRY();
504
505         _pthread_mutex_lock(&private_display->lock);
506
507         private_module = private_output->private_module;
508         func_hwc_window = &private_module->func_hwc_window;
509
510         if (!func_hwc_window->hwc_window_set_cursor_image) {
511                 _pthread_mutex_unlock(&private_display->lock);
512                 TDM_WRN("not implemented!!");
513                 return TDM_ERROR_NOT_IMPLEMENTED;
514         }
515
516         ret = func_hwc_window->hwc_window_set_cursor_image(private_hwc_window->hwc_window_backend, width, height, stride, ptr);
517
518         _pthread_mutex_unlock(&private_display->lock);
519
520         return ret;
521 }
522 /* LCOV_EXCL_STOP */