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_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 func_output = &private_display->func_output;
964 if (!func_output->output_wait_vblank) {
965 _pthread_mutex_unlock(&private_display->lock);
966 TDM_DBG("failed: not implemented!!");
967 return TDM_ERROR_NOT_IMPLEMENTED;
970 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
971 if (!vblank_handler) {
972 TDM_ERR("failed: alloc memory");
973 _pthread_mutex_unlock(&private_display->lock);
974 return TDM_ERROR_OUT_OF_MEMORY;
977 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
978 vblank_handler->private_output = private_output;
979 vblank_handler->func = func;
980 vblank_handler->user_data = user_data;
981 vblank_handler->owner_tid = syscall(SYS_gettid);
983 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
984 sync, vblank_handler);
985 if (ret != TDM_ERROR_NONE) {
986 _pthread_mutex_unlock(&private_display->lock);
990 if (!private_output->regist_vblank_cb) {
991 private_output->regist_vblank_cb = 1;
992 ret = func_output->output_set_vblank_handler(private_output->output_backend,
993 tdm_output_cb_vblank);
996 _pthread_mutex_unlock(&private_display->lock);
1002 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1005 tdm_func_output *func_output;
1006 tdm_private_commit_handler *commit_handler;
1007 OUTPUT_FUNC_ENTRY();
1009 func_output = &private_display->func_output;
1011 if (!func_output->output_commit) {
1012 TDM_DBG("failed: not implemented!!");
1013 return TDM_ERROR_NOT_IMPLEMENTED;
1016 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1017 if (!commit_handler) {
1018 TDM_ERR("failed: alloc memory");
1019 return TDM_ERROR_OUT_OF_MEMORY;
1022 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1023 commit_handler->private_output = private_output;
1024 commit_handler->func = func;
1025 commit_handler->user_data = user_data;
1026 commit_handler->owner_tid = syscall(SYS_gettid);
1028 ret = func_output->output_commit(private_output->output_backend, sync,
1030 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1032 if (!private_output->regist_commit_cb) {
1033 private_output->regist_commit_cb = 1;
1034 ret = func_output->output_set_commit_handler(private_output->output_backend,
1035 tdm_output_cb_commit);
1042 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1045 OUTPUT_FUNC_ENTRY();
1047 _pthread_mutex_lock(&private_display->lock);
1049 ret = _tdm_output_commit(output, sync, func, user_data);
1051 _pthread_mutex_unlock(&private_display->lock);
1057 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1059 tdm_func_output *func_output;
1060 OUTPUT_FUNC_ENTRY();
1062 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1064 _pthread_mutex_lock(&private_display->lock);
1066 func_output = &private_display->func_output;
1068 if (!func_output->output_set_mode) {
1069 _pthread_mutex_unlock(&private_display->lock);
1070 TDM_DBG("failed: not implemented!!");
1071 return TDM_ERROR_NOT_IMPLEMENTED;
1074 ret = func_output->output_set_mode(private_output->output_backend, mode);
1076 _pthread_mutex_unlock(&private_display->lock);
1082 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1084 tdm_func_output *func_output;
1085 OUTPUT_FUNC_ENTRY();
1087 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1089 _pthread_mutex_lock(&private_display->lock);
1091 func_output = &private_display->func_output;
1093 if (!func_output->output_get_mode) {
1094 _pthread_mutex_unlock(&private_display->lock);
1095 TDM_DBG("failed: not implemented!!");
1096 return TDM_ERROR_NOT_IMPLEMENTED;
1099 ret = func_output->output_get_mode(private_output->output_backend, mode);
1101 _pthread_mutex_unlock(&private_display->lock);
1107 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1109 tdm_func_output *func_output;
1110 OUTPUT_FUNC_ENTRY();
1112 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1113 dpms_value = TDM_OUTPUT_DPMS_ON;
1114 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1115 dpms_value = TDM_OUTPUT_DPMS_OFF;
1117 _pthread_mutex_lock(&private_display->lock);
1119 func_output = &private_display->func_output;
1121 if (!func_output->output_set_dpms) {
1122 _pthread_mutex_unlock(&private_display->lock);
1123 TDM_DBG("failed: not implemented!!");
1124 return TDM_ERROR_NOT_IMPLEMENTED;
1127 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1129 _pthread_mutex_unlock(&private_display->lock);
1135 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1137 tdm_func_output *func_output;
1138 OUTPUT_FUNC_ENTRY();
1140 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1142 _pthread_mutex_lock(&private_display->lock);
1144 func_output = &private_display->func_output;
1146 if (!func_output->output_get_dpms) {
1147 _pthread_mutex_unlock(&private_display->lock);
1148 TDM_DBG("failed: not implemented!!");
1149 return TDM_ERROR_NOT_IMPLEMENTED;
1152 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1154 _pthread_mutex_unlock(&private_display->lock);
1159 EXTERN tdm_capture *
1160 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1162 tdm_capture *capture = NULL;
1164 OUTPUT_FUNC_ENTRY_ERROR();
1166 _pthread_mutex_lock(&private_display->lock);
1168 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1171 _pthread_mutex_unlock(&private_display->lock);
1177 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1178 struct list_head *change_handler_list,
1179 tdm_output_change_type type,
1182 tdm_private_display *private_display;
1183 tdm_private_change_handler *change_handler;
1185 TDM_RETURN_IF_FAIL(private_output);
1187 private_display = private_output->private_display;
1188 if (!tdm_thread_in_display_thread(private_display->private_loop,
1189 syscall(SYS_gettid))) {
1190 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1191 TDM_INFO("output(%d) changed: %s (%d)",
1192 private_output->pipe, status_str(value.u32), value.u32);
1193 if (type & TDM_OUTPUT_CHANGE_DPMS)
1194 TDM_INFO("output(%d) changed: dpms %s (%d)",
1195 private_output->pipe, dpms_str(value.u32), value.u32);
1198 if (LIST_IS_EMPTY(change_handler_list))
1201 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1202 if (change_handler->owner_tid != syscall(SYS_gettid))
1203 TDM_NEVER_GET_HERE();
1205 change_handler->func(private_output, type,
1206 value, change_handler->user_data);
1211 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1215 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1217 _pthread_mutex_lock(&private_display->lock);
1219 *capabilities = private_layer->caps.capabilities;
1221 _pthread_mutex_unlock(&private_display->lock);
1227 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1232 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1233 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1235 _pthread_mutex_lock(&private_display->lock);
1237 *formats = (const tbm_format *)private_layer->caps.formats;
1238 *count = private_layer->caps.format_count;
1240 _pthread_mutex_unlock(&private_display->lock);
1246 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1251 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1252 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1254 _pthread_mutex_lock(&private_display->lock);
1256 *props = (const tdm_prop *)private_layer->caps.props;
1257 *count = private_layer->caps.prop_count;
1259 _pthread_mutex_unlock(&private_display->lock);
1265 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1269 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1271 _pthread_mutex_lock(&private_display->lock);
1273 *zpos = private_layer->caps.zpos;
1275 _pthread_mutex_unlock(&private_display->lock);
1281 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1283 tdm_func_layer *func_layer;
1286 _pthread_mutex_lock(&private_display->lock);
1288 func_layer = &private_display->func_layer;
1290 if (!func_layer->layer_set_property) {
1291 _pthread_mutex_unlock(&private_display->lock);
1292 TDM_DBG("failed: not implemented!!");
1293 return TDM_ERROR_NOT_IMPLEMENTED;
1296 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1298 _pthread_mutex_unlock(&private_display->lock);
1304 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1306 tdm_func_layer *func_layer;
1309 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1311 _pthread_mutex_lock(&private_display->lock);
1313 func_layer = &private_display->func_layer;
1315 if (!func_layer->layer_get_property) {
1316 _pthread_mutex_unlock(&private_display->lock);
1317 TDM_DBG("failed: not implemented!!");
1318 return TDM_ERROR_NOT_IMPLEMENTED;
1321 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1323 _pthread_mutex_unlock(&private_display->lock);
1329 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1331 tdm_func_layer *func_layer;
1334 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1336 _pthread_mutex_lock(&private_display->lock);
1338 func_layer = &private_display->func_layer;
1340 private_layer->usable = 0;
1342 if (!func_layer->layer_set_info) {
1343 _pthread_mutex_unlock(&private_display->lock);
1344 TDM_DBG("failed: not implemented!!");
1345 return TDM_ERROR_NOT_IMPLEMENTED;
1348 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1349 private_layer, info->src_config.size.h, info->src_config.size.v,
1350 info->src_config.pos.x, info->src_config.pos.y,
1351 info->src_config.pos.w, info->src_config.pos.h,
1352 FOURCC_STR(info->src_config.format),
1353 info->dst_pos.x, info->dst_pos.y,
1354 info->dst_pos.w, info->dst_pos.h,
1357 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1358 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1360 _pthread_mutex_unlock(&private_display->lock);
1366 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1368 tdm_func_layer *func_layer;
1371 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1373 _pthread_mutex_lock(&private_display->lock);
1375 func_layer = &private_display->func_layer;
1377 if (!func_layer->layer_get_info) {
1378 _pthread_mutex_unlock(&private_display->lock);
1379 TDM_DBG("failed: not implemented!!");
1380 return TDM_ERROR_NOT_IMPLEMENTED;
1383 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1385 _pthread_mutex_unlock(&private_display->lock);
1391 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1393 tdm_func_layer *func_layer;
1397 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1399 _pthread_mutex_lock(&private_display->lock);
1401 func_layer = &private_display->func_layer;
1403 private_layer->usable = 0;
1405 if (!func_layer->layer_set_buffer) {
1406 _pthread_mutex_unlock(&private_display->lock);
1407 TDM_DBG("failed: not implemented!!");
1408 return TDM_ERROR_NOT_IMPLEMENTED;
1411 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1412 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1414 if (ret == TDM_ERROR_NONE) {
1415 /* FIXME: should save to pending_buffer first. And after committing
1416 * successfully, need to move to waiting_buffer.
1418 if (private_layer->waiting_buffer) {
1419 _pthread_mutex_unlock(&private_display->lock);
1420 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1421 _pthread_mutex_lock(&private_display->lock);
1424 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1425 if (tdm_debug_buffer)
1426 TDM_INFO("layer(%p) waiting_buffer(%p)",
1427 private_layer, private_layer->waiting_buffer);
1430 _pthread_mutex_unlock(&private_display->lock);
1436 tdm_layer_unset_buffer(tdm_layer *layer)
1438 tdm_func_layer *func_layer;
1441 _pthread_mutex_lock(&private_display->lock);
1443 func_layer = &private_display->func_layer;
1445 if (private_layer->waiting_buffer) {
1446 _pthread_mutex_unlock(&private_display->lock);
1447 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1448 _pthread_mutex_lock(&private_display->lock);
1449 private_layer->waiting_buffer = NULL;
1451 if (tdm_debug_buffer)
1452 TDM_INFO("layer(%p) waiting_buffer(%p)",
1453 private_layer, private_layer->waiting_buffer);
1456 if (private_layer->showing_buffer) {
1457 _pthread_mutex_unlock(&private_display->lock);
1458 tdm_buffer_unref_backend(private_layer->showing_buffer);
1459 _pthread_mutex_lock(&private_display->lock);
1460 private_layer->showing_buffer = NULL;
1462 if (tdm_debug_buffer)
1463 TDM_INFO("layer(%p) showing_buffer(%p)",
1464 private_layer, private_layer->showing_buffer);
1467 private_layer->usable = 1;
1469 if (!func_layer->layer_unset_buffer) {
1470 _pthread_mutex_unlock(&private_display->lock);
1471 TDM_DBG("failed: not implemented!!");
1472 return TDM_ERROR_NOT_IMPLEMENTED;
1475 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1476 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1478 _pthread_mutex_unlock(&private_display->lock);
1484 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1486 TDM_RETURN_IF_FAIL(data != NULL);
1487 tdm_layer *layer = data;
1488 tdm_func_layer *func_layer;
1489 tbm_surface_h surface = NULL;
1490 LAYER_FUNC_ENTRY_VOID_RETURN();
1492 _pthread_mutex_lock(&private_display->lock);
1494 func_layer = &private_display->func_layer;
1495 if (!func_layer->layer_set_buffer) {
1496 _pthread_mutex_unlock(&private_display->lock);
1500 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1501 private_layer->buffer_queue, &surface) ||
1503 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1504 private_layer, surface);
1505 _pthread_mutex_unlock(&private_display->lock);
1509 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1510 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1512 if (ret == TDM_ERROR_NONE) {
1513 if (private_layer->waiting_buffer) {
1514 _pthread_mutex_unlock(&private_display->lock);
1515 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1516 tbm_surface_queue_release(private_layer->buffer_queue,
1517 private_layer->waiting_buffer);
1518 _pthread_mutex_lock(&private_display->lock);
1521 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1523 if (tdm_debug_buffer)
1524 TDM_INFO("layer(%p) waiting_buffer(%p)",
1525 private_layer, private_layer->waiting_buffer);
1527 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1528 if (ret != TDM_ERROR_NONE)
1529 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1532 _pthread_mutex_unlock(&private_display->lock);
1536 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1538 TDM_RETURN_IF_FAIL(data != NULL);
1539 tdm_layer *layer = data;
1540 LAYER_FUNC_ENTRY_VOID_RETURN();
1541 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1543 _pthread_mutex_lock(&private_display->lock);
1545 if (private_layer->waiting_buffer) {
1546 _pthread_mutex_unlock(&private_display->lock);
1547 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1548 tbm_surface_queue_release(private_layer->buffer_queue,
1549 private_layer->waiting_buffer);
1550 _pthread_mutex_lock(&private_display->lock);
1553 private_layer->buffer_queue = NULL;
1555 _pthread_mutex_unlock(&private_display->lock);
1559 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1561 tdm_func_layer *func_layer;
1564 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1566 _pthread_mutex_lock(&private_display->lock);
1568 func_layer = &private_display->func_layer;
1570 private_layer->usable = 0;
1572 if (!func_layer->layer_set_buffer) {
1573 _pthread_mutex_unlock(&private_display->lock);
1574 TDM_DBG("failed: not implemented!!");
1575 return TDM_ERROR_NOT_IMPLEMENTED;
1578 if (buffer_queue == private_layer->buffer_queue) {
1579 _pthread_mutex_unlock(&private_display->lock);
1580 return TDM_ERROR_NONE;
1583 if (private_layer->waiting_buffer) {
1584 _pthread_mutex_unlock(&private_display->lock);
1585 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1586 tbm_surface_queue_release(private_layer->buffer_queue,
1587 private_layer->waiting_buffer);
1588 private_layer->waiting_buffer = NULL;
1589 _pthread_mutex_lock(&private_display->lock);
1591 if (tdm_debug_buffer)
1592 TDM_INFO("layer(%p) waiting_buffer(%p)",
1593 private_layer, private_layer->waiting_buffer);
1596 private_layer->buffer_queue = buffer_queue;
1597 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1598 _tbm_layer_queue_acquirable_cb,
1600 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1601 _tbm_layer_queue_destroy_cb,
1603 _pthread_mutex_unlock(&private_display->lock);
1609 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1611 tdm_func_layer *func_layer;
1614 _pthread_mutex_lock(&private_display->lock);
1616 func_layer = &private_display->func_layer;
1618 if (private_layer->waiting_buffer) {
1619 _pthread_mutex_unlock(&private_display->lock);
1620 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1621 tbm_surface_queue_release(private_layer->buffer_queue,
1622 private_layer->waiting_buffer);
1623 private_layer->waiting_buffer = NULL;
1624 _pthread_mutex_lock(&private_display->lock);
1626 if (tdm_debug_buffer)
1627 TDM_INFO("layer(%p) waiting_buffer(%p)",
1628 private_layer, private_layer->waiting_buffer);
1631 if (private_layer->showing_buffer) {
1632 _pthread_mutex_unlock(&private_display->lock);
1633 tdm_buffer_unref_backend(private_layer->showing_buffer);
1634 tbm_surface_queue_release(private_layer->buffer_queue,
1635 private_layer->showing_buffer);
1636 _pthread_mutex_lock(&private_display->lock);
1637 private_layer->showing_buffer = NULL;
1639 if (tdm_debug_buffer)
1640 TDM_INFO("layer(%p) showing_buffer(%p)",
1641 private_layer, private_layer->showing_buffer);
1644 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1645 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1646 private_layer->buffer_queue = NULL;
1647 private_layer->usable = 1;
1649 if (!func_layer->layer_unset_buffer) {
1650 _pthread_mutex_unlock(&private_display->lock);
1651 TDM_DBG("failed: not implemented!!");
1652 return TDM_ERROR_NOT_IMPLEMENTED;
1655 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1657 _pthread_mutex_unlock(&private_display->lock);
1663 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1667 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1669 _pthread_mutex_lock(&private_display->lock);
1671 *usable = private_layer->usable;
1673 _pthread_mutex_unlock(&private_display->lock);
1679 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1681 tdm_func_layer *func_layer;
1684 _pthread_mutex_lock(&private_display->lock);
1686 func_layer = &private_display->func_layer;
1688 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1689 TDM_ERR("layer(%p) is not video layer", private_layer);
1690 _pthread_mutex_unlock(&private_display->lock);
1691 return TDM_ERROR_INVALID_PARAMETER;
1694 if (!func_layer->layer_set_video_pos) {
1695 _pthread_mutex_unlock(&private_display->lock);
1696 TDM_DBG("failed: not implemented!!");
1697 return TDM_ERROR_NOT_IMPLEMENTED;
1700 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1702 _pthread_mutex_unlock(&private_display->lock);
1707 EXTERN tdm_capture *
1708 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1710 tdm_capture *capture = NULL;
1712 LAYER_FUNC_ENTRY_ERROR();
1714 _pthread_mutex_lock(&private_display->lock);
1716 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1719 _pthread_mutex_unlock(&private_display->lock);