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