apply wayland coding style
[platform/core/uifw/libtdm.git] / src / tdm_display.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
44 #define COUNT_MAX   10
45
46 #define DISPLAY_FUNC_ENTRY() \
47     tdm_private_display *private_display; \
48     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
49     TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
50     private_display = (tdm_private_display*)dpy;
51
52 #define DISPLAY_FUNC_ENTRY_ERROR() \
53     tdm_private_display *private_display; \
54     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
55     TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
56     private_display = (tdm_private_display*)dpy;
57
58 #define OUTPUT_FUNC_ENTRY() \
59     tdm_private_display *private_display; \
60     tdm_private_output *private_output; \
61     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
62     TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
63     private_output = (tdm_private_output*)output; \
64     private_display = private_output->private_display
65
66 #define OUTPUT_FUNC_ENTRY_ERROR() \
67     tdm_private_display *private_display; \
68     tdm_private_output *private_output; \
69     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
70     TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
71     private_output = (tdm_private_output*)output; \
72     private_display = private_output->private_display
73
74 #define LAYER_FUNC_ENTRY() \
75     tdm_private_display *private_display; \
76     tdm_private_output *private_output; \
77     tdm_private_layer *private_layer; \
78     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
79     TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
80     private_layer = (tdm_private_layer*)layer; \
81     private_output = private_layer->private_output; \
82     private_display = private_output->private_display
83
84 #define LAYER_FUNC_ENTRY_ERROR() \
85     tdm_private_display *private_display; \
86     tdm_private_output *private_output; \
87     tdm_private_layer *private_layer; \
88     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
89     TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
90     private_layer = (tdm_private_layer*)layer; \
91     private_output = private_layer->private_output; \
92     private_display = private_output->private_display
93
94 #define LAYER_FUNC_ENTRY_VOID_RETURN() \
95     tdm_private_display *private_display; \
96     tdm_private_output *private_output; \
97     tdm_private_layer *private_layer; \
98     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
99     TDM_RETURN_IF_FAIL(layer != NULL); \
100     private_layer = (tdm_private_layer*)layer; \
101     private_output = private_layer->private_output; \
102     private_display = private_output->private_display
103
104 EXTERN tdm_error
105 tdm_display_get_capabilities(tdm_display *dpy,
106                              tdm_display_capability *capabilities)
107 {
108         DISPLAY_FUNC_ENTRY();
109
110         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
111
112         pthread_mutex_lock(&private_display->lock);
113
114         *capabilities = private_display->capabilities;
115
116         pthread_mutex_unlock(&private_display->lock);
117
118         return ret;
119 }
120
121 EXTERN tdm_error
122 tdm_display_get_pp_capabilities(tdm_display *dpy,
123                                 tdm_pp_capability *capabilities)
124 {
125         DISPLAY_FUNC_ENTRY();
126
127         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
128
129         pthread_mutex_lock(&private_display->lock);
130
131         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
132                 TDM_ERR("no pp capability");
133                 pthread_mutex_unlock(&private_display->lock);
134                 return TDM_ERROR_NO_CAPABILITY;
135         }
136
137         *capabilities = private_display->caps_pp.capabilities;
138
139         pthread_mutex_unlock(&private_display->lock);
140
141         return ret;
142 }
143
144 EXTERN tdm_error
145 tdm_display_get_pp_available_formats(tdm_display *dpy,
146                                      const tbm_format **formats, int *count)
147 {
148         DISPLAY_FUNC_ENTRY();
149
150         TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
151         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
152
153         pthread_mutex_lock(&private_display->lock);
154
155         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
156                 TDM_ERR("no pp capability");
157                 pthread_mutex_unlock(&private_display->lock);
158                 return TDM_ERROR_NO_CAPABILITY;
159         }
160
161         *formats = (const tbm_format *)private_display->caps_pp.formats;
162         *count = private_display->caps_pp.format_count;
163
164         pthread_mutex_unlock(&private_display->lock);
165
166         return ret;
167 }
168
169 EXTERN tdm_error
170 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
171                                   int *max_w, int *max_h, int *preferred_align)
172 {
173         DISPLAY_FUNC_ENTRY();
174
175         pthread_mutex_lock(&private_display->lock);
176
177         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
178                 TDM_ERR("no pp capability");
179                 pthread_mutex_unlock(&private_display->lock);
180                 return TDM_ERROR_NO_CAPABILITY;
181         }
182
183         if (min_w)
184                 *min_w = private_display->caps_pp.min_w;
185         if (min_h)
186                 *min_h = private_display->caps_pp.min_h;
187         if (max_w)
188                 *max_w = private_display->caps_pp.max_w;
189         if (max_h)
190                 *max_h = private_display->caps_pp.max_h;
191         if (preferred_align)
192                 *preferred_align = private_display->caps_pp.preferred_align;
193
194         pthread_mutex_unlock(&private_display->lock);
195
196         return ret;
197 }
198
199 EXTERN tdm_error
200 tdm_display_get_capture_capabilities(tdm_display *dpy,
201                                      tdm_capture_capability *capabilities)
202 {
203         DISPLAY_FUNC_ENTRY();
204
205         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
206
207         pthread_mutex_lock(&private_display->lock);
208
209         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
210                 TDM_ERR("no capture capability");
211                 pthread_mutex_unlock(&private_display->lock);
212                 return TDM_ERROR_NO_CAPABILITY;
213         }
214
215         *capabilities = private_display->caps_capture.capabilities;
216
217         pthread_mutex_unlock(&private_display->lock);
218
219         return ret;
220 }
221
222 EXTERN tdm_error
223 tdm_display_get_catpure_available_formats(tdm_display *dpy,
224                 const tbm_format **formats, int *count)
225 {
226         DISPLAY_FUNC_ENTRY();
227
228         TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
229         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
230
231         pthread_mutex_lock(&private_display->lock);
232
233         if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
234                 TDM_ERR("no capture capability");
235                 pthread_mutex_unlock(&private_display->lock);
236                 return TDM_ERROR_NO_CAPABILITY;
237         }
238
239         *formats = (const tbm_format *)private_display->caps_capture.formats;
240         *count = private_display->caps_capture.format_count;
241
242         pthread_mutex_unlock(&private_display->lock);
243
244         return ret;
245 }
246
247 EXTERN tdm_error
248 tdm_display_get_output_count(tdm_display *dpy, int *count)
249 {
250         tdm_private_output *private_output = NULL;
251
252         DISPLAY_FUNC_ENTRY();
253
254         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
255
256         pthread_mutex_lock(&private_display->lock);
257
258         *count = 0;
259         LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
260         (*count)++;
261
262         if (*count == 0) {
263                 pthread_mutex_unlock(&private_display->lock);
264                 return TDM_ERROR_NONE;
265         }
266
267         pthread_mutex_unlock(&private_display->lock);
268
269         return ret;
270 }
271
272
273 EXTERN tdm_output *
274 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
275 {
276         tdm_private_output *private_output = NULL;
277         int i = 0;
278
279         DISPLAY_FUNC_ENTRY_ERROR();
280
281         pthread_mutex_lock(&private_display->lock);
282
283         if (error)
284                 *error = TDM_ERROR_NONE;
285
286         i = 0;
287         LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
288                 if (i == index) {
289                         pthread_mutex_unlock(&private_display->lock);
290                         return private_output;
291                 }
292                 i++;
293         }
294
295         pthread_mutex_unlock(&private_display->lock);
296
297         return NULL;
298 }
299
300 EXTERN tdm_error
301 tdm_display_get_fd(tdm_display *dpy, int *fd)
302 {
303         tdm_func_display *func_display;
304         DISPLAY_FUNC_ENTRY();
305
306         TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
307
308         pthread_mutex_lock(&private_display->lock);
309
310         func_display = &private_display->func_display;
311
312         if (!func_display->display_get_fd) {
313                 pthread_mutex_unlock(&private_display->lock);
314                 return TDM_ERROR_NONE;
315         }
316
317         ret = func_display->display_get_fd(private_display->bdata, fd);
318
319         pthread_mutex_unlock(&private_display->lock);
320
321         return ret;
322 }
323
324 EXTERN tdm_error
325 tdm_display_handle_events(tdm_display *dpy)
326 {
327         tdm_func_display *func_display;
328         DISPLAY_FUNC_ENTRY();
329
330         pthread_mutex_lock(&private_display->lock);
331
332         func_display = &private_display->func_display;
333
334         if (!func_display->display_handle_events) {
335                 pthread_mutex_unlock(&private_display->lock);
336                 return TDM_ERROR_NONE;
337         }
338
339         ret = func_display->display_handle_events(private_display->bdata);
340
341         pthread_mutex_unlock(&private_display->lock);
342
343         return ret;
344 }
345
346 EXTERN tdm_pp *
347 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
348 {
349         tdm_pp *pp;
350
351         DISPLAY_FUNC_ENTRY_ERROR();
352
353         pthread_mutex_lock(&private_display->lock);
354
355         pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
356
357         pthread_mutex_unlock(&private_display->lock);
358
359         return pp;
360 }
361
362 EXTERN tdm_error
363 tdm_output_get_model_info(tdm_output *output, const char **maker,
364                           const char **model, const char **name)
365 {
366         OUTPUT_FUNC_ENTRY();
367
368         pthread_mutex_lock(&private_display->lock);
369
370         if (maker)
371                 *maker = private_output->caps.maker;
372         if (model)
373                 *model = private_output->caps.model;
374         if (name)
375                 *name = private_output->caps.name;
376
377         pthread_mutex_unlock(&private_display->lock);
378
379         return ret;
380 }
381
382 EXTERN tdm_error
383 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
384 {
385         OUTPUT_FUNC_ENTRY();
386
387         TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
388
389         pthread_mutex_lock(&private_display->lock);
390
391         *status = private_output->caps.status;
392
393         pthread_mutex_unlock(&private_display->lock);
394
395         return ret;
396 }
397
398 EXTERN tdm_error
399 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
400 {
401         OUTPUT_FUNC_ENTRY();
402
403         TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
404
405         pthread_mutex_lock(&private_display->lock);
406
407         *type = private_output->caps.type;
408
409         pthread_mutex_unlock(&private_display->lock);
410
411         return ret;
412 }
413
414 EXTERN tdm_error
415 tdm_output_get_layer_count(tdm_output *output, int *count)
416 {
417         tdm_private_layer *private_layer = NULL;
418
419         OUTPUT_FUNC_ENTRY();
420
421         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
422
423         pthread_mutex_lock(&private_display->lock);
424
425         *count = 0;
426         LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
427         (*count)++;
428         if (*count == 0) {
429                 pthread_mutex_unlock(&private_display->lock);
430                 return TDM_ERROR_NONE;
431         }
432
433         pthread_mutex_unlock(&private_display->lock);
434
435         return ret;
436 }
437
438
439 EXTERN tdm_layer *
440 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
441 {
442         tdm_private_layer *private_layer = NULL;
443         int i = 0;
444
445         OUTPUT_FUNC_ENTRY_ERROR();
446
447         pthread_mutex_lock(&private_display->lock);
448
449         if (error)
450                 *error = TDM_ERROR_NONE;
451
452         LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
453                 if (i == index) {
454                         pthread_mutex_unlock(&private_display->lock);
455                         return private_layer;
456                 }
457                 i++;
458         }
459
460         pthread_mutex_unlock(&private_display->lock);
461
462         return NULL;
463 }
464
465 EXTERN tdm_error
466 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
467                                     int *count)
468 {
469         OUTPUT_FUNC_ENTRY();
470
471         TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
472         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
473
474         pthread_mutex_lock(&private_display->lock);
475
476         *props = (const tdm_prop *)private_output->caps.props;
477         *count = private_output->caps.prop_count;
478
479         pthread_mutex_unlock(&private_display->lock);
480
481         return ret;
482 }
483
484 EXTERN tdm_error
485 tdm_output_get_available_modes(tdm_output *output,
486                                const tdm_output_mode **modes, int *count)
487 {
488         OUTPUT_FUNC_ENTRY();
489
490         TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
491         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
492
493         pthread_mutex_lock(&private_display->lock);
494
495         *modes = (const tdm_output_mode *)private_output->caps.modes;
496         *count = private_output->caps.mode_count;
497
498         pthread_mutex_unlock(&private_display->lock);
499
500         return ret;
501 }
502
503 EXTERN tdm_error
504 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
505                               int *max_w, int *max_h, int *preferred_align)
506 {
507         OUTPUT_FUNC_ENTRY();
508
509         pthread_mutex_lock(&private_display->lock);
510
511         if (min_w)
512                 *min_w = private_output->caps.min_w;
513         if (min_h)
514                 *min_h = private_output->caps.min_h;
515         if (max_w)
516                 *max_w = private_output->caps.max_w;
517         if (max_h)
518                 *max_h = private_output->caps.max_h;
519         if (preferred_align)
520                 *preferred_align = private_output->caps.preferred_align;
521
522         pthread_mutex_unlock(&private_display->lock);
523
524         return ret;
525 }
526
527 EXTERN tdm_error
528 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
529                              unsigned int *mmHeight)
530 {
531         OUTPUT_FUNC_ENTRY();
532
533         pthread_mutex_lock(&private_display->lock);
534
535         if (mmWidth)
536                 *mmWidth = private_output->caps.mmWidth;
537         if (mmHeight)
538                 *mmHeight = private_output->caps.mmHeight;
539
540         pthread_mutex_unlock(&private_display->lock);
541
542         return ret;
543 }
544
545 EXTERN tdm_error
546 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
547 {
548         OUTPUT_FUNC_ENTRY();
549         TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
550
551         pthread_mutex_lock(&private_display->lock);
552
553         *subpixel = private_output->caps.subpixel;
554
555         pthread_mutex_unlock(&private_display->lock);
556
557         return ret;
558 }
559
560 EXTERN tdm_error
561 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
562 {
563         OUTPUT_FUNC_ENTRY();
564         TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
565
566         pthread_mutex_lock(&private_display->lock);
567
568         *pipe = private_output->pipe;
569
570         pthread_mutex_unlock(&private_display->lock);
571
572         return ret;
573 }
574
575
576 EXTERN tdm_error
577 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
578 {
579         tdm_func_output *func_output;
580         OUTPUT_FUNC_ENTRY();
581
582         pthread_mutex_lock(&private_display->lock);
583
584         func_output = &private_display->func_output;
585
586         if (!func_output->output_set_property) {
587                 pthread_mutex_unlock(&private_display->lock);
588                 return TDM_ERROR_NONE;
589         }
590
591         ret = func_output->output_set_property(private_output->output_backend, id,
592                                                value);
593
594         pthread_mutex_unlock(&private_display->lock);
595
596         return ret;
597 }
598
599 EXTERN tdm_error
600 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
601 {
602         tdm_func_output *func_output;
603         OUTPUT_FUNC_ENTRY();
604
605         TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
606
607         pthread_mutex_lock(&private_display->lock);
608
609         func_output = &private_display->func_output;
610
611         if (!func_output->output_get_property) {
612                 pthread_mutex_unlock(&private_display->lock);
613                 return TDM_ERROR_NONE;
614         }
615
616         ret = func_output->output_get_property(private_output->output_backend, id,
617                                                value);
618
619         pthread_mutex_unlock(&private_display->lock);
620
621         return ret;
622 }
623
624 static void
625 _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
626                       unsigned int tv_sec, unsigned int tv_usec, void *user_data)
627 {
628         tdm_private_vblank_handler *vblank_handler = user_data;
629         tdm_private_display *private_display;
630
631         TDM_RETURN_IF_FAIL(vblank_handler);
632
633         private_display = vblank_handler->private_output->private_display;
634
635         if (vblank_handler->func) {
636                 pthread_mutex_unlock(&private_display->lock);
637                 vblank_handler->func(vblank_handler->private_output, sequence,
638                                      tv_sec, tv_usec, vblank_handler->user_data);
639                 pthread_mutex_lock(&private_display->lock);
640         }
641
642         LIST_DEL(&vblank_handler->link);
643         free(vblank_handler);
644 }
645
646 static void
647 _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
648                       unsigned int tv_sec, unsigned int tv_usec, void *user_data)
649 {
650         tdm_private_commit_handler *commit_handler = user_data;
651         tdm_private_display *private_display;
652         tdm_private_output *private_output;
653         tdm_private_layer *private_layer = NULL;
654
655         TDM_RETURN_IF_FAIL(commit_handler);
656
657         private_output = commit_handler->private_output;
658         private_display = private_output->private_display;
659
660         LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
661                 if (!private_layer->waiting_buffer)
662                         continue;
663
664                 if (private_layer->showing_buffer) {
665                         pthread_mutex_unlock(&private_display->lock);
666                         tdm_buffer_unref_backend(private_layer->showing_buffer);
667                         pthread_mutex_lock(&private_display->lock);
668
669                         if (private_layer->buffer_queue) {
670                                 pthread_mutex_unlock(&private_display->lock);
671                                 tbm_surface_queue_release(private_layer->buffer_queue,
672                                                           private_layer->showing_buffer);
673                                 pthread_mutex_lock(&private_display->lock);
674                         }
675                 }
676
677                 private_layer->showing_buffer = private_layer->waiting_buffer;
678                 private_layer->waiting_buffer = NULL;
679         }
680
681         if (commit_handler->func) {
682                 pthread_mutex_unlock(&private_display->lock);
683                 commit_handler->func(private_output, sequence,
684                                      tv_sec, tv_usec, commit_handler->user_data);
685                 pthread_mutex_lock(&private_display->lock);
686         }
687
688         LIST_DEL(&commit_handler->link);
689         free(commit_handler);
690 }
691
692 EXTERN tdm_error
693 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
694                        tdm_output_vblank_handler func, void *user_data)
695 {
696         tdm_func_output *func_output;
697         tdm_private_vblank_handler *vblank_handler;
698         OUTPUT_FUNC_ENTRY();
699
700         pthread_mutex_lock(&private_display->lock);
701
702         func_output = &private_display->func_output;
703
704         if (!func_output->output_wait_vblank) {
705                 pthread_mutex_unlock(&private_display->lock);
706                 return TDM_ERROR_NONE;
707         }
708
709         vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
710         if (!vblank_handler) {
711                 TDM_ERR("failed: alloc memory");
712                 pthread_mutex_unlock(&private_display->lock);
713                 return TDM_ERROR_OUT_OF_MEMORY;
714         }
715
716         LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
717         vblank_handler->private_output = private_output;
718         vblank_handler->func = func;
719         vblank_handler->user_data = user_data;
720
721         ret = func_output->output_wait_vblank(private_output->output_backend, interval,
722                                               sync, vblank_handler);
723         if (ret != TDM_ERROR_NONE) {
724                 pthread_mutex_unlock(&private_display->lock);
725                 return ret;
726         }
727
728         if (!private_output->regist_vblank_cb) {
729                 private_output->regist_vblank_cb = 1;
730                 ret = func_output->output_set_vblank_handler(private_output->output_backend,
731                                 _tdm_output_cb_vblank);
732         }
733
734         pthread_mutex_unlock(&private_display->lock);
735
736         return ret;
737 }
738
739 static tdm_error
740 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
741                    void *user_data)
742 {
743         tdm_func_output *func_output;
744         tdm_private_commit_handler *commit_handler;
745         OUTPUT_FUNC_ENTRY();
746
747         func_output = &private_display->func_output;
748
749         if (!func_output->output_commit) {
750                 return TDM_ERROR_NONE;
751         }
752
753         commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
754         if (!commit_handler) {
755                 TDM_ERR("failed: alloc memory");
756                 return TDM_ERROR_OUT_OF_MEMORY;
757         }
758
759         LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
760         commit_handler->private_output = private_output;
761         commit_handler->func = func;
762         commit_handler->user_data = user_data;
763
764         ret = func_output->output_commit(private_output->output_backend, sync,
765                                          commit_handler);
766         if (ret != TDM_ERROR_NONE) {
767                 return ret;
768         }
769
770         if (!private_output->regist_commit_cb) {
771                 private_output->regist_commit_cb = 1;
772                 ret = func_output->output_set_commit_handler(private_output->output_backend,
773                                 _tdm_output_cb_commit);
774         }
775
776         return ret;
777 }
778
779 EXTERN tdm_error
780 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
781                   void *user_data)
782 {
783         OUTPUT_FUNC_ENTRY();
784
785         pthread_mutex_lock(&private_display->lock);
786
787         ret = _tdm_output_commit(output, sync, func, user_data);
788
789         pthread_mutex_unlock(&private_display->lock);
790
791         return ret;
792 }
793
794 EXTERN tdm_error
795 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
796 {
797         tdm_func_output *func_output;
798         OUTPUT_FUNC_ENTRY();
799
800         TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
801
802         pthread_mutex_lock(&private_display->lock);
803
804         func_output = &private_display->func_output;
805
806         if (!func_output->output_set_mode) {
807                 pthread_mutex_unlock(&private_display->lock);
808                 return TDM_ERROR_NONE;
809         }
810
811         ret = func_output->output_set_mode(private_output->output_backend, mode);
812
813         pthread_mutex_unlock(&private_display->lock);
814
815         return ret;
816 }
817
818 EXTERN tdm_error
819 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
820 {
821         tdm_func_output *func_output;
822         OUTPUT_FUNC_ENTRY();
823
824         TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
825
826         pthread_mutex_lock(&private_display->lock);
827
828         func_output = &private_display->func_output;
829
830         if (!func_output->output_get_mode) {
831                 pthread_mutex_unlock(&private_display->lock);
832                 return TDM_ERROR_NONE;
833         }
834
835         ret = func_output->output_get_mode(private_output->output_backend, mode);
836
837         pthread_mutex_unlock(&private_display->lock);
838
839         return ret;
840 }
841
842 EXTERN tdm_error
843 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
844 {
845         tdm_func_output *func_output;
846         OUTPUT_FUNC_ENTRY();
847
848         if (dpms_value < TDM_OUTPUT_DPMS_ON)
849                 dpms_value = TDM_OUTPUT_DPMS_ON;
850         else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
851                 dpms_value = TDM_OUTPUT_DPMS_OFF;
852
853         pthread_mutex_lock(&private_display->lock);
854
855         func_output = &private_display->func_output;
856
857         if (!func_output->output_set_dpms) {
858                 pthread_mutex_unlock(&private_display->lock);
859                 return TDM_ERROR_NONE;
860         }
861
862         ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
863
864         pthread_mutex_unlock(&private_display->lock);
865
866         return ret;
867 }
868
869 EXTERN tdm_error
870 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
871 {
872         tdm_func_output *func_output;
873         OUTPUT_FUNC_ENTRY();
874
875         TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
876
877         pthread_mutex_lock(&private_display->lock);
878
879         func_output = &private_display->func_output;
880
881         if (!func_output->output_get_dpms) {
882                 pthread_mutex_unlock(&private_display->lock);
883                 return TDM_ERROR_NONE;
884         }
885
886         ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
887
888         pthread_mutex_unlock(&private_display->lock);
889
890         return ret;
891 }
892
893 EXTERN tdm_capture *
894 tdm_output_create_capture(tdm_output *output, tdm_error *error)
895 {
896         tdm_capture *capture = NULL;
897
898         OUTPUT_FUNC_ENTRY_ERROR();
899
900         pthread_mutex_lock(&private_display->lock);
901
902         capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
903                         error);
904
905         pthread_mutex_unlock(&private_display->lock);
906
907         return capture;
908 }
909
910 EXTERN tdm_error
911 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
912 {
913         LAYER_FUNC_ENTRY();
914
915         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
916
917         pthread_mutex_lock(&private_display->lock);
918
919         *capabilities = private_layer->caps.capabilities;
920
921         pthread_mutex_unlock(&private_display->lock);
922
923         return ret;
924 }
925
926 EXTERN tdm_error
927 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
928                                 int *count)
929 {
930         LAYER_FUNC_ENTRY();
931
932         TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
933         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
934
935         pthread_mutex_lock(&private_display->lock);
936
937         *formats = (const tbm_format *)private_layer->caps.formats;
938         *count = private_layer->caps.format_count;
939
940         pthread_mutex_unlock(&private_display->lock);
941
942         return ret;
943 }
944
945 EXTERN tdm_error
946 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
947                                    int *count)
948 {
949         LAYER_FUNC_ENTRY();
950
951         TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
952         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
953
954         pthread_mutex_lock(&private_display->lock);
955
956         *props = (const tdm_prop *)private_layer->caps.props;
957         *count = private_layer->caps.prop_count;
958
959         pthread_mutex_unlock(&private_display->lock);
960
961         return ret;
962 }
963
964 EXTERN tdm_error
965 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
966 {
967         LAYER_FUNC_ENTRY();
968
969         TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
970
971         pthread_mutex_lock(&private_display->lock);
972
973         *zpos = private_layer->caps.zpos;
974
975         pthread_mutex_unlock(&private_display->lock);
976
977         return ret;
978 }
979
980 EXTERN tdm_error
981 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
982 {
983         tdm_func_layer *func_layer;
984         LAYER_FUNC_ENTRY();
985
986         pthread_mutex_lock(&private_display->lock);
987
988         func_layer = &private_display->func_layer;
989
990         if (!func_layer->layer_set_property) {
991                 pthread_mutex_unlock(&private_display->lock);
992                 return TDM_ERROR_NONE;
993         }
994
995         ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
996
997         pthread_mutex_unlock(&private_display->lock);
998
999         return ret;
1000 }
1001
1002 EXTERN tdm_error
1003 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1004 {
1005         tdm_func_layer *func_layer;
1006         LAYER_FUNC_ENTRY();
1007
1008         TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1009
1010         pthread_mutex_lock(&private_display->lock);
1011
1012         func_layer = &private_display->func_layer;
1013
1014         if (!func_layer->layer_get_property) {
1015                 pthread_mutex_unlock(&private_display->lock);
1016                 return TDM_ERROR_NONE;
1017         }
1018
1019         ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1020
1021         pthread_mutex_unlock(&private_display->lock);
1022
1023         return ret;
1024 }
1025
1026 EXTERN tdm_error
1027 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1028 {
1029         tdm_func_layer *func_layer;
1030         LAYER_FUNC_ENTRY();
1031
1032         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1033
1034         pthread_mutex_lock(&private_display->lock);
1035
1036         func_layer = &private_display->func_layer;
1037
1038         private_layer->usable = 0;
1039
1040         if (!func_layer->layer_set_info) {
1041                 pthread_mutex_unlock(&private_display->lock);
1042                 return TDM_ERROR_NONE;
1043         }
1044
1045         ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1046
1047         pthread_mutex_unlock(&private_display->lock);
1048
1049         return ret;
1050 }
1051
1052 EXTERN tdm_error
1053 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1054 {
1055         tdm_func_layer *func_layer;
1056         LAYER_FUNC_ENTRY();
1057
1058         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1059
1060         pthread_mutex_lock(&private_display->lock);
1061
1062         func_layer = &private_display->func_layer;
1063
1064         if (!func_layer->layer_get_info) {
1065                 pthread_mutex_unlock(&private_display->lock);
1066                 return TDM_ERROR_NONE;
1067         }
1068
1069         ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1070
1071         pthread_mutex_unlock(&private_display->lock);
1072
1073         return ret;
1074 }
1075
1076 EXTERN tdm_error
1077 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1078 {
1079         tdm_func_layer *func_layer;
1080         LAYER_FUNC_ENTRY();
1081
1082         TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1083
1084         pthread_mutex_lock(&private_display->lock);
1085
1086         func_layer = &private_display->func_layer;
1087
1088         private_layer->usable = 0;
1089
1090         if (!func_layer->layer_set_buffer) {
1091                 pthread_mutex_unlock(&private_display->lock);
1092                 return TDM_ERROR_NONE;
1093         }
1094
1095         if (private_layer->waiting_buffer) {
1096                 pthread_mutex_unlock(&private_display->lock);
1097                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1098                 pthread_mutex_lock(&private_display->lock);
1099         }
1100
1101         private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1102
1103         ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1104
1105         pthread_mutex_unlock(&private_display->lock);
1106
1107         return ret;
1108 }
1109
1110 EXTERN tdm_error
1111 tdm_layer_unset_buffer(tdm_layer *layer)
1112 {
1113         tdm_func_layer *func_layer;
1114         LAYER_FUNC_ENTRY();
1115
1116         pthread_mutex_lock(&private_display->lock);
1117
1118         func_layer = &private_display->func_layer;
1119
1120         if (private_layer->waiting_buffer) {
1121                 pthread_mutex_unlock(&private_display->lock);
1122                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1123                 pthread_mutex_lock(&private_display->lock);
1124                 private_layer->waiting_buffer = NULL;
1125         }
1126
1127         if (private_layer->showing_buffer) {
1128                 pthread_mutex_unlock(&private_display->lock);
1129                 tdm_buffer_unref_backend(private_layer->showing_buffer);
1130                 pthread_mutex_lock(&private_display->lock);
1131                 private_layer->showing_buffer = NULL;
1132         }
1133
1134         private_layer->usable = 1;
1135
1136         if (!func_layer->layer_unset_buffer) {
1137                 pthread_mutex_unlock(&private_display->lock);
1138                 return TDM_ERROR_NONE;
1139         }
1140
1141         ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1142
1143         pthread_mutex_unlock(&private_display->lock);
1144
1145         return ret;
1146 }
1147
1148 static void
1149 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1150 {
1151         TDM_RETURN_IF_FAIL(data != NULL);
1152         tdm_layer *layer = data;
1153         tdm_func_layer *func_layer;
1154         tbm_surface_h surface = NULL;
1155         LAYER_FUNC_ENTRY_VOID_RETURN();
1156
1157         pthread_mutex_lock(&private_display->lock);
1158
1159         func_layer = &private_display->func_layer;
1160         if (!func_layer->layer_set_buffer) {
1161                 pthread_mutex_unlock(&private_display->lock);
1162                 return;
1163         }
1164
1165         if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1166                     private_layer->buffer_queue, &surface) ||
1167             surface == NULL) {
1168                 TDM_ERR("tbm_surface_queue_acquire() failed surface:%p", surface);
1169                 pthread_mutex_unlock(&private_display->lock);
1170                 return;
1171         }
1172
1173         if (private_layer->waiting_buffer) {
1174                 pthread_mutex_unlock(&private_display->lock);
1175                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1176                 tbm_surface_queue_release(private_layer->buffer_queue,
1177                                           private_layer->waiting_buffer);
1178                 pthread_mutex_lock(&private_display->lock);
1179         }
1180
1181         private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1182
1183         func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1184
1185         ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1186         if (ret != TDM_ERROR_NONE)
1187                 TDM_ERR("_tdm_output_commit() is fail");
1188
1189         pthread_mutex_unlock(&private_display->lock);
1190 }
1191
1192 static void
1193 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1194 {
1195         TDM_RETURN_IF_FAIL(data != NULL);
1196         tdm_layer *layer = data;
1197         LAYER_FUNC_ENTRY_VOID_RETURN();
1198         TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1199
1200         pthread_mutex_lock(&private_display->lock);
1201
1202         if (private_layer->waiting_buffer) {
1203                 pthread_mutex_unlock(&private_display->lock);
1204                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1205                 tbm_surface_queue_release(private_layer->buffer_queue,
1206                                           private_layer->waiting_buffer);
1207                 pthread_mutex_lock(&private_display->lock);
1208         }
1209
1210         private_layer->buffer_queue = NULL;
1211
1212         pthread_mutex_unlock(&private_display->lock);
1213 }
1214
1215 EXTERN tdm_error
1216 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1217 {
1218         tdm_func_layer *func_layer;
1219         LAYER_FUNC_ENTRY();
1220
1221         TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1222
1223         pthread_mutex_lock(&private_display->lock);
1224
1225         func_layer = &private_display->func_layer;
1226
1227         private_layer->usable = 0;
1228
1229         if (!func_layer->layer_set_buffer) {
1230                 pthread_mutex_unlock(&private_display->lock);
1231                 return TDM_ERROR_NONE;
1232         }
1233
1234         if (buffer_queue == private_layer->buffer_queue) {
1235                 pthread_mutex_unlock(&private_display->lock);
1236                 return TDM_ERROR_NONE;
1237         }
1238
1239         if (private_layer->waiting_buffer) {
1240                 pthread_mutex_unlock(&private_display->lock);
1241                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1242                 tbm_surface_queue_release(private_layer->buffer_queue,
1243                                           private_layer->waiting_buffer);
1244                 private_layer->waiting_buffer = NULL;
1245                 pthread_mutex_lock(&private_display->lock);
1246         }
1247
1248         private_layer->buffer_queue = buffer_queue;
1249         tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue,
1250                                             _tbm_layer_queue_acquirable_cb,
1251                                             layer);
1252         tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue,
1253                                          _tbm_layer_queue_destroy_cb,
1254                                          layer);
1255         pthread_mutex_unlock(&private_display->lock);
1256
1257         return ret;
1258 }
1259
1260 EXTERN tdm_error
1261 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1262 {
1263         tdm_func_layer *func_layer;
1264         LAYER_FUNC_ENTRY();
1265
1266         pthread_mutex_lock(&private_display->lock);
1267
1268         func_layer = &private_display->func_layer;
1269
1270         if (private_layer->waiting_buffer) {
1271                 pthread_mutex_unlock(&private_display->lock);
1272                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1273                 tbm_surface_queue_release(private_layer->buffer_queue,
1274                                           private_layer->waiting_buffer);
1275                 private_layer->waiting_buffer = NULL;
1276                 pthread_mutex_lock(&private_display->lock);
1277         }
1278
1279         if (private_layer->showing_buffer) {
1280                 pthread_mutex_unlock(&private_display->lock);
1281                 tdm_buffer_unref_backend(private_layer->showing_buffer);
1282                 tbm_surface_queue_release(private_layer->buffer_queue,
1283                                           private_layer->showing_buffer);
1284                 pthread_mutex_lock(&private_display->lock);
1285                 private_layer->showing_buffer = NULL;
1286         }
1287
1288         tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, NULL, NULL);
1289         tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue, NULL, NULL);
1290         private_layer->buffer_queue = NULL;
1291         private_layer->usable = 1;
1292
1293         if (!func_layer->layer_unset_buffer) {
1294                 pthread_mutex_unlock(&private_display->lock);
1295                 return TDM_ERROR_NONE;
1296         }
1297
1298         ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1299
1300         pthread_mutex_unlock(&private_display->lock);
1301
1302         return ret;
1303 }
1304
1305 EXTERN tdm_error
1306 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1307 {
1308         LAYER_FUNC_ENTRY();
1309
1310         TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1311
1312         pthread_mutex_lock(&private_display->lock);
1313
1314         *usable = private_layer->usable;
1315
1316         pthread_mutex_unlock(&private_display->lock);
1317
1318         return ret;
1319 }
1320
1321 EXTERN tdm_error
1322 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1323 {
1324         tdm_func_layer *func_layer;
1325         LAYER_FUNC_ENTRY();
1326
1327         pthread_mutex_lock(&private_display->lock);
1328
1329         func_layer = &private_display->func_layer;
1330
1331         if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1332                 TDM_ERR("layer is not video layer");
1333                 pthread_mutex_unlock(&private_display->lock);
1334                 return TDM_ERROR_INVALID_PARAMETER;
1335         }
1336
1337         if (!func_layer->layer_set_video_pos) {
1338                 pthread_mutex_unlock(&private_display->lock);
1339                 return TDM_ERROR_NONE;
1340         }
1341
1342         ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1343
1344         pthread_mutex_unlock(&private_display->lock);
1345
1346         return ret;
1347 }
1348
1349 EXTERN tdm_capture *
1350 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1351 {
1352         tdm_capture *capture = NULL;
1353
1354         LAYER_FUNC_ENTRY_ERROR();
1355
1356         pthread_mutex_lock(&private_display->lock);
1357
1358         capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1359                         error);
1360
1361         pthread_mutex_unlock(&private_display->lock);
1362
1363         return capture;
1364 }