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
106 _tdm_display_lock(tdm_display *dpy, const char *func)
108 tdm_private_display *private_display = (tdm_private_display*)dpy;
112 TDM_INFO("mutex lock: %s", func);
114 ret = pthread_mutex_trylock(&private_display->lock);
117 TDM_ERR("mutex lock busy: %s", func);
119 TDM_ERR("mutex lock failed: %s(%m)", func);
120 return TDM_ERROR_OPERATION_FAILED;
123 pthread_mutex_lock(&tdm_mutex_check_lock);
124 tdm_mutex_locked = 1;
125 pthread_mutex_unlock(&tdm_mutex_check_lock);
127 return TDM_ERROR_NONE;
131 _tdm_display_unlock(tdm_display *dpy, const char *func)
133 tdm_private_display *private_display = (tdm_private_display*)dpy;
136 TDM_INFO("mutex unlock: %s", func);
138 pthread_mutex_lock(&tdm_mutex_check_lock);
139 tdm_mutex_locked = 0;
140 pthread_mutex_unlock(&tdm_mutex_check_lock);
142 pthread_mutex_unlock(&private_display->lock);
146 tdm_display_get_capabilities(tdm_display *dpy,
147 tdm_display_capability *capabilities)
149 DISPLAY_FUNC_ENTRY();
151 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
153 _pthread_mutex_lock(&private_display->lock);
155 *capabilities = private_display->capabilities;
157 _pthread_mutex_unlock(&private_display->lock);
163 tdm_display_get_pp_capabilities(tdm_display *dpy,
164 tdm_pp_capability *capabilities)
166 DISPLAY_FUNC_ENTRY();
168 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
170 _pthread_mutex_lock(&private_display->lock);
172 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
173 TDM_ERR("no pp capability");
174 _pthread_mutex_unlock(&private_display->lock);
175 return TDM_ERROR_NO_CAPABILITY;
178 *capabilities = private_display->caps_pp.capabilities;
180 _pthread_mutex_unlock(&private_display->lock);
186 tdm_display_get_pp_available_formats(tdm_display *dpy,
187 const tbm_format **formats, int *count)
189 DISPLAY_FUNC_ENTRY();
191 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
192 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
194 _pthread_mutex_lock(&private_display->lock);
196 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
197 TDM_ERR("no pp capability");
198 _pthread_mutex_unlock(&private_display->lock);
199 return TDM_ERROR_NO_CAPABILITY;
202 *formats = (const tbm_format *)private_display->caps_pp.formats;
203 *count = private_display->caps_pp.format_count;
205 _pthread_mutex_unlock(&private_display->lock);
211 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
212 int *max_w, int *max_h, int *preferred_align)
214 DISPLAY_FUNC_ENTRY();
216 _pthread_mutex_lock(&private_display->lock);
218 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
219 TDM_ERR("no pp capability");
220 _pthread_mutex_unlock(&private_display->lock);
221 return TDM_ERROR_NO_CAPABILITY;
225 *min_w = private_display->caps_pp.min_w;
227 *min_h = private_display->caps_pp.min_h;
229 *max_w = private_display->caps_pp.max_w;
231 *max_h = private_display->caps_pp.max_h;
233 *preferred_align = private_display->caps_pp.preferred_align;
235 _pthread_mutex_unlock(&private_display->lock);
241 tdm_display_get_capture_capabilities(tdm_display *dpy,
242 tdm_capture_capability *capabilities)
244 DISPLAY_FUNC_ENTRY();
246 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
248 _pthread_mutex_lock(&private_display->lock);
250 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
251 TDM_ERR("no capture capability");
252 _pthread_mutex_unlock(&private_display->lock);
253 return TDM_ERROR_NO_CAPABILITY;
256 *capabilities = private_display->caps_capture.capabilities;
258 _pthread_mutex_unlock(&private_display->lock);
264 tdm_display_get_catpure_available_formats(tdm_display *dpy,
265 const tbm_format **formats, int *count)
267 DISPLAY_FUNC_ENTRY();
269 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
270 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
272 _pthread_mutex_lock(&private_display->lock);
274 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
275 TDM_ERR("no capture capability");
276 _pthread_mutex_unlock(&private_display->lock);
277 return TDM_ERROR_NO_CAPABILITY;
280 *formats = (const tbm_format *)private_display->caps_capture.formats;
281 *count = private_display->caps_capture.format_count;
283 _pthread_mutex_unlock(&private_display->lock);
289 tdm_display_get_output_count(tdm_display *dpy, int *count)
291 tdm_private_output *private_output = NULL;
293 DISPLAY_FUNC_ENTRY();
295 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
297 _pthread_mutex_lock(&private_display->lock);
300 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
304 _pthread_mutex_unlock(&private_display->lock);
305 return TDM_ERROR_NONE;
308 _pthread_mutex_unlock(&private_display->lock);
315 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
317 tdm_private_output *private_output = NULL;
320 DISPLAY_FUNC_ENTRY_ERROR();
322 _pthread_mutex_lock(&private_display->lock);
325 *error = TDM_ERROR_NONE;
328 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
330 _pthread_mutex_unlock(&private_display->lock);
331 return private_output;
336 _pthread_mutex_unlock(&private_display->lock);
342 tdm_display_get_fd(tdm_display *dpy, int *fd)
344 DISPLAY_FUNC_ENTRY();
346 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
348 _pthread_mutex_lock(&private_display->lock);
350 if (tdm_thread_is_running())
351 *fd = tdm_thread_get_fd(private_display->private_loop);
353 *fd = tdm_event_loop_get_fd(private_display);
355 _pthread_mutex_unlock(&private_display->lock);
361 tdm_display_handle_events(tdm_display *dpy)
366 DISPLAY_FUNC_ENTRY();
368 ret = tdm_display_get_fd(dpy, &fd);
369 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
375 if (tdm_debug_thread)
376 TDM_INFO("fd(%d) polling in", fd);
378 while (poll(&fds, 1, -1) < 0) {
379 if (errno == EINTR || errno == EAGAIN) /* normal case */
382 TDM_ERR("poll failed: %m");
383 return TDM_ERROR_OPERATION_FAILED;
387 if (tdm_debug_thread)
388 TDM_INFO("fd(%d) polling out", fd);
390 if (tdm_thread_is_running())
391 ret = tdm_thread_handle_cb(private_display->private_loop);
393 ret = tdm_event_loop_dispatch(private_display);
399 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
403 DISPLAY_FUNC_ENTRY_ERROR();
405 _pthread_mutex_lock(&private_display->lock);
407 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
409 _pthread_mutex_unlock(&private_display->lock);
415 tdm_output_get_model_info(tdm_output *output, const char **maker,
416 const char **model, const char **name)
420 _pthread_mutex_lock(&private_display->lock);
423 *maker = private_output->caps.maker;
425 *model = private_output->caps.model;
427 *name = private_output->caps.name;
429 _pthread_mutex_unlock(&private_display->lock);
435 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
439 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
441 _pthread_mutex_lock(&private_display->lock);
443 *status = private_output->caps.status;
445 _pthread_mutex_unlock(&private_display->lock);
451 _tdm_output_update(tdm_output *output_backend, void *user_data)
453 tdm_private_display *private_display;
454 tdm_private_output *private_output = user_data;
457 TDM_RETURN_IF_FAIL(private_output);
459 private_display = private_output->private_display;
461 ret = tdm_display_update_output(private_display, output_backend, private_output->pipe);
462 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
466 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
469 tdm_private_display *private_display;
470 tdm_private_output *private_output = user_data;
473 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
474 TDM_RETURN_IF_FAIL(private_output);
476 private_display = private_output->private_display;
478 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
479 tdm_thread_cb_output_status output_status;
482 _tdm_output_update(output_backend, user_data);
484 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
485 output_status.base.length = sizeof output_status;
486 output_status.output_stamp = private_output->stamp;
487 output_status.status = status;
488 output_status.user_data = user_data;
491 tdm_output_call_change_handler_internal(private_output,
492 &private_output->change_handler_list_sub,
493 TDM_OUTPUT_CHANGE_CONNECTION,
496 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
497 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
502 if (!tdm_thread_is_running())
503 _tdm_output_update(output_backend, user_data);
506 tdm_output_call_change_handler_internal(private_output,
507 &private_output->change_handler_list_main,
508 TDM_OUTPUT_CHANGE_CONNECTION,
513 tdm_output_add_change_handler(tdm_output *output,
514 tdm_output_change_handler func,
517 tdm_private_change_handler *change_handler;
520 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
522 pthread_mutex_lock(&private_display->lock);
524 change_handler = calloc(1, sizeof(tdm_private_change_handler));
525 if (!change_handler) {
526 TDM_ERR("failed: alloc memory");
527 _pthread_mutex_unlock(&private_display->lock);
528 return TDM_ERROR_OUT_OF_MEMORY;
531 change_handler->private_output = private_output;
532 change_handler->func = func;
533 change_handler->user_data = user_data;
534 change_handler->owner_tid = syscall(SYS_gettid);
536 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
537 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
539 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
541 _pthread_mutex_unlock(&private_display->lock);
547 tdm_output_remove_change_handler(tdm_output *output,
548 tdm_output_change_handler func,
551 tdm_private_display *private_display;
552 tdm_private_output *private_output;
553 tdm_private_change_handler *h = NULL, *hh = NULL;
555 TDM_RETURN_IF_FAIL(output != NULL);
556 TDM_RETURN_IF_FAIL(func != NULL);
558 private_output = (tdm_private_output*)output;
559 private_display = private_output->private_display;
561 _pthread_mutex_lock(&private_display->lock);
563 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
564 if (h->func != func || h->user_data != user_data)
570 _pthread_mutex_unlock(&private_display->lock);
575 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
576 if (h->func != func || h->user_data != user_data)
582 _pthread_mutex_unlock(&private_display->lock);
587 _pthread_mutex_unlock(&private_display->lock);
591 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
595 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
597 _pthread_mutex_lock(&private_display->lock);
599 *type = private_output->caps.type;
601 _pthread_mutex_unlock(&private_display->lock);
607 tdm_output_get_layer_count(tdm_output *output, int *count)
609 tdm_private_layer *private_layer = NULL;
613 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
615 _pthread_mutex_lock(&private_display->lock);
618 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
621 _pthread_mutex_unlock(&private_display->lock);
622 return TDM_ERROR_NONE;
625 _pthread_mutex_unlock(&private_display->lock);
632 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
634 tdm_private_layer *private_layer = NULL;
637 OUTPUT_FUNC_ENTRY_ERROR();
639 _pthread_mutex_lock(&private_display->lock);
642 *error = TDM_ERROR_NONE;
644 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
646 _pthread_mutex_unlock(&private_display->lock);
647 return private_layer;
652 _pthread_mutex_unlock(&private_display->lock);
658 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
663 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
664 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
666 _pthread_mutex_lock(&private_display->lock);
668 *props = (const tdm_prop *)private_output->caps.props;
669 *count = private_output->caps.prop_count;
671 _pthread_mutex_unlock(&private_display->lock);
677 tdm_output_get_available_modes(tdm_output *output,
678 const tdm_output_mode **modes, int *count)
682 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
683 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
685 _pthread_mutex_lock(&private_display->lock);
687 *modes = (const tdm_output_mode *)private_output->caps.modes;
688 *count = private_output->caps.mode_count;
690 _pthread_mutex_unlock(&private_display->lock);
696 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
697 int *max_w, int *max_h, int *preferred_align)
701 _pthread_mutex_lock(&private_display->lock);
704 *min_w = private_output->caps.min_w;
706 *min_h = private_output->caps.min_h;
708 *max_w = private_output->caps.max_w;
710 *max_h = private_output->caps.max_h;
712 *preferred_align = private_output->caps.preferred_align;
714 _pthread_mutex_unlock(&private_display->lock);
720 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
721 unsigned int *mmHeight)
725 _pthread_mutex_lock(&private_display->lock);
728 *mmWidth = private_output->caps.mmWidth;
730 *mmHeight = private_output->caps.mmHeight;
732 _pthread_mutex_unlock(&private_display->lock);
738 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
741 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
743 _pthread_mutex_lock(&private_display->lock);
745 *subpixel = private_output->caps.subpixel;
747 _pthread_mutex_unlock(&private_display->lock);
753 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
756 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
758 _pthread_mutex_lock(&private_display->lock);
760 *pipe = private_output->pipe;
762 _pthread_mutex_unlock(&private_display->lock);
769 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
771 tdm_func_output *func_output;
774 _pthread_mutex_lock(&private_display->lock);
776 func_output = &private_display->func_output;
778 if (!func_output->output_set_property) {
779 _pthread_mutex_unlock(&private_display->lock);
780 TDM_ERR("not implemented!!");
781 return TDM_ERROR_NOT_IMPLEMENTED;
784 ret = func_output->output_set_property(private_output->output_backend, id,
787 _pthread_mutex_unlock(&private_display->lock);
793 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
795 tdm_func_output *func_output;
798 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
800 _pthread_mutex_lock(&private_display->lock);
802 func_output = &private_display->func_output;
804 if (!func_output->output_get_property) {
805 _pthread_mutex_unlock(&private_display->lock);
806 TDM_ERR("not implemented!!");
807 return TDM_ERROR_NOT_IMPLEMENTED;
810 ret = func_output->output_get_property(private_output->output_backend, id,
813 _pthread_mutex_unlock(&private_display->lock);
819 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
820 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
822 tdm_private_vblank_handler *vblank_handler = user_data;
823 tdm_private_display *private_display;
825 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
826 TDM_RETURN_IF_FAIL(vblank_handler);
828 private_display = vblank_handler->private_output->private_display;
830 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
831 tdm_thread_cb_output_vblank output_vblank;
834 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
835 output_vblank.base.length = sizeof output_vblank;
836 output_vblank.output_stamp = vblank_handler->private_output->stamp;
837 output_vblank.sequence = sequence;
838 output_vblank.tv_sec = tv_sec;
839 output_vblank.tv_usec = tv_usec;
840 output_vblank.user_data = user_data;
842 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
843 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
848 if (vblank_handler->owner_tid != syscall(SYS_gettid))
849 TDM_NEVER_GET_HERE();
851 if (vblank_handler->func) {
852 _pthread_mutex_unlock(&private_display->lock);
853 vblank_handler->func(vblank_handler->private_output, sequence,
854 tv_sec, tv_usec, vblank_handler->user_data);
855 _pthread_mutex_lock(&private_display->lock);
858 LIST_DEL(&vblank_handler->link);
859 free(vblank_handler);
863 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
864 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
866 tdm_private_commit_handler *commit_handler = user_data;
867 tdm_private_display *private_display;
868 tdm_private_output *private_output;
869 tdm_private_layer *private_layer = NULL;
871 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
872 TDM_RETURN_IF_FAIL(commit_handler);
874 private_output = commit_handler->private_output;
875 private_display = private_output->private_display;
877 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
878 tdm_thread_cb_output_commit output_commit;
881 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
882 output_commit.base.length = sizeof output_commit;
883 output_commit.output_stamp = private_output->stamp;
884 output_commit.sequence = sequence;
885 output_commit.tv_sec = tv_sec;
886 output_commit.tv_usec = tv_usec;
887 output_commit.user_data = user_data;
889 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
890 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
895 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
896 if (!private_layer->waiting_buffer)
899 if (private_layer->showing_buffer) {
900 _pthread_mutex_unlock(&private_display->lock);
901 tdm_buffer_unref_backend(private_layer->showing_buffer);
902 _pthread_mutex_lock(&private_display->lock);
904 if (private_layer->buffer_queue) {
905 _pthread_mutex_unlock(&private_display->lock);
906 tbm_surface_queue_release(private_layer->buffer_queue,
907 private_layer->showing_buffer);
908 _pthread_mutex_lock(&private_display->lock);
912 private_layer->showing_buffer = private_layer->waiting_buffer;
913 private_layer->waiting_buffer = NULL;
915 if (tdm_debug_buffer)
916 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
917 private_layer, private_layer->waiting_buffer,
918 private_layer->showing_buffer);
921 if (commit_handler->func) {
922 _pthread_mutex_unlock(&private_display->lock);
923 commit_handler->func(private_output, sequence,
924 tv_sec, tv_usec, commit_handler->user_data);
925 _pthread_mutex_lock(&private_display->lock);
928 LIST_DEL(&commit_handler->link);
929 free(commit_handler);
933 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
934 tdm_output_vblank_handler func, void *user_data)
936 tdm_func_output *func_output;
937 tdm_private_vblank_handler *vblank_handler;
940 _pthread_mutex_lock(&private_display->lock);
942 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
943 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
944 tdm_dpms_str(private_output->current_dpms_value));
945 _pthread_mutex_unlock(&private_display->lock);
946 return TDM_ERROR_BAD_REQUEST;
949 func_output = &private_display->func_output;
951 if (!func_output->output_wait_vblank) {
952 _pthread_mutex_unlock(&private_display->lock);
953 TDM_ERR("not implemented!!");
954 return TDM_ERROR_NOT_IMPLEMENTED;
957 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
958 if (!vblank_handler) {
959 TDM_ERR("failed: alloc memory");
960 _pthread_mutex_unlock(&private_display->lock);
961 return TDM_ERROR_OUT_OF_MEMORY;
964 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
965 vblank_handler->private_output = private_output;
966 vblank_handler->func = func;
967 vblank_handler->user_data = user_data;
968 vblank_handler->owner_tid = syscall(SYS_gettid);
970 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
971 sync, vblank_handler);
972 if (ret != TDM_ERROR_NONE) {
973 _pthread_mutex_unlock(&private_display->lock);
977 if (!private_output->regist_vblank_cb) {
978 private_output->regist_vblank_cb = 1;
979 ret = func_output->output_set_vblank_handler(private_output->output_backend,
980 tdm_output_cb_vblank);
983 _pthread_mutex_unlock(&private_display->lock);
989 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
992 tdm_func_output *func_output;
993 tdm_private_commit_handler *commit_handler;
996 func_output = &private_display->func_output;
998 if (!func_output->output_commit) {
999 TDM_ERR("not implemented!!");
1000 return TDM_ERROR_NOT_IMPLEMENTED;
1003 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1004 if (!commit_handler) {
1005 TDM_ERR("failed: alloc memory");
1006 return TDM_ERROR_OUT_OF_MEMORY;
1009 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1010 commit_handler->private_output = private_output;
1011 commit_handler->func = func;
1012 commit_handler->user_data = user_data;
1013 commit_handler->owner_tid = syscall(SYS_gettid);
1015 if (!private_output->regist_commit_cb) {
1016 private_output->regist_commit_cb = 1;
1017 ret = func_output->output_set_commit_handler(private_output->output_backend,
1018 tdm_output_cb_commit);
1021 ret = func_output->output_commit(private_output->output_backend, sync,
1023 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1029 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1032 OUTPUT_FUNC_ENTRY();
1034 _pthread_mutex_lock(&private_display->lock);
1036 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1037 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1038 tdm_dpms_str(private_output->current_dpms_value));
1039 _pthread_mutex_unlock(&private_display->lock);
1040 return TDM_ERROR_BAD_REQUEST;
1043 ret = _tdm_output_commit(output, sync, func, user_data);
1045 _pthread_mutex_unlock(&private_display->lock);
1051 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1053 tdm_func_output *func_output;
1054 OUTPUT_FUNC_ENTRY();
1056 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1058 _pthread_mutex_lock(&private_display->lock);
1060 func_output = &private_display->func_output;
1062 if (!func_output->output_set_mode) {
1063 _pthread_mutex_unlock(&private_display->lock);
1064 TDM_ERR("not implemented!!");
1065 return TDM_ERROR_NOT_IMPLEMENTED;
1068 ret = func_output->output_set_mode(private_output->output_backend, mode);
1070 _pthread_mutex_unlock(&private_display->lock);
1076 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1078 tdm_func_output *func_output;
1079 OUTPUT_FUNC_ENTRY();
1081 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1083 _pthread_mutex_lock(&private_display->lock);
1085 func_output = &private_display->func_output;
1087 if (!func_output->output_get_mode) {
1088 _pthread_mutex_unlock(&private_display->lock);
1089 TDM_ERR("not implemented!!");
1090 return TDM_ERROR_NOT_IMPLEMENTED;
1093 ret = func_output->output_get_mode(private_output->output_backend, mode);
1095 _pthread_mutex_unlock(&private_display->lock);
1101 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1103 tdm_func_output *func_output;
1104 OUTPUT_FUNC_ENTRY();
1106 if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1107 dpms_value = TDM_OUTPUT_DPMS_OFF;
1109 _pthread_mutex_lock(&private_display->lock);
1111 if (private_output->current_dpms_value == dpms_value) {
1112 _pthread_mutex_unlock(&private_display->lock);
1113 return TDM_ERROR_NONE;
1116 func_output = &private_display->func_output;
1118 if (!func_output->output_set_dpms) {
1119 _pthread_mutex_unlock(&private_display->lock);
1120 private_output->current_dpms_value = dpms_value;
1121 TDM_WRN("not implemented!!");
1122 return TDM_ERROR_NONE;
1125 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1126 if (ret == TDM_ERROR_NONE) {
1129 private_output->current_dpms_value = dpms_value;
1131 value.u32 = dpms_value;
1132 tdm_output_call_change_handler_internal(private_output,
1133 &private_output->change_handler_list_main,
1134 TDM_OUTPUT_CHANGE_DPMS,
1137 //TODO: safe? We can't take care of the user_data of callback functions.
1138 tdm_output_call_change_handler_internal(private_output,
1139 &private_output->change_handler_list_sub,
1140 TDM_OUTPUT_CHANGE_DPMS,
1144 _pthread_mutex_unlock(&private_display->lock);
1150 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1152 tdm_func_output *func_output;
1153 OUTPUT_FUNC_ENTRY();
1155 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1157 _pthread_mutex_lock(&private_display->lock);
1159 func_output = &private_display->func_output;
1161 if (!func_output->output_get_dpms) {
1162 *dpms_value = private_output->current_dpms_value;
1163 _pthread_mutex_unlock(&private_display->lock);
1164 TDM_WRN("not implemented!!");
1165 return TDM_ERROR_NONE;
1168 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1170 _pthread_mutex_unlock(&private_display->lock);
1175 EXTERN tdm_capture *
1176 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1178 tdm_capture *capture = NULL;
1180 OUTPUT_FUNC_ENTRY_ERROR();
1182 _pthread_mutex_lock(&private_display->lock);
1184 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output, error);
1186 _pthread_mutex_unlock(&private_display->lock);
1192 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1193 struct list_head *change_handler_list,
1194 tdm_output_change_type type,
1196 int no_check_thread_id)
1198 tdm_private_display *private_display;
1199 tdm_private_change_handler *change_handler = NULL;
1201 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1202 TDM_RETURN_IF_FAIL(private_output);
1204 private_display = private_output->private_display;
1205 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1206 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1207 TDM_INFO("output(%d) changed: %s (%d)",
1208 private_output->pipe, tdm_status_str(value.u32), value.u32);
1209 if (type & TDM_OUTPUT_CHANGE_DPMS)
1210 TDM_INFO("output(%d) changed: dpms %s (%d)",
1211 private_output->pipe, tdm_dpms_str(value.u32), value.u32);
1214 if (LIST_IS_EMPTY(change_handler_list))
1217 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1218 if (!no_check_thread_id && change_handler->owner_tid != syscall(SYS_gettid))
1219 TDM_NEVER_GET_HERE();
1221 _pthread_mutex_unlock(&private_display->lock);
1222 change_handler->func(private_output, type,
1223 value, change_handler->user_data);
1224 _pthread_mutex_lock(&private_display->lock);
1229 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1233 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1235 _pthread_mutex_lock(&private_display->lock);
1237 *capabilities = private_layer->caps.capabilities;
1239 _pthread_mutex_unlock(&private_display->lock);
1245 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
1249 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1250 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1252 _pthread_mutex_lock(&private_display->lock);
1254 *formats = (const tbm_format *)private_layer->caps.formats;
1255 *count = private_layer->caps.format_count;
1257 _pthread_mutex_unlock(&private_display->lock);
1263 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
1267 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1268 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1270 _pthread_mutex_lock(&private_display->lock);
1272 *props = (const tdm_prop *)private_layer->caps.props;
1273 *count = private_layer->caps.prop_count;
1275 _pthread_mutex_unlock(&private_display->lock);
1281 tdm_layer_get_zpos(tdm_layer *layer, int *zpos)
1285 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1287 _pthread_mutex_lock(&private_display->lock);
1289 *zpos = private_layer->caps.zpos;
1291 _pthread_mutex_unlock(&private_display->lock);
1297 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1299 tdm_func_layer *func_layer;
1302 _pthread_mutex_lock(&private_display->lock);
1304 func_layer = &private_display->func_layer;
1306 if (!func_layer->layer_set_property) {
1307 _pthread_mutex_unlock(&private_display->lock);
1308 TDM_ERR("not implemented!!");
1309 return TDM_ERROR_NOT_IMPLEMENTED;
1312 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1314 _pthread_mutex_unlock(&private_display->lock);
1320 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1322 tdm_func_layer *func_layer;
1325 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1327 _pthread_mutex_lock(&private_display->lock);
1329 func_layer = &private_display->func_layer;
1331 if (!func_layer->layer_get_property) {
1332 _pthread_mutex_unlock(&private_display->lock);
1333 TDM_ERR("not implemented!!");
1334 return TDM_ERROR_NOT_IMPLEMENTED;
1337 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1339 _pthread_mutex_unlock(&private_display->lock);
1345 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1347 tdm_func_layer *func_layer;
1350 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1352 _pthread_mutex_lock(&private_display->lock);
1354 func_layer = &private_display->func_layer;
1356 if (private_layer->usable)
1357 TDM_INFO("layer(%p) not usable", private_layer);
1359 private_layer->usable = 0;
1361 if (!func_layer->layer_set_info) {
1362 _pthread_mutex_unlock(&private_display->lock);
1363 TDM_ERR("not implemented!!");
1364 return TDM_ERROR_NOT_IMPLEMENTED;
1367 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1368 private_layer, info->src_config.size.h, info->src_config.size.v,
1369 info->src_config.pos.x, info->src_config.pos.y,
1370 info->src_config.pos.w, info->src_config.pos.h,
1371 FOURCC_STR(info->src_config.format),
1372 info->dst_pos.x, info->dst_pos.y,
1373 info->dst_pos.w, info->dst_pos.h,
1376 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1377 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1379 _pthread_mutex_unlock(&private_display->lock);
1385 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1387 tdm_func_layer *func_layer;
1390 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1392 _pthread_mutex_lock(&private_display->lock);
1394 func_layer = &private_display->func_layer;
1396 if (!func_layer->layer_get_info) {
1397 _pthread_mutex_unlock(&private_display->lock);
1398 TDM_ERR("not implemented!!");
1399 return TDM_ERROR_NOT_IMPLEMENTED;
1402 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1404 _pthread_mutex_unlock(&private_display->lock);
1410 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1412 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1413 tdm_private_output *private_output = private_layer->private_output;
1416 char fname[PATH_MAX];
1418 pipe = private_output->pipe;
1419 zpos = private_layer->caps.zpos;
1421 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1423 tbm_surface_internal_dump_buffer(buffer, fname);
1424 TDM_DBG("%s dump excute", fname);
1430 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1432 tdm_func_layer *func_layer;
1436 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1438 _pthread_mutex_lock(&private_display->lock);
1440 func_layer = &private_display->func_layer;
1442 if (private_layer->usable)
1443 TDM_INFO("layer(%p) not usable", private_layer);
1445 private_layer->usable = 0;
1447 if (!func_layer->layer_set_buffer) {
1448 _pthread_mutex_unlock(&private_display->lock);
1449 TDM_ERR("not implemented!!");
1450 return TDM_ERROR_NOT_IMPLEMENTED;
1453 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1454 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1457 if (tdm_dump_enable)
1458 _tdm_layer_dump_buffer(layer, buffer);
1460 if (ret == TDM_ERROR_NONE) {
1461 /* FIXME: should save to pending_buffer first. And after committing
1462 * successfully, need to move to waiting_buffer.
1464 if (private_layer->waiting_buffer) {
1465 _pthread_mutex_unlock(&private_display->lock);
1466 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1467 _pthread_mutex_lock(&private_display->lock);
1470 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1471 if (tdm_debug_buffer)
1472 TDM_INFO("layer(%p) waiting_buffer(%p)",
1473 private_layer, private_layer->waiting_buffer);
1476 _pthread_mutex_unlock(&private_display->lock);
1482 tdm_layer_unset_buffer(tdm_layer *layer)
1484 tdm_func_layer *func_layer;
1487 _pthread_mutex_lock(&private_display->lock);
1489 func_layer = &private_display->func_layer;
1491 if (private_layer->waiting_buffer) {
1492 _pthread_mutex_unlock(&private_display->lock);
1493 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1494 _pthread_mutex_lock(&private_display->lock);
1495 private_layer->waiting_buffer = NULL;
1497 if (tdm_debug_buffer)
1498 TDM_INFO("layer(%p) waiting_buffer(%p)",
1499 private_layer, private_layer->waiting_buffer);
1502 if (private_layer->showing_buffer) {
1503 _pthread_mutex_unlock(&private_display->lock);
1504 tdm_buffer_unref_backend(private_layer->showing_buffer);
1505 _pthread_mutex_lock(&private_display->lock);
1506 private_layer->showing_buffer = NULL;
1508 if (tdm_debug_buffer)
1509 TDM_INFO("layer(%p) showing_buffer(%p)",
1510 private_layer, private_layer->showing_buffer);
1513 private_layer->usable = 1;
1515 if (private_layer->usable)
1516 TDM_INFO("layer(%p) now usable", private_layer);
1518 if (!func_layer->layer_unset_buffer) {
1519 _pthread_mutex_unlock(&private_display->lock);
1520 TDM_ERR("not implemented!!");
1521 return TDM_ERROR_NOT_IMPLEMENTED;
1524 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1525 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1527 _pthread_mutex_unlock(&private_display->lock);
1532 EXTERN tbm_surface_h
1533 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1535 tbm_surface_h buffer;
1536 LAYER_FUNC_ENTRY_ERROR();
1538 _pthread_mutex_lock(&private_display->lock);
1541 *error = TDM_ERROR_NONE;
1543 if (private_layer->showing_buffer) {
1544 buffer = private_layer->showing_buffer;
1547 *error = TDM_ERROR_OPERATION_FAILED;
1548 _pthread_mutex_unlock(&private_display->lock);
1549 TDM_DBG("layer(%p) showing_buffer is null", private_layer);
1552 _pthread_mutex_unlock(&private_display->lock);
1558 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1560 TDM_RETURN_IF_FAIL(data != NULL);
1561 tdm_layer *layer = data;
1562 tdm_func_layer *func_layer;
1563 tbm_surface_h surface = NULL;
1564 LAYER_FUNC_ENTRY_VOID_RETURN();
1566 _pthread_mutex_lock(&private_display->lock);
1568 func_layer = &private_display->func_layer;
1569 if (!func_layer->layer_set_buffer) {
1570 _pthread_mutex_unlock(&private_display->lock);
1574 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
1576 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1577 private_layer, surface);
1578 _pthread_mutex_unlock(&private_display->lock);
1582 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1583 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1585 if (ret == TDM_ERROR_NONE) {
1586 if (private_layer->waiting_buffer) {
1587 TDM_DBG("layer(%p) drop waiting_buffer(%p)", private_layer, private_layer->waiting_buffer);
1588 _pthread_mutex_unlock(&private_display->lock);
1589 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1590 tbm_surface_queue_release(private_layer->buffer_queue,
1591 private_layer->waiting_buffer);
1592 _pthread_mutex_lock(&private_display->lock);
1595 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1597 if (tdm_debug_buffer)
1598 TDM_INFO("layer(%p) waiting_buffer(%p)",
1599 private_layer, private_layer->waiting_buffer);
1601 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1602 if (ret != TDM_ERROR_NONE)
1603 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1606 _pthread_mutex_unlock(&private_display->lock);
1610 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1612 TDM_RETURN_IF_FAIL(data != NULL);
1613 tdm_layer *layer = data;
1614 LAYER_FUNC_ENTRY_VOID_RETURN();
1615 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1617 _pthread_mutex_lock(&private_display->lock);
1619 if (private_layer->waiting_buffer) {
1620 _pthread_mutex_unlock(&private_display->lock);
1621 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1622 tbm_surface_queue_release(private_layer->buffer_queue,
1623 private_layer->waiting_buffer);
1624 _pthread_mutex_lock(&private_display->lock);
1627 private_layer->buffer_queue = NULL;
1629 _pthread_mutex_unlock(&private_display->lock);
1633 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1635 tdm_func_layer *func_layer;
1638 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1640 _pthread_mutex_lock(&private_display->lock);
1642 func_layer = &private_display->func_layer;
1644 if (private_layer->usable)
1645 TDM_INFO("layer(%p) not usable", private_layer);
1647 private_layer->usable = 0;
1649 if (!func_layer->layer_set_buffer) {
1650 _pthread_mutex_unlock(&private_display->lock);
1651 TDM_ERR("not implemented!!");
1652 return TDM_ERROR_NOT_IMPLEMENTED;
1655 if (buffer_queue == private_layer->buffer_queue) {
1656 _pthread_mutex_unlock(&private_display->lock);
1657 return TDM_ERROR_NONE;
1660 if (private_layer->waiting_buffer) {
1661 _pthread_mutex_unlock(&private_display->lock);
1662 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1663 tbm_surface_queue_release(private_layer->buffer_queue,
1664 private_layer->waiting_buffer);
1665 private_layer->waiting_buffer = NULL;
1666 _pthread_mutex_lock(&private_display->lock);
1668 if (tdm_debug_buffer)
1669 TDM_INFO("layer(%p) waiting_buffer(%p)",
1670 private_layer, private_layer->waiting_buffer);
1673 private_layer->buffer_queue = buffer_queue;
1674 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1675 _tbm_layer_queue_acquirable_cb,
1677 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1678 _tbm_layer_queue_destroy_cb,
1680 _pthread_mutex_unlock(&private_display->lock);
1686 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1688 tdm_func_layer *func_layer;
1691 _pthread_mutex_lock(&private_display->lock);
1693 func_layer = &private_display->func_layer;
1695 if (private_layer->waiting_buffer) {
1696 _pthread_mutex_unlock(&private_display->lock);
1697 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1698 tbm_surface_queue_release(private_layer->buffer_queue,
1699 private_layer->waiting_buffer);
1700 private_layer->waiting_buffer = NULL;
1701 _pthread_mutex_lock(&private_display->lock);
1703 if (tdm_debug_buffer)
1704 TDM_INFO("layer(%p) waiting_buffer(%p)",
1705 private_layer, private_layer->waiting_buffer);
1708 if (private_layer->showing_buffer) {
1709 _pthread_mutex_unlock(&private_display->lock);
1710 tdm_buffer_unref_backend(private_layer->showing_buffer);
1711 tbm_surface_queue_release(private_layer->buffer_queue,
1712 private_layer->showing_buffer);
1713 _pthread_mutex_lock(&private_display->lock);
1714 private_layer->showing_buffer = NULL;
1716 if (tdm_debug_buffer)
1717 TDM_INFO("layer(%p) showing_buffer(%p)",
1718 private_layer, private_layer->showing_buffer);
1721 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1722 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1723 private_layer->buffer_queue = NULL;
1724 private_layer->usable = 1;
1726 if (private_layer->usable)
1727 TDM_INFO("layer(%p) now usable", private_layer);
1729 if (!func_layer->layer_unset_buffer) {
1730 _pthread_mutex_unlock(&private_display->lock);
1731 TDM_ERR("not implemented!!");
1732 return TDM_ERROR_NOT_IMPLEMENTED;
1735 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1737 _pthread_mutex_unlock(&private_display->lock);
1743 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1747 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1749 _pthread_mutex_lock(&private_display->lock);
1751 *usable = private_layer->usable;
1753 _pthread_mutex_unlock(&private_display->lock);
1759 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1761 tdm_func_layer *func_layer;
1764 _pthread_mutex_lock(&private_display->lock);
1766 func_layer = &private_display->func_layer;
1768 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1769 TDM_ERR("layer(%p) is not video layer", private_layer);
1770 _pthread_mutex_unlock(&private_display->lock);
1771 return TDM_ERROR_INVALID_PARAMETER;
1774 if (!func_layer->layer_set_video_pos) {
1775 _pthread_mutex_unlock(&private_display->lock);
1776 TDM_ERR("not implemented!!");
1777 return TDM_ERROR_NOT_IMPLEMENTED;
1780 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1782 _pthread_mutex_unlock(&private_display->lock);
1787 EXTERN tdm_capture *
1788 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1790 tdm_capture *capture = NULL;
1792 LAYER_FUNC_ENTRY_ERROR();
1794 _pthread_mutex_lock(&private_display->lock);
1796 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer, error);
1798 _pthread_mutex_unlock(&private_display->lock);
1804 tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
1806 tdm_func_layer *func_layer;
1809 _pthread_mutex_lock(&private_display->lock);
1811 func_layer = &private_display->func_layer;
1813 if (!func_layer->layer_get_buffer_flags) {
1814 _pthread_mutex_unlock(&private_display->lock);
1815 TDM_ERR("not implemented!!");
1816 return TDM_ERROR_NOT_IMPLEMENTED;
1819 ret = func_layer->layer_get_buffer_flags(private_layer->layer_backend, flags);
1821 _pthread_mutex_unlock(&private_display->lock);