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