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 if (!private_output->regist_change_cb) {
525 _pthread_mutex_unlock(&private_display->lock);
526 TDM_ERR("not implemented!!");
527 return TDM_ERROR_NOT_IMPLEMENTED;
530 change_handler = calloc(1, sizeof(tdm_private_change_handler));
531 if (!change_handler) {
532 TDM_ERR("failed: alloc memory");
533 _pthread_mutex_unlock(&private_display->lock);
534 return TDM_ERROR_OUT_OF_MEMORY;
537 change_handler->private_output = private_output;
538 change_handler->func = func;
539 change_handler->user_data = user_data;
540 change_handler->owner_tid = syscall(SYS_gettid);
542 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
543 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
545 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
547 _pthread_mutex_unlock(&private_display->lock);
553 tdm_output_remove_change_handler(tdm_output *output,
554 tdm_output_change_handler func,
557 tdm_private_display *private_display;
558 tdm_private_output *private_output;
559 tdm_private_change_handler *h = NULL, *hh = NULL;
561 TDM_RETURN_IF_FAIL(output != NULL);
562 TDM_RETURN_IF_FAIL(func != NULL);
564 private_output = (tdm_private_output*)output;
565 private_display = private_output->private_display;
567 _pthread_mutex_lock(&private_display->lock);
569 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
570 if (h->func != func || h->user_data != user_data)
576 _pthread_mutex_unlock(&private_display->lock);
581 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
582 if (h->func != func || h->user_data != user_data)
588 _pthread_mutex_unlock(&private_display->lock);
593 _pthread_mutex_unlock(&private_display->lock);
597 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
601 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
603 _pthread_mutex_lock(&private_display->lock);
605 *type = private_output->caps.type;
607 _pthread_mutex_unlock(&private_display->lock);
613 tdm_output_get_layer_count(tdm_output *output, int *count)
615 tdm_private_layer *private_layer = NULL;
619 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
621 _pthread_mutex_lock(&private_display->lock);
624 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
627 _pthread_mutex_unlock(&private_display->lock);
628 return TDM_ERROR_NONE;
631 _pthread_mutex_unlock(&private_display->lock);
638 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
640 tdm_private_layer *private_layer = NULL;
643 OUTPUT_FUNC_ENTRY_ERROR();
645 _pthread_mutex_lock(&private_display->lock);
648 *error = TDM_ERROR_NONE;
650 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
652 _pthread_mutex_unlock(&private_display->lock);
653 return private_layer;
658 _pthread_mutex_unlock(&private_display->lock);
664 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
669 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
670 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
672 _pthread_mutex_lock(&private_display->lock);
674 *props = (const tdm_prop *)private_output->caps.props;
675 *count = private_output->caps.prop_count;
677 _pthread_mutex_unlock(&private_display->lock);
683 tdm_output_get_available_modes(tdm_output *output,
684 const tdm_output_mode **modes, int *count)
688 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
689 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
691 _pthread_mutex_lock(&private_display->lock);
693 *modes = (const tdm_output_mode *)private_output->caps.modes;
694 *count = private_output->caps.mode_count;
696 _pthread_mutex_unlock(&private_display->lock);
702 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
703 int *max_w, int *max_h, int *preferred_align)
707 _pthread_mutex_lock(&private_display->lock);
710 *min_w = private_output->caps.min_w;
712 *min_h = private_output->caps.min_h;
714 *max_w = private_output->caps.max_w;
716 *max_h = private_output->caps.max_h;
718 *preferred_align = private_output->caps.preferred_align;
720 _pthread_mutex_unlock(&private_display->lock);
726 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
727 unsigned int *mmHeight)
731 _pthread_mutex_lock(&private_display->lock);
734 *mmWidth = private_output->caps.mmWidth;
736 *mmHeight = private_output->caps.mmHeight;
738 _pthread_mutex_unlock(&private_display->lock);
744 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
747 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
749 _pthread_mutex_lock(&private_display->lock);
751 *subpixel = private_output->caps.subpixel;
753 _pthread_mutex_unlock(&private_display->lock);
759 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
762 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
764 _pthread_mutex_lock(&private_display->lock);
766 *pipe = private_output->pipe;
768 _pthread_mutex_unlock(&private_display->lock);
775 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
777 tdm_func_output *func_output;
780 _pthread_mutex_lock(&private_display->lock);
782 func_output = &private_display->func_output;
784 if (!func_output->output_set_property) {
785 _pthread_mutex_unlock(&private_display->lock);
786 TDM_ERR("not implemented!!");
787 return TDM_ERROR_NOT_IMPLEMENTED;
790 ret = func_output->output_set_property(private_output->output_backend, id,
793 _pthread_mutex_unlock(&private_display->lock);
799 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
801 tdm_func_output *func_output;
804 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
806 _pthread_mutex_lock(&private_display->lock);
808 func_output = &private_display->func_output;
810 if (!func_output->output_get_property) {
811 _pthread_mutex_unlock(&private_display->lock);
812 TDM_ERR("not implemented!!");
813 return TDM_ERROR_NOT_IMPLEMENTED;
816 ret = func_output->output_get_property(private_output->output_backend, id,
819 _pthread_mutex_unlock(&private_display->lock);
825 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
826 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
828 tdm_private_vblank_handler *vblank_handler = user_data;
829 tdm_private_display *private_display;
831 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
832 TDM_RETURN_IF_FAIL(vblank_handler);
834 private_display = vblank_handler->private_output->private_display;
836 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
837 tdm_thread_cb_output_vblank output_vblank;
840 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
841 output_vblank.base.length = sizeof output_vblank;
842 output_vblank.output_stamp = vblank_handler->private_output->stamp;
843 output_vblank.sequence = sequence;
844 output_vblank.tv_sec = tv_sec;
845 output_vblank.tv_usec = tv_usec;
846 output_vblank.user_data = user_data;
848 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
849 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
854 if (vblank_handler->owner_tid != syscall(SYS_gettid))
855 TDM_NEVER_GET_HERE();
857 if (vblank_handler->func) {
858 _pthread_mutex_unlock(&private_display->lock);
859 vblank_handler->func(vblank_handler->private_output, sequence,
860 tv_sec, tv_usec, vblank_handler->user_data);
861 _pthread_mutex_lock(&private_display->lock);
864 LIST_DEL(&vblank_handler->link);
865 free(vblank_handler);
869 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
870 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
872 tdm_private_commit_handler *commit_handler = user_data;
873 tdm_private_display *private_display;
874 tdm_private_output *private_output;
875 tdm_private_layer *private_layer = NULL;
877 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
878 TDM_RETURN_IF_FAIL(commit_handler);
880 private_output = commit_handler->private_output;
881 private_display = private_output->private_display;
883 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
884 tdm_thread_cb_output_commit output_commit;
887 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
888 output_commit.base.length = sizeof output_commit;
889 output_commit.output_stamp = private_output->stamp;
890 output_commit.sequence = sequence;
891 output_commit.tv_sec = tv_sec;
892 output_commit.tv_usec = tv_usec;
893 output_commit.user_data = user_data;
895 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
896 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
901 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
902 if (!private_layer->waiting_buffer)
905 if (private_layer->showing_buffer) {
906 _pthread_mutex_unlock(&private_display->lock);
907 tdm_buffer_unref_backend(private_layer->showing_buffer);
908 _pthread_mutex_lock(&private_display->lock);
910 if (private_layer->buffer_queue) {
911 _pthread_mutex_unlock(&private_display->lock);
912 tbm_surface_queue_release(private_layer->buffer_queue,
913 private_layer->showing_buffer);
914 _pthread_mutex_lock(&private_display->lock);
918 private_layer->showing_buffer = private_layer->waiting_buffer;
919 private_layer->waiting_buffer = NULL;
921 if (tdm_debug_buffer)
922 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
923 private_layer, private_layer->waiting_buffer,
924 private_layer->showing_buffer);
927 if (commit_handler->func) {
928 _pthread_mutex_unlock(&private_display->lock);
929 commit_handler->func(private_output, sequence,
930 tv_sec, tv_usec, commit_handler->user_data);
931 _pthread_mutex_lock(&private_display->lock);
934 LIST_DEL(&commit_handler->link);
935 free(commit_handler);
939 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
940 tdm_output_vblank_handler func, void *user_data)
942 tdm_func_output *func_output;
943 tdm_private_vblank_handler *vblank_handler;
946 _pthread_mutex_lock(&private_display->lock);
948 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
949 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
950 tdm_dpms_str(private_output->current_dpms_value));
951 _pthread_mutex_unlock(&private_display->lock);
952 return TDM_ERROR_BAD_REQUEST;
955 func_output = &private_display->func_output;
957 if (!func_output->output_wait_vblank) {
958 _pthread_mutex_unlock(&private_display->lock);
959 TDM_ERR("not implemented!!");
960 return TDM_ERROR_NOT_IMPLEMENTED;
963 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
964 if (!vblank_handler) {
965 TDM_ERR("failed: alloc memory");
966 _pthread_mutex_unlock(&private_display->lock);
967 return TDM_ERROR_OUT_OF_MEMORY;
970 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
971 vblank_handler->private_output = private_output;
972 vblank_handler->func = func;
973 vblank_handler->user_data = user_data;
974 vblank_handler->owner_tid = syscall(SYS_gettid);
976 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
977 sync, vblank_handler);
978 if (ret != TDM_ERROR_NONE) {
979 _pthread_mutex_unlock(&private_display->lock);
983 if (!private_output->regist_vblank_cb) {
984 private_output->regist_vblank_cb = 1;
985 ret = func_output->output_set_vblank_handler(private_output->output_backend,
986 tdm_output_cb_vblank);
989 _pthread_mutex_unlock(&private_display->lock);
995 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
998 tdm_func_output *func_output;
999 tdm_private_commit_handler *commit_handler;
1000 OUTPUT_FUNC_ENTRY();
1002 func_output = &private_display->func_output;
1004 if (!func_output->output_commit) {
1005 TDM_ERR("not implemented!!");
1006 return TDM_ERROR_NOT_IMPLEMENTED;
1009 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1010 if (!commit_handler) {
1011 TDM_ERR("failed: alloc memory");
1012 return TDM_ERROR_OUT_OF_MEMORY;
1015 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1016 commit_handler->private_output = private_output;
1017 commit_handler->func = func;
1018 commit_handler->user_data = user_data;
1019 commit_handler->owner_tid = syscall(SYS_gettid);
1021 if (!private_output->regist_commit_cb) {
1022 private_output->regist_commit_cb = 1;
1023 ret = func_output->output_set_commit_handler(private_output->output_backend,
1024 tdm_output_cb_commit);
1027 ret = func_output->output_commit(private_output->output_backend, sync,
1029 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1035 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1038 OUTPUT_FUNC_ENTRY();
1040 _pthread_mutex_lock(&private_display->lock);
1042 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1043 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1044 tdm_dpms_str(private_output->current_dpms_value));
1045 _pthread_mutex_unlock(&private_display->lock);
1046 return TDM_ERROR_BAD_REQUEST;
1049 ret = _tdm_output_commit(output, sync, func, user_data);
1051 _pthread_mutex_unlock(&private_display->lock);
1057 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1059 tdm_func_output *func_output;
1060 OUTPUT_FUNC_ENTRY();
1062 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1064 _pthread_mutex_lock(&private_display->lock);
1066 func_output = &private_display->func_output;
1068 if (!func_output->output_set_mode) {
1069 _pthread_mutex_unlock(&private_display->lock);
1070 TDM_ERR("not implemented!!");
1071 return TDM_ERROR_NOT_IMPLEMENTED;
1074 ret = func_output->output_set_mode(private_output->output_backend, mode);
1076 _pthread_mutex_unlock(&private_display->lock);
1082 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1084 tdm_func_output *func_output;
1085 OUTPUT_FUNC_ENTRY();
1087 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1089 _pthread_mutex_lock(&private_display->lock);
1091 func_output = &private_display->func_output;
1093 if (!func_output->output_get_mode) {
1094 _pthread_mutex_unlock(&private_display->lock);
1095 TDM_ERR("not implemented!!");
1096 return TDM_ERROR_NOT_IMPLEMENTED;
1099 ret = func_output->output_get_mode(private_output->output_backend, mode);
1101 _pthread_mutex_unlock(&private_display->lock);
1107 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1109 tdm_func_output *func_output;
1110 OUTPUT_FUNC_ENTRY();
1112 if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1113 dpms_value = TDM_OUTPUT_DPMS_OFF;
1115 _pthread_mutex_lock(&private_display->lock);
1117 if (private_output->current_dpms_value == dpms_value) {
1118 _pthread_mutex_unlock(&private_display->lock);
1119 return TDM_ERROR_NONE;
1122 func_output = &private_display->func_output;
1124 if (!func_output->output_set_dpms) {
1125 _pthread_mutex_unlock(&private_display->lock);
1126 private_output->current_dpms_value = dpms_value;
1127 TDM_WRN("not implemented!!");
1128 return TDM_ERROR_NONE;
1131 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1132 if (ret == TDM_ERROR_NONE) {
1135 private_output->current_dpms_value = dpms_value;
1137 value.u32 = dpms_value;
1138 tdm_output_call_change_handler_internal(private_output,
1139 &private_output->change_handler_list_main,
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,
1197 tdm_private_display *private_display;
1198 tdm_private_change_handler *change_handler = NULL;
1200 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1201 TDM_RETURN_IF_FAIL(private_output);
1203 private_display = private_output->private_display;
1204 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1205 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1206 TDM_INFO("output(%d) changed: %s (%d)",
1207 private_output->pipe, tdm_status_str(value.u32), value.u32);
1208 if (type & TDM_OUTPUT_CHANGE_DPMS)
1209 TDM_INFO("output(%d) changed: dpms %s (%d)",
1210 private_output->pipe, tdm_dpms_str(value.u32), value.u32);
1213 if (LIST_IS_EMPTY(change_handler_list))
1216 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1217 if (change_handler->owner_tid != syscall(SYS_gettid))
1218 TDM_NEVER_GET_HERE();
1220 _pthread_mutex_unlock(&private_display->lock);
1221 change_handler->func(private_output, type,
1222 value, change_handler->user_data);
1223 _pthread_mutex_lock(&private_display->lock);
1228 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1232 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1234 _pthread_mutex_lock(&private_display->lock);
1236 *capabilities = private_layer->caps.capabilities;
1238 _pthread_mutex_unlock(&private_display->lock);
1244 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
1248 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1249 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1251 _pthread_mutex_lock(&private_display->lock);
1253 *formats = (const tbm_format *)private_layer->caps.formats;
1254 *count = private_layer->caps.format_count;
1256 _pthread_mutex_unlock(&private_display->lock);
1262 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
1266 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1267 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1269 _pthread_mutex_lock(&private_display->lock);
1271 *props = (const tdm_prop *)private_layer->caps.props;
1272 *count = private_layer->caps.prop_count;
1274 _pthread_mutex_unlock(&private_display->lock);
1280 tdm_layer_get_zpos(tdm_layer *layer, int *zpos)
1284 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1286 _pthread_mutex_lock(&private_display->lock);
1288 *zpos = private_layer->caps.zpos;
1290 _pthread_mutex_unlock(&private_display->lock);
1296 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1298 tdm_func_layer *func_layer;
1301 _pthread_mutex_lock(&private_display->lock);
1303 func_layer = &private_display->func_layer;
1305 if (!func_layer->layer_set_property) {
1306 _pthread_mutex_unlock(&private_display->lock);
1307 TDM_ERR("not implemented!!");
1308 return TDM_ERROR_NOT_IMPLEMENTED;
1311 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1313 _pthread_mutex_unlock(&private_display->lock);
1319 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1321 tdm_func_layer *func_layer;
1324 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1326 _pthread_mutex_lock(&private_display->lock);
1328 func_layer = &private_display->func_layer;
1330 if (!func_layer->layer_get_property) {
1331 _pthread_mutex_unlock(&private_display->lock);
1332 TDM_ERR("not implemented!!");
1333 return TDM_ERROR_NOT_IMPLEMENTED;
1336 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1338 _pthread_mutex_unlock(&private_display->lock);
1344 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1346 tdm_func_layer *func_layer;
1349 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1351 _pthread_mutex_lock(&private_display->lock);
1353 func_layer = &private_display->func_layer;
1355 if (private_layer->usable)
1356 TDM_INFO("layer(%p) not usable", private_layer);
1358 private_layer->usable = 0;
1360 if (!func_layer->layer_set_info) {
1361 _pthread_mutex_unlock(&private_display->lock);
1362 TDM_ERR("not implemented!!");
1363 return TDM_ERROR_NOT_IMPLEMENTED;
1366 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1367 private_layer, info->src_config.size.h, info->src_config.size.v,
1368 info->src_config.pos.x, info->src_config.pos.y,
1369 info->src_config.pos.w, info->src_config.pos.h,
1370 FOURCC_STR(info->src_config.format),
1371 info->dst_pos.x, info->dst_pos.y,
1372 info->dst_pos.w, info->dst_pos.h,
1375 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1376 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1378 _pthread_mutex_unlock(&private_display->lock);
1384 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1386 tdm_func_layer *func_layer;
1389 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1391 _pthread_mutex_lock(&private_display->lock);
1393 func_layer = &private_display->func_layer;
1395 if (!func_layer->layer_get_info) {
1396 _pthread_mutex_unlock(&private_display->lock);
1397 TDM_ERR("not implemented!!");
1398 return TDM_ERROR_NOT_IMPLEMENTED;
1401 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1403 _pthread_mutex_unlock(&private_display->lock);
1409 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1411 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1412 tdm_private_output *private_output = private_layer->private_output;
1415 char fname[PATH_MAX];
1417 pipe = private_output->pipe;
1418 zpos = private_layer->caps.zpos;
1420 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1422 tbm_surface_internal_dump_buffer(buffer, fname);
1423 TDM_DBG("%s dump excute", fname);
1429 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1431 tdm_func_layer *func_layer;
1435 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1437 _pthread_mutex_lock(&private_display->lock);
1439 func_layer = &private_display->func_layer;
1441 if (private_layer->usable)
1442 TDM_INFO("layer(%p) not usable", private_layer);
1444 private_layer->usable = 0;
1446 if (!func_layer->layer_set_buffer) {
1447 _pthread_mutex_unlock(&private_display->lock);
1448 TDM_ERR("not implemented!!");
1449 return TDM_ERROR_NOT_IMPLEMENTED;
1452 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1453 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1456 if (tdm_dump_enable)
1457 _tdm_layer_dump_buffer(layer, buffer);
1459 if (ret == TDM_ERROR_NONE) {
1460 /* FIXME: should save to pending_buffer first. And after committing
1461 * successfully, need to move to waiting_buffer.
1463 if (private_layer->waiting_buffer) {
1464 _pthread_mutex_unlock(&private_display->lock);
1465 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1466 _pthread_mutex_lock(&private_display->lock);
1469 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1470 if (tdm_debug_buffer)
1471 TDM_INFO("layer(%p) waiting_buffer(%p)",
1472 private_layer, private_layer->waiting_buffer);
1475 _pthread_mutex_unlock(&private_display->lock);
1481 tdm_layer_unset_buffer(tdm_layer *layer)
1483 tdm_func_layer *func_layer;
1486 _pthread_mutex_lock(&private_display->lock);
1488 func_layer = &private_display->func_layer;
1490 if (private_layer->waiting_buffer) {
1491 _pthread_mutex_unlock(&private_display->lock);
1492 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1493 _pthread_mutex_lock(&private_display->lock);
1494 private_layer->waiting_buffer = NULL;
1496 if (tdm_debug_buffer)
1497 TDM_INFO("layer(%p) waiting_buffer(%p)",
1498 private_layer, private_layer->waiting_buffer);
1501 if (private_layer->showing_buffer) {
1502 _pthread_mutex_unlock(&private_display->lock);
1503 tdm_buffer_unref_backend(private_layer->showing_buffer);
1504 _pthread_mutex_lock(&private_display->lock);
1505 private_layer->showing_buffer = NULL;
1507 if (tdm_debug_buffer)
1508 TDM_INFO("layer(%p) showing_buffer(%p)",
1509 private_layer, private_layer->showing_buffer);
1512 private_layer->usable = 1;
1514 if (private_layer->usable)
1515 TDM_INFO("layer(%p) now usable", private_layer);
1517 if (!func_layer->layer_unset_buffer) {
1518 _pthread_mutex_unlock(&private_display->lock);
1519 TDM_ERR("not implemented!!");
1520 return TDM_ERROR_NOT_IMPLEMENTED;
1523 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1524 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1526 _pthread_mutex_unlock(&private_display->lock);
1531 EXTERN tbm_surface_h
1532 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1534 tbm_surface_h buffer;
1535 LAYER_FUNC_ENTRY_ERROR();
1537 _pthread_mutex_lock(&private_display->lock);
1540 *error = TDM_ERROR_NONE;
1542 if (private_layer->showing_buffer) {
1543 buffer = private_layer->showing_buffer;
1546 *error = TDM_ERROR_OPERATION_FAILED;
1547 _pthread_mutex_unlock(&private_display->lock);
1548 TDM_DBG("layer(%p) showing_buffer is null", private_layer);
1551 _pthread_mutex_unlock(&private_display->lock);
1557 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1559 TDM_RETURN_IF_FAIL(data != NULL);
1560 tdm_layer *layer = data;
1561 tdm_func_layer *func_layer;
1562 tbm_surface_h surface = NULL;
1563 LAYER_FUNC_ENTRY_VOID_RETURN();
1565 _pthread_mutex_lock(&private_display->lock);
1567 func_layer = &private_display->func_layer;
1568 if (!func_layer->layer_set_buffer) {
1569 _pthread_mutex_unlock(&private_display->lock);
1573 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
1575 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1576 private_layer, surface);
1577 _pthread_mutex_unlock(&private_display->lock);
1581 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1582 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1584 if (ret == TDM_ERROR_NONE) {
1585 if (private_layer->waiting_buffer) {
1586 TDM_DBG("layer(%p) drop waiting_buffer(%p)", private_layer, private_layer->waiting_buffer);
1587 _pthread_mutex_unlock(&private_display->lock);
1588 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1589 tbm_surface_queue_release(private_layer->buffer_queue,
1590 private_layer->waiting_buffer);
1591 _pthread_mutex_lock(&private_display->lock);
1594 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1596 if (tdm_debug_buffer)
1597 TDM_INFO("layer(%p) waiting_buffer(%p)",
1598 private_layer, private_layer->waiting_buffer);
1600 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1601 if (ret != TDM_ERROR_NONE)
1602 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1605 _pthread_mutex_unlock(&private_display->lock);
1609 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1611 TDM_RETURN_IF_FAIL(data != NULL);
1612 tdm_layer *layer = data;
1613 LAYER_FUNC_ENTRY_VOID_RETURN();
1614 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1616 _pthread_mutex_lock(&private_display->lock);
1618 if (private_layer->waiting_buffer) {
1619 _pthread_mutex_unlock(&private_display->lock);
1620 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1621 tbm_surface_queue_release(private_layer->buffer_queue,
1622 private_layer->waiting_buffer);
1623 _pthread_mutex_lock(&private_display->lock);
1626 private_layer->buffer_queue = NULL;
1628 _pthread_mutex_unlock(&private_display->lock);
1632 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1634 tdm_func_layer *func_layer;
1637 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1639 _pthread_mutex_lock(&private_display->lock);
1641 func_layer = &private_display->func_layer;
1643 if (private_layer->usable)
1644 TDM_INFO("layer(%p) not usable", private_layer);
1646 private_layer->usable = 0;
1648 if (!func_layer->layer_set_buffer) {
1649 _pthread_mutex_unlock(&private_display->lock);
1650 TDM_ERR("not implemented!!");
1651 return TDM_ERROR_NOT_IMPLEMENTED;
1654 if (buffer_queue == private_layer->buffer_queue) {
1655 _pthread_mutex_unlock(&private_display->lock);
1656 return TDM_ERROR_NONE;
1659 if (private_layer->waiting_buffer) {
1660 _pthread_mutex_unlock(&private_display->lock);
1661 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1662 tbm_surface_queue_release(private_layer->buffer_queue,
1663 private_layer->waiting_buffer);
1664 private_layer->waiting_buffer = NULL;
1665 _pthread_mutex_lock(&private_display->lock);
1667 if (tdm_debug_buffer)
1668 TDM_INFO("layer(%p) waiting_buffer(%p)",
1669 private_layer, private_layer->waiting_buffer);
1672 private_layer->buffer_queue = buffer_queue;
1673 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1674 _tbm_layer_queue_acquirable_cb,
1676 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1677 _tbm_layer_queue_destroy_cb,
1679 _pthread_mutex_unlock(&private_display->lock);
1685 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1687 tdm_func_layer *func_layer;
1690 _pthread_mutex_lock(&private_display->lock);
1692 func_layer = &private_display->func_layer;
1694 if (private_layer->waiting_buffer) {
1695 _pthread_mutex_unlock(&private_display->lock);
1696 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1697 tbm_surface_queue_release(private_layer->buffer_queue,
1698 private_layer->waiting_buffer);
1699 private_layer->waiting_buffer = NULL;
1700 _pthread_mutex_lock(&private_display->lock);
1702 if (tdm_debug_buffer)
1703 TDM_INFO("layer(%p) waiting_buffer(%p)",
1704 private_layer, private_layer->waiting_buffer);
1707 if (private_layer->showing_buffer) {
1708 _pthread_mutex_unlock(&private_display->lock);
1709 tdm_buffer_unref_backend(private_layer->showing_buffer);
1710 tbm_surface_queue_release(private_layer->buffer_queue,
1711 private_layer->showing_buffer);
1712 _pthread_mutex_lock(&private_display->lock);
1713 private_layer->showing_buffer = NULL;
1715 if (tdm_debug_buffer)
1716 TDM_INFO("layer(%p) showing_buffer(%p)",
1717 private_layer, private_layer->showing_buffer);
1720 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1721 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1722 private_layer->buffer_queue = NULL;
1723 private_layer->usable = 1;
1725 if (private_layer->usable)
1726 TDM_INFO("layer(%p) now usable", private_layer);
1728 if (!func_layer->layer_unset_buffer) {
1729 _pthread_mutex_unlock(&private_display->lock);
1730 TDM_ERR("not implemented!!");
1731 return TDM_ERROR_NOT_IMPLEMENTED;
1734 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1736 _pthread_mutex_unlock(&private_display->lock);
1742 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1746 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1748 _pthread_mutex_lock(&private_display->lock);
1750 *usable = private_layer->usable;
1752 _pthread_mutex_unlock(&private_display->lock);
1758 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1760 tdm_func_layer *func_layer;
1763 _pthread_mutex_lock(&private_display->lock);
1765 func_layer = &private_display->func_layer;
1767 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1768 TDM_ERR("layer(%p) is not video layer", private_layer);
1769 _pthread_mutex_unlock(&private_display->lock);
1770 return TDM_ERROR_INVALID_PARAMETER;
1773 if (!func_layer->layer_set_video_pos) {
1774 _pthread_mutex_unlock(&private_display->lock);
1775 TDM_ERR("not implemented!!");
1776 return TDM_ERROR_NOT_IMPLEMENTED;
1779 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1781 _pthread_mutex_unlock(&private_display->lock);
1786 EXTERN tdm_capture *
1787 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1789 tdm_capture *capture = NULL;
1791 LAYER_FUNC_ENTRY_ERROR();
1793 _pthread_mutex_lock(&private_display->lock);
1795 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer, error);
1797 _pthread_mutex_unlock(&private_display->lock);
1803 tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
1805 tdm_func_layer *func_layer;
1808 _pthread_mutex_lock(&private_display->lock);
1810 func_layer = &private_display->func_layer;
1812 if (!func_layer->layer_get_buffer_flags) {
1813 _pthread_mutex_unlock(&private_display->lock);
1814 TDM_ERR("not implemented!!");
1815 return TDM_ERROR_NOT_IMPLEMENTED;
1818 ret = func_layer->layer_get_buffer_flags(private_layer->layer_backend, flags);
1820 _pthread_mutex_unlock(&private_display->lock);