hwc: change the type of the zpos
[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, int32_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         TDM_RETURN_VAL_IF_FAIL(composition_type >= TDM_COMPOSITION_NONE, TDM_ERROR_INVALID_PARAMETER);
142         TDM_RETURN_VAL_IF_FAIL(composition_type <= TDM_COMPOSITION_CURSOR, TDM_ERROR_INVALID_PARAMETER);
143
144         _pthread_mutex_lock(&private_display->lock);
145
146         func_hwc_window = &private_display->func_hwc_window;
147
148         if (!func_hwc_window->hwc_window_set_composition_type) {
149                 /* LCOV_EXCL_START */
150                 _pthread_mutex_unlock(&private_display->lock);
151                 TDM_ERR("not implemented!!");
152                 return TDM_ERROR_NOT_IMPLEMENTED;
153                 /* LCOV_EXCL_STOP */
154         }
155
156         ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
157
158         _pthread_mutex_unlock(&private_display->lock);
159
160         return ret;
161 }
162
163 EXTERN tdm_error
164 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
165 {
166         tdm_func_hwc_window *func_hwc_window = NULL;
167
168         HWC_WINDOW_FUNC_ENTRY();
169         if (damage.num_rects > 0)
170                 TDM_RETURN_VAL_IF_FAIL(damage.rects != NULL, TDM_ERROR_INVALID_PARAMETER);
171
172         _pthread_mutex_lock(&private_display->lock);
173
174         func_hwc_window = &private_display->func_hwc_window;
175
176         if (!func_hwc_window->hwc_window_set_buffer_damage) {
177                 /* LCOV_EXCL_START */
178                 _pthread_mutex_unlock(&private_display->lock);
179                 TDM_ERR("not implemented!!");
180                 return TDM_ERROR_NOT_IMPLEMENTED;
181                 /* LCOV_EXCL_STOP */
182         }
183
184         ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
185
186         _pthread_mutex_unlock(&private_display->lock);
187
188         return ret;
189 }
190
191
192 EXTERN tdm_error
193 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
194 {
195         tdm_func_hwc_window *func_hwc_window = NULL;
196         char fmtstr[128];
197
198         HWC_WINDOW_FUNC_ENTRY();
199
200         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
201
202         _pthread_mutex_lock(&private_display->lock);
203
204         func_hwc_window = &private_display->func_hwc_window;
205
206         if (!func_hwc_window->hwc_window_set_info) {
207                 /* LCOV_EXCL_START */
208                 _pthread_mutex_unlock(&private_display->lock);
209                 TDM_ERR("not implemented!!");
210                 return TDM_ERROR_NOT_IMPLEMENTED;
211                 /* LCOV_EXCL_STOP */
212         }
213
214         if (info->src_config.format)
215                 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
216         else
217                 snprintf(fmtstr, 128, "NONE");
218
219         TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
220                          private_hwc_window, info->src_config.size.h, info->src_config.size.v,
221                          info->src_config.pos.x, info->src_config.pos.y,
222                          info->src_config.pos.w, info->src_config.pos.h,
223                          fmtstr,
224                          info->dst_pos.x, info->dst_pos.y,
225                          info->dst_pos.w, info->dst_pos.h,
226                          info->transform);
227
228         ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
229
230         _pthread_mutex_unlock(&private_display->lock);
231
232         return ret;
233 }
234
235 /* LCOV_EXCL_START */
236 static void
237 _tdm_window_dump_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
238 {
239         tdm_private_hwc_window *private_window = (tdm_private_hwc_window *)hwc_window;
240         tdm_private_output *private_output = private_window->private_output;
241         unsigned int pipe;
242         uint32_t zpos;
243         char fname[PATH_MAX];
244
245         pipe = private_output->pipe;
246         zpos = private_window->zpos;
247
248         snprintf(fname, sizeof(fname), "tdm_%d_win_%d", pipe, zpos);
249
250         tbm_surface_internal_dump_buffer(buffer, fname);
251         TDM_DBG("%s dump excute", fname);
252
253         return;
254 }
255 /* LCOV_EXCL_STOP */
256
257 EXTERN tdm_error
258 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
259 {
260         tdm_func_hwc_window *func_hwc_window;
261
262         HWC_WINDOW_FUNC_ENTRY();
263
264         _pthread_mutex_lock(&private_display->lock);
265
266         if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
267                 /* LCOV_EXCL_START */
268                 char str[TDM_PATH_LEN];
269                 static int i;
270                 snprintf(str, TDM_PATH_LEN, "window_%d_%d_%03d",
271                                  private_output->index, private_hwc_window->zpos, i++);
272                 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
273                 /* LCOV_EXCL_STOP */
274         }
275
276         func_hwc_window = &private_display->func_hwc_window;
277
278         if (!func_hwc_window->hwc_window_set_buffer) {
279                 /* LCOV_EXCL_START */
280                 _pthread_mutex_unlock(&private_display->lock);
281                 TDM_ERR("not implemented!!");
282                 return TDM_ERROR_NOT_IMPLEMENTED;
283                 /* LCOV_EXCL_STOP */
284         }
285
286         /* dump buffer */
287         /* LCOV_EXCL_START */
288         if (tdm_dump_enable && buffer)
289                 _tdm_window_dump_buffer(hwc_window, buffer);
290         /* LCOV_EXCL_STOP */
291
292         ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
293
294         _pthread_mutex_unlock(&private_display->lock);
295
296         return ret;
297 }
298
299 INTERN tdm_hwc_window *
300 tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video,
301                                                                    tdm_error *error)
302 {
303         tdm_private_display *private_display = private_output->private_display;
304         tdm_func_output *func_output = &private_display->func_output;
305         tdm_private_hwc_window *private_hwc_window = NULL;
306         tdm_hwc_window *hwc_window_backend = NULL;
307         tdm_error ret = TDM_ERROR_NONE;
308
309         TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
310
311         if (!is_video) {
312                 if (!func_output->output_hwc_create_window) {
313                         /* LCOV_EXCL_START */
314                         if (error)
315                                 *error = TDM_ERROR_BAD_MODULE;
316                         return NULL;
317                         /* LCOV_EXCL_STOP */
318                 }
319
320                 hwc_window_backend = func_output->output_hwc_create_window(
321                                                  private_output->output_backend, &ret);
322                 if (ret != TDM_ERROR_NONE) {
323                         if (error)
324                                 *error = ret;
325                         return NULL;
326                 }
327         } else {
328                 if (!func_output->output_hwc_create_video_window) {
329                         /* LCOV_EXCL_START */
330                         if (error)
331                                 *error = TDM_ERROR_NOT_IMPLEMENTED;
332                         return NULL;
333                         /* LCOV_EXCL_STOP */
334                 }
335
336                 hwc_window_backend = func_output->output_hwc_create_video_window(
337                                                  private_output->output_backend, &ret);
338                 if (ret != TDM_ERROR_NONE) {
339                         if (error)
340                                 *error = ret;
341                         return NULL;
342                 }
343         }
344
345         private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window));
346         if (!private_hwc_window) {
347                 /* LCOV_EXCL_START */
348                 TDM_ERR("failed: alloc memory");
349                 func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend);
350                 if (error)
351                         *error = TDM_ERROR_OUT_OF_MEMORY;
352                 return NULL;
353                 /* LCOV_EXCL_STOP */
354         }
355
356         LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list);
357
358         private_hwc_window->private_display = private_display;
359         private_hwc_window->private_output = private_output;
360         private_hwc_window->hwc_window_backend = hwc_window_backend;
361
362         TDM_DBG("hwc_window(%p) create", private_hwc_window);
363
364         if (error)
365                 *error = TDM_ERROR_NONE;
366
367         return private_hwc_window;
368 }
369
370 INTERN tdm_error
371 tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window)
372 {
373         tdm_private_display *private_display;
374         tdm_private_output *private_output;
375         tdm_func_output *func_output;
376
377         TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
378
379         if (!private_hwc_window)
380                 return TDM_ERROR_OPERATION_FAILED;
381
382         private_display = private_hwc_window->private_display;
383         private_output = private_hwc_window->private_output;
384
385         LIST_DEL(&private_hwc_window->link);
386
387         func_output = &private_display->func_output;
388         func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend);
389
390         free(private_hwc_window);
391         return TDM_ERROR_NONE;
392 }
393
394 EXTERN tdm_error
395 tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
396 {
397         tdm_func_hwc_window *func_hwc_window = NULL;
398
399         HWC_WINDOW_FUNC_ENTRY();
400
401         _pthread_mutex_lock(&private_display->lock);
402
403         func_hwc_window = &private_display->func_hwc_window;
404
405         if (!func_hwc_window->hwc_window_set_flags) {
406                 /* LCOV_EXCL_START */
407                 _pthread_mutex_unlock(&private_display->lock);
408                 TDM_ERR("not implemented!!");
409                 return TDM_ERROR_NOT_IMPLEMENTED;
410                 /* LCOV_EXCL_STOP */
411         }
412
413         ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags);
414
415         _pthread_mutex_unlock(&private_display->lock);
416
417         return ret;
418 }
419
420 EXTERN tdm_error
421 tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
422 {
423         tdm_func_hwc_window *func_hwc_window = NULL;
424
425         HWC_WINDOW_FUNC_ENTRY();
426
427         _pthread_mutex_lock(&private_display->lock);
428
429         func_hwc_window = &private_display->func_hwc_window;
430
431         if (!func_hwc_window->hwc_window_unset_flags) {
432                 /* LCOV_EXCL_START */
433                 _pthread_mutex_unlock(&private_display->lock);
434                 TDM_ERR("not implemented!!");
435                 return TDM_ERROR_NOT_IMPLEMENTED;
436                 /* LCOV_EXCL_STOP */
437         }
438
439         ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags);
440
441         _pthread_mutex_unlock(&private_display->lock);
442
443         return ret;
444 }
445
446 EXTERN tdm_error
447 tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
448                                                                         tdm_hwc_window_video_capability *video_capability)
449 {
450         tdm_func_hwc_window *func_hwc_window = NULL;
451
452         HWC_WINDOW_FUNC_ENTRY();
453
454         TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
455
456         _pthread_mutex_lock(&private_display->lock);
457
458         func_hwc_window = &private_display->func_hwc_window;
459
460         if (!func_hwc_window->hwc_window_video_get_capability) {
461                 /* LCOV_EXCL_START */
462                 _pthread_mutex_unlock(&private_display->lock);
463                 TDM_ERR("not implemented!!");
464                 return TDM_ERROR_NOT_IMPLEMENTED;
465                 /* LCOV_EXCL_STOP */
466         }
467
468         ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend,
469                                                                                                                    video_capability);
470
471         _pthread_mutex_unlock(&private_display->lock);
472
473         return ret;
474 }
475
476 EXTERN tdm_error
477 tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window,
478                                                                                           const tdm_prop **props, int *count)
479 {
480         tdm_func_hwc_window *func_hwc_window = NULL;
481
482         HWC_WINDOW_FUNC_ENTRY();
483
484         TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
485         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
486
487         _pthread_mutex_lock(&private_display->lock);
488
489         func_hwc_window = &private_display->func_hwc_window;
490
491         if (!func_hwc_window->hwc_window_video_get_available_properties) {
492                 /* LCOV_EXCL_START */
493                 _pthread_mutex_unlock(&private_display->lock);
494                 TDM_ERR("not implemented!!");
495                 return TDM_ERROR_NOT_IMPLEMENTED;
496                 /* LCOV_EXCL_STOP */
497         }
498
499         ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend,
500                                                                                                                                          props, count);
501
502         _pthread_mutex_unlock(&private_display->lock);
503
504         return ret;
505 }
506
507 EXTERN tdm_error
508 tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window,
509                                                                         unsigned int id, tdm_value *value)
510 {
511         tdm_func_hwc_window *func_hwc_window = NULL;
512
513         HWC_WINDOW_FUNC_ENTRY();
514
515         TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
516
517         _pthread_mutex_lock(&private_display->lock);
518
519         func_hwc_window = &private_display->func_hwc_window;
520
521         if (!func_hwc_window->hwc_window_video_get_property) {
522                 /* LCOV_EXCL_START */
523                 _pthread_mutex_unlock(&private_display->lock);
524                 TDM_ERR("not implemented!!");
525                 return TDM_ERROR_NOT_IMPLEMENTED;
526                 /* LCOV_EXCL_STOP */
527         }
528
529         ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend,
530                                                                                                                  id, value);
531
532         _pthread_mutex_unlock(&private_display->lock);
533
534         return ret;
535 }
536
537 EXTERN tdm_error
538 tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window,
539                                                                         unsigned int id, tdm_value value)
540 {
541         tdm_func_hwc_window *func_hwc_window = NULL;
542
543         HWC_WINDOW_FUNC_ENTRY();
544
545         _pthread_mutex_lock(&private_display->lock);
546
547         func_hwc_window = &private_display->func_hwc_window;
548
549         if (!func_hwc_window->hwc_window_video_set_property) {
550                 /* LCOV_EXCL_START */
551                 _pthread_mutex_unlock(&private_display->lock);
552                 TDM_ERR("not implemented!!");
553                 return TDM_ERROR_NOT_IMPLEMENTED;
554                 /* LCOV_EXCL_STOP */
555         }
556
557         ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend,
558                                                                                                                  id, value);
559
560         _pthread_mutex_unlock(&private_display->lock);
561
562         return ret;
563 }