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"
43 #include "tdm_helper.h"
47 #define DISPLAY_FUNC_ENTRY() \
48 tdm_private_display *private_display; \
49 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50 TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
51 private_display = (tdm_private_display*)dpy;
53 #define DISPLAY_FUNC_ENTRY_ERROR() \
54 tdm_private_display *private_display; \
55 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
56 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
57 private_display = (tdm_private_display*)dpy;
59 #define OUTPUT_FUNC_ENTRY() \
60 tdm_private_display *private_display; \
61 tdm_private_output *private_output; \
62 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
63 TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
64 private_output = (tdm_private_output*)output; \
65 private_display = private_output->private_display
67 #define OUTPUT_FUNC_ENTRY_ERROR() \
68 tdm_private_display *private_display; \
69 tdm_private_output *private_output; \
70 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
71 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
72 private_output = (tdm_private_output*)output; \
73 private_display = private_output->private_display
75 #define LAYER_FUNC_ENTRY() \
76 tdm_private_display *private_display; \
77 tdm_private_output *private_output; \
78 tdm_private_layer *private_layer; \
79 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
80 TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
81 private_layer = (tdm_private_layer*)layer; \
82 private_output = private_layer->private_output; \
83 private_display = private_output->private_display
85 #define LAYER_FUNC_ENTRY_ERROR() \
86 tdm_private_display *private_display; \
87 tdm_private_output *private_output; \
88 tdm_private_layer *private_layer; \
89 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
90 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
91 private_layer = (tdm_private_layer*)layer; \
92 private_output = private_layer->private_output; \
93 private_display = private_output->private_display
95 #define LAYER_FUNC_ENTRY_VOID_RETURN() \
96 tdm_private_display *private_display; \
97 tdm_private_output *private_output; \
98 tdm_private_layer *private_layer; \
99 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
100 TDM_RETURN_IF_FAIL(layer != NULL); \
101 private_layer = (tdm_private_layer*)layer; \
102 private_output = private_layer->private_output; \
103 private_display = private_output->private_display
105 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
112 #define type_name_fn(res) \
113 const char * res##_str(int type) { \
115 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
116 if (res##_names[i].type == type) \
117 return res##_names[i].name; \
119 return "(invalid)"; \
122 struct type_name dpms_names[] = {
123 { TDM_OUTPUT_DPMS_ON, "on" },
124 { TDM_OUTPUT_DPMS_STANDBY, "standby" },
125 { TDM_OUTPUT_DPMS_SUSPEND, "suspend" },
126 { TDM_OUTPUT_DPMS_OFF, "off" },
129 INTERN type_name_fn(dpms)
131 struct type_name status_names[] = {
132 { TDM_OUTPUT_CONN_STATUS_DISCONNECTED, "disconnected" },
133 { TDM_OUTPUT_CONN_STATUS_CONNECTED, "connected" },
134 { TDM_OUTPUT_CONN_STATUS_MODE_SETTED, "mode_setted" },
137 INTERN type_name_fn(status)
140 tdm_display_get_capabilities(tdm_display *dpy,
141 tdm_display_capability *capabilities)
143 DISPLAY_FUNC_ENTRY();
145 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
147 _pthread_mutex_lock(&private_display->lock);
149 *capabilities = private_display->capabilities;
151 _pthread_mutex_unlock(&private_display->lock);
157 tdm_display_get_pp_capabilities(tdm_display *dpy,
158 tdm_pp_capability *capabilities)
160 DISPLAY_FUNC_ENTRY();
162 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
164 _pthread_mutex_lock(&private_display->lock);
166 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
167 TDM_ERR("no pp capability");
168 _pthread_mutex_unlock(&private_display->lock);
169 return TDM_ERROR_NO_CAPABILITY;
172 *capabilities = private_display->caps_pp.capabilities;
174 _pthread_mutex_unlock(&private_display->lock);
180 tdm_display_get_pp_available_formats(tdm_display *dpy,
181 const tbm_format **formats, int *count)
183 DISPLAY_FUNC_ENTRY();
185 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
186 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
188 _pthread_mutex_lock(&private_display->lock);
190 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
191 TDM_ERR("no pp capability");
192 _pthread_mutex_unlock(&private_display->lock);
193 return TDM_ERROR_NO_CAPABILITY;
196 *formats = (const tbm_format *)private_display->caps_pp.formats;
197 *count = private_display->caps_pp.format_count;
199 _pthread_mutex_unlock(&private_display->lock);
205 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
206 int *max_w, int *max_h, int *preferred_align)
208 DISPLAY_FUNC_ENTRY();
210 _pthread_mutex_lock(&private_display->lock);
212 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
213 TDM_ERR("no pp capability");
214 _pthread_mutex_unlock(&private_display->lock);
215 return TDM_ERROR_NO_CAPABILITY;
219 *min_w = private_display->caps_pp.min_w;
221 *min_h = private_display->caps_pp.min_h;
223 *max_w = private_display->caps_pp.max_w;
225 *max_h = private_display->caps_pp.max_h;
227 *preferred_align = private_display->caps_pp.preferred_align;
229 _pthread_mutex_unlock(&private_display->lock);
235 tdm_display_get_capture_capabilities(tdm_display *dpy,
236 tdm_capture_capability *capabilities)
238 DISPLAY_FUNC_ENTRY();
240 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
242 _pthread_mutex_lock(&private_display->lock);
244 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
245 TDM_ERR("no capture capability");
246 _pthread_mutex_unlock(&private_display->lock);
247 return TDM_ERROR_NO_CAPABILITY;
250 *capabilities = private_display->caps_capture.capabilities;
252 _pthread_mutex_unlock(&private_display->lock);
258 tdm_display_get_catpure_available_formats(tdm_display *dpy,
259 const tbm_format **formats, int *count)
261 DISPLAY_FUNC_ENTRY();
263 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
264 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
266 _pthread_mutex_lock(&private_display->lock);
268 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
269 TDM_ERR("no capture capability");
270 _pthread_mutex_unlock(&private_display->lock);
271 return TDM_ERROR_NO_CAPABILITY;
274 *formats = (const tbm_format *)private_display->caps_capture.formats;
275 *count = private_display->caps_capture.format_count;
277 _pthread_mutex_unlock(&private_display->lock);
283 tdm_display_get_output_count(tdm_display *dpy, int *count)
285 tdm_private_output *private_output = NULL;
287 DISPLAY_FUNC_ENTRY();
289 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
291 _pthread_mutex_lock(&private_display->lock);
294 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
298 _pthread_mutex_unlock(&private_display->lock);
299 return TDM_ERROR_NONE;
302 _pthread_mutex_unlock(&private_display->lock);
309 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
311 tdm_private_output *private_output = NULL;
314 DISPLAY_FUNC_ENTRY_ERROR();
316 _pthread_mutex_lock(&private_display->lock);
319 *error = TDM_ERROR_NONE;
322 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
324 _pthread_mutex_unlock(&private_display->lock);
325 return private_output;
330 _pthread_mutex_unlock(&private_display->lock);
336 tdm_display_get_fd(tdm_display *dpy, int *fd)
338 DISPLAY_FUNC_ENTRY();
340 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
342 _pthread_mutex_lock(&private_display->lock);
344 if (private_display->private_loop->private_thread) {
345 _pthread_mutex_unlock(&private_display->lock);
346 *fd = tdm_thread_get_fd(private_display->private_loop);
347 _pthread_mutex_lock(&private_display->lock);
350 *fd = tdm_event_loop_get_fd(private_display);
352 _pthread_mutex_unlock(&private_display->lock);
358 tdm_display_handle_events(tdm_display *dpy)
363 DISPLAY_FUNC_ENTRY();
365 ret = tdm_display_get_fd(dpy, &fd);
366 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
372 if (tdm_debug_thread)
373 TDM_INFO("fd(%d) polling in", fd);
375 while (poll(&fds, 1, -1) < 0) {
376 if (errno == EBUSY) /* normal case */
379 TDM_ERR("poll failed: %m");
380 return TDM_ERROR_OPERATION_FAILED;
384 if (tdm_debug_thread)
385 TDM_INFO("fd(%d) polling out", fd);
387 _pthread_mutex_lock(&private_display->lock);
389 if (private_display->private_loop->private_thread) {
390 _pthread_mutex_unlock(&private_display->lock);
391 ret = tdm_thread_handle_cb(private_display->private_loop);
392 _pthread_mutex_lock(&private_display->lock);
395 ret = tdm_event_loop_dispatch(private_display);
397 _pthread_mutex_unlock(&private_display->lock);
403 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
407 DISPLAY_FUNC_ENTRY_ERROR();
409 _pthread_mutex_lock(&private_display->lock);
411 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
413 _pthread_mutex_unlock(&private_display->lock);
419 tdm_output_get_model_info(tdm_output *output, const char **maker,
420 const char **model, const char **name)
424 _pthread_mutex_lock(&private_display->lock);
427 *maker = private_output->caps.maker;
429 *model = private_output->caps.model;
431 *name = private_output->caps.name;
433 _pthread_mutex_unlock(&private_display->lock);
439 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
443 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
445 _pthread_mutex_lock(&private_display->lock);
447 *status = private_output->caps.status;
449 _pthread_mutex_unlock(&private_display->lock);
455 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
458 tdm_private_display *private_display;
459 tdm_private_output *private_output = user_data;
461 int lock_after_cb_done = 0;
464 TDM_RETURN_IF_FAIL(private_output);
466 private_display = private_output->private_display;
468 if (!tdm_thread_in_display_thread(private_display->private_loop,
469 syscall(SYS_gettid))) {
470 tdm_thread_cb_output_status output_status;
473 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
474 output_status.base.length = sizeof output_status;
475 output_status.output_stamp = private_output->stamp;
476 output_status.status = status;
477 output_status.user_data = user_data;
480 tdm_output_call_change_handler_internal(private_output,
481 &private_output->change_handler_list_sub,
482 TDM_OUTPUT_CHANGE_CONNECTION,
485 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
486 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
491 ret = pthread_mutex_trylock(&private_display->lock);
493 _pthread_mutex_unlock(&private_display->lock);
494 else if (ret == EBUSY) {
495 _pthread_mutex_unlock(&private_display->lock);
496 lock_after_cb_done = 1;
500 tdm_output_call_change_handler_internal(private_output,
501 &private_output->change_handler_list_main,
502 TDM_OUTPUT_CHANGE_CONNECTION,
505 if (lock_after_cb_done)
506 _pthread_mutex_lock(&private_display->lock);
510 tdm_output_add_change_handler(tdm_output *output,
511 tdm_output_change_handler func,
514 tdm_private_change_handler *change_handler;
517 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
519 pthread_mutex_lock(&private_display->lock);
521 if (!private_output->regist_change_cb) {
522 _pthread_mutex_unlock(&private_display->lock);
523 TDM_DBG("failed: not implemented!!");
524 return TDM_ERROR_NOT_IMPLEMENTED;
527 change_handler = calloc(1, sizeof(tdm_private_change_handler));
528 if (!change_handler) {
529 TDM_ERR("failed: alloc memory");
530 _pthread_mutex_unlock(&private_display->lock);
531 return TDM_ERROR_OUT_OF_MEMORY;
534 change_handler->private_output = private_output;
535 change_handler->func = func;
536 change_handler->user_data = user_data;
537 change_handler->owner_tid = syscall(SYS_gettid);
539 if (!tdm_thread_in_display_thread(private_display->private_loop,
540 change_handler->owner_tid))
541 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
543 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
545 _pthread_mutex_unlock(&private_display->lock);
551 tdm_output_remove_change_handler(tdm_output *output,
552 tdm_output_change_handler func,
555 tdm_private_display *private_display;
556 tdm_private_output *private_output;
557 tdm_private_change_handler *h = NULL, *hh = NULL;
559 TDM_RETURN_IF_FAIL(output != NULL);
560 TDM_RETURN_IF_FAIL(func != NULL);
562 private_output = (tdm_private_output*)output;
563 private_display = private_output->private_display;
565 _pthread_mutex_lock(&private_display->lock);
567 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
568 if (h->func != func || h->user_data != user_data)
574 _pthread_mutex_unlock(&private_display->lock);
579 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
580 if (h->func != func || h->user_data != user_data)
586 _pthread_mutex_unlock(&private_display->lock);
591 _pthread_mutex_unlock(&private_display->lock);
595 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
599 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
601 _pthread_mutex_lock(&private_display->lock);
603 *type = private_output->caps.type;
605 _pthread_mutex_unlock(&private_display->lock);
611 tdm_output_get_layer_count(tdm_output *output, int *count)
613 tdm_private_layer *private_layer = NULL;
617 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
619 _pthread_mutex_lock(&private_display->lock);
622 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
625 _pthread_mutex_unlock(&private_display->lock);
626 return TDM_ERROR_NONE;
629 _pthread_mutex_unlock(&private_display->lock);
636 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
638 tdm_private_layer *private_layer = NULL;
641 OUTPUT_FUNC_ENTRY_ERROR();
643 _pthread_mutex_lock(&private_display->lock);
646 *error = TDM_ERROR_NONE;
648 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
650 _pthread_mutex_unlock(&private_display->lock);
651 return private_layer;
656 _pthread_mutex_unlock(&private_display->lock);
662 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
667 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
668 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
670 _pthread_mutex_lock(&private_display->lock);
672 *props = (const tdm_prop *)private_output->caps.props;
673 *count = private_output->caps.prop_count;
675 _pthread_mutex_unlock(&private_display->lock);
681 tdm_output_get_available_modes(tdm_output *output,
682 const tdm_output_mode **modes, int *count)
686 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
687 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
689 _pthread_mutex_lock(&private_display->lock);
691 *modes = (const tdm_output_mode *)private_output->caps.modes;
692 *count = private_output->caps.mode_count;
694 _pthread_mutex_unlock(&private_display->lock);
700 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
701 int *max_w, int *max_h, int *preferred_align)
705 _pthread_mutex_lock(&private_display->lock);
708 *min_w = private_output->caps.min_w;
710 *min_h = private_output->caps.min_h;
712 *max_w = private_output->caps.max_w;
714 *max_h = private_output->caps.max_h;
716 *preferred_align = private_output->caps.preferred_align;
718 _pthread_mutex_unlock(&private_display->lock);
724 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
725 unsigned int *mmHeight)
729 _pthread_mutex_lock(&private_display->lock);
732 *mmWidth = private_output->caps.mmWidth;
734 *mmHeight = private_output->caps.mmHeight;
736 _pthread_mutex_unlock(&private_display->lock);
742 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
745 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
747 _pthread_mutex_lock(&private_display->lock);
749 *subpixel = private_output->caps.subpixel;
751 _pthread_mutex_unlock(&private_display->lock);
757 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
760 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
762 _pthread_mutex_lock(&private_display->lock);
764 *pipe = private_output->pipe;
766 _pthread_mutex_unlock(&private_display->lock);
773 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
775 tdm_func_output *func_output;
778 _pthread_mutex_lock(&private_display->lock);
780 func_output = &private_display->func_output;
782 if (!func_output->output_set_property) {
783 _pthread_mutex_unlock(&private_display->lock);
784 TDM_DBG("failed: not implemented!!");
785 return TDM_ERROR_NOT_IMPLEMENTED;
788 ret = func_output->output_set_property(private_output->output_backend, id,
791 _pthread_mutex_unlock(&private_display->lock);
797 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
799 tdm_func_output *func_output;
802 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
804 _pthread_mutex_lock(&private_display->lock);
806 func_output = &private_display->func_output;
808 if (!func_output->output_get_property) {
809 _pthread_mutex_unlock(&private_display->lock);
810 TDM_DBG("failed: not implemented!!");
811 return TDM_ERROR_NOT_IMPLEMENTED;
814 ret = func_output->output_get_property(private_output->output_backend, id,
817 _pthread_mutex_unlock(&private_display->lock);
823 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
824 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
826 tdm_private_vblank_handler *vblank_handler = user_data;
827 tdm_private_display *private_display;
829 TDM_RETURN_IF_FAIL(vblank_handler);
831 private_display = vblank_handler->private_output->private_display;
833 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
834 tdm_thread_cb_output_vblank output_vblank;
837 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
838 output_vblank.base.length = sizeof output_vblank;
839 output_vblank.output_stamp = vblank_handler->private_output->stamp;
840 output_vblank.sequence = sequence;
841 output_vblank.tv_sec = tv_sec;
842 output_vblank.tv_usec = tv_usec;
843 output_vblank.user_data = user_data;
845 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
846 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
851 if (vblank_handler->owner_tid != syscall(SYS_gettid))
852 TDM_NEVER_GET_HERE();
854 if (vblank_handler->func) {
855 int lock_after_cb_done = 0;
858 ret = pthread_mutex_trylock(&private_display->lock);
860 _pthread_mutex_unlock(&private_display->lock);
861 else if (ret == EBUSY) {
862 _pthread_mutex_unlock(&private_display->lock);
863 lock_after_cb_done = 1;
866 vblank_handler->func(vblank_handler->private_output, sequence,
867 tv_sec, tv_usec, vblank_handler->user_data);
869 if (lock_after_cb_done)
870 _pthread_mutex_lock(&private_display->lock);
873 LIST_DEL(&vblank_handler->link);
874 free(vblank_handler);
878 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
879 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
881 tdm_private_commit_handler *commit_handler = user_data;
882 tdm_private_display *private_display;
883 tdm_private_output *private_output;
884 tdm_private_layer *private_layer = NULL;
885 int lock_after_cb_done = 0;
888 TDM_RETURN_IF_FAIL(commit_handler);
890 private_output = commit_handler->private_output;
891 private_display = private_output->private_display;
893 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
894 tdm_thread_cb_output_commit output_commit;
897 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
898 output_commit.base.length = sizeof output_commit;
899 output_commit.output_stamp = private_output->stamp;
900 output_commit.sequence = sequence;
901 output_commit.tv_sec = tv_sec;
902 output_commit.tv_usec = tv_usec;
903 output_commit.user_data = user_data;
905 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
906 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
911 ret = pthread_mutex_trylock(&private_display->lock);
913 _pthread_mutex_unlock(&private_display->lock);
914 else if (ret == EBUSY) {
915 _pthread_mutex_unlock(&private_display->lock);
916 lock_after_cb_done = 1;
919 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
920 if (!private_layer->waiting_buffer)
923 if (private_layer->showing_buffer) {
924 tdm_buffer_unref_backend(private_layer->showing_buffer);
926 if (private_layer->buffer_queue) {
927 tbm_surface_queue_release(private_layer->buffer_queue,
928 private_layer->showing_buffer);
932 private_layer->showing_buffer = private_layer->waiting_buffer;
933 private_layer->waiting_buffer = NULL;
935 if (tdm_debug_buffer)
936 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
937 private_layer, private_layer->waiting_buffer,
938 private_layer->showing_buffer);
941 if (commit_handler->func) {
942 commit_handler->func(private_output, sequence,
943 tv_sec, tv_usec, commit_handler->user_data);
946 if (lock_after_cb_done)
947 _pthread_mutex_lock(&private_display->lock);
949 LIST_DEL(&commit_handler->link);
950 free(commit_handler);
954 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
955 tdm_output_vblank_handler func, void *user_data)
957 tdm_func_output *func_output;
958 tdm_private_vblank_handler *vblank_handler;
961 _pthread_mutex_lock(&private_display->lock);
963 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
964 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
965 dpms_str(private_output->current_dpms_value));
966 _pthread_mutex_unlock(&private_display->lock);
967 return TDM_ERROR_BAD_REQUEST;
970 func_output = &private_display->func_output;
972 if (!func_output->output_wait_vblank) {
973 _pthread_mutex_unlock(&private_display->lock);
974 TDM_DBG("failed: not implemented!!");
975 return TDM_ERROR_NOT_IMPLEMENTED;
978 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
979 if (!vblank_handler) {
980 TDM_ERR("failed: alloc memory");
981 _pthread_mutex_unlock(&private_display->lock);
982 return TDM_ERROR_OUT_OF_MEMORY;
985 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
986 vblank_handler->private_output = private_output;
987 vblank_handler->func = func;
988 vblank_handler->user_data = user_data;
989 vblank_handler->owner_tid = syscall(SYS_gettid);
991 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
992 sync, vblank_handler);
993 if (ret != TDM_ERROR_NONE) {
994 _pthread_mutex_unlock(&private_display->lock);
998 if (!private_output->regist_vblank_cb) {
999 private_output->regist_vblank_cb = 1;
1000 ret = func_output->output_set_vblank_handler(private_output->output_backend,
1001 tdm_output_cb_vblank);
1004 _pthread_mutex_unlock(&private_display->lock);
1010 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1013 tdm_func_output *func_output;
1014 tdm_private_commit_handler *commit_handler;
1015 OUTPUT_FUNC_ENTRY();
1017 func_output = &private_display->func_output;
1019 if (!func_output->output_commit) {
1020 TDM_DBG("failed: not implemented!!");
1021 return TDM_ERROR_NOT_IMPLEMENTED;
1024 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1025 if (!commit_handler) {
1026 TDM_ERR("failed: alloc memory");
1027 return TDM_ERROR_OUT_OF_MEMORY;
1030 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1031 commit_handler->private_output = private_output;
1032 commit_handler->func = func;
1033 commit_handler->user_data = user_data;
1034 commit_handler->owner_tid = syscall(SYS_gettid);
1036 ret = func_output->output_commit(private_output->output_backend, sync,
1038 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1040 if (!private_output->regist_commit_cb) {
1041 private_output->regist_commit_cb = 1;
1042 ret = func_output->output_set_commit_handler(private_output->output_backend,
1043 tdm_output_cb_commit);
1050 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1053 OUTPUT_FUNC_ENTRY();
1055 _pthread_mutex_lock(&private_display->lock);
1057 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1058 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
1059 dpms_str(private_output->current_dpms_value));
1060 _pthread_mutex_unlock(&private_display->lock);
1061 return TDM_ERROR_BAD_REQUEST;
1064 ret = _tdm_output_commit(output, sync, func, user_data);
1066 _pthread_mutex_unlock(&private_display->lock);
1072 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1074 tdm_func_output *func_output;
1075 OUTPUT_FUNC_ENTRY();
1077 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1079 _pthread_mutex_lock(&private_display->lock);
1081 func_output = &private_display->func_output;
1083 if (!func_output->output_set_mode) {
1084 _pthread_mutex_unlock(&private_display->lock);
1085 TDM_DBG("failed: not implemented!!");
1086 return TDM_ERROR_NOT_IMPLEMENTED;
1089 ret = func_output->output_set_mode(private_output->output_backend, mode);
1091 _pthread_mutex_unlock(&private_display->lock);
1097 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1099 tdm_func_output *func_output;
1100 OUTPUT_FUNC_ENTRY();
1102 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1104 _pthread_mutex_lock(&private_display->lock);
1106 func_output = &private_display->func_output;
1108 if (!func_output->output_get_mode) {
1109 _pthread_mutex_unlock(&private_display->lock);
1110 TDM_DBG("failed: not implemented!!");
1111 return TDM_ERROR_NOT_IMPLEMENTED;
1114 ret = func_output->output_get_mode(private_output->output_backend, mode);
1116 _pthread_mutex_unlock(&private_display->lock);
1122 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1124 tdm_func_output *func_output;
1125 OUTPUT_FUNC_ENTRY();
1127 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1128 dpms_value = TDM_OUTPUT_DPMS_ON;
1129 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1130 dpms_value = TDM_OUTPUT_DPMS_OFF;
1132 _pthread_mutex_lock(&private_display->lock);
1134 if (private_output->current_dpms_value == dpms_value) {
1135 _pthread_mutex_unlock(&private_display->lock);
1136 return TDM_ERROR_NONE;
1139 func_output = &private_display->func_output;
1141 if (!func_output->output_set_dpms) {
1142 _pthread_mutex_unlock(&private_display->lock);
1143 TDM_DBG("failed: not implemented!!");
1144 return TDM_ERROR_NOT_IMPLEMENTED;
1147 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1148 if (ret == TDM_ERROR_NONE) {
1151 private_output->current_dpms_value = dpms_value;
1153 value.u32 = dpms_value;
1154 tdm_output_call_change_handler_internal(private_output,
1155 &private_output->change_handler_list_main,
1156 TDM_OUTPUT_CHANGE_DPMS,
1160 _pthread_mutex_unlock(&private_display->lock);
1166 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1168 tdm_func_output *func_output;
1169 OUTPUT_FUNC_ENTRY();
1171 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1173 _pthread_mutex_lock(&private_display->lock);
1175 func_output = &private_display->func_output;
1177 if (!func_output->output_get_dpms) {
1178 _pthread_mutex_unlock(&private_display->lock);
1179 TDM_DBG("failed: not implemented!!");
1180 return TDM_ERROR_NOT_IMPLEMENTED;
1183 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1185 _pthread_mutex_unlock(&private_display->lock);
1190 EXTERN tdm_capture *
1191 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1193 tdm_capture *capture = NULL;
1195 OUTPUT_FUNC_ENTRY_ERROR();
1197 _pthread_mutex_lock(&private_display->lock);
1199 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1202 _pthread_mutex_unlock(&private_display->lock);
1208 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1209 struct list_head *change_handler_list,
1210 tdm_output_change_type type,
1213 tdm_private_display *private_display;
1214 tdm_private_change_handler *change_handler;
1216 TDM_RETURN_IF_FAIL(private_output);
1218 private_display = private_output->private_display;
1219 if (!tdm_thread_in_display_thread(private_display->private_loop,
1220 syscall(SYS_gettid))) {
1221 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1222 TDM_INFO("output(%d) changed: %s (%d)",
1223 private_output->pipe, status_str(value.u32), value.u32);
1224 if (type & TDM_OUTPUT_CHANGE_DPMS)
1225 TDM_INFO("output(%d) changed: dpms %s (%d)",
1226 private_output->pipe, dpms_str(value.u32), value.u32);
1229 if (LIST_IS_EMPTY(change_handler_list))
1232 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1233 if (change_handler->owner_tid != syscall(SYS_gettid))
1234 TDM_NEVER_GET_HERE();
1236 change_handler->func(private_output, type,
1237 value, change_handler->user_data);
1242 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1246 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1248 _pthread_mutex_lock(&private_display->lock);
1250 *capabilities = private_layer->caps.capabilities;
1252 _pthread_mutex_unlock(&private_display->lock);
1258 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1263 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1264 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1266 _pthread_mutex_lock(&private_display->lock);
1268 *formats = (const tbm_format *)private_layer->caps.formats;
1269 *count = private_layer->caps.format_count;
1271 _pthread_mutex_unlock(&private_display->lock);
1277 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1282 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1283 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1285 _pthread_mutex_lock(&private_display->lock);
1287 *props = (const tdm_prop *)private_layer->caps.props;
1288 *count = private_layer->caps.prop_count;
1290 _pthread_mutex_unlock(&private_display->lock);
1296 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1300 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1302 _pthread_mutex_lock(&private_display->lock);
1304 *zpos = private_layer->caps.zpos;
1306 _pthread_mutex_unlock(&private_display->lock);
1312 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1314 tdm_func_layer *func_layer;
1317 _pthread_mutex_lock(&private_display->lock);
1319 func_layer = &private_display->func_layer;
1321 if (!func_layer->layer_set_property) {
1322 _pthread_mutex_unlock(&private_display->lock);
1323 TDM_DBG("failed: not implemented!!");
1324 return TDM_ERROR_NOT_IMPLEMENTED;
1327 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1329 _pthread_mutex_unlock(&private_display->lock);
1335 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1337 tdm_func_layer *func_layer;
1340 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1342 _pthread_mutex_lock(&private_display->lock);
1344 func_layer = &private_display->func_layer;
1346 if (!func_layer->layer_get_property) {
1347 _pthread_mutex_unlock(&private_display->lock);
1348 TDM_DBG("failed: not implemented!!");
1349 return TDM_ERROR_NOT_IMPLEMENTED;
1352 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1354 _pthread_mutex_unlock(&private_display->lock);
1360 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1362 tdm_func_layer *func_layer;
1365 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1367 _pthread_mutex_lock(&private_display->lock);
1369 func_layer = &private_display->func_layer;
1371 private_layer->usable = 0;
1373 if (!func_layer->layer_set_info) {
1374 _pthread_mutex_unlock(&private_display->lock);
1375 TDM_DBG("failed: not implemented!!");
1376 return TDM_ERROR_NOT_IMPLEMENTED;
1379 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1380 private_layer, info->src_config.size.h, info->src_config.size.v,
1381 info->src_config.pos.x, info->src_config.pos.y,
1382 info->src_config.pos.w, info->src_config.pos.h,
1383 FOURCC_STR(info->src_config.format),
1384 info->dst_pos.x, info->dst_pos.y,
1385 info->dst_pos.w, info->dst_pos.h,
1388 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1389 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1391 _pthread_mutex_unlock(&private_display->lock);
1397 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1399 tdm_func_layer *func_layer;
1402 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1404 _pthread_mutex_lock(&private_display->lock);
1406 func_layer = &private_display->func_layer;
1408 if (!func_layer->layer_get_info) {
1409 _pthread_mutex_unlock(&private_display->lock);
1410 TDM_DBG("failed: not implemented!!");
1411 return TDM_ERROR_NOT_IMPLEMENTED;
1414 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1416 _pthread_mutex_unlock(&private_display->lock);
1422 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1424 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1425 tdm_private_output *private_output = private_layer->private_output;
1430 tbm_surface_info_s info;
1431 tbm_surface_error_e err;
1433 path = tdm_helper_get_dump_path();
1434 TDM_RETURN_IF_FAIL(path != NULL);
1436 count = tdm_helper_get_dump_count();
1437 TDM_RETURN_IF_FAIL(count != 0);
1439 err = tbm_surface_map(buffer, TBM_SURF_OPTION_READ, &info);
1440 TDM_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
1442 char fullpath[PATH_MAX] = {0, };
1444 pipe = private_output->pipe;
1445 zpos = private_layer->caps.zpos;
1447 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1448 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d.png",
1449 path, count, pipe, zpos);
1451 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d_%dx%d_%c%c%c%c.yuv",
1452 path, count, pipe, zpos, info.planes[0].stride, info.height, FOURCC_STR(info.format));
1454 tbm_surface_unmap(buffer);
1456 tdm_helper_dump_buffer(buffer, fullpath);
1457 TDM_DBG("%d, %s dump excute", count, fullpath);
1463 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1465 tdm_func_layer *func_layer;
1469 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1471 _pthread_mutex_lock(&private_display->lock);
1473 func_layer = &private_display->func_layer;
1475 private_layer->usable = 0;
1477 if (!func_layer->layer_set_buffer) {
1478 _pthread_mutex_unlock(&private_display->lock);
1479 TDM_DBG("failed: not implemented!!");
1480 return TDM_ERROR_NOT_IMPLEMENTED;
1483 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1484 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1487 _tdm_layer_dump_buffer(layer, buffer);
1489 if (ret == TDM_ERROR_NONE) {
1490 /* FIXME: should save to pending_buffer first. And after committing
1491 * successfully, need to move to waiting_buffer.
1493 if (private_layer->waiting_buffer) {
1494 _pthread_mutex_unlock(&private_display->lock);
1495 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1496 _pthread_mutex_lock(&private_display->lock);
1499 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1500 if (tdm_debug_buffer)
1501 TDM_INFO("layer(%p) waiting_buffer(%p)",
1502 private_layer, private_layer->waiting_buffer);
1505 _pthread_mutex_unlock(&private_display->lock);
1511 tdm_layer_unset_buffer(tdm_layer *layer)
1513 tdm_func_layer *func_layer;
1516 _pthread_mutex_lock(&private_display->lock);
1518 func_layer = &private_display->func_layer;
1520 if (private_layer->waiting_buffer) {
1521 _pthread_mutex_unlock(&private_display->lock);
1522 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1523 _pthread_mutex_lock(&private_display->lock);
1524 private_layer->waiting_buffer = NULL;
1526 if (tdm_debug_buffer)
1527 TDM_INFO("layer(%p) waiting_buffer(%p)",
1528 private_layer, private_layer->waiting_buffer);
1531 if (private_layer->showing_buffer) {
1532 _pthread_mutex_unlock(&private_display->lock);
1533 tdm_buffer_unref_backend(private_layer->showing_buffer);
1534 _pthread_mutex_lock(&private_display->lock);
1535 private_layer->showing_buffer = NULL;
1537 if (tdm_debug_buffer)
1538 TDM_INFO("layer(%p) showing_buffer(%p)",
1539 private_layer, private_layer->showing_buffer);
1542 private_layer->usable = 1;
1544 if (!func_layer->layer_unset_buffer) {
1545 _pthread_mutex_unlock(&private_display->lock);
1546 TDM_DBG("failed: not implemented!!");
1547 return TDM_ERROR_NOT_IMPLEMENTED;
1550 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1551 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1553 _pthread_mutex_unlock(&private_display->lock);
1559 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1561 TDM_RETURN_IF_FAIL(data != NULL);
1562 tdm_layer *layer = data;
1563 tdm_func_layer *func_layer;
1564 tbm_surface_h surface = NULL;
1565 LAYER_FUNC_ENTRY_VOID_RETURN();
1567 _pthread_mutex_lock(&private_display->lock);
1569 func_layer = &private_display->func_layer;
1570 if (!func_layer->layer_set_buffer) {
1571 _pthread_mutex_unlock(&private_display->lock);
1575 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1576 private_layer->buffer_queue, &surface) ||
1578 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1579 private_layer, surface);
1580 _pthread_mutex_unlock(&private_display->lock);
1584 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1585 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1587 if (ret == TDM_ERROR_NONE) {
1588 if (private_layer->waiting_buffer) {
1589 _pthread_mutex_unlock(&private_display->lock);
1590 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1591 tbm_surface_queue_release(private_layer->buffer_queue,
1592 private_layer->waiting_buffer);
1593 _pthread_mutex_lock(&private_display->lock);
1596 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1598 if (tdm_debug_buffer)
1599 TDM_INFO("layer(%p) waiting_buffer(%p)",
1600 private_layer, private_layer->waiting_buffer);
1602 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1603 if (ret != TDM_ERROR_NONE)
1604 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1607 _pthread_mutex_unlock(&private_display->lock);
1611 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1613 TDM_RETURN_IF_FAIL(data != NULL);
1614 tdm_layer *layer = data;
1615 LAYER_FUNC_ENTRY_VOID_RETURN();
1616 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1618 _pthread_mutex_lock(&private_display->lock);
1620 if (private_layer->waiting_buffer) {
1621 _pthread_mutex_unlock(&private_display->lock);
1622 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1623 tbm_surface_queue_release(private_layer->buffer_queue,
1624 private_layer->waiting_buffer);
1625 _pthread_mutex_lock(&private_display->lock);
1628 private_layer->buffer_queue = NULL;
1630 _pthread_mutex_unlock(&private_display->lock);
1634 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1636 tdm_func_layer *func_layer;
1639 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1641 _pthread_mutex_lock(&private_display->lock);
1643 func_layer = &private_display->func_layer;
1645 private_layer->usable = 0;
1647 if (!func_layer->layer_set_buffer) {
1648 _pthread_mutex_unlock(&private_display->lock);
1649 TDM_DBG("failed: not implemented!!");
1650 return TDM_ERROR_NOT_IMPLEMENTED;
1653 if (buffer_queue == private_layer->buffer_queue) {
1654 _pthread_mutex_unlock(&private_display->lock);
1655 return TDM_ERROR_NONE;
1658 if (private_layer->waiting_buffer) {
1659 _pthread_mutex_unlock(&private_display->lock);
1660 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1661 tbm_surface_queue_release(private_layer->buffer_queue,
1662 private_layer->waiting_buffer);
1663 private_layer->waiting_buffer = NULL;
1664 _pthread_mutex_lock(&private_display->lock);
1666 if (tdm_debug_buffer)
1667 TDM_INFO("layer(%p) waiting_buffer(%p)",
1668 private_layer, private_layer->waiting_buffer);
1671 private_layer->buffer_queue = buffer_queue;
1672 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1673 _tbm_layer_queue_acquirable_cb,
1675 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1676 _tbm_layer_queue_destroy_cb,
1678 _pthread_mutex_unlock(&private_display->lock);
1684 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1686 tdm_func_layer *func_layer;
1689 _pthread_mutex_lock(&private_display->lock);
1691 func_layer = &private_display->func_layer;
1693 if (private_layer->waiting_buffer) {
1694 _pthread_mutex_unlock(&private_display->lock);
1695 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1696 tbm_surface_queue_release(private_layer->buffer_queue,
1697 private_layer->waiting_buffer);
1698 private_layer->waiting_buffer = NULL;
1699 _pthread_mutex_lock(&private_display->lock);
1701 if (tdm_debug_buffer)
1702 TDM_INFO("layer(%p) waiting_buffer(%p)",
1703 private_layer, private_layer->waiting_buffer);
1706 if (private_layer->showing_buffer) {
1707 _pthread_mutex_unlock(&private_display->lock);
1708 tdm_buffer_unref_backend(private_layer->showing_buffer);
1709 tbm_surface_queue_release(private_layer->buffer_queue,
1710 private_layer->showing_buffer);
1711 _pthread_mutex_lock(&private_display->lock);
1712 private_layer->showing_buffer = NULL;
1714 if (tdm_debug_buffer)
1715 TDM_INFO("layer(%p) showing_buffer(%p)",
1716 private_layer, private_layer->showing_buffer);
1719 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1720 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1721 private_layer->buffer_queue = NULL;
1722 private_layer->usable = 1;
1724 if (!func_layer->layer_unset_buffer) {
1725 _pthread_mutex_unlock(&private_display->lock);
1726 TDM_DBG("failed: not implemented!!");
1727 return TDM_ERROR_NOT_IMPLEMENTED;
1730 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1732 _pthread_mutex_unlock(&private_display->lock);
1738 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1742 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1744 _pthread_mutex_lock(&private_display->lock);
1746 *usable = private_layer->usable;
1748 _pthread_mutex_unlock(&private_display->lock);
1754 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1756 tdm_func_layer *func_layer;
1759 _pthread_mutex_lock(&private_display->lock);
1761 func_layer = &private_display->func_layer;
1763 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1764 TDM_ERR("layer(%p) is not video layer", private_layer);
1765 _pthread_mutex_unlock(&private_display->lock);
1766 return TDM_ERROR_INVALID_PARAMETER;
1769 if (!func_layer->layer_set_video_pos) {
1770 _pthread_mutex_unlock(&private_display->lock);
1771 TDM_DBG("failed: not implemented!!");
1772 return TDM_ERROR_NOT_IMPLEMENTED;
1775 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1777 _pthread_mutex_unlock(&private_display->lock);
1782 EXTERN tdm_capture *
1783 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1785 tdm_capture *capture = NULL;
1787 LAYER_FUNC_ENTRY_ERROR();
1789 _pthread_mutex_lock(&private_display->lock);
1791 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1794 _pthread_mutex_unlock(&private_display->lock);