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 INTERN 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 INTERN 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_loop->private_thread) {
344 _pthread_mutex_unlock(&private_display->lock);
345 *fd = tdm_thread_get_fd(private_display->private_loop);
346 _pthread_mutex_lock(&private_display->lock);
349 *fd = tdm_event_loop_get_fd(private_display);
351 _pthread_mutex_unlock(&private_display->lock);
357 tdm_display_handle_events(tdm_display *dpy)
362 DISPLAY_FUNC_ENTRY();
364 ret = tdm_display_get_fd(dpy, &fd);
365 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
371 if (tdm_debug_thread)
372 TDM_INFO("fd(%d) polling in", fd);
374 while (poll(&fds, 1, -1) < 0) {
375 if (errno == EBUSY) /* normal case */
378 TDM_ERR("poll failed: %m");
379 return TDM_ERROR_OPERATION_FAILED;
383 if (tdm_debug_thread)
384 TDM_INFO("fd(%d) polling out", fd);
386 _pthread_mutex_lock(&private_display->lock);
388 if (private_display->private_loop->private_thread) {
389 _pthread_mutex_unlock(&private_display->lock);
390 ret = tdm_thread_handle_cb(private_display->private_loop);
391 _pthread_mutex_lock(&private_display->lock);
394 ret = tdm_event_loop_dispatch(private_display);
396 _pthread_mutex_unlock(&private_display->lock);
402 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
406 DISPLAY_FUNC_ENTRY_ERROR();
408 _pthread_mutex_lock(&private_display->lock);
410 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
412 _pthread_mutex_unlock(&private_display->lock);
418 tdm_output_get_model_info(tdm_output *output, const char **maker,
419 const char **model, const char **name)
423 _pthread_mutex_lock(&private_display->lock);
426 *maker = private_output->caps.maker;
428 *model = private_output->caps.model;
430 *name = private_output->caps.name;
432 _pthread_mutex_unlock(&private_display->lock);
438 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
442 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
444 _pthread_mutex_lock(&private_display->lock);
446 *status = private_output->caps.status;
448 _pthread_mutex_unlock(&private_display->lock);
454 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
457 tdm_private_display *private_display;
458 tdm_private_output *private_output = user_data;
460 int lock_after_cb_done = 0;
463 TDM_RETURN_IF_FAIL(private_output);
465 private_display = private_output->private_display;
467 if (!tdm_thread_in_display_thread(private_display->private_loop,
468 syscall(SYS_gettid))) {
469 tdm_thread_cb_output_status output_status;
472 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
473 output_status.base.length = sizeof output_status;
474 output_status.output_stamp = private_output->stamp;
475 output_status.status = status;
476 output_status.user_data = user_data;
479 tdm_output_call_change_handler_internal(private_output,
480 &private_output->change_handler_list_sub,
481 TDM_OUTPUT_CHANGE_CONNECTION,
484 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
485 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
490 ret = pthread_mutex_trylock(&private_display->lock);
492 _pthread_mutex_unlock(&private_display->lock);
493 else if (ret == EBUSY) {
494 _pthread_mutex_unlock(&private_display->lock);
495 lock_after_cb_done = 1;
499 tdm_output_call_change_handler_internal(private_output,
500 &private_output->change_handler_list_main,
501 TDM_OUTPUT_CHANGE_CONNECTION,
504 if (lock_after_cb_done)
505 _pthread_mutex_lock(&private_display->lock);
509 tdm_output_add_change_handler(tdm_output *output,
510 tdm_output_change_handler func,
513 tdm_private_change_handler *change_handler;
516 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
518 pthread_mutex_lock(&private_display->lock);
520 if (!private_output->regist_change_cb) {
521 _pthread_mutex_unlock(&private_display->lock);
522 TDM_DBG("failed: not implemented!!");
523 return TDM_ERROR_NOT_IMPLEMENTED;
526 change_handler = calloc(1, sizeof(tdm_private_change_handler));
527 if (!change_handler) {
528 TDM_ERR("failed: alloc memory");
529 _pthread_mutex_unlock(&private_display->lock);
530 return TDM_ERROR_OUT_OF_MEMORY;
533 change_handler->private_output = private_output;
534 change_handler->func = func;
535 change_handler->user_data = user_data;
536 change_handler->owner_tid = syscall(SYS_gettid);
538 if (!tdm_thread_in_display_thread(private_display->private_loop,
539 change_handler->owner_tid))
540 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
542 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
544 _pthread_mutex_unlock(&private_display->lock);
550 tdm_output_remove_change_handler(tdm_output *output,
551 tdm_output_change_handler func,
554 tdm_private_display *private_display;
555 tdm_private_output *private_output;
556 tdm_private_change_handler *h = NULL, *hh = NULL;
558 TDM_RETURN_IF_FAIL(output != NULL);
559 TDM_RETURN_IF_FAIL(func != NULL);
561 private_output = (tdm_private_output*)output;
562 private_display = private_output->private_display;
564 _pthread_mutex_lock(&private_display->lock);
566 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
567 if (h->func != func || h->user_data != user_data)
573 _pthread_mutex_unlock(&private_display->lock);
578 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
579 if (h->func != func || h->user_data != user_data)
585 _pthread_mutex_unlock(&private_display->lock);
590 _pthread_mutex_unlock(&private_display->lock);
594 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
598 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
600 _pthread_mutex_lock(&private_display->lock);
602 *type = private_output->caps.type;
604 _pthread_mutex_unlock(&private_display->lock);
610 tdm_output_get_layer_count(tdm_output *output, int *count)
612 tdm_private_layer *private_layer = NULL;
616 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
618 _pthread_mutex_lock(&private_display->lock);
621 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
624 _pthread_mutex_unlock(&private_display->lock);
625 return TDM_ERROR_NONE;
628 _pthread_mutex_unlock(&private_display->lock);
635 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
637 tdm_private_layer *private_layer = NULL;
640 OUTPUT_FUNC_ENTRY_ERROR();
642 _pthread_mutex_lock(&private_display->lock);
645 *error = TDM_ERROR_NONE;
647 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
649 _pthread_mutex_unlock(&private_display->lock);
650 return private_layer;
655 _pthread_mutex_unlock(&private_display->lock);
661 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
666 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
667 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
669 _pthread_mutex_lock(&private_display->lock);
671 *props = (const tdm_prop *)private_output->caps.props;
672 *count = private_output->caps.prop_count;
674 _pthread_mutex_unlock(&private_display->lock);
680 tdm_output_get_available_modes(tdm_output *output,
681 const tdm_output_mode **modes, int *count)
685 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
686 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
688 _pthread_mutex_lock(&private_display->lock);
690 *modes = (const tdm_output_mode *)private_output->caps.modes;
691 *count = private_output->caps.mode_count;
693 _pthread_mutex_unlock(&private_display->lock);
699 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
700 int *max_w, int *max_h, int *preferred_align)
704 _pthread_mutex_lock(&private_display->lock);
707 *min_w = private_output->caps.min_w;
709 *min_h = private_output->caps.min_h;
711 *max_w = private_output->caps.max_w;
713 *max_h = private_output->caps.max_h;
715 *preferred_align = private_output->caps.preferred_align;
717 _pthread_mutex_unlock(&private_display->lock);
723 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
724 unsigned int *mmHeight)
728 _pthread_mutex_lock(&private_display->lock);
731 *mmWidth = private_output->caps.mmWidth;
733 *mmHeight = private_output->caps.mmHeight;
735 _pthread_mutex_unlock(&private_display->lock);
741 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
744 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
746 _pthread_mutex_lock(&private_display->lock);
748 *subpixel = private_output->caps.subpixel;
750 _pthread_mutex_unlock(&private_display->lock);
756 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
759 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
761 _pthread_mutex_lock(&private_display->lock);
763 *pipe = private_output->pipe;
765 _pthread_mutex_unlock(&private_display->lock);
772 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
774 tdm_func_output *func_output;
777 _pthread_mutex_lock(&private_display->lock);
779 func_output = &private_display->func_output;
781 if (!func_output->output_set_property) {
782 _pthread_mutex_unlock(&private_display->lock);
783 TDM_DBG("failed: not implemented!!");
784 return TDM_ERROR_NOT_IMPLEMENTED;
787 ret = func_output->output_set_property(private_output->output_backend, id,
790 _pthread_mutex_unlock(&private_display->lock);
796 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
798 tdm_func_output *func_output;
801 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
803 _pthread_mutex_lock(&private_display->lock);
805 func_output = &private_display->func_output;
807 if (!func_output->output_get_property) {
808 _pthread_mutex_unlock(&private_display->lock);
809 TDM_DBG("failed: not implemented!!");
810 return TDM_ERROR_NOT_IMPLEMENTED;
813 ret = func_output->output_get_property(private_output->output_backend, id,
816 _pthread_mutex_unlock(&private_display->lock);
822 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
823 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
825 tdm_private_vblank_handler *vblank_handler = user_data;
826 tdm_private_display *private_display;
828 TDM_RETURN_IF_FAIL(vblank_handler);
830 private_display = vblank_handler->private_output->private_display;
832 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
833 tdm_thread_cb_output_vblank output_vblank;
836 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
837 output_vblank.base.length = sizeof output_vblank;
838 output_vblank.output_stamp = vblank_handler->private_output->stamp;
839 output_vblank.sequence = sequence;
840 output_vblank.tv_sec = tv_sec;
841 output_vblank.tv_usec = tv_usec;
842 output_vblank.user_data = user_data;
844 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
845 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
850 if (vblank_handler->owner_tid != syscall(SYS_gettid))
851 TDM_NEVER_GET_HERE();
853 if (vblank_handler->func) {
854 int lock_after_cb_done = 0;
857 ret = pthread_mutex_trylock(&private_display->lock);
859 _pthread_mutex_unlock(&private_display->lock);
860 else if (ret == EBUSY) {
861 _pthread_mutex_unlock(&private_display->lock);
862 lock_after_cb_done = 1;
865 vblank_handler->func(vblank_handler->private_output, sequence,
866 tv_sec, tv_usec, vblank_handler->user_data);
868 if (lock_after_cb_done)
869 _pthread_mutex_lock(&private_display->lock);
872 LIST_DEL(&vblank_handler->link);
873 free(vblank_handler);
877 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
878 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
880 tdm_private_commit_handler *commit_handler = user_data;
881 tdm_private_display *private_display;
882 tdm_private_output *private_output;
883 tdm_private_layer *private_layer = NULL;
884 int lock_after_cb_done = 0;
887 TDM_RETURN_IF_FAIL(commit_handler);
889 private_output = commit_handler->private_output;
890 private_display = private_output->private_display;
892 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
893 tdm_thread_cb_output_commit output_commit;
896 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
897 output_commit.base.length = sizeof output_commit;
898 output_commit.output_stamp = private_output->stamp;
899 output_commit.sequence = sequence;
900 output_commit.tv_sec = tv_sec;
901 output_commit.tv_usec = tv_usec;
902 output_commit.user_data = user_data;
904 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
905 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
910 ret = pthread_mutex_trylock(&private_display->lock);
912 _pthread_mutex_unlock(&private_display->lock);
913 else if (ret == EBUSY) {
914 _pthread_mutex_unlock(&private_display->lock);
915 lock_after_cb_done = 1;
918 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
919 if (!private_layer->waiting_buffer)
922 if (private_layer->showing_buffer) {
923 tdm_buffer_unref_backend(private_layer->showing_buffer);
925 if (private_layer->buffer_queue) {
926 tbm_surface_queue_release(private_layer->buffer_queue,
927 private_layer->showing_buffer);
931 private_layer->showing_buffer = private_layer->waiting_buffer;
932 private_layer->waiting_buffer = NULL;
934 if (tdm_debug_buffer)
935 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
936 private_layer, private_layer->waiting_buffer,
937 private_layer->showing_buffer);
940 if (commit_handler->func) {
941 commit_handler->func(private_output, sequence,
942 tv_sec, tv_usec, commit_handler->user_data);
945 if (lock_after_cb_done)
946 _pthread_mutex_lock(&private_display->lock);
948 LIST_DEL(&commit_handler->link);
949 free(commit_handler);
953 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
954 tdm_output_vblank_handler func, void *user_data)
956 tdm_func_output *func_output;
957 tdm_private_vblank_handler *vblank_handler;
960 _pthread_mutex_lock(&private_display->lock);
962 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
963 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
964 dpms_str(private_output->current_dpms_value));
965 _pthread_mutex_unlock(&private_display->lock);
966 return TDM_ERROR_BAD_REQUEST;
969 func_output = &private_display->func_output;
971 if (!func_output->output_wait_vblank) {
972 _pthread_mutex_unlock(&private_display->lock);
973 TDM_DBG("failed: not implemented!!");
974 return TDM_ERROR_NOT_IMPLEMENTED;
977 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
978 if (!vblank_handler) {
979 TDM_ERR("failed: alloc memory");
980 _pthread_mutex_unlock(&private_display->lock);
981 return TDM_ERROR_OUT_OF_MEMORY;
984 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
985 vblank_handler->private_output = private_output;
986 vblank_handler->func = func;
987 vblank_handler->user_data = user_data;
988 vblank_handler->owner_tid = syscall(SYS_gettid);
990 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
991 sync, vblank_handler);
992 if (ret != TDM_ERROR_NONE) {
993 _pthread_mutex_unlock(&private_display->lock);
997 if (!private_output->regist_vblank_cb) {
998 private_output->regist_vblank_cb = 1;
999 ret = func_output->output_set_vblank_handler(private_output->output_backend,
1000 tdm_output_cb_vblank);
1003 _pthread_mutex_unlock(&private_display->lock);
1009 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1012 tdm_func_output *func_output;
1013 tdm_private_commit_handler *commit_handler;
1014 OUTPUT_FUNC_ENTRY();
1016 func_output = &private_display->func_output;
1018 if (!func_output->output_commit) {
1019 TDM_DBG("failed: not implemented!!");
1020 return TDM_ERROR_NOT_IMPLEMENTED;
1023 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1024 if (!commit_handler) {
1025 TDM_ERR("failed: alloc memory");
1026 return TDM_ERROR_OUT_OF_MEMORY;
1029 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1030 commit_handler->private_output = private_output;
1031 commit_handler->func = func;
1032 commit_handler->user_data = user_data;
1033 commit_handler->owner_tid = syscall(SYS_gettid);
1035 ret = func_output->output_commit(private_output->output_backend, sync,
1037 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1039 if (!private_output->regist_commit_cb) {
1040 private_output->regist_commit_cb = 1;
1041 ret = func_output->output_set_commit_handler(private_output->output_backend,
1042 tdm_output_cb_commit);
1049 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1052 OUTPUT_FUNC_ENTRY();
1054 _pthread_mutex_lock(&private_display->lock);
1056 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1057 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
1058 dpms_str(private_output->current_dpms_value));
1059 _pthread_mutex_unlock(&private_display->lock);
1060 return TDM_ERROR_BAD_REQUEST;
1063 ret = _tdm_output_commit(output, sync, func, user_data);
1065 _pthread_mutex_unlock(&private_display->lock);
1071 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1073 tdm_func_output *func_output;
1074 OUTPUT_FUNC_ENTRY();
1076 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1078 _pthread_mutex_lock(&private_display->lock);
1080 func_output = &private_display->func_output;
1082 if (!func_output->output_set_mode) {
1083 _pthread_mutex_unlock(&private_display->lock);
1084 TDM_DBG("failed: not implemented!!");
1085 return TDM_ERROR_NOT_IMPLEMENTED;
1088 ret = func_output->output_set_mode(private_output->output_backend, mode);
1090 _pthread_mutex_unlock(&private_display->lock);
1096 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1098 tdm_func_output *func_output;
1099 OUTPUT_FUNC_ENTRY();
1101 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1103 _pthread_mutex_lock(&private_display->lock);
1105 func_output = &private_display->func_output;
1107 if (!func_output->output_get_mode) {
1108 _pthread_mutex_unlock(&private_display->lock);
1109 TDM_DBG("failed: not implemented!!");
1110 return TDM_ERROR_NOT_IMPLEMENTED;
1113 ret = func_output->output_get_mode(private_output->output_backend, mode);
1115 _pthread_mutex_unlock(&private_display->lock);
1121 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1123 tdm_func_output *func_output;
1124 OUTPUT_FUNC_ENTRY();
1126 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1127 dpms_value = TDM_OUTPUT_DPMS_ON;
1128 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1129 dpms_value = TDM_OUTPUT_DPMS_OFF;
1131 _pthread_mutex_lock(&private_display->lock);
1133 func_output = &private_display->func_output;
1135 if (!func_output->output_set_dpms) {
1136 _pthread_mutex_unlock(&private_display->lock);
1137 TDM_DBG("failed: not implemented!!");
1138 return TDM_ERROR_NOT_IMPLEMENTED;
1141 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1142 if (ret == TDM_ERROR_NONE)
1143 private_output->current_dpms_value = dpms_value;
1145 _pthread_mutex_unlock(&private_display->lock);
1151 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1153 tdm_func_output *func_output;
1154 OUTPUT_FUNC_ENTRY();
1156 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1158 _pthread_mutex_lock(&private_display->lock);
1160 func_output = &private_display->func_output;
1162 if (!func_output->output_get_dpms) {
1163 _pthread_mutex_unlock(&private_display->lock);
1164 TDM_DBG("failed: not implemented!!");
1165 return TDM_ERROR_NOT_IMPLEMENTED;
1168 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1170 _pthread_mutex_unlock(&private_display->lock);
1175 EXTERN tdm_capture *
1176 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1178 tdm_capture *capture = NULL;
1180 OUTPUT_FUNC_ENTRY_ERROR();
1182 _pthread_mutex_lock(&private_display->lock);
1184 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1187 _pthread_mutex_unlock(&private_display->lock);
1193 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1194 struct list_head *change_handler_list,
1195 tdm_output_change_type type,
1198 tdm_private_display *private_display;
1199 tdm_private_change_handler *change_handler;
1201 TDM_RETURN_IF_FAIL(private_output);
1203 private_display = private_output->private_display;
1204 if (!tdm_thread_in_display_thread(private_display->private_loop,
1205 syscall(SYS_gettid))) {
1206 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1207 TDM_INFO("output(%d) changed: %s (%d)",
1208 private_output->pipe, status_str(value.u32), value.u32);
1209 if (type & TDM_OUTPUT_CHANGE_DPMS)
1210 TDM_INFO("output(%d) changed: dpms %s (%d)",
1211 private_output->pipe, dpms_str(value.u32), value.u32);
1214 if (LIST_IS_EMPTY(change_handler_list))
1217 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1218 if (change_handler->owner_tid != syscall(SYS_gettid))
1219 TDM_NEVER_GET_HERE();
1221 change_handler->func(private_output, type,
1222 value, change_handler->user_data);
1227 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1231 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1233 _pthread_mutex_lock(&private_display->lock);
1235 *capabilities = private_layer->caps.capabilities;
1237 _pthread_mutex_unlock(&private_display->lock);
1243 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1248 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1249 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1251 _pthread_mutex_lock(&private_display->lock);
1253 *formats = (const tbm_format *)private_layer->caps.formats;
1254 *count = private_layer->caps.format_count;
1256 _pthread_mutex_unlock(&private_display->lock);
1262 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1267 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1268 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1270 _pthread_mutex_lock(&private_display->lock);
1272 *props = (const tdm_prop *)private_layer->caps.props;
1273 *count = private_layer->caps.prop_count;
1275 _pthread_mutex_unlock(&private_display->lock);
1281 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1285 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1287 _pthread_mutex_lock(&private_display->lock);
1289 *zpos = private_layer->caps.zpos;
1291 _pthread_mutex_unlock(&private_display->lock);
1297 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1299 tdm_func_layer *func_layer;
1302 _pthread_mutex_lock(&private_display->lock);
1304 func_layer = &private_display->func_layer;
1306 if (!func_layer->layer_set_property) {
1307 _pthread_mutex_unlock(&private_display->lock);
1308 TDM_DBG("failed: not implemented!!");
1309 return TDM_ERROR_NOT_IMPLEMENTED;
1312 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1314 _pthread_mutex_unlock(&private_display->lock);
1320 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1322 tdm_func_layer *func_layer;
1325 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1327 _pthread_mutex_lock(&private_display->lock);
1329 func_layer = &private_display->func_layer;
1331 if (!func_layer->layer_get_property) {
1332 _pthread_mutex_unlock(&private_display->lock);
1333 TDM_DBG("failed: not implemented!!");
1334 return TDM_ERROR_NOT_IMPLEMENTED;
1337 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1339 _pthread_mutex_unlock(&private_display->lock);
1345 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1347 tdm_func_layer *func_layer;
1350 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1352 _pthread_mutex_lock(&private_display->lock);
1354 func_layer = &private_display->func_layer;
1356 private_layer->usable = 0;
1358 if (!func_layer->layer_set_info) {
1359 _pthread_mutex_unlock(&private_display->lock);
1360 TDM_DBG("failed: not implemented!!");
1361 return TDM_ERROR_NOT_IMPLEMENTED;
1364 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1365 private_layer, info->src_config.size.h, info->src_config.size.v,
1366 info->src_config.pos.x, info->src_config.pos.y,
1367 info->src_config.pos.w, info->src_config.pos.h,
1368 FOURCC_STR(info->src_config.format),
1369 info->dst_pos.x, info->dst_pos.y,
1370 info->dst_pos.w, info->dst_pos.h,
1373 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1374 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1376 _pthread_mutex_unlock(&private_display->lock);
1382 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1384 tdm_func_layer *func_layer;
1387 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1389 _pthread_mutex_lock(&private_display->lock);
1391 func_layer = &private_display->func_layer;
1393 if (!func_layer->layer_get_info) {
1394 _pthread_mutex_unlock(&private_display->lock);
1395 TDM_DBG("failed: not implemented!!");
1396 return TDM_ERROR_NOT_IMPLEMENTED;
1399 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1401 _pthread_mutex_unlock(&private_display->lock);
1407 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1409 tdm_func_layer *func_layer;
1413 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1415 _pthread_mutex_lock(&private_display->lock);
1417 func_layer = &private_display->func_layer;
1419 private_layer->usable = 0;
1421 if (!func_layer->layer_set_buffer) {
1422 _pthread_mutex_unlock(&private_display->lock);
1423 TDM_DBG("failed: not implemented!!");
1424 return TDM_ERROR_NOT_IMPLEMENTED;
1427 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1428 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1430 if (ret == TDM_ERROR_NONE) {
1431 /* FIXME: should save to pending_buffer first. And after committing
1432 * successfully, need to move to waiting_buffer.
1434 if (private_layer->waiting_buffer) {
1435 _pthread_mutex_unlock(&private_display->lock);
1436 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1437 _pthread_mutex_lock(&private_display->lock);
1440 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1441 if (tdm_debug_buffer)
1442 TDM_INFO("layer(%p) waiting_buffer(%p)",
1443 private_layer, private_layer->waiting_buffer);
1446 _pthread_mutex_unlock(&private_display->lock);
1452 tdm_layer_unset_buffer(tdm_layer *layer)
1454 tdm_func_layer *func_layer;
1457 _pthread_mutex_lock(&private_display->lock);
1459 func_layer = &private_display->func_layer;
1461 if (private_layer->waiting_buffer) {
1462 _pthread_mutex_unlock(&private_display->lock);
1463 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1464 _pthread_mutex_lock(&private_display->lock);
1465 private_layer->waiting_buffer = NULL;
1467 if (tdm_debug_buffer)
1468 TDM_INFO("layer(%p) waiting_buffer(%p)",
1469 private_layer, private_layer->waiting_buffer);
1472 if (private_layer->showing_buffer) {
1473 _pthread_mutex_unlock(&private_display->lock);
1474 tdm_buffer_unref_backend(private_layer->showing_buffer);
1475 _pthread_mutex_lock(&private_display->lock);
1476 private_layer->showing_buffer = NULL;
1478 if (tdm_debug_buffer)
1479 TDM_INFO("layer(%p) showing_buffer(%p)",
1480 private_layer, private_layer->showing_buffer);
1483 private_layer->usable = 1;
1485 if (!func_layer->layer_unset_buffer) {
1486 _pthread_mutex_unlock(&private_display->lock);
1487 TDM_DBG("failed: not implemented!!");
1488 return TDM_ERROR_NOT_IMPLEMENTED;
1491 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1492 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1494 _pthread_mutex_unlock(&private_display->lock);
1500 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1502 TDM_RETURN_IF_FAIL(data != NULL);
1503 tdm_layer *layer = data;
1504 tdm_func_layer *func_layer;
1505 tbm_surface_h surface = NULL;
1506 LAYER_FUNC_ENTRY_VOID_RETURN();
1508 _pthread_mutex_lock(&private_display->lock);
1510 func_layer = &private_display->func_layer;
1511 if (!func_layer->layer_set_buffer) {
1512 _pthread_mutex_unlock(&private_display->lock);
1516 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1517 private_layer->buffer_queue, &surface) ||
1519 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1520 private_layer, surface);
1521 _pthread_mutex_unlock(&private_display->lock);
1525 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1526 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1528 if (ret == TDM_ERROR_NONE) {
1529 if (private_layer->waiting_buffer) {
1530 _pthread_mutex_unlock(&private_display->lock);
1531 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1532 tbm_surface_queue_release(private_layer->buffer_queue,
1533 private_layer->waiting_buffer);
1534 _pthread_mutex_lock(&private_display->lock);
1537 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1539 if (tdm_debug_buffer)
1540 TDM_INFO("layer(%p) waiting_buffer(%p)",
1541 private_layer, private_layer->waiting_buffer);
1543 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1544 if (ret != TDM_ERROR_NONE)
1545 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1548 _pthread_mutex_unlock(&private_display->lock);
1552 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1554 TDM_RETURN_IF_FAIL(data != NULL);
1555 tdm_layer *layer = data;
1556 LAYER_FUNC_ENTRY_VOID_RETURN();
1557 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1559 _pthread_mutex_lock(&private_display->lock);
1561 if (private_layer->waiting_buffer) {
1562 _pthread_mutex_unlock(&private_display->lock);
1563 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1564 tbm_surface_queue_release(private_layer->buffer_queue,
1565 private_layer->waiting_buffer);
1566 _pthread_mutex_lock(&private_display->lock);
1569 private_layer->buffer_queue = NULL;
1571 _pthread_mutex_unlock(&private_display->lock);
1575 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1577 tdm_func_layer *func_layer;
1580 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1582 _pthread_mutex_lock(&private_display->lock);
1584 func_layer = &private_display->func_layer;
1586 private_layer->usable = 0;
1588 if (!func_layer->layer_set_buffer) {
1589 _pthread_mutex_unlock(&private_display->lock);
1590 TDM_DBG("failed: not implemented!!");
1591 return TDM_ERROR_NOT_IMPLEMENTED;
1594 if (buffer_queue == private_layer->buffer_queue) {
1595 _pthread_mutex_unlock(&private_display->lock);
1596 return TDM_ERROR_NONE;
1599 if (private_layer->waiting_buffer) {
1600 _pthread_mutex_unlock(&private_display->lock);
1601 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1602 tbm_surface_queue_release(private_layer->buffer_queue,
1603 private_layer->waiting_buffer);
1604 private_layer->waiting_buffer = NULL;
1605 _pthread_mutex_lock(&private_display->lock);
1607 if (tdm_debug_buffer)
1608 TDM_INFO("layer(%p) waiting_buffer(%p)",
1609 private_layer, private_layer->waiting_buffer);
1612 private_layer->buffer_queue = buffer_queue;
1613 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1614 _tbm_layer_queue_acquirable_cb,
1616 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1617 _tbm_layer_queue_destroy_cb,
1619 _pthread_mutex_unlock(&private_display->lock);
1625 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1627 tdm_func_layer *func_layer;
1630 _pthread_mutex_lock(&private_display->lock);
1632 func_layer = &private_display->func_layer;
1634 if (private_layer->waiting_buffer) {
1635 _pthread_mutex_unlock(&private_display->lock);
1636 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1637 tbm_surface_queue_release(private_layer->buffer_queue,
1638 private_layer->waiting_buffer);
1639 private_layer->waiting_buffer = NULL;
1640 _pthread_mutex_lock(&private_display->lock);
1642 if (tdm_debug_buffer)
1643 TDM_INFO("layer(%p) waiting_buffer(%p)",
1644 private_layer, private_layer->waiting_buffer);
1647 if (private_layer->showing_buffer) {
1648 _pthread_mutex_unlock(&private_display->lock);
1649 tdm_buffer_unref_backend(private_layer->showing_buffer);
1650 tbm_surface_queue_release(private_layer->buffer_queue,
1651 private_layer->showing_buffer);
1652 _pthread_mutex_lock(&private_display->lock);
1653 private_layer->showing_buffer = NULL;
1655 if (tdm_debug_buffer)
1656 TDM_INFO("layer(%p) showing_buffer(%p)",
1657 private_layer, private_layer->showing_buffer);
1660 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1661 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1662 private_layer->buffer_queue = NULL;
1663 private_layer->usable = 1;
1665 if (!func_layer->layer_unset_buffer) {
1666 _pthread_mutex_unlock(&private_display->lock);
1667 TDM_DBG("failed: not implemented!!");
1668 return TDM_ERROR_NOT_IMPLEMENTED;
1671 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1673 _pthread_mutex_unlock(&private_display->lock);
1679 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1683 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1685 _pthread_mutex_lock(&private_display->lock);
1687 *usable = private_layer->usable;
1689 _pthread_mutex_unlock(&private_display->lock);
1695 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1697 tdm_func_layer *func_layer;
1700 _pthread_mutex_lock(&private_display->lock);
1702 func_layer = &private_display->func_layer;
1704 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1705 TDM_ERR("layer(%p) is not video layer", private_layer);
1706 _pthread_mutex_unlock(&private_display->lock);
1707 return TDM_ERROR_INVALID_PARAMETER;
1710 if (!func_layer->layer_set_video_pos) {
1711 _pthread_mutex_unlock(&private_display->lock);
1712 TDM_DBG("failed: not implemented!!");
1713 return TDM_ERROR_NOT_IMPLEMENTED;
1716 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1718 _pthread_mutex_unlock(&private_display->lock);
1723 EXTERN tdm_capture *
1724 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1726 tdm_capture *capture = NULL;
1728 LAYER_FUNC_ENTRY_ERROR();
1730 _pthread_mutex_lock(&private_display->lock);
1732 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1735 _pthread_mutex_unlock(&private_display->lock);