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