31e62ad65c3258fa63daeced398d6c86d246780f
[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_get_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_get_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_get_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 tdm_error
218 tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
219                                                                         tdm_hwc_window_composition composition_type)
220 {
221         tdm_private_module *private_module;
222         tdm_func_hwc_window *func_hwc_window = NULL;
223
224         HWC_WINDOW_FUNC_ENTRY();
225         TDM_RETURN_VAL_IF_FAIL(composition_type >= TDM_COMPOSITION_NONE, TDM_ERROR_INVALID_PARAMETER);
226         TDM_RETURN_VAL_IF_FAIL(composition_type <= TDM_COMPOSITION_VIDEO, TDM_ERROR_INVALID_PARAMETER);
227
228         _pthread_mutex_lock(&private_display->lock);
229
230         private_module = private_output->private_module;
231         func_hwc_window = &private_module->func_hwc_window;
232
233         if (!func_hwc_window->hwc_window_set_composition_type) {
234                 _pthread_mutex_unlock(&private_display->lock);
235                 TDM_WRN("not implemented!!");
236                 return TDM_ERROR_NOT_IMPLEMENTED;
237         }
238
239         ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
240
241         _pthread_mutex_unlock(&private_display->lock);
242
243         return ret;
244 }
245
246 EXTERN tdm_error
247 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
248 {
249         tdm_private_module *private_module;
250         tdm_func_hwc_window *func_hwc_window = NULL;
251
252         HWC_WINDOW_FUNC_ENTRY();
253         if (damage.num_rects > 0)
254                 TDM_RETURN_VAL_IF_FAIL(damage.rects != NULL, TDM_ERROR_INVALID_PARAMETER);
255
256         _pthread_mutex_lock(&private_display->lock);
257
258         private_module = private_output->private_module;
259         func_hwc_window = &private_module->func_hwc_window;
260
261         if (!func_hwc_window->hwc_window_set_buffer_damage) {
262                 _pthread_mutex_unlock(&private_display->lock);
263                 TDM_WRN("not implemented!!");
264                 return TDM_ERROR_NOT_IMPLEMENTED;
265         }
266
267         ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
268
269         _pthread_mutex_unlock(&private_display->lock);
270
271         return ret;
272 }
273
274
275 EXTERN tdm_error
276 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
277 {
278         tdm_private_module *private_module;
279         tdm_func_hwc_window *func_hwc_window = NULL;
280         char fmtstr[128];
281
282         HWC_WINDOW_FUNC_ENTRY();
283
284         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
285
286         _pthread_mutex_lock(&private_display->lock);
287
288         private_module = private_output->private_module;
289         func_hwc_window = &private_module->func_hwc_window;
290
291         if (!func_hwc_window->hwc_window_set_info) {
292                 _pthread_mutex_unlock(&private_display->lock);
293                 TDM_WRN("not implemented!!");
294                 return TDM_ERROR_NOT_IMPLEMENTED;
295         }
296
297         if (info->src_config.format)
298                 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
299         else
300                 snprintf(fmtstr, 128, "NONE");
301
302         TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
303                          private_hwc_window, info->src_config.size.h, info->src_config.size.v,
304                          info->src_config.pos.x, info->src_config.pos.y,
305                          info->src_config.pos.w, info->src_config.pos.h,
306                          fmtstr,
307                          info->dst_pos.x, info->dst_pos.y,
308                          info->dst_pos.w, info->dst_pos.h,
309                          info->transform);
310
311         ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
312
313         _pthread_mutex_unlock(&private_display->lock);
314
315         return ret;
316 }
317
318 EXTERN tdm_error
319 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
320 {
321         tdm_private_module *private_module;
322         tdm_func_hwc_window *func_hwc_window;
323
324         HWC_WINDOW_FUNC_ENTRY();
325
326         _pthread_mutex_lock(&private_display->lock);
327
328         if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
329                 char str[TDM_PATH_LEN];
330                 static int i;
331                 snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++);
332                 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
333         }
334
335         private_module = private_output->private_module;
336         func_hwc_window = &private_module->func_hwc_window;
337
338         if (!func_hwc_window->hwc_window_set_buffer) {
339                 _pthread_mutex_unlock(&private_display->lock);
340                 TDM_WRN("not implemented!!");
341                 return TDM_ERROR_NOT_IMPLEMENTED;
342         }
343
344         ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
345
346         _pthread_mutex_unlock(&private_display->lock);
347
348         return ret;
349 }
350
351 EXTERN tdm_error
352 tdm_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
353 {
354         tdm_private_module *private_module;
355         tdm_func_hwc_window *func_hwc_window = NULL;
356
357         HWC_WINDOW_FUNC_ENTRY();
358
359         TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
360
361         _pthread_mutex_lock(&private_display->lock);
362
363         private_module = private_output->private_module;
364         func_hwc_window = &private_module->func_hwc_window;
365
366         if (!func_hwc_window->hwc_window_get_property) {
367                 /* LCOV_EXCL_START */
368                 _pthread_mutex_unlock(&private_display->lock);
369                 TDM_WRN("not implemented!!");
370                 return TDM_ERROR_NOT_IMPLEMENTED;
371         }
372
373         ret = func_hwc_window->hwc_window_get_property(private_hwc_window->hwc_window_backend, id, value);
374
375         _pthread_mutex_unlock(&private_display->lock);
376
377         return ret;
378 }
379
380 EXTERN tdm_error
381 tdm_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
382 {
383         tdm_private_module *private_module;
384         tdm_func_hwc_window *func_hwc_window = NULL;
385
386         HWC_WINDOW_FUNC_ENTRY();
387
388         _pthread_mutex_lock(&private_display->lock);
389
390         private_module = private_output->private_module;
391         func_hwc_window = &private_module->func_hwc_window;
392
393         if (!func_hwc_window->hwc_window_set_property) {
394                 /* LCOV_EXCL_START */
395                 _pthread_mutex_unlock(&private_display->lock);
396                 TDM_WRN("not implemented!!");
397                 return TDM_ERROR_NOT_IMPLEMENTED;
398         }
399
400         ret = func_hwc_window->hwc_window_set_property(private_hwc_window->hwc_window_backend, id, value);
401
402         _pthread_mutex_unlock(&private_display->lock);
403
404         return ret;
405 }
406
407 EXTERN tdm_error
408 tdm_hwc_window_get_preparation_types(tdm_hwc_window *hwc_window,
409                                                                          int *preparation_types)
410 {
411         tdm_private_module *private_module;
412         tdm_func_hwc_window *func_hwc_window = NULL;
413
414         HWC_WINDOW_FUNC_ENTRY();
415
416         _pthread_mutex_lock(&private_display->lock);
417
418         private_module = private_output->private_module;
419         func_hwc_window = &private_module->func_hwc_window;
420
421         if (!func_hwc_window->hwc_window_get_preparation_types) {
422                 _pthread_mutex_unlock(&private_display->lock);
423                 TDM_WRN("not implemented!!");
424                 return TDM_ERROR_NOT_IMPLEMENTED;
425         }
426
427         ret = func_hwc_window->hwc_window_get_preparation_types(private_hwc_window->hwc_window_backend, preparation_types);
428
429         _pthread_mutex_unlock(&private_display->lock);
430
431         return ret;
432 }
433 /* LCOV_EXCL_STOP */