1 /**************************************************************************
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
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>
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:
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
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.
34 **************************************************************************/
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
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;
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;
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
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
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
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
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
104 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
111 #define type_name_fn(res) \
112 const char * res##_str(int type) { \
114 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
115 if (res##_names[i].type == type) \
116 return res##_names[i].name; \
118 return "(invalid)"; \
121 struct type_name dpms_names[] = {
122 { TDM_OUTPUT_DPMS_ON, "on" },
123 { TDM_OUTPUT_DPMS_STANDBY, "standby" },
124 { TDM_OUTPUT_DPMS_SUSPEND, "suspend" },
125 { TDM_OUTPUT_DPMS_OFF, "off" },
128 static type_name_fn(dpms)
130 struct type_name status_names[] = {
131 { TDM_OUTPUT_CONN_STATUS_DISCONNECTED, "disconnected" },
132 { TDM_OUTPUT_CONN_STATUS_CONNECTED, "connected" },
133 { TDM_OUTPUT_CONN_STATUS_MODE_SETTED, "mode_setted" },
136 static type_name_fn(status)
139 tdm_display_get_capabilities(tdm_display *dpy,
140 tdm_display_capability *capabilities)
142 DISPLAY_FUNC_ENTRY();
144 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
146 _pthread_mutex_lock(&private_display->lock);
148 *capabilities = private_display->capabilities;
150 _pthread_mutex_unlock(&private_display->lock);
156 tdm_display_get_pp_capabilities(tdm_display *dpy,
157 tdm_pp_capability *capabilities)
159 DISPLAY_FUNC_ENTRY();
161 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
163 _pthread_mutex_lock(&private_display->lock);
165 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
166 TDM_ERR("no pp capability");
167 _pthread_mutex_unlock(&private_display->lock);
168 return TDM_ERROR_NO_CAPABILITY;
171 *capabilities = private_display->caps_pp.capabilities;
173 _pthread_mutex_unlock(&private_display->lock);
179 tdm_display_get_pp_available_formats(tdm_display *dpy,
180 const tbm_format **formats, int *count)
182 DISPLAY_FUNC_ENTRY();
184 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
185 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
187 _pthread_mutex_lock(&private_display->lock);
189 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
190 TDM_ERR("no pp capability");
191 _pthread_mutex_unlock(&private_display->lock);
192 return TDM_ERROR_NO_CAPABILITY;
195 *formats = (const tbm_format *)private_display->caps_pp.formats;
196 *count = private_display->caps_pp.format_count;
198 _pthread_mutex_unlock(&private_display->lock);
204 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
205 int *max_w, int *max_h, int *preferred_align)
207 DISPLAY_FUNC_ENTRY();
209 _pthread_mutex_lock(&private_display->lock);
211 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
212 TDM_ERR("no pp capability");
213 _pthread_mutex_unlock(&private_display->lock);
214 return TDM_ERROR_NO_CAPABILITY;
218 *min_w = private_display->caps_pp.min_w;
220 *min_h = private_display->caps_pp.min_h;
222 *max_w = private_display->caps_pp.max_w;
224 *max_h = private_display->caps_pp.max_h;
226 *preferred_align = private_display->caps_pp.preferred_align;
228 _pthread_mutex_unlock(&private_display->lock);
234 tdm_display_get_capture_capabilities(tdm_display *dpy,
235 tdm_capture_capability *capabilities)
237 DISPLAY_FUNC_ENTRY();
239 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
241 _pthread_mutex_lock(&private_display->lock);
243 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
244 TDM_ERR("no capture capability");
245 _pthread_mutex_unlock(&private_display->lock);
246 return TDM_ERROR_NO_CAPABILITY;
249 *capabilities = private_display->caps_capture.capabilities;
251 _pthread_mutex_unlock(&private_display->lock);
257 tdm_display_get_catpure_available_formats(tdm_display *dpy,
258 const tbm_format **formats, int *count)
260 DISPLAY_FUNC_ENTRY();
262 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
263 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
265 _pthread_mutex_lock(&private_display->lock);
267 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
268 TDM_ERR("no capture capability");
269 _pthread_mutex_unlock(&private_display->lock);
270 return TDM_ERROR_NO_CAPABILITY;
273 *formats = (const tbm_format *)private_display->caps_capture.formats;
274 *count = private_display->caps_capture.format_count;
276 _pthread_mutex_unlock(&private_display->lock);
282 tdm_display_get_output_count(tdm_display *dpy, int *count)
284 tdm_private_output *private_output = NULL;
286 DISPLAY_FUNC_ENTRY();
288 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
290 _pthread_mutex_lock(&private_display->lock);
293 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
297 _pthread_mutex_unlock(&private_display->lock);
298 return TDM_ERROR_NONE;
301 _pthread_mutex_unlock(&private_display->lock);
308 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
310 tdm_private_output *private_output = NULL;
313 DISPLAY_FUNC_ENTRY_ERROR();
315 _pthread_mutex_lock(&private_display->lock);
318 *error = TDM_ERROR_NONE;
321 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
323 _pthread_mutex_unlock(&private_display->lock);
324 return private_output;
329 _pthread_mutex_unlock(&private_display->lock);
335 tdm_display_get_fd(tdm_display *dpy, int *fd)
337 DISPLAY_FUNC_ENTRY();
339 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
341 _pthread_mutex_lock(&private_display->lock);
343 if (private_display->private_thread)
344 *fd = tdm_thread_get_fd(private_display);
346 *fd = tdm_event_loop_get_fd(private_display);
348 _pthread_mutex_unlock(&private_display->lock);
354 tdm_display_handle_events(tdm_display *dpy)
359 DISPLAY_FUNC_ENTRY();
361 ret = tdm_display_get_fd(dpy, &fd);
362 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
368 if (tdm_debug_thread)
369 TDM_INFO("fd(%d) polling in", fd);
371 while (poll(&fds, 1, -1) < 0) {
372 if (errno == EBUSY) /* normal case */
375 TDM_ERR("poll failed: %m");
376 return TDM_ERROR_OPERATION_FAILED;
380 if (tdm_debug_thread)
381 TDM_INFO("fd(%d) polling out", fd);
383 _pthread_mutex_lock(&private_display->lock);
385 if (private_display->private_thread)
386 ret = tdm_thread_handle_cb(private_display);
388 ret = tdm_event_loop_dispatch(private_display);
390 _pthread_mutex_unlock(&private_display->lock);
396 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
400 DISPLAY_FUNC_ENTRY_ERROR();
402 _pthread_mutex_lock(&private_display->lock);
404 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
406 _pthread_mutex_unlock(&private_display->lock);
412 tdm_output_get_model_info(tdm_output *output, const char **maker,
413 const char **model, const char **name)
417 _pthread_mutex_lock(&private_display->lock);
420 *maker = private_output->caps.maker;
422 *model = private_output->caps.model;
424 *name = private_output->caps.name;
426 _pthread_mutex_unlock(&private_display->lock);
432 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
436 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
438 _pthread_mutex_lock(&private_display->lock);
440 *status = private_output->caps.status;
442 _pthread_mutex_unlock(&private_display->lock);
448 tdm_output_add_change_handler(tdm_output *output,
449 tdm_output_change_handler func,
452 tdm_private_change_handler *change_handler;
455 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
457 pthread_mutex_lock(&private_display->lock);
459 if (!private_output->regist_change_cb) {
460 _pthread_mutex_unlock(&private_display->lock);
461 TDM_DBG("failed: not implemented!!");
462 return TDM_ERROR_NOT_IMPLEMENTED;
465 change_handler = calloc(1, sizeof(tdm_private_change_handler));
466 if (!change_handler) {
467 TDM_ERR("failed: alloc memory");
468 _pthread_mutex_unlock(&private_display->lock);
469 return TDM_ERROR_OUT_OF_MEMORY;
472 LIST_ADD(&change_handler->link, &private_output->change_handler_list);
473 change_handler->private_output = private_output;
474 change_handler->func = func;
475 change_handler->user_data = user_data;
477 _pthread_mutex_unlock(&private_display->lock);
483 tdm_output_remove_change_handler(tdm_output *output,
484 tdm_output_change_handler func,
487 tdm_private_display *private_display;
488 tdm_private_output *private_output;
489 tdm_private_change_handler *h = NULL, *hh = NULL;
491 TDM_RETURN_IF_FAIL(output != NULL);
492 TDM_RETURN_IF_FAIL(func != NULL);
494 private_output = (tdm_private_output*)output;
495 private_display = private_output->private_display;
497 _pthread_mutex_lock(&private_display->lock);
499 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list, link) {
500 if (h->func != func || h->user_data != user_data)
506 _pthread_mutex_unlock(&private_display->lock);
511 _pthread_mutex_unlock(&private_display->lock);
515 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
519 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
521 _pthread_mutex_lock(&private_display->lock);
523 *type = private_output->caps.type;
525 _pthread_mutex_unlock(&private_display->lock);
531 tdm_output_get_layer_count(tdm_output *output, int *count)
533 tdm_private_layer *private_layer = NULL;
537 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
539 _pthread_mutex_lock(&private_display->lock);
542 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
545 _pthread_mutex_unlock(&private_display->lock);
546 return TDM_ERROR_NONE;
549 _pthread_mutex_unlock(&private_display->lock);
556 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
558 tdm_private_layer *private_layer = NULL;
561 OUTPUT_FUNC_ENTRY_ERROR();
563 _pthread_mutex_lock(&private_display->lock);
566 *error = TDM_ERROR_NONE;
568 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
570 _pthread_mutex_unlock(&private_display->lock);
571 return private_layer;
576 _pthread_mutex_unlock(&private_display->lock);
582 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
587 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
588 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
590 _pthread_mutex_lock(&private_display->lock);
592 *props = (const tdm_prop *)private_output->caps.props;
593 *count = private_output->caps.prop_count;
595 _pthread_mutex_unlock(&private_display->lock);
601 tdm_output_get_available_modes(tdm_output *output,
602 const tdm_output_mode **modes, int *count)
606 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
607 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
609 _pthread_mutex_lock(&private_display->lock);
611 *modes = (const tdm_output_mode *)private_output->caps.modes;
612 *count = private_output->caps.mode_count;
614 _pthread_mutex_unlock(&private_display->lock);
620 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
621 int *max_w, int *max_h, int *preferred_align)
625 _pthread_mutex_lock(&private_display->lock);
628 *min_w = private_output->caps.min_w;
630 *min_h = private_output->caps.min_h;
632 *max_w = private_output->caps.max_w;
634 *max_h = private_output->caps.max_h;
636 *preferred_align = private_output->caps.preferred_align;
638 _pthread_mutex_unlock(&private_display->lock);
644 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
645 unsigned int *mmHeight)
649 _pthread_mutex_lock(&private_display->lock);
652 *mmWidth = private_output->caps.mmWidth;
654 *mmHeight = private_output->caps.mmHeight;
656 _pthread_mutex_unlock(&private_display->lock);
662 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
665 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
667 _pthread_mutex_lock(&private_display->lock);
669 *subpixel = private_output->caps.subpixel;
671 _pthread_mutex_unlock(&private_display->lock);
677 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
680 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
682 _pthread_mutex_lock(&private_display->lock);
684 *pipe = private_output->pipe;
686 _pthread_mutex_unlock(&private_display->lock);
693 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
695 tdm_func_output *func_output;
698 _pthread_mutex_lock(&private_display->lock);
700 func_output = &private_display->func_output;
702 if (!func_output->output_set_property) {
703 _pthread_mutex_unlock(&private_display->lock);
704 TDM_DBG("failed: not implemented!!");
705 return TDM_ERROR_NOT_IMPLEMENTED;
708 ret = func_output->output_set_property(private_output->output_backend, id,
711 _pthread_mutex_unlock(&private_display->lock);
717 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
719 tdm_func_output *func_output;
722 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
724 _pthread_mutex_lock(&private_display->lock);
726 func_output = &private_display->func_output;
728 if (!func_output->output_get_property) {
729 _pthread_mutex_unlock(&private_display->lock);
730 TDM_DBG("failed: not implemented!!");
731 return TDM_ERROR_NOT_IMPLEMENTED;
734 ret = func_output->output_get_property(private_output->output_backend, id,
737 _pthread_mutex_unlock(&private_display->lock);
743 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
744 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
746 tdm_private_vblank_handler *vblank_handler = user_data;
747 tdm_private_display *private_display;
749 TDM_RETURN_IF_FAIL(vblank_handler);
751 private_display = vblank_handler->private_output->private_display;
753 if (!tdm_thread_in_display_thread(private_display)) {
754 tdm_thread_cb_output_vblank output_vblank;
757 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
758 output_vblank.base.length = sizeof output_vblank;
759 output_vblank.output_stamp = vblank_handler->private_output->stamp;
760 output_vblank.sequence = sequence;
761 output_vblank.tv_sec = tv_sec;
762 output_vblank.tv_usec = tv_usec;
763 output_vblank.user_data = user_data;
765 ret = tdm_thread_send_cb(private_display, &output_vblank.base);
766 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
771 if (vblank_handler->func) {
772 _pthread_mutex_unlock(&private_display->lock);
773 vblank_handler->func(vblank_handler->private_output, sequence,
774 tv_sec, tv_usec, vblank_handler->user_data);
775 _pthread_mutex_lock(&private_display->lock);
778 LIST_DEL(&vblank_handler->link);
779 free(vblank_handler);
783 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
784 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
786 tdm_private_commit_handler *commit_handler = user_data;
787 tdm_private_display *private_display;
788 tdm_private_output *private_output;
789 tdm_private_layer *private_layer = NULL;
791 TDM_RETURN_IF_FAIL(commit_handler);
793 private_output = commit_handler->private_output;
794 private_display = private_output->private_display;
796 if (!tdm_thread_in_display_thread(private_display)) {
797 tdm_thread_cb_output_commit output_commit;
800 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
801 output_commit.base.length = sizeof output_commit;
802 output_commit.output_stamp = private_output->stamp;
803 output_commit.sequence = sequence;
804 output_commit.tv_sec = tv_sec;
805 output_commit.tv_usec = tv_usec;
806 output_commit.user_data = user_data;
808 ret = tdm_thread_send_cb(private_display, &output_commit.base);
809 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
814 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
815 if (!private_layer->waiting_buffer)
818 if (private_layer->showing_buffer) {
819 _pthread_mutex_unlock(&private_display->lock);
820 tdm_buffer_unref_backend(private_layer->showing_buffer);
821 _pthread_mutex_lock(&private_display->lock);
823 if (private_layer->buffer_queue) {
824 _pthread_mutex_unlock(&private_display->lock);
825 tbm_surface_queue_release(private_layer->buffer_queue,
826 private_layer->showing_buffer);
827 _pthread_mutex_lock(&private_display->lock);
831 private_layer->showing_buffer = private_layer->waiting_buffer;
832 private_layer->waiting_buffer = NULL;
834 if (tdm_debug_buffer)
835 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
836 private_layer, private_layer->waiting_buffer,
837 private_layer->showing_buffer);
840 if (commit_handler->func) {
841 _pthread_mutex_unlock(&private_display->lock);
842 commit_handler->func(private_output, sequence,
843 tv_sec, tv_usec, commit_handler->user_data);
844 _pthread_mutex_lock(&private_display->lock);
847 LIST_DEL(&commit_handler->link);
848 free(commit_handler);
852 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
853 tdm_output_vblank_handler func, void *user_data)
855 tdm_func_output *func_output;
856 tdm_private_vblank_handler *vblank_handler;
859 _pthread_mutex_lock(&private_display->lock);
861 func_output = &private_display->func_output;
863 if (!func_output->output_wait_vblank) {
864 _pthread_mutex_unlock(&private_display->lock);
865 TDM_DBG("failed: not implemented!!");
866 return TDM_ERROR_NOT_IMPLEMENTED;
869 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
870 if (!vblank_handler) {
871 TDM_ERR("failed: alloc memory");
872 _pthread_mutex_unlock(&private_display->lock);
873 return TDM_ERROR_OUT_OF_MEMORY;
876 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
877 vblank_handler->private_output = private_output;
878 vblank_handler->func = func;
879 vblank_handler->user_data = user_data;
881 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
882 sync, vblank_handler);
883 if (ret != TDM_ERROR_NONE) {
884 _pthread_mutex_unlock(&private_display->lock);
888 if (!private_output->regist_vblank_cb) {
889 private_output->regist_vblank_cb = 1;
890 ret = func_output->output_set_vblank_handler(private_output->output_backend,
891 tdm_output_cb_vblank);
894 _pthread_mutex_unlock(&private_display->lock);
900 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
903 tdm_func_output *func_output;
904 tdm_private_commit_handler *commit_handler;
907 func_output = &private_display->func_output;
909 if (!func_output->output_commit) {
910 TDM_DBG("failed: not implemented!!");
911 return TDM_ERROR_NOT_IMPLEMENTED;
914 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
915 if (!commit_handler) {
916 TDM_ERR("failed: alloc memory");
917 return TDM_ERROR_OUT_OF_MEMORY;
920 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
921 commit_handler->private_output = private_output;
922 commit_handler->func = func;
923 commit_handler->user_data = user_data;
925 ret = func_output->output_commit(private_output->output_backend, sync,
927 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
929 if (!private_output->regist_commit_cb) {
930 private_output->regist_commit_cb = 1;
931 ret = func_output->output_set_commit_handler(private_output->output_backend,
932 tdm_output_cb_commit);
939 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
944 _pthread_mutex_lock(&private_display->lock);
946 ret = _tdm_output_commit(output, sync, func, user_data);
948 _pthread_mutex_unlock(&private_display->lock);
954 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
956 tdm_func_output *func_output;
959 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
961 _pthread_mutex_lock(&private_display->lock);
963 func_output = &private_display->func_output;
965 if (!func_output->output_set_mode) {
966 _pthread_mutex_unlock(&private_display->lock);
967 TDM_DBG("failed: not implemented!!");
968 return TDM_ERROR_NOT_IMPLEMENTED;
971 ret = func_output->output_set_mode(private_output->output_backend, mode);
973 _pthread_mutex_unlock(&private_display->lock);
979 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
981 tdm_func_output *func_output;
984 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
986 _pthread_mutex_lock(&private_display->lock);
988 func_output = &private_display->func_output;
990 if (!func_output->output_get_mode) {
991 _pthread_mutex_unlock(&private_display->lock);
992 TDM_DBG("failed: not implemented!!");
993 return TDM_ERROR_NOT_IMPLEMENTED;
996 ret = func_output->output_get_mode(private_output->output_backend, mode);
998 _pthread_mutex_unlock(&private_display->lock);
1004 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1006 tdm_func_output *func_output;
1007 OUTPUT_FUNC_ENTRY();
1009 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1010 dpms_value = TDM_OUTPUT_DPMS_ON;
1011 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1012 dpms_value = TDM_OUTPUT_DPMS_OFF;
1014 _pthread_mutex_lock(&private_display->lock);
1016 func_output = &private_display->func_output;
1018 if (!func_output->output_set_dpms) {
1019 _pthread_mutex_unlock(&private_display->lock);
1020 TDM_DBG("failed: not implemented!!");
1021 return TDM_ERROR_NOT_IMPLEMENTED;
1024 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1026 _pthread_mutex_unlock(&private_display->lock);
1032 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1034 tdm_func_output *func_output;
1035 OUTPUT_FUNC_ENTRY();
1037 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1039 _pthread_mutex_lock(&private_display->lock);
1041 func_output = &private_display->func_output;
1043 if (!func_output->output_get_dpms) {
1044 _pthread_mutex_unlock(&private_display->lock);
1045 TDM_DBG("failed: not implemented!!");
1046 return TDM_ERROR_NOT_IMPLEMENTED;
1049 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1051 _pthread_mutex_unlock(&private_display->lock);
1056 EXTERN tdm_capture *
1057 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1059 tdm_capture *capture = NULL;
1061 OUTPUT_FUNC_ENTRY_ERROR();
1063 _pthread_mutex_lock(&private_display->lock);
1065 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1068 _pthread_mutex_unlock(&private_display->lock);
1074 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1075 tdm_output_change_type type,
1078 tdm_private_change_handler *change_handler;
1079 tdm_private_display *private_display;
1081 TDM_RETURN_IF_FAIL(private_output);
1083 private_display = private_output->private_display;
1085 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1086 TDM_INFO("output(%d) changed: %s",
1087 private_output->pipe, status_str(value.u32));
1088 if (type & TDM_OUTPUT_CHANGE_DPMS)
1089 TDM_INFO("output(%d) changed: dpms %s",
1090 private_output->pipe, dpms_str(value.u32));
1092 _pthread_mutex_unlock(&private_display->lock);
1094 LIST_FOR_EACH_ENTRY(change_handler, &private_output->change_handler_list, link) {
1095 change_handler->func(private_output, type,
1096 value, change_handler->user_data);
1099 _pthread_mutex_lock(&private_display->lock);
1103 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1107 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1109 _pthread_mutex_lock(&private_display->lock);
1111 *capabilities = private_layer->caps.capabilities;
1113 _pthread_mutex_unlock(&private_display->lock);
1119 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1124 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1125 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1127 _pthread_mutex_lock(&private_display->lock);
1129 *formats = (const tbm_format *)private_layer->caps.formats;
1130 *count = private_layer->caps.format_count;
1132 _pthread_mutex_unlock(&private_display->lock);
1138 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1143 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1144 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1146 _pthread_mutex_lock(&private_display->lock);
1148 *props = (const tdm_prop *)private_layer->caps.props;
1149 *count = private_layer->caps.prop_count;
1151 _pthread_mutex_unlock(&private_display->lock);
1157 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1161 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1163 _pthread_mutex_lock(&private_display->lock);
1165 *zpos = private_layer->caps.zpos;
1167 _pthread_mutex_unlock(&private_display->lock);
1173 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1175 tdm_func_layer *func_layer;
1178 _pthread_mutex_lock(&private_display->lock);
1180 func_layer = &private_display->func_layer;
1182 if (!func_layer->layer_set_property) {
1183 _pthread_mutex_unlock(&private_display->lock);
1184 TDM_DBG("failed: not implemented!!");
1185 return TDM_ERROR_NOT_IMPLEMENTED;
1188 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1190 _pthread_mutex_unlock(&private_display->lock);
1196 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1198 tdm_func_layer *func_layer;
1201 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1203 _pthread_mutex_lock(&private_display->lock);
1205 func_layer = &private_display->func_layer;
1207 if (!func_layer->layer_get_property) {
1208 _pthread_mutex_unlock(&private_display->lock);
1209 TDM_DBG("failed: not implemented!!");
1210 return TDM_ERROR_NOT_IMPLEMENTED;
1213 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1215 _pthread_mutex_unlock(&private_display->lock);
1221 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1223 tdm_func_layer *func_layer;
1226 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1228 _pthread_mutex_lock(&private_display->lock);
1230 func_layer = &private_display->func_layer;
1232 private_layer->usable = 0;
1234 if (!func_layer->layer_set_info) {
1235 _pthread_mutex_unlock(&private_display->lock);
1236 TDM_DBG("failed: not implemented!!");
1237 return TDM_ERROR_NOT_IMPLEMENTED;
1240 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1241 private_layer, info->src_config.size.h, info->src_config.size.v,
1242 info->src_config.pos.x, info->src_config.pos.y,
1243 info->src_config.pos.w, info->src_config.pos.h,
1244 FOURCC_STR(info->src_config.format),
1245 info->dst_pos.x, info->dst_pos.y,
1246 info->dst_pos.w, info->dst_pos.h,
1249 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1250 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1252 _pthread_mutex_unlock(&private_display->lock);
1258 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1260 tdm_func_layer *func_layer;
1263 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1265 _pthread_mutex_lock(&private_display->lock);
1267 func_layer = &private_display->func_layer;
1269 if (!func_layer->layer_get_info) {
1270 _pthread_mutex_unlock(&private_display->lock);
1271 TDM_DBG("failed: not implemented!!");
1272 return TDM_ERROR_NOT_IMPLEMENTED;
1275 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1277 _pthread_mutex_unlock(&private_display->lock);
1283 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1285 tdm_func_layer *func_layer;
1289 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1291 _pthread_mutex_lock(&private_display->lock);
1293 func_layer = &private_display->func_layer;
1295 private_layer->usable = 0;
1297 if (!func_layer->layer_set_buffer) {
1298 _pthread_mutex_unlock(&private_display->lock);
1299 TDM_DBG("failed: not implemented!!");
1300 return TDM_ERROR_NOT_IMPLEMENTED;
1303 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1304 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1306 if (ret == TDM_ERROR_NONE) {
1307 /* FIXME: should save to pending_buffer first. And after committing
1308 * successfully, need to move to waiting_buffer.
1310 if (private_layer->waiting_buffer) {
1311 _pthread_mutex_unlock(&private_display->lock);
1312 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1313 _pthread_mutex_lock(&private_display->lock);
1316 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1317 if (tdm_debug_buffer)
1318 TDM_INFO("layer(%p) waiting_buffer(%p)",
1319 private_layer, private_layer->waiting_buffer);
1322 _pthread_mutex_unlock(&private_display->lock);
1328 tdm_layer_unset_buffer(tdm_layer *layer)
1330 tdm_func_layer *func_layer;
1333 _pthread_mutex_lock(&private_display->lock);
1335 func_layer = &private_display->func_layer;
1337 if (private_layer->waiting_buffer) {
1338 _pthread_mutex_unlock(&private_display->lock);
1339 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1340 _pthread_mutex_lock(&private_display->lock);
1341 private_layer->waiting_buffer = NULL;
1343 if (tdm_debug_buffer)
1344 TDM_INFO("layer(%p) waiting_buffer(%p)",
1345 private_layer, private_layer->waiting_buffer);
1348 if (private_layer->showing_buffer) {
1349 _pthread_mutex_unlock(&private_display->lock);
1350 tdm_buffer_unref_backend(private_layer->showing_buffer);
1351 _pthread_mutex_lock(&private_display->lock);
1352 private_layer->showing_buffer = NULL;
1354 if (tdm_debug_buffer)
1355 TDM_INFO("layer(%p) showing_buffer(%p)",
1356 private_layer, private_layer->showing_buffer);
1359 private_layer->usable = 1;
1361 if (!func_layer->layer_unset_buffer) {
1362 _pthread_mutex_unlock(&private_display->lock);
1363 TDM_DBG("failed: not implemented!!");
1364 return TDM_ERROR_NOT_IMPLEMENTED;
1367 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1368 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1370 _pthread_mutex_unlock(&private_display->lock);
1376 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1378 TDM_RETURN_IF_FAIL(data != NULL);
1379 tdm_layer *layer = data;
1380 tdm_func_layer *func_layer;
1381 tbm_surface_h surface = NULL;
1382 LAYER_FUNC_ENTRY_VOID_RETURN();
1384 _pthread_mutex_lock(&private_display->lock);
1386 func_layer = &private_display->func_layer;
1387 if (!func_layer->layer_set_buffer) {
1388 _pthread_mutex_unlock(&private_display->lock);
1392 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1393 private_layer->buffer_queue, &surface) ||
1395 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1396 private_layer, surface);
1397 _pthread_mutex_unlock(&private_display->lock);
1401 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1402 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1404 if (ret == TDM_ERROR_NONE) {
1405 if (private_layer->waiting_buffer) {
1406 _pthread_mutex_unlock(&private_display->lock);
1407 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1408 tbm_surface_queue_release(private_layer->buffer_queue,
1409 private_layer->waiting_buffer);
1410 _pthread_mutex_lock(&private_display->lock);
1413 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1415 if (tdm_debug_buffer)
1416 TDM_INFO("layer(%p) waiting_buffer(%p)",
1417 private_layer, private_layer->waiting_buffer);
1419 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1420 if (ret != TDM_ERROR_NONE)
1421 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1424 _pthread_mutex_unlock(&private_display->lock);
1428 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1430 TDM_RETURN_IF_FAIL(data != NULL);
1431 tdm_layer *layer = data;
1432 LAYER_FUNC_ENTRY_VOID_RETURN();
1433 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1435 _pthread_mutex_lock(&private_display->lock);
1437 if (private_layer->waiting_buffer) {
1438 _pthread_mutex_unlock(&private_display->lock);
1439 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1440 tbm_surface_queue_release(private_layer->buffer_queue,
1441 private_layer->waiting_buffer);
1442 _pthread_mutex_lock(&private_display->lock);
1445 private_layer->buffer_queue = NULL;
1447 _pthread_mutex_unlock(&private_display->lock);
1451 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1453 tdm_func_layer *func_layer;
1456 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1458 _pthread_mutex_lock(&private_display->lock);
1460 func_layer = &private_display->func_layer;
1462 private_layer->usable = 0;
1464 if (!func_layer->layer_set_buffer) {
1465 _pthread_mutex_unlock(&private_display->lock);
1466 TDM_DBG("failed: not implemented!!");
1467 return TDM_ERROR_NOT_IMPLEMENTED;
1470 if (buffer_queue == private_layer->buffer_queue) {
1471 _pthread_mutex_unlock(&private_display->lock);
1472 return TDM_ERROR_NONE;
1475 if (private_layer->waiting_buffer) {
1476 _pthread_mutex_unlock(&private_display->lock);
1477 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1478 tbm_surface_queue_release(private_layer->buffer_queue,
1479 private_layer->waiting_buffer);
1480 private_layer->waiting_buffer = NULL;
1481 _pthread_mutex_lock(&private_display->lock);
1483 if (tdm_debug_buffer)
1484 TDM_INFO("layer(%p) waiting_buffer(%p)",
1485 private_layer, private_layer->waiting_buffer);
1488 private_layer->buffer_queue = buffer_queue;
1489 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1490 _tbm_layer_queue_acquirable_cb,
1492 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1493 _tbm_layer_queue_destroy_cb,
1495 _pthread_mutex_unlock(&private_display->lock);
1501 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1503 tdm_func_layer *func_layer;
1506 _pthread_mutex_lock(&private_display->lock);
1508 func_layer = &private_display->func_layer;
1510 if (private_layer->waiting_buffer) {
1511 _pthread_mutex_unlock(&private_display->lock);
1512 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1513 tbm_surface_queue_release(private_layer->buffer_queue,
1514 private_layer->waiting_buffer);
1515 private_layer->waiting_buffer = NULL;
1516 _pthread_mutex_lock(&private_display->lock);
1518 if (tdm_debug_buffer)
1519 TDM_INFO("layer(%p) waiting_buffer(%p)",
1520 private_layer, private_layer->waiting_buffer);
1523 if (private_layer->showing_buffer) {
1524 _pthread_mutex_unlock(&private_display->lock);
1525 tdm_buffer_unref_backend(private_layer->showing_buffer);
1526 tbm_surface_queue_release(private_layer->buffer_queue,
1527 private_layer->showing_buffer);
1528 _pthread_mutex_lock(&private_display->lock);
1529 private_layer->showing_buffer = NULL;
1531 if (tdm_debug_buffer)
1532 TDM_INFO("layer(%p) showing_buffer(%p)",
1533 private_layer, private_layer->showing_buffer);
1536 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1537 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1538 private_layer->buffer_queue = NULL;
1539 private_layer->usable = 1;
1541 if (!func_layer->layer_unset_buffer) {
1542 _pthread_mutex_unlock(&private_display->lock);
1543 TDM_DBG("failed: not implemented!!");
1544 return TDM_ERROR_NOT_IMPLEMENTED;
1547 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1549 _pthread_mutex_unlock(&private_display->lock);
1555 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1559 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1561 _pthread_mutex_lock(&private_display->lock);
1563 *usable = private_layer->usable;
1565 _pthread_mutex_unlock(&private_display->lock);
1571 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1573 tdm_func_layer *func_layer;
1576 _pthread_mutex_lock(&private_display->lock);
1578 func_layer = &private_display->func_layer;
1580 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1581 TDM_ERR("layer(%p) is not video layer", private_layer);
1582 _pthread_mutex_unlock(&private_display->lock);
1583 return TDM_ERROR_INVALID_PARAMETER;
1586 if (!func_layer->layer_set_video_pos) {
1587 _pthread_mutex_unlock(&private_display->lock);
1588 TDM_DBG("failed: not implemented!!");
1589 return TDM_ERROR_NOT_IMPLEMENTED;
1592 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1594 _pthread_mutex_unlock(&private_display->lock);
1599 EXTERN tdm_capture *
1600 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1602 tdm_capture *capture = NULL;
1604 LAYER_FUNC_ENTRY_ERROR();
1606 _pthread_mutex_lock(&private_display->lock);
1608 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1611 _pthread_mutex_unlock(&private_display->lock);