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