[hwc] use TDM_OUTPUT_CAPABILITY_HWC instead of TDM_DISPLAY_CAPABILITY_HWC
[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                 _pthread_mutex_unlock(&private_display->lock);
91                 TDM_ERR("not implemented!!");
92                 if (error)
93                         *error = TDM_ERROR_NOT_IMPLEMENTED;
94                 return NULL;
95         }
96
97         queue = func_hwc_window->hwc_window_get_tbm_buffer_queue(private_hwc_window->hwc_window_backend, error);
98
99         _pthread_mutex_unlock(&private_display->lock);
100
101         return queue;
102 }
103
104 EXTERN tdm_error
105 tdm_hwc_window_set_zpos(tdm_hwc_window *hwc_window, uint32_t zpos)
106 {
107         tdm_func_hwc_window *func_hwc_window = NULL;
108
109         HWC_WINDOW_FUNC_ENTRY();
110
111         _pthread_mutex_lock(&private_display->lock);
112
113         func_hwc_window = &private_display->func_hwc_window;
114
115         if (!func_hwc_window->hwc_window_set_zpos) {
116                 _pthread_mutex_unlock(&private_display->lock);
117                 TDM_ERR("not implemented!!");
118                 return TDM_ERROR_NOT_IMPLEMENTED;
119         }
120
121         ret = func_hwc_window->hwc_window_set_zpos(private_hwc_window->hwc_window_backend, zpos);
122         if (ret == TDM_ERROR_NONE)
123                 private_hwc_window->zpos = zpos;
124
125         _pthread_mutex_unlock(&private_display->lock);
126
127         return ret;
128 }
129
130 EXTERN tdm_error
131 tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
132                                                                         tdm_hwc_window_composition composition_type)
133 {
134         tdm_func_hwc_window *func_hwc_window = NULL;
135
136         HWC_WINDOW_FUNC_ENTRY();
137
138         _pthread_mutex_lock(&private_display->lock);
139
140         func_hwc_window = &private_display->func_hwc_window;
141
142         if (!func_hwc_window->hwc_window_set_composition_type) {
143                 _pthread_mutex_unlock(&private_display->lock);
144                 TDM_ERR("not implemented!!");
145                 return TDM_ERROR_NOT_IMPLEMENTED;
146         }
147
148         ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type);
149
150         _pthread_mutex_unlock(&private_display->lock);
151
152         return ret;
153 }
154
155 EXTERN tdm_error
156 tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
157 {
158         tdm_func_hwc_window *func_hwc_window = NULL;
159
160         HWC_WINDOW_FUNC_ENTRY();
161
162         _pthread_mutex_lock(&private_display->lock);
163
164         func_hwc_window = &private_display->func_hwc_window;
165
166         if (!func_hwc_window->hwc_window_set_buffer_damage) {
167                 _pthread_mutex_unlock(&private_display->lock);
168                 TDM_ERR("not implemented!!");
169                 return TDM_ERROR_NOT_IMPLEMENTED;
170         }
171
172         ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage);
173
174         _pthread_mutex_unlock(&private_display->lock);
175
176         return ret;
177 }
178
179
180 EXTERN tdm_error
181 tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
182 {
183         tdm_func_hwc_window *func_hwc_window = NULL;
184         char fmtstr[128];
185
186         HWC_WINDOW_FUNC_ENTRY();
187
188         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
189
190         _pthread_mutex_lock(&private_display->lock);
191
192         func_hwc_window = &private_display->func_hwc_window;
193
194         if (!func_hwc_window->hwc_window_set_info) {
195                 _pthread_mutex_unlock(&private_display->lock);
196                 TDM_ERR("not implemented!!");
197                 return TDM_ERROR_NOT_IMPLEMENTED;
198         }
199
200         if (info->src_config.format)
201                 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
202         else
203                 snprintf(fmtstr, 128, "NONE");
204
205         TDM_INFO("hwc_window(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
206                          private_hwc_window, info->src_config.size.h, info->src_config.size.v,
207                          info->src_config.pos.x, info->src_config.pos.y,
208                          info->src_config.pos.w, info->src_config.pos.h,
209                          fmtstr,
210                          info->dst_pos.x, info->dst_pos.y,
211                          info->dst_pos.w, info->dst_pos.h,
212                          info->transform);
213
214         ret = func_hwc_window->hwc_window_set_info(private_hwc_window->hwc_window_backend, info);
215
216         _pthread_mutex_unlock(&private_display->lock);
217
218         return ret;
219 }
220
221 static void
222 _tdm_window_dump_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
223 {
224         tdm_private_hwc_window *private_window = (tdm_private_hwc_window *)hwc_window;
225         tdm_private_output *private_output = private_window->private_output;
226         unsigned int pipe;
227         uint32_t zpos;
228         char fname[PATH_MAX];
229
230         pipe = private_output->pipe;
231         zpos = private_window->zpos;
232
233         snprintf(fname, sizeof(fname), "tdm_%d_win_%d", pipe, zpos);
234
235         tbm_surface_internal_dump_buffer(buffer, fname);
236         TDM_DBG("%s dump excute", fname);
237
238         return;
239 }
240
241 EXTERN tdm_error
242 tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer)
243 {
244         tdm_func_hwc_window *func_hwc_window;
245
246         HWC_WINDOW_FUNC_ENTRY();
247
248         _pthread_mutex_lock(&private_display->lock);
249
250         if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) {
251                 char str[TDM_PATH_LEN];
252                 static int i;
253                 snprintf(str, TDM_PATH_LEN, "window_%d_%d_%03d",
254                                  private_output->index, private_hwc_window->zpos, i++);
255                 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
256         }
257
258         func_hwc_window = &private_display->func_hwc_window;
259
260         if (!func_hwc_window->hwc_window_set_buffer) {
261                 _pthread_mutex_unlock(&private_display->lock);
262                 TDM_ERR("not implemented!!");
263                 return TDM_ERROR_NOT_IMPLEMENTED;
264         }
265
266         /* dump buffer */
267         if (tdm_dump_enable && buffer)
268                 _tdm_window_dump_buffer(hwc_window, buffer);
269
270         ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer);
271
272         _pthread_mutex_unlock(&private_display->lock);
273
274         return ret;
275 }
276
277 INTERN tdm_hwc_window *
278 tdm_hwc_window_create_internal(tdm_private_output *private_output,
279                                                                    tdm_error *error)
280 {
281         tdm_private_display *private_display = private_output->private_display;
282         tdm_func_output *func_output = &private_display->func_output;
283         tdm_private_hwc_window *private_hwc_window = NULL;
284         tdm_hwc_window *hwc_window_backend = NULL;
285         tdm_error ret = TDM_ERROR_NONE;
286
287         TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL);
288
289         if (!func_output->output_hwc_create_window) {
290                 if (error)
291                         *error = TDM_ERROR_BAD_MODULE;
292                 return NULL;
293         }
294
295         hwc_window_backend = func_output->output_hwc_create_window(
296                                                  private_output->output_backend, &ret);
297         if (ret != TDM_ERROR_NONE) {
298                 if (error)
299                         *error = ret;
300                 return NULL;
301         }
302
303         private_hwc_window = calloc(1, sizeof(tdm_private_capture));
304         if (!private_hwc_window) {
305                 TDM_ERR("failed: alloc memory");
306                 func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend);
307                 if (error)
308                         *error = TDM_ERROR_OUT_OF_MEMORY;
309                 return NULL;
310         }
311
312         LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list);
313
314         private_hwc_window->private_display = private_display;
315         private_hwc_window->private_output = private_output;
316         private_hwc_window->hwc_window_backend = hwc_window_backend;
317
318         TDM_DBG("hwc_window(%p) create", private_hwc_window);
319
320         if (error)
321                 *error = TDM_ERROR_NONE;
322
323         return private_hwc_window;
324 }
325
326 INTERN tdm_error
327 tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window)
328 {
329         tdm_private_display *private_display;
330         tdm_private_output *private_output;
331         tdm_func_output *func_output;
332
333         TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
334
335         if (!private_hwc_window)
336                 return TDM_ERROR_OPERATION_FAILED;
337
338         private_display = private_hwc_window->private_display;
339         private_output = private_hwc_window->private_output;
340
341         LIST_DEL(&private_hwc_window->link);
342
343         func_output = &private_display->func_output;
344         func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend);
345
346         free(private_hwc_window);
347         return TDM_ERROR_NONE;
348 }
349
350 EXTERN tdm_error
351 tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
352 {
353         tdm_func_hwc_window *func_hwc_window = NULL;
354
355         HWC_WINDOW_FUNC_ENTRY();
356
357         _pthread_mutex_lock(&private_display->lock);
358
359         func_hwc_window = &private_display->func_hwc_window;
360
361         if (!func_hwc_window->hwc_window_set_flags) {
362                 _pthread_mutex_unlock(&private_display->lock);
363                 TDM_ERR("not implemented!!");
364                 return TDM_ERROR_NOT_IMPLEMENTED;
365         }
366
367         ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags);
368
369         _pthread_mutex_unlock(&private_display->lock);
370
371         return ret;
372 }
373
374 EXTERN tdm_error
375 tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
376 {
377         tdm_func_hwc_window *func_hwc_window = NULL;
378
379         HWC_WINDOW_FUNC_ENTRY();
380
381         _pthread_mutex_lock(&private_display->lock);
382
383         func_hwc_window = &private_display->func_hwc_window;
384
385         if (!func_hwc_window->hwc_window_unset_flags) {
386                 _pthread_mutex_unlock(&private_display->lock);
387                 TDM_ERR("not implemented!!");
388                 return TDM_ERROR_NOT_IMPLEMENTED;
389         }
390
391         ret = func_hwc_window->hwc_window_unset_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_video_get_capability(tdm_hwc_window *hwc_window,
400                                                                         tdm_hwc_window_video_capability *video_capability)
401 {
402         tdm_func_hwc_window *func_hwc_window = NULL;
403
404         HWC_WINDOW_FUNC_ENTRY();
405
406         TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
407
408         _pthread_mutex_lock(&private_display->lock);
409
410         func_hwc_window = &private_display->func_hwc_window;
411
412         if (!func_hwc_window->hwc_window_video_get_capability) {
413                 _pthread_mutex_unlock(&private_display->lock);
414                 TDM_ERR("not implemented!!");
415                 return TDM_ERROR_NOT_IMPLEMENTED;
416         }
417
418         ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend,
419                                                                                                                    video_capability);
420
421         _pthread_mutex_unlock(&private_display->lock);
422
423         return ret;
424 }
425
426 EXTERN tdm_error
427 tdm_hwc_window_video_get_supported_format(tdm_hwc_window *hwc_window,
428                                                                                   const tbm_format **formats,
429                                                                                   int *count)
430 {
431         tdm_func_hwc_window *func_hwc_window = NULL;
432
433         HWC_WINDOW_FUNC_ENTRY();
434
435         TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
436         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
437
438         _pthread_mutex_lock(&private_display->lock);
439
440         func_hwc_window = &private_display->func_hwc_window;
441
442         if (!func_hwc_window->hwc_window_video_get_supported_format) {
443                 _pthread_mutex_unlock(&private_display->lock);
444                 TDM_ERR("not implemented!!");
445                 return TDM_ERROR_NOT_IMPLEMENTED;
446         }
447
448         ret = func_hwc_window->hwc_window_video_get_supported_format(private_hwc_window->hwc_window_backend,
449                                                                                                                                  formats, count);
450
451         _pthread_mutex_unlock(&private_display->lock);
452
453         return ret;
454 }