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 if (private_output->current_dpms_value == dpms_value) {
1134 _pthread_mutex_unlock(&private_display->lock);
1135 return TDM_ERROR_NONE;
1138 func_output = &private_display->func_output;
1140 if (!func_output->output_set_dpms) {
1141 _pthread_mutex_unlock(&private_display->lock);
1142 TDM_DBG("failed: not implemented!!");
1143 return TDM_ERROR_NOT_IMPLEMENTED;
1146 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1147 if (ret == TDM_ERROR_NONE) {
1150 private_output->current_dpms_value = dpms_value;
1152 value.u32 = dpms_value;
1153 tdm_output_call_change_handler_internal(private_output,
1154 &private_output->change_handler_list_main,
1155 TDM_OUTPUT_CHANGE_DPMS,
1159 _pthread_mutex_unlock(&private_display->lock);
1165 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1167 tdm_func_output *func_output;
1168 OUTPUT_FUNC_ENTRY();
1170 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1172 _pthread_mutex_lock(&private_display->lock);
1174 func_output = &private_display->func_output;
1176 if (!func_output->output_get_dpms) {
1177 _pthread_mutex_unlock(&private_display->lock);
1178 TDM_DBG("failed: not implemented!!");
1179 return TDM_ERROR_NOT_IMPLEMENTED;
1182 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1184 _pthread_mutex_unlock(&private_display->lock);
1189 EXTERN tdm_capture *
1190 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1192 tdm_capture *capture = NULL;
1194 OUTPUT_FUNC_ENTRY_ERROR();
1196 _pthread_mutex_lock(&private_display->lock);
1198 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1201 _pthread_mutex_unlock(&private_display->lock);
1207 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1208 struct list_head *change_handler_list,
1209 tdm_output_change_type type,
1212 tdm_private_display *private_display;
1213 tdm_private_change_handler *change_handler;
1215 TDM_RETURN_IF_FAIL(private_output);
1217 private_display = private_output->private_display;
1218 if (!tdm_thread_in_display_thread(private_display->private_loop,
1219 syscall(SYS_gettid))) {
1220 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1221 TDM_INFO("output(%d) changed: %s (%d)",
1222 private_output->pipe, status_str(value.u32), value.u32);
1223 if (type & TDM_OUTPUT_CHANGE_DPMS)
1224 TDM_INFO("output(%d) changed: dpms %s (%d)",
1225 private_output->pipe, dpms_str(value.u32), value.u32);
1228 if (LIST_IS_EMPTY(change_handler_list))
1231 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1232 if (change_handler->owner_tid != syscall(SYS_gettid))
1233 TDM_NEVER_GET_HERE();
1235 change_handler->func(private_output, type,
1236 value, change_handler->user_data);
1241 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1245 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1247 _pthread_mutex_lock(&private_display->lock);
1249 *capabilities = private_layer->caps.capabilities;
1251 _pthread_mutex_unlock(&private_display->lock);
1257 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1262 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1263 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1265 _pthread_mutex_lock(&private_display->lock);
1267 *formats = (const tbm_format *)private_layer->caps.formats;
1268 *count = private_layer->caps.format_count;
1270 _pthread_mutex_unlock(&private_display->lock);
1276 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1281 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1282 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1284 _pthread_mutex_lock(&private_display->lock);
1286 *props = (const tdm_prop *)private_layer->caps.props;
1287 *count = private_layer->caps.prop_count;
1289 _pthread_mutex_unlock(&private_display->lock);
1295 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1299 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1301 _pthread_mutex_lock(&private_display->lock);
1303 *zpos = private_layer->caps.zpos;
1305 _pthread_mutex_unlock(&private_display->lock);
1311 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1313 tdm_func_layer *func_layer;
1316 _pthread_mutex_lock(&private_display->lock);
1318 func_layer = &private_display->func_layer;
1320 if (!func_layer->layer_set_property) {
1321 _pthread_mutex_unlock(&private_display->lock);
1322 TDM_DBG("failed: not implemented!!");
1323 return TDM_ERROR_NOT_IMPLEMENTED;
1326 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1328 _pthread_mutex_unlock(&private_display->lock);
1334 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1336 tdm_func_layer *func_layer;
1339 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1341 _pthread_mutex_lock(&private_display->lock);
1343 func_layer = &private_display->func_layer;
1345 if (!func_layer->layer_get_property) {
1346 _pthread_mutex_unlock(&private_display->lock);
1347 TDM_DBG("failed: not implemented!!");
1348 return TDM_ERROR_NOT_IMPLEMENTED;
1351 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1353 _pthread_mutex_unlock(&private_display->lock);
1359 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1361 tdm_func_layer *func_layer;
1364 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1366 _pthread_mutex_lock(&private_display->lock);
1368 func_layer = &private_display->func_layer;
1370 private_layer->usable = 0;
1372 if (!func_layer->layer_set_info) {
1373 _pthread_mutex_unlock(&private_display->lock);
1374 TDM_DBG("failed: not implemented!!");
1375 return TDM_ERROR_NOT_IMPLEMENTED;
1378 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1379 private_layer, info->src_config.size.h, info->src_config.size.v,
1380 info->src_config.pos.x, info->src_config.pos.y,
1381 info->src_config.pos.w, info->src_config.pos.h,
1382 FOURCC_STR(info->src_config.format),
1383 info->dst_pos.x, info->dst_pos.y,
1384 info->dst_pos.w, info->dst_pos.h,
1387 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1388 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1390 _pthread_mutex_unlock(&private_display->lock);
1396 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1398 tdm_func_layer *func_layer;
1401 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1403 _pthread_mutex_lock(&private_display->lock);
1405 func_layer = &private_display->func_layer;
1407 if (!func_layer->layer_get_info) {
1408 _pthread_mutex_unlock(&private_display->lock);
1409 TDM_DBG("failed: not implemented!!");
1410 return TDM_ERROR_NOT_IMPLEMENTED;
1413 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1415 _pthread_mutex_unlock(&private_display->lock);
1421 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1423 tdm_func_layer *func_layer;
1427 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1429 _pthread_mutex_lock(&private_display->lock);
1431 func_layer = &private_display->func_layer;
1433 private_layer->usable = 0;
1435 if (!func_layer->layer_set_buffer) {
1436 _pthread_mutex_unlock(&private_display->lock);
1437 TDM_DBG("failed: not implemented!!");
1438 return TDM_ERROR_NOT_IMPLEMENTED;
1441 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1442 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1444 if (ret == TDM_ERROR_NONE) {
1445 /* FIXME: should save to pending_buffer first. And after committing
1446 * successfully, need to move to waiting_buffer.
1448 if (private_layer->waiting_buffer) {
1449 _pthread_mutex_unlock(&private_display->lock);
1450 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1451 _pthread_mutex_lock(&private_display->lock);
1454 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1455 if (tdm_debug_buffer)
1456 TDM_INFO("layer(%p) waiting_buffer(%p)",
1457 private_layer, private_layer->waiting_buffer);
1460 _pthread_mutex_unlock(&private_display->lock);
1466 tdm_layer_unset_buffer(tdm_layer *layer)
1468 tdm_func_layer *func_layer;
1471 _pthread_mutex_lock(&private_display->lock);
1473 func_layer = &private_display->func_layer;
1475 if (private_layer->waiting_buffer) {
1476 _pthread_mutex_unlock(&private_display->lock);
1477 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1478 _pthread_mutex_lock(&private_display->lock);
1479 private_layer->waiting_buffer = NULL;
1481 if (tdm_debug_buffer)
1482 TDM_INFO("layer(%p) waiting_buffer(%p)",
1483 private_layer, private_layer->waiting_buffer);
1486 if (private_layer->showing_buffer) {
1487 _pthread_mutex_unlock(&private_display->lock);
1488 tdm_buffer_unref_backend(private_layer->showing_buffer);
1489 _pthread_mutex_lock(&private_display->lock);
1490 private_layer->showing_buffer = NULL;
1492 if (tdm_debug_buffer)
1493 TDM_INFO("layer(%p) showing_buffer(%p)",
1494 private_layer, private_layer->showing_buffer);
1497 private_layer->usable = 1;
1499 if (!func_layer->layer_unset_buffer) {
1500 _pthread_mutex_unlock(&private_display->lock);
1501 TDM_DBG("failed: not implemented!!");
1502 return TDM_ERROR_NOT_IMPLEMENTED;
1505 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1506 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1508 _pthread_mutex_unlock(&private_display->lock);
1514 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1516 TDM_RETURN_IF_FAIL(data != NULL);
1517 tdm_layer *layer = data;
1518 tdm_func_layer *func_layer;
1519 tbm_surface_h surface = NULL;
1520 LAYER_FUNC_ENTRY_VOID_RETURN();
1522 _pthread_mutex_lock(&private_display->lock);
1524 func_layer = &private_display->func_layer;
1525 if (!func_layer->layer_set_buffer) {
1526 _pthread_mutex_unlock(&private_display->lock);
1530 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1531 private_layer->buffer_queue, &surface) ||
1533 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1534 private_layer, surface);
1535 _pthread_mutex_unlock(&private_display->lock);
1539 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1540 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1542 if (ret == TDM_ERROR_NONE) {
1543 if (private_layer->waiting_buffer) {
1544 _pthread_mutex_unlock(&private_display->lock);
1545 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1546 tbm_surface_queue_release(private_layer->buffer_queue,
1547 private_layer->waiting_buffer);
1548 _pthread_mutex_lock(&private_display->lock);
1551 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1553 if (tdm_debug_buffer)
1554 TDM_INFO("layer(%p) waiting_buffer(%p)",
1555 private_layer, private_layer->waiting_buffer);
1557 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1558 if (ret != TDM_ERROR_NONE)
1559 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1562 _pthread_mutex_unlock(&private_display->lock);
1566 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1568 TDM_RETURN_IF_FAIL(data != NULL);
1569 tdm_layer *layer = data;
1570 LAYER_FUNC_ENTRY_VOID_RETURN();
1571 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1573 _pthread_mutex_lock(&private_display->lock);
1575 if (private_layer->waiting_buffer) {
1576 _pthread_mutex_unlock(&private_display->lock);
1577 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1578 tbm_surface_queue_release(private_layer->buffer_queue,
1579 private_layer->waiting_buffer);
1580 _pthread_mutex_lock(&private_display->lock);
1583 private_layer->buffer_queue = NULL;
1585 _pthread_mutex_unlock(&private_display->lock);
1589 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1591 tdm_func_layer *func_layer;
1594 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1596 _pthread_mutex_lock(&private_display->lock);
1598 func_layer = &private_display->func_layer;
1600 private_layer->usable = 0;
1602 if (!func_layer->layer_set_buffer) {
1603 _pthread_mutex_unlock(&private_display->lock);
1604 TDM_DBG("failed: not implemented!!");
1605 return TDM_ERROR_NOT_IMPLEMENTED;
1608 if (buffer_queue == private_layer->buffer_queue) {
1609 _pthread_mutex_unlock(&private_display->lock);
1610 return TDM_ERROR_NONE;
1613 if (private_layer->waiting_buffer) {
1614 _pthread_mutex_unlock(&private_display->lock);
1615 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1616 tbm_surface_queue_release(private_layer->buffer_queue,
1617 private_layer->waiting_buffer);
1618 private_layer->waiting_buffer = NULL;
1619 _pthread_mutex_lock(&private_display->lock);
1621 if (tdm_debug_buffer)
1622 TDM_INFO("layer(%p) waiting_buffer(%p)",
1623 private_layer, private_layer->waiting_buffer);
1626 private_layer->buffer_queue = buffer_queue;
1627 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1628 _tbm_layer_queue_acquirable_cb,
1630 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1631 _tbm_layer_queue_destroy_cb,
1633 _pthread_mutex_unlock(&private_display->lock);
1639 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1641 tdm_func_layer *func_layer;
1644 _pthread_mutex_lock(&private_display->lock);
1646 func_layer = &private_display->func_layer;
1648 if (private_layer->waiting_buffer) {
1649 _pthread_mutex_unlock(&private_display->lock);
1650 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1651 tbm_surface_queue_release(private_layer->buffer_queue,
1652 private_layer->waiting_buffer);
1653 private_layer->waiting_buffer = NULL;
1654 _pthread_mutex_lock(&private_display->lock);
1656 if (tdm_debug_buffer)
1657 TDM_INFO("layer(%p) waiting_buffer(%p)",
1658 private_layer, private_layer->waiting_buffer);
1661 if (private_layer->showing_buffer) {
1662 _pthread_mutex_unlock(&private_display->lock);
1663 tdm_buffer_unref_backend(private_layer->showing_buffer);
1664 tbm_surface_queue_release(private_layer->buffer_queue,
1665 private_layer->showing_buffer);
1666 _pthread_mutex_lock(&private_display->lock);
1667 private_layer->showing_buffer = NULL;
1669 if (tdm_debug_buffer)
1670 TDM_INFO("layer(%p) showing_buffer(%p)",
1671 private_layer, private_layer->showing_buffer);
1674 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1675 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1676 private_layer->buffer_queue = NULL;
1677 private_layer->usable = 1;
1679 if (!func_layer->layer_unset_buffer) {
1680 _pthread_mutex_unlock(&private_display->lock);
1681 TDM_DBG("failed: not implemented!!");
1682 return TDM_ERROR_NOT_IMPLEMENTED;
1685 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1687 _pthread_mutex_unlock(&private_display->lock);
1693 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1697 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1699 _pthread_mutex_lock(&private_display->lock);
1701 *usable = private_layer->usable;
1703 _pthread_mutex_unlock(&private_display->lock);
1709 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1711 tdm_func_layer *func_layer;
1714 _pthread_mutex_lock(&private_display->lock);
1716 func_layer = &private_display->func_layer;
1718 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1719 TDM_ERR("layer(%p) is not video layer", private_layer);
1720 _pthread_mutex_unlock(&private_display->lock);
1721 return TDM_ERROR_INVALID_PARAMETER;
1724 if (!func_layer->layer_set_video_pos) {
1725 _pthread_mutex_unlock(&private_display->lock);
1726 TDM_DBG("failed: not implemented!!");
1727 return TDM_ERROR_NOT_IMPLEMENTED;
1730 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1732 _pthread_mutex_unlock(&private_display->lock);
1737 EXTERN tdm_capture *
1738 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1740 tdm_capture *capture = NULL;
1742 LAYER_FUNC_ENTRY_ERROR();
1744 _pthread_mutex_lock(&private_display->lock);
1746 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1749 _pthread_mutex_unlock(&private_display->lock);