change deprecated APIs
[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                 if (tdm_debug_buffer)
681                         TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
682                                  private_layer, private_layer->waiting_buffer,
683                                  private_layer->showing_buffer);
684         }
685
686         if (commit_handler->func) {
687                 pthread_mutex_unlock(&private_display->lock);
688                 commit_handler->func(private_output, sequence,
689                                      tv_sec, tv_usec, commit_handler->user_data);
690                 pthread_mutex_lock(&private_display->lock);
691         }
692
693         LIST_DEL(&commit_handler->link);
694         free(commit_handler);
695 }
696
697 EXTERN tdm_error
698 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
699                        tdm_output_vblank_handler func, void *user_data)
700 {
701         tdm_func_output *func_output;
702         tdm_private_vblank_handler *vblank_handler;
703         OUTPUT_FUNC_ENTRY();
704
705         pthread_mutex_lock(&private_display->lock);
706
707         func_output = &private_display->func_output;
708
709         if (!func_output->output_wait_vblank) {
710                 pthread_mutex_unlock(&private_display->lock);
711                 return TDM_ERROR_NONE;
712         }
713
714         vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
715         if (!vblank_handler) {
716                 TDM_ERR("failed: alloc memory");
717                 pthread_mutex_unlock(&private_display->lock);
718                 return TDM_ERROR_OUT_OF_MEMORY;
719         }
720
721         LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
722         vblank_handler->private_output = private_output;
723         vblank_handler->func = func;
724         vblank_handler->user_data = user_data;
725
726         ret = func_output->output_wait_vblank(private_output->output_backend, interval,
727                                               sync, vblank_handler);
728         if (ret != TDM_ERROR_NONE) {
729                 pthread_mutex_unlock(&private_display->lock);
730                 return ret;
731         }
732
733         if (!private_output->regist_vblank_cb) {
734                 private_output->regist_vblank_cb = 1;
735                 ret = func_output->output_set_vblank_handler(private_output->output_backend,
736                                 _tdm_output_cb_vblank);
737         }
738
739         pthread_mutex_unlock(&private_display->lock);
740
741         return ret;
742 }
743
744 static tdm_error
745 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
746                    void *user_data)
747 {
748         tdm_func_output *func_output;
749         tdm_private_commit_handler *commit_handler;
750         OUTPUT_FUNC_ENTRY();
751
752         func_output = &private_display->func_output;
753
754         if (!func_output->output_commit) {
755                 return TDM_ERROR_NONE;
756         }
757
758         commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
759         if (!commit_handler) {
760                 TDM_ERR("failed: alloc memory");
761                 return TDM_ERROR_OUT_OF_MEMORY;
762         }
763
764         LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
765         commit_handler->private_output = private_output;
766         commit_handler->func = func;
767         commit_handler->user_data = user_data;
768
769         ret = func_output->output_commit(private_output->output_backend, sync,
770                                          commit_handler);
771         TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
772
773         if (!private_output->regist_commit_cb) {
774                 private_output->regist_commit_cb = 1;
775                 ret = func_output->output_set_commit_handler(private_output->output_backend,
776                                 _tdm_output_cb_commit);
777         }
778
779         return ret;
780 }
781
782 EXTERN tdm_error
783 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
784                   void *user_data)
785 {
786         OUTPUT_FUNC_ENTRY();
787
788         pthread_mutex_lock(&private_display->lock);
789
790         ret = _tdm_output_commit(output, sync, func, user_data);
791
792         pthread_mutex_unlock(&private_display->lock);
793
794         return ret;
795 }
796
797 EXTERN tdm_error
798 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
799 {
800         tdm_func_output *func_output;
801         OUTPUT_FUNC_ENTRY();
802
803         TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
804
805         pthread_mutex_lock(&private_display->lock);
806
807         func_output = &private_display->func_output;
808
809         if (!func_output->output_set_mode) {
810                 pthread_mutex_unlock(&private_display->lock);
811                 return TDM_ERROR_NONE;
812         }
813
814         ret = func_output->output_set_mode(private_output->output_backend, mode);
815
816         pthread_mutex_unlock(&private_display->lock);
817
818         return ret;
819 }
820
821 EXTERN tdm_error
822 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
823 {
824         tdm_func_output *func_output;
825         OUTPUT_FUNC_ENTRY();
826
827         TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
828
829         pthread_mutex_lock(&private_display->lock);
830
831         func_output = &private_display->func_output;
832
833         if (!func_output->output_get_mode) {
834                 pthread_mutex_unlock(&private_display->lock);
835                 return TDM_ERROR_NONE;
836         }
837
838         ret = func_output->output_get_mode(private_output->output_backend, mode);
839
840         pthread_mutex_unlock(&private_display->lock);
841
842         return ret;
843 }
844
845 EXTERN tdm_error
846 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
847 {
848         tdm_func_output *func_output;
849         OUTPUT_FUNC_ENTRY();
850
851         if (dpms_value < TDM_OUTPUT_DPMS_ON)
852                 dpms_value = TDM_OUTPUT_DPMS_ON;
853         else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
854                 dpms_value = TDM_OUTPUT_DPMS_OFF;
855
856         pthread_mutex_lock(&private_display->lock);
857
858         func_output = &private_display->func_output;
859
860         if (!func_output->output_set_dpms) {
861                 pthread_mutex_unlock(&private_display->lock);
862                 return TDM_ERROR_NONE;
863         }
864
865         ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
866
867         pthread_mutex_unlock(&private_display->lock);
868
869         return ret;
870 }
871
872 EXTERN tdm_error
873 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
874 {
875         tdm_func_output *func_output;
876         OUTPUT_FUNC_ENTRY();
877
878         TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
879
880         pthread_mutex_lock(&private_display->lock);
881
882         func_output = &private_display->func_output;
883
884         if (!func_output->output_get_dpms) {
885                 pthread_mutex_unlock(&private_display->lock);
886                 return TDM_ERROR_NONE;
887         }
888
889         ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
890
891         pthread_mutex_unlock(&private_display->lock);
892
893         return ret;
894 }
895
896 EXTERN tdm_capture *
897 tdm_output_create_capture(tdm_output *output, tdm_error *error)
898 {
899         tdm_capture *capture = NULL;
900
901         OUTPUT_FUNC_ENTRY_ERROR();
902
903         pthread_mutex_lock(&private_display->lock);
904
905         capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
906                         error);
907
908         pthread_mutex_unlock(&private_display->lock);
909
910         return capture;
911 }
912
913 EXTERN tdm_error
914 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
915 {
916         LAYER_FUNC_ENTRY();
917
918         TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
919
920         pthread_mutex_lock(&private_display->lock);
921
922         *capabilities = private_layer->caps.capabilities;
923
924         pthread_mutex_unlock(&private_display->lock);
925
926         return ret;
927 }
928
929 EXTERN tdm_error
930 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
931                                 int *count)
932 {
933         LAYER_FUNC_ENTRY();
934
935         TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
936         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
937
938         pthread_mutex_lock(&private_display->lock);
939
940         *formats = (const tbm_format *)private_layer->caps.formats;
941         *count = private_layer->caps.format_count;
942
943         pthread_mutex_unlock(&private_display->lock);
944
945         return ret;
946 }
947
948 EXTERN tdm_error
949 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
950                                    int *count)
951 {
952         LAYER_FUNC_ENTRY();
953
954         TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
955         TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
956
957         pthread_mutex_lock(&private_display->lock);
958
959         *props = (const tdm_prop *)private_layer->caps.props;
960         *count = private_layer->caps.prop_count;
961
962         pthread_mutex_unlock(&private_display->lock);
963
964         return ret;
965 }
966
967 EXTERN tdm_error
968 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
969 {
970         LAYER_FUNC_ENTRY();
971
972         TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
973
974         pthread_mutex_lock(&private_display->lock);
975
976         *zpos = private_layer->caps.zpos;
977
978         pthread_mutex_unlock(&private_display->lock);
979
980         return ret;
981 }
982
983 EXTERN tdm_error
984 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
985 {
986         tdm_func_layer *func_layer;
987         LAYER_FUNC_ENTRY();
988
989         pthread_mutex_lock(&private_display->lock);
990
991         func_layer = &private_display->func_layer;
992
993         if (!func_layer->layer_set_property) {
994                 pthread_mutex_unlock(&private_display->lock);
995                 return TDM_ERROR_NONE;
996         }
997
998         ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
999
1000         pthread_mutex_unlock(&private_display->lock);
1001
1002         return ret;
1003 }
1004
1005 EXTERN tdm_error
1006 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1007 {
1008         tdm_func_layer *func_layer;
1009         LAYER_FUNC_ENTRY();
1010
1011         TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1012
1013         pthread_mutex_lock(&private_display->lock);
1014
1015         func_layer = &private_display->func_layer;
1016
1017         if (!func_layer->layer_get_property) {
1018                 pthread_mutex_unlock(&private_display->lock);
1019                 return TDM_ERROR_NONE;
1020         }
1021
1022         ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1023
1024         pthread_mutex_unlock(&private_display->lock);
1025
1026         return ret;
1027 }
1028
1029 EXTERN tdm_error
1030 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1031 {
1032         tdm_func_layer *func_layer;
1033         LAYER_FUNC_ENTRY();
1034
1035         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1036
1037         pthread_mutex_lock(&private_display->lock);
1038
1039         func_layer = &private_display->func_layer;
1040
1041         private_layer->usable = 0;
1042
1043         if (!func_layer->layer_set_info) {
1044                 pthread_mutex_unlock(&private_display->lock);
1045                 return TDM_ERROR_NONE;
1046         }
1047
1048         TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1049                  private_layer, info->src_config.size.h, info->src_config.size.v,
1050                  info->src_config.pos.x, info->src_config.pos.y,
1051                  info->src_config.pos.w, info->src_config.pos.h,
1052                  FOURCC_STR(info->src_config.format),
1053                  info->dst_pos.x, info->dst_pos.y,
1054                  info->dst_pos.w, info->dst_pos.h,
1055                  info->transform);
1056
1057         ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1058         TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1059
1060         pthread_mutex_unlock(&private_display->lock);
1061
1062         return ret;
1063 }
1064
1065 EXTERN tdm_error
1066 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1067 {
1068         tdm_func_layer *func_layer;
1069         LAYER_FUNC_ENTRY();
1070
1071         TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1072
1073         pthread_mutex_lock(&private_display->lock);
1074
1075         func_layer = &private_display->func_layer;
1076
1077         if (!func_layer->layer_get_info) {
1078                 pthread_mutex_unlock(&private_display->lock);
1079                 return TDM_ERROR_NONE;
1080         }
1081
1082         ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1083
1084         pthread_mutex_unlock(&private_display->lock);
1085
1086         return ret;
1087 }
1088
1089 EXTERN tdm_error
1090 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1091 {
1092         tdm_func_layer *func_layer;
1093
1094         LAYER_FUNC_ENTRY();
1095
1096         TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1097
1098         pthread_mutex_lock(&private_display->lock);
1099
1100         func_layer = &private_display->func_layer;
1101
1102         private_layer->usable = 0;
1103
1104         if (!func_layer->layer_set_buffer) {
1105                 pthread_mutex_unlock(&private_display->lock);
1106                 return TDM_ERROR_NONE;
1107         }
1108
1109         ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1110         TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1111
1112         if (ret == TDM_ERROR_NONE) {
1113                 /* FIXME: should save to pending_buffer first. And after committing
1114                  * successfully, need to move to waiting_buffer.
1115                  */
1116                 if (private_layer->waiting_buffer) {
1117                         pthread_mutex_unlock(&private_display->lock);
1118                         tdm_buffer_unref_backend(private_layer->waiting_buffer);
1119                         pthread_mutex_lock(&private_display->lock);
1120                 }
1121
1122                 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1123                 if (tdm_debug_buffer)
1124                         TDM_INFO("layer(%p) waiting_buffer(%p)",
1125                                  private_layer, private_layer->waiting_buffer);
1126         }
1127
1128         pthread_mutex_unlock(&private_display->lock);
1129
1130         return ret;
1131 }
1132
1133 EXTERN tdm_error
1134 tdm_layer_unset_buffer(tdm_layer *layer)
1135 {
1136         tdm_func_layer *func_layer;
1137         LAYER_FUNC_ENTRY();
1138
1139         pthread_mutex_lock(&private_display->lock);
1140
1141         func_layer = &private_display->func_layer;
1142
1143         if (private_layer->waiting_buffer) {
1144                 pthread_mutex_unlock(&private_display->lock);
1145                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1146                 pthread_mutex_lock(&private_display->lock);
1147                 private_layer->waiting_buffer = NULL;
1148
1149                 if (tdm_debug_buffer)
1150                         TDM_INFO("layer(%p) waiting_buffer(%p)",
1151                                  private_layer, private_layer->waiting_buffer);
1152         }
1153
1154         if (private_layer->showing_buffer) {
1155                 pthread_mutex_unlock(&private_display->lock);
1156                 tdm_buffer_unref_backend(private_layer->showing_buffer);
1157                 pthread_mutex_lock(&private_display->lock);
1158                 private_layer->showing_buffer = NULL;
1159
1160                 if (tdm_debug_buffer)
1161                         TDM_INFO("layer(%p) showing_buffer(%p)",
1162                                  private_layer, private_layer->showing_buffer);
1163         }
1164
1165         private_layer->usable = 1;
1166
1167         if (!func_layer->layer_unset_buffer) {
1168                 pthread_mutex_unlock(&private_display->lock);
1169                 return TDM_ERROR_NONE;
1170         }
1171
1172         ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1173         TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1174
1175         pthread_mutex_unlock(&private_display->lock);
1176
1177         return ret;
1178 }
1179
1180 static void
1181 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1182 {
1183         TDM_RETURN_IF_FAIL(data != NULL);
1184         tdm_layer *layer = data;
1185         tdm_func_layer *func_layer;
1186         tbm_surface_h surface = NULL;
1187         LAYER_FUNC_ENTRY_VOID_RETURN();
1188
1189         pthread_mutex_lock(&private_display->lock);
1190
1191         func_layer = &private_display->func_layer;
1192         if (!func_layer->layer_set_buffer) {
1193                 pthread_mutex_unlock(&private_display->lock);
1194                 return;
1195         }
1196
1197         if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1198                     private_layer->buffer_queue, &surface) ||
1199             surface == NULL) {
1200                 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1201                         private_layer, surface);
1202                 pthread_mutex_unlock(&private_display->lock);
1203                 return;
1204         }
1205
1206         ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1207         TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1208
1209         if (ret == TDM_ERROR_NONE) {
1210                 if (private_layer->waiting_buffer) {
1211                         pthread_mutex_unlock(&private_display->lock);
1212                         tdm_buffer_unref_backend(private_layer->waiting_buffer);
1213                         tbm_surface_queue_release(private_layer->buffer_queue,
1214                                                   private_layer->waiting_buffer);
1215                         pthread_mutex_lock(&private_display->lock);
1216                 }
1217
1218                 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1219
1220                 if (tdm_debug_buffer)
1221                         TDM_INFO("layer(%p) waiting_buffer(%p)",
1222                                  private_layer, private_layer->waiting_buffer);
1223
1224                 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1225                 if (ret != TDM_ERROR_NONE)
1226                         TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1227         }
1228
1229         pthread_mutex_unlock(&private_display->lock);
1230 }
1231
1232 static void
1233 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1234 {
1235         TDM_RETURN_IF_FAIL(data != NULL);
1236         tdm_layer *layer = data;
1237         LAYER_FUNC_ENTRY_VOID_RETURN();
1238         TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1239
1240         pthread_mutex_lock(&private_display->lock);
1241
1242         if (private_layer->waiting_buffer) {
1243                 pthread_mutex_unlock(&private_display->lock);
1244                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1245                 tbm_surface_queue_release(private_layer->buffer_queue,
1246                                           private_layer->waiting_buffer);
1247                 pthread_mutex_lock(&private_display->lock);
1248         }
1249
1250         private_layer->buffer_queue = NULL;
1251
1252         pthread_mutex_unlock(&private_display->lock);
1253 }
1254
1255 EXTERN tdm_error
1256 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1257 {
1258         tdm_func_layer *func_layer;
1259         LAYER_FUNC_ENTRY();
1260
1261         TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1262
1263         pthread_mutex_lock(&private_display->lock);
1264
1265         func_layer = &private_display->func_layer;
1266
1267         private_layer->usable = 0;
1268
1269         if (!func_layer->layer_set_buffer) {
1270                 pthread_mutex_unlock(&private_display->lock);
1271                 return TDM_ERROR_NONE;
1272         }
1273
1274         if (buffer_queue == private_layer->buffer_queue) {
1275                 pthread_mutex_unlock(&private_display->lock);
1276                 return TDM_ERROR_NONE;
1277         }
1278
1279         if (private_layer->waiting_buffer) {
1280                 pthread_mutex_unlock(&private_display->lock);
1281                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1282                 tbm_surface_queue_release(private_layer->buffer_queue,
1283                                           private_layer->waiting_buffer);
1284                 private_layer->waiting_buffer = NULL;
1285                 pthread_mutex_lock(&private_display->lock);
1286
1287                 if (tdm_debug_buffer)
1288                         TDM_INFO("layer(%p) waiting_buffer(%p)",
1289                                  private_layer, private_layer->waiting_buffer);
1290         }
1291
1292         private_layer->buffer_queue = buffer_queue;
1293         tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1294                                             _tbm_layer_queue_acquirable_cb,
1295                                             layer);
1296         tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1297                                          _tbm_layer_queue_destroy_cb,
1298                                          layer);
1299         pthread_mutex_unlock(&private_display->lock);
1300
1301         return ret;
1302 }
1303
1304 EXTERN tdm_error
1305 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1306 {
1307         tdm_func_layer *func_layer;
1308         LAYER_FUNC_ENTRY();
1309
1310         pthread_mutex_lock(&private_display->lock);
1311
1312         func_layer = &private_display->func_layer;
1313
1314         if (private_layer->waiting_buffer) {
1315                 pthread_mutex_unlock(&private_display->lock);
1316                 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1317                 tbm_surface_queue_release(private_layer->buffer_queue,
1318                                           private_layer->waiting_buffer);
1319                 private_layer->waiting_buffer = NULL;
1320                 pthread_mutex_lock(&private_display->lock);
1321
1322                 if (tdm_debug_buffer)
1323                         TDM_INFO("layer(%p) waiting_buffer(%p)",
1324                                  private_layer, private_layer->waiting_buffer);
1325         }
1326
1327         if (private_layer->showing_buffer) {
1328                 pthread_mutex_unlock(&private_display->lock);
1329                 tdm_buffer_unref_backend(private_layer->showing_buffer);
1330                 tbm_surface_queue_release(private_layer->buffer_queue,
1331                                           private_layer->showing_buffer);
1332                 pthread_mutex_lock(&private_display->lock);
1333                 private_layer->showing_buffer = NULL;
1334
1335                 if (tdm_debug_buffer)
1336                         TDM_INFO("layer(%p) showing_buffer(%p)",
1337                                  private_layer, private_layer->showing_buffer);
1338         }
1339
1340         tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1341         tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1342         private_layer->buffer_queue = NULL;
1343         private_layer->usable = 1;
1344
1345         if (!func_layer->layer_unset_buffer) {
1346                 pthread_mutex_unlock(&private_display->lock);
1347                 return TDM_ERROR_NONE;
1348         }
1349
1350         ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1351
1352         pthread_mutex_unlock(&private_display->lock);
1353
1354         return ret;
1355 }
1356
1357 EXTERN tdm_error
1358 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1359 {
1360         LAYER_FUNC_ENTRY();
1361
1362         TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1363
1364         pthread_mutex_lock(&private_display->lock);
1365
1366         *usable = private_layer->usable;
1367
1368         pthread_mutex_unlock(&private_display->lock);
1369
1370         return ret;
1371 }
1372
1373 EXTERN tdm_error
1374 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1375 {
1376         tdm_func_layer *func_layer;
1377         LAYER_FUNC_ENTRY();
1378
1379         pthread_mutex_lock(&private_display->lock);
1380
1381         func_layer = &private_display->func_layer;
1382
1383         if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1384                 TDM_ERR("layer(%p) is not video layer", private_layer);
1385                 pthread_mutex_unlock(&private_display->lock);
1386                 return TDM_ERROR_INVALID_PARAMETER;
1387         }
1388
1389         if (!func_layer->layer_set_video_pos) {
1390                 pthread_mutex_unlock(&private_display->lock);
1391                 return TDM_ERROR_NONE;
1392         }
1393
1394         ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1395
1396         pthread_mutex_unlock(&private_display->lock);
1397
1398         return ret;
1399 }
1400
1401 EXTERN tdm_capture *
1402 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1403 {
1404         tdm_capture *capture = NULL;
1405
1406         LAYER_FUNC_ENTRY_ERROR();
1407
1408         pthread_mutex_lock(&private_display->lock);
1409
1410         capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1411                         error);
1412
1413         pthread_mutex_unlock(&private_display->lock);
1414
1415         return capture;
1416 }