1 /**************************************************************************
5 * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
7 * Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8 * JinYoung Jeon <jy0.jeon@samsung.com>,
9 * Taeheon Kim <th908.kim@samsung.com>,
10 * YoungJun Cho <yj44.cho@samsung.com>,
11 * SooChan Lim <sc1.lim@samsung.com>,
12 * Boram Park <sc1.lim@samsung.com>
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the
16 * "Software"), to deal in the Software without restriction, including
17 * without limitation the rights to use, copy, modify, merge, publish,
18 * distribute, sub license, and/or sell copies of the Software, and to
19 * permit persons to whom the Software is furnished to do so, subject to
20 * the following conditions:
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 **************************************************************************/
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
43 #include "tdm_helper.h"
47 #define DISPLAY_FUNC_ENTRY() \
48 tdm_private_display *private_display; \
49 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50 TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
51 private_display = (tdm_private_display*)dpy;
53 #define DISPLAY_FUNC_ENTRY_ERROR() \
54 tdm_private_display *private_display; \
55 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
56 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
57 private_display = (tdm_private_display*)dpy;
59 #define OUTPUT_FUNC_ENTRY() \
60 tdm_private_display *private_display; \
61 tdm_private_output *private_output; \
62 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
63 TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
64 private_output = (tdm_private_output*)output; \
65 private_display = private_output->private_display
67 #define OUTPUT_FUNC_ENTRY_ERROR() \
68 tdm_private_display *private_display; \
69 tdm_private_output *private_output; \
70 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
71 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
72 private_output = (tdm_private_output*)output; \
73 private_display = private_output->private_display
75 #define LAYER_FUNC_ENTRY() \
76 tdm_private_display *private_display; \
77 tdm_private_output *private_output; \
78 tdm_private_layer *private_layer; \
79 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
80 TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
81 private_layer = (tdm_private_layer*)layer; \
82 private_output = private_layer->private_output; \
83 private_display = private_output->private_display
85 #define LAYER_FUNC_ENTRY_ERROR() \
86 tdm_private_display *private_display; \
87 tdm_private_output *private_output; \
88 tdm_private_layer *private_layer; \
89 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
90 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
91 private_layer = (tdm_private_layer*)layer; \
92 private_output = private_layer->private_output; \
93 private_display = private_output->private_display
95 #define LAYER_FUNC_ENTRY_VOID_RETURN() \
96 tdm_private_display *private_display; \
97 tdm_private_output *private_output; \
98 tdm_private_layer *private_layer; \
99 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
100 TDM_RETURN_IF_FAIL(layer != NULL); \
101 private_layer = (tdm_private_layer*)layer; \
102 private_output = private_layer->private_output; \
103 private_display = private_output->private_display
105 static void _tdm_layer_committed(tdm_private_layer *private_layer);
106 static void _tdm_layer_cb_output_commit(tdm_output *output, unsigned int sequence,
107 unsigned int tv_sec, unsigned int tv_usec, void *user_data);
108 static void _tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
109 unsigned int tv_sec, unsigned int tv_usec, void *user_data);
112 tdm_display_get_capabilities(tdm_display *dpy,
113 tdm_display_capability *capabilities)
115 DISPLAY_FUNC_ENTRY();
117 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
119 _pthread_mutex_lock(&private_display->lock);
121 *capabilities = private_display->capabilities;
123 _pthread_mutex_unlock(&private_display->lock);
129 tdm_display_get_pp_capabilities(tdm_display *dpy,
130 tdm_pp_capability *capabilities)
132 DISPLAY_FUNC_ENTRY();
134 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
136 _pthread_mutex_lock(&private_display->lock);
138 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
139 TDM_ERR("no pp capability");
140 _pthread_mutex_unlock(&private_display->lock);
141 return TDM_ERROR_NO_CAPABILITY;
144 *capabilities = private_display->caps_pp.capabilities;
146 _pthread_mutex_unlock(&private_display->lock);
152 tdm_display_get_pp_available_formats(tdm_display *dpy,
153 const tbm_format **formats, int *count)
155 DISPLAY_FUNC_ENTRY();
157 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
158 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
160 _pthread_mutex_lock(&private_display->lock);
162 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
163 TDM_ERR("no pp capability");
164 _pthread_mutex_unlock(&private_display->lock);
165 return TDM_ERROR_NO_CAPABILITY;
168 *formats = (const tbm_format *)private_display->caps_pp.formats;
169 *count = private_display->caps_pp.format_count;
171 _pthread_mutex_unlock(&private_display->lock);
177 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
178 int *max_w, int *max_h, int *preferred_align)
180 DISPLAY_FUNC_ENTRY();
182 _pthread_mutex_lock(&private_display->lock);
184 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
185 TDM_ERR("no pp capability");
186 _pthread_mutex_unlock(&private_display->lock);
187 return TDM_ERROR_NO_CAPABILITY;
191 *min_w = TDM_FRONT_VALUE(private_display->caps_pp.min_w);
193 *min_h = TDM_FRONT_VALUE(private_display->caps_pp.min_h);
195 *max_w = TDM_FRONT_VALUE(private_display->caps_pp.max_w);
197 *max_h = TDM_FRONT_VALUE(private_display->caps_pp.max_h);
199 *preferred_align = TDM_FRONT_VALUE(private_display->caps_pp.preferred_align);
201 _pthread_mutex_unlock(&private_display->lock);
207 tdm_display_get_capture_capabilities(tdm_display *dpy,
208 tdm_capture_capability *capabilities)
210 DISPLAY_FUNC_ENTRY();
212 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
214 _pthread_mutex_lock(&private_display->lock);
216 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
217 TDM_ERR("no capture capability");
218 _pthread_mutex_unlock(&private_display->lock);
219 return TDM_ERROR_NO_CAPABILITY;
222 *capabilities = private_display->caps_capture.capabilities;
224 _pthread_mutex_unlock(&private_display->lock);
230 tdm_display_get_catpure_available_formats(tdm_display *dpy,
231 const tbm_format **formats, int *count)
233 DISPLAY_FUNC_ENTRY();
235 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
236 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
238 _pthread_mutex_lock(&private_display->lock);
240 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
241 TDM_ERR("no capture capability");
242 _pthread_mutex_unlock(&private_display->lock);
243 return TDM_ERROR_NO_CAPABILITY;
246 *formats = (const tbm_format *)private_display->caps_capture.formats;
247 *count = private_display->caps_capture.format_count;
249 _pthread_mutex_unlock(&private_display->lock);
255 tdm_display_get_capture_available_size(tdm_display *dpy, int *min_w, int *min_h,
256 int *max_w, int *max_h, int *preferred_align)
258 DISPLAY_FUNC_ENTRY();
260 _pthread_mutex_lock(&private_display->lock);
262 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
263 TDM_ERR("no capture capability");
264 _pthread_mutex_unlock(&private_display->lock);
265 return TDM_ERROR_NO_CAPABILITY;
269 *min_w = TDM_FRONT_VALUE(private_display->caps_capture.min_w);
271 *min_h = TDM_FRONT_VALUE(private_display->caps_capture.min_h);
273 *max_w = TDM_FRONT_VALUE(private_display->caps_capture.max_w);
275 *max_h = TDM_FRONT_VALUE(private_display->caps_capture.max_h);
277 *preferred_align = TDM_FRONT_VALUE(private_display->caps_capture.preferred_align);
279 _pthread_mutex_unlock(&private_display->lock);
285 tdm_display_get_max_layer_count(tdm_display *dpy, int *max_count)
287 DISPLAY_FUNC_ENTRY();
289 TDM_RETURN_VAL_IF_FAIL(max_count != NULL, TDM_ERROR_INVALID_PARAMETER);
291 _pthread_mutex_lock(&private_display->lock);
293 *max_count = TDM_FRONT_VALUE(private_display->caps_display.max_layer_count);
295 _pthread_mutex_unlock(&private_display->lock);
301 tdm_display_get_output_count(tdm_display *dpy, int *count)
303 tdm_private_output *private_output = NULL;
305 DISPLAY_FUNC_ENTRY();
307 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
309 _pthread_mutex_lock(&private_display->lock);
312 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
316 _pthread_mutex_unlock(&private_display->lock);
317 return TDM_ERROR_NONE;
320 _pthread_mutex_unlock(&private_display->lock);
327 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
329 tdm_private_output *private_output = NULL;
331 DISPLAY_FUNC_ENTRY_ERROR();
333 _pthread_mutex_lock(&private_display->lock);
336 *error = TDM_ERROR_NONE;
338 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
339 if (private_output->index == index) {
340 _pthread_mutex_unlock(&private_display->lock);
341 return private_output;
345 _pthread_mutex_unlock(&private_display->lock);
351 tdm_display_get_fd(tdm_display *dpy, int *fd)
353 DISPLAY_FUNC_ENTRY();
355 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
357 _pthread_mutex_lock(&private_display->lock);
359 if (tdm_thread_is_running())
360 *fd = tdm_thread_get_fd(private_display->private_loop);
362 *fd = tdm_event_loop_get_fd(private_display);
364 _pthread_mutex_unlock(&private_display->lock);
370 tdm_display_handle_events(tdm_display *dpy)
375 DISPLAY_FUNC_ENTRY();
377 ret = tdm_display_get_fd(dpy, &fd);
378 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
384 if (tdm_debug_module & TDM_DEBUG_THREAD)
385 TDM_INFO("fd(%d) polling in", fd);
387 while (poll(&fds, 1, -1) < 0) {
388 if (errno == EINTR || errno == EAGAIN) /* normal case */
391 TDM_ERR("poll failed: %m");
392 return TDM_ERROR_OPERATION_FAILED;
396 if (tdm_debug_module & TDM_DEBUG_THREAD)
397 TDM_INFO("fd(%d) polling out", fd);
399 if (tdm_thread_is_running())
400 ret = tdm_thread_handle_cb(private_display->private_loop);
402 ret = tdm_event_loop_dispatch(private_display);
408 tdm_display_get_backend_info(tdm_display *dpy, const char **name,
409 const char **vendor, int *major, int *minor)
411 tdm_backend_module *module_data;
413 DISPLAY_FUNC_ENTRY();
415 _pthread_mutex_lock(&private_display->lock);
417 module_data = private_display->module_data;
420 *name = module_data->name;
422 *vendor = module_data->vendor;
424 *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version);
426 *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version);
428 _pthread_mutex_unlock(&private_display->lock);
434 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
438 DISPLAY_FUNC_ENTRY_ERROR();
440 _pthread_mutex_lock(&private_display->lock);
442 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
444 _pthread_mutex_unlock(&private_display->lock);
450 tdm_output_get_model_info(tdm_output *output, const char **maker,
451 const char **model, const char **name)
455 _pthread_mutex_lock(&private_display->lock);
458 *maker = private_output->caps.maker;
460 *model = private_output->caps.model;
462 *name = private_output->caps.name;
464 _pthread_mutex_unlock(&private_display->lock);
470 tdm_output_get_capabilities(tdm_output *output, tdm_output_capability *capabilities)
474 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
476 _pthread_mutex_lock(&private_display->lock);
478 *capabilities = private_output->caps.capabilities;
480 _pthread_mutex_unlock(&private_display->lock);
486 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
490 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
492 _pthread_mutex_lock(&private_display->lock);
494 *status = private_output->caps.status;
496 _pthread_mutex_unlock(&private_display->lock);
502 _tdm_output_used_layer_count(tdm_private_output *private_output)
504 tdm_private_layer *private_layer = NULL;
505 unsigned int count = 0;
507 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
508 if (!private_layer->usable)
516 _tdm_output_update(tdm_output *output_backend, void *user_data)
518 tdm_private_display *private_display;
519 tdm_private_output *private_output = user_data;
522 TDM_RETURN_IF_FAIL(private_output);
524 private_display = private_output->private_display;
526 ret = tdm_display_update_output(private_display, output_backend, private_output->pipe);
527 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
531 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
534 tdm_private_display *private_display;
535 tdm_private_output *private_output = user_data;
538 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
539 TDM_RETURN_IF_FAIL(private_output);
541 private_display = private_output->private_display;
543 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
544 tdm_thread_cb_output_status output_status;
547 _tdm_output_update(output_backend, user_data);
549 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
550 output_status.base.length = sizeof output_status;
551 output_status.output_stamp = private_output->stamp;
552 output_status.status = status;
553 output_status.user_data = user_data;
556 tdm_output_call_change_handler_internal(private_output,
557 &private_output->change_handler_list_sub,
558 TDM_OUTPUT_CHANGE_CONNECTION,
561 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
562 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
567 if (!tdm_thread_is_running())
568 _tdm_output_update(output_backend, user_data);
571 tdm_output_call_change_handler_internal(private_output,
572 &private_output->change_handler_list_main,
573 TDM_OUTPUT_CHANGE_CONNECTION,
578 tdm_output_add_change_handler(tdm_output *output,
579 tdm_output_change_handler func,
582 tdm_private_change_handler *change_handler;
585 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
587 pthread_mutex_lock(&private_display->lock);
589 change_handler = calloc(1, sizeof(tdm_private_change_handler));
590 if (!change_handler) {
591 TDM_ERR("failed: alloc memory");
592 _pthread_mutex_unlock(&private_display->lock);
593 return TDM_ERROR_OUT_OF_MEMORY;
596 change_handler->private_output = private_output;
597 change_handler->func = func;
598 change_handler->user_data = user_data;
599 change_handler->owner_tid = syscall(SYS_gettid);
601 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
602 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
604 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
606 _pthread_mutex_unlock(&private_display->lock);
612 tdm_output_remove_change_handler(tdm_output *output,
613 tdm_output_change_handler func,
616 tdm_private_display *private_display;
617 tdm_private_output *private_output;
618 tdm_private_change_handler *h = NULL, *hh = NULL;
620 TDM_RETURN_IF_FAIL(output != NULL);
621 TDM_RETURN_IF_FAIL(func != NULL);
623 private_output = (tdm_private_output*)output;
624 private_display = private_output->private_display;
626 _pthread_mutex_lock(&private_display->lock);
628 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
629 if (h->func != func || h->user_data != user_data)
635 _pthread_mutex_unlock(&private_display->lock);
640 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
641 if (h->func != func || h->user_data != user_data)
647 _pthread_mutex_unlock(&private_display->lock);
652 _pthread_mutex_unlock(&private_display->lock);
656 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
660 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
662 _pthread_mutex_lock(&private_display->lock);
664 *type = private_output->caps.type;
666 _pthread_mutex_unlock(&private_display->lock);
672 tdm_output_get_layer_count(tdm_output *output, int *count)
674 tdm_private_layer *private_layer = NULL;
678 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
680 _pthread_mutex_lock(&private_display->lock);
683 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
686 _pthread_mutex_unlock(&private_display->lock);
687 return TDM_ERROR_NONE;
690 _pthread_mutex_unlock(&private_display->lock);
697 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
699 tdm_private_layer *private_layer = NULL;
701 OUTPUT_FUNC_ENTRY_ERROR();
703 _pthread_mutex_lock(&private_display->lock);
706 *error = TDM_ERROR_NONE;
708 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
709 if (private_layer->index == index) {
710 _pthread_mutex_unlock(&private_display->lock);
711 return private_layer;
715 _pthread_mutex_unlock(&private_display->lock);
721 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
726 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
727 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
729 _pthread_mutex_lock(&private_display->lock);
731 *props = (const tdm_prop *)private_output->caps.props;
732 *count = private_output->caps.prop_count;
734 _pthread_mutex_unlock(&private_display->lock);
740 tdm_output_get_available_modes(tdm_output *output,
741 const tdm_output_mode **modes, int *count)
745 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
746 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
748 _pthread_mutex_lock(&private_display->lock);
750 *modes = (const tdm_output_mode *)private_output->caps.modes;
751 *count = private_output->caps.mode_count;
753 _pthread_mutex_unlock(&private_display->lock);
759 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
760 int *max_w, int *max_h, int *preferred_align)
764 _pthread_mutex_lock(&private_display->lock);
767 *min_w = TDM_FRONT_VALUE(private_output->caps.min_w);
769 *min_h = TDM_FRONT_VALUE(private_output->caps.min_h);
771 *max_w = TDM_FRONT_VALUE(private_output->caps.max_w);
773 *max_h = TDM_FRONT_VALUE(private_output->caps.max_h);
775 *preferred_align = TDM_FRONT_VALUE(private_output->caps.preferred_align);
777 _pthread_mutex_unlock(&private_display->lock);
783 tdm_output_get_cursor_available_size(tdm_output *output, int *min_w, int *min_h,
784 int *max_w, int *max_h, int *preferred_align)
788 _pthread_mutex_lock(&private_display->lock);
790 if (!tdm_display_check_module_abi(private_display, 1, 5)) {
801 *preferred_align = -1;
803 _pthread_mutex_unlock(&private_display->lock);
805 return TDM_ERROR_BAD_MODULE;
809 *min_w = TDM_FRONT_VALUE(private_output->caps.cursor_min_w);
811 *min_h = TDM_FRONT_VALUE(private_output->caps.cursor_min_h);
813 *max_w = TDM_FRONT_VALUE(private_output->caps.cursor_max_w);
815 *max_h = TDM_FRONT_VALUE(private_output->caps.cursor_max_h);
817 *preferred_align = TDM_FRONT_VALUE(private_output->caps.cursor_preferred_align);
819 _pthread_mutex_unlock(&private_display->lock);
825 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
826 unsigned int *mmHeight)
830 _pthread_mutex_lock(&private_display->lock);
833 *mmWidth = private_output->caps.mmWidth;
835 *mmHeight = private_output->caps.mmHeight;
837 _pthread_mutex_unlock(&private_display->lock);
843 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
846 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
848 _pthread_mutex_lock(&private_display->lock);
850 *subpixel = private_output->caps.subpixel;
852 _pthread_mutex_unlock(&private_display->lock);
858 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
861 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
863 _pthread_mutex_lock(&private_display->lock);
865 *pipe = private_output->pipe;
867 _pthread_mutex_unlock(&private_display->lock);
873 tdm_output_get_primary_index(tdm_output *output, int *index)
875 tdm_private_layer *private_layer = NULL;
878 TDM_RETURN_VAL_IF_FAIL(index != NULL, TDM_ERROR_INVALID_PARAMETER);
880 _pthread_mutex_lock(&private_display->lock);
882 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
883 if (private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_PRIMARY) {
884 *index = private_layer->index;
889 _pthread_mutex_unlock(&private_display->lock);
895 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
897 tdm_func_output *func_output;
900 _pthread_mutex_lock(&private_display->lock);
902 func_output = &private_display->func_output;
904 if (!func_output->output_set_property) {
905 _pthread_mutex_unlock(&private_display->lock);
906 TDM_ERR("not implemented!!");
907 return TDM_ERROR_NOT_IMPLEMENTED;
910 ret = func_output->output_set_property(private_output->output_backend, id,
913 _pthread_mutex_unlock(&private_display->lock);
919 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
921 tdm_func_output *func_output;
924 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
926 _pthread_mutex_lock(&private_display->lock);
928 func_output = &private_display->func_output;
930 if (!func_output->output_get_property) {
931 _pthread_mutex_unlock(&private_display->lock);
932 TDM_ERR("not implemented!!");
933 return TDM_ERROR_NOT_IMPLEMENTED;
936 ret = func_output->output_get_property(private_output->output_backend, id,
939 _pthread_mutex_unlock(&private_display->lock);
945 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
946 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
948 tdm_private_vblank_handler *vblank_handler = user_data;
949 tdm_private_vblank_handler *v = NULL, *vv = NULL;
950 tdm_private_output *private_output;
951 tdm_private_display *private_display;
952 struct list_head clone_list;
954 pid_t tid = syscall(SYS_gettid);
956 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
957 TDM_RETURN_IF_FAIL(vblank_handler);
959 private_output = vblank_handler->private_output;
960 private_display = private_output->private_display;
962 if (vblank_handler->owner_tid != tid) {
963 tdm_thread_cb_output_vblank output_vblank;
966 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
967 output_vblank.base.length = sizeof output_vblank;
968 output_vblank.output_stamp = vblank_handler->private_output->stamp;
969 output_vblank.sequence = sequence;
970 output_vblank.tv_sec = tv_sec;
971 output_vblank.tv_usec = tv_usec;
972 output_vblank.user_data = user_data;
974 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
975 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
980 if (vblank_handler->owner_tid != tid)
981 TDM_NEVER_GET_HERE();
983 interval = vblank_handler->interval;
984 sync = vblank_handler->sync;
986 LIST_INITHEAD(&clone_list);
988 LIST_FOR_EACH_ENTRY_SAFE(v, vv, &private_output->vblank_handler_list, link) {
989 if (v->interval != interval || v->sync != sync || v->owner_tid != tid)
993 LIST_ADD(&v->link, &clone_list);
996 _pthread_mutex_unlock(&private_display->lock);
997 LIST_FOR_EACH_ENTRY_SAFE(v, vv, &clone_list, link) {
999 v->func(v->private_output, sequence, tv_sec, tv_usec, v->user_data);
1003 _pthread_mutex_lock(&private_display->lock);
1007 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
1008 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
1010 tdm_private_output_commit_handler *output_commit_handler = user_data;
1011 tdm_private_display *private_display;
1012 tdm_private_output *private_output;
1013 tdm_private_layer *private_layer = NULL;
1015 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1016 TDM_RETURN_IF_FAIL(output_commit_handler);
1018 private_output = output_commit_handler->private_output;
1019 private_display = private_output->private_display;
1021 if (output_commit_handler->owner_tid != syscall(SYS_gettid)) {
1022 tdm_thread_cb_output_commit output_commit;
1025 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
1026 output_commit.base.length = sizeof output_commit;
1027 output_commit.output_stamp = private_output->stamp;
1028 output_commit.sequence = sequence;
1029 output_commit.tv_sec = tv_sec;
1030 output_commit.tv_usec = tv_usec;
1031 output_commit.user_data = user_data;
1033 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
1034 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1039 if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
1040 /* In case of layer commit, the below will be handled in the layer commit callback */
1041 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
1042 _tdm_layer_committed(private_layer);
1046 if (output_commit_handler->func) {
1047 _pthread_mutex_unlock(&private_display->lock);
1048 output_commit_handler->func(private_output, sequence,
1049 tv_sec, tv_usec, output_commit_handler->user_data);
1050 _pthread_mutex_lock(&private_display->lock);
1053 LIST_DEL(&output_commit_handler->link);
1054 free(output_commit_handler);
1058 _tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
1059 tdm_output_vblank_handler func, void *user_data)
1061 tdm_func_output *func_output;
1062 tdm_private_vblank_handler *vblank_handler = NULL, *v = NULL;
1063 unsigned int skip_request = 0;
1064 pid_t tid = syscall(SYS_gettid);
1066 OUTPUT_FUNC_ENTRY();
1068 func_output = &private_display->func_output;
1070 if (!func_output->output_wait_vblank) {
1071 TDM_ERR("not implemented!!");
1072 return TDM_ERROR_NOT_IMPLEMENTED;
1075 if (!private_output->regist_vblank_cb) {
1076 private_output->regist_vblank_cb = 1;
1077 ret = func_output->output_set_vblank_handler(private_output->output_backend,
1078 tdm_output_cb_vblank);
1081 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
1082 if (!vblank_handler) {
1083 TDM_ERR("failed: alloc memory");
1084 return TDM_ERROR_OUT_OF_MEMORY;
1087 LIST_FOR_EACH_ENTRY(v, &private_output->vblank_handler_list, link) {
1088 if (v->interval == interval && v->sync == sync && v->owner_tid == tid) {
1094 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
1095 vblank_handler->private_output = private_output;
1096 vblank_handler->interval = interval;
1097 vblank_handler->sync = sync;
1098 vblank_handler->func = func;
1099 vblank_handler->user_data = user_data;
1100 vblank_handler->owner_tid = tid;
1102 /* If there is the previous request, we can skip to call output_wait_vblank() */
1103 if (!skip_request) {
1104 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
1105 sync, vblank_handler);
1106 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
1112 if (vblank_handler) {
1113 LIST_DEL(&vblank_handler->link);
1114 free(vblank_handler);
1120 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
1121 tdm_output_vblank_handler func, void *user_data)
1123 OUTPUT_FUNC_ENTRY();
1125 _pthread_mutex_lock(&private_display->lock);
1127 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1128 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
1129 tdm_dpms_str(private_output->current_dpms_value));
1130 _pthread_mutex_unlock(&private_display->lock);
1131 return TDM_ERROR_DPMS_OFF;
1134 ret = _tdm_output_wait_vblank(output, interval, sync, func, user_data);
1136 _pthread_mutex_unlock(&private_display->lock);
1142 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1145 tdm_func_output *func_output;
1146 tdm_private_output_commit_handler *output_commit_handler = NULL;
1147 OUTPUT_FUNC_ENTRY();
1149 func_output = &private_display->func_output;
1151 if (!func_output->output_commit) {
1152 TDM_ERR("not implemented!!");
1153 return TDM_ERROR_NOT_IMPLEMENTED;
1156 if (!private_output->regist_commit_cb) {
1157 private_output->regist_commit_cb = 1;
1158 ret = func_output->output_set_commit_handler(private_output->output_backend,
1159 tdm_output_cb_commit);
1160 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
1163 output_commit_handler = calloc(1, sizeof(tdm_private_output_commit_handler));
1164 if (!output_commit_handler) {
1165 TDM_ERR("failed: alloc memory");
1166 return TDM_ERROR_OUT_OF_MEMORY;
1169 LIST_ADD(&output_commit_handler->link, &private_output->output_commit_handler_list);
1170 output_commit_handler->private_output = private_output;
1171 output_commit_handler->func = func;
1172 output_commit_handler->user_data = user_data;
1173 output_commit_handler->owner_tid = syscall(SYS_gettid);
1175 ret = func_output->output_commit(private_output->output_backend, sync,
1176 output_commit_handler);
1177 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
1179 if (tdm_debug_module & TDM_DEBUG_COMMIT)
1180 TDM_INFO("output(%d) backend commit", private_output->pipe);
1185 if (output_commit_handler) {
1186 LIST_DEL(&output_commit_handler->link);
1187 free(output_commit_handler);
1193 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1196 OUTPUT_FUNC_ENTRY();
1198 _pthread_mutex_lock(&private_display->lock);
1200 if (private_display->commit_type == TDM_COMMIT_TYPE_NONE)
1201 private_display->commit_type = TDM_COMMIT_TYPE_OUTPUT;
1202 else if (private_display->commit_type == TDM_COMMIT_TYPE_LAYER) {
1203 TDM_ERR("Can't supported. Use tdm_layer_commit");
1204 _pthread_mutex_unlock(&private_display->lock);
1205 return TDM_ERROR_BAD_REQUEST;
1208 if (private_display->commit_per_vblank) {
1209 TDM_ERR("Use tdm_layer_commit");
1210 _pthread_mutex_unlock(&private_display->lock);
1211 return TDM_ERROR_BAD_REQUEST;
1214 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1215 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1216 tdm_dpms_str(private_output->current_dpms_value));
1217 _pthread_mutex_unlock(&private_display->lock);
1218 return TDM_ERROR_DPMS_OFF;
1221 if (tdm_debug_module & TDM_DEBUG_COMMIT)
1222 TDM_INFO("output(%d) commit", private_output->pipe);
1224 ret = _tdm_output_commit(output, sync, func, user_data);
1226 _pthread_mutex_unlock(&private_display->lock);
1232 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1234 tdm_func_output *func_output;
1235 OUTPUT_FUNC_ENTRY();
1237 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1239 _pthread_mutex_lock(&private_display->lock);
1241 func_output = &private_display->func_output;
1243 if (!func_output->output_set_mode) {
1244 _pthread_mutex_unlock(&private_display->lock);
1245 TDM_ERR("not implemented!!");
1246 return TDM_ERROR_NOT_IMPLEMENTED;
1249 ret = func_output->output_set_mode(private_output->output_backend, mode);
1250 if (ret == TDM_ERROR_NONE)
1251 private_output->current_mode = mode;
1252 _pthread_mutex_unlock(&private_display->lock);
1258 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1260 OUTPUT_FUNC_ENTRY();
1262 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1264 _pthread_mutex_lock(&private_display->lock);
1266 *mode = private_output->current_mode;
1268 _pthread_mutex_unlock(&private_display->lock);
1274 _tdm_output_dpms_changed_timeout(void *user_data)
1276 tdm_private_output *private_output = user_data;
1279 value.u32 = private_output->current_dpms_value;
1280 tdm_output_call_change_handler_internal(private_output,
1281 &private_output->change_handler_list_sub,
1282 TDM_OUTPUT_CHANGE_DPMS,
1285 return TDM_ERROR_NONE;
1289 tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data)
1291 tdm_private_display *private_display;
1292 tdm_private_output *private_output = user_data;
1295 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1296 TDM_RETURN_IF_FAIL(private_output);
1298 private_display = private_output->private_display;
1300 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1301 tdm_thread_cb_output_dpms output_dpms;
1304 _tdm_output_update(output_backend, user_data);
1306 output_dpms.base.type = TDM_THREAD_CB_OUTPUT_DPMS;
1307 output_dpms.base.length = sizeof output_dpms;
1308 output_dpms.output_stamp = private_output->stamp;
1309 output_dpms.dpms = dpms;
1310 output_dpms.user_data = user_data;
1313 tdm_output_call_change_handler_internal(private_output,
1314 &private_output->change_handler_list_sub,
1315 TDM_OUTPUT_CHANGE_DPMS,
1318 ret = tdm_thread_send_cb(private_display->private_loop, &output_dpms.base);
1319 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1324 private_output->current_dpms_value = dpms;
1327 tdm_output_call_change_handler_internal(private_output,
1328 &private_output->change_handler_list_main,
1329 TDM_OUTPUT_CHANGE_DPMS,
1334 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1336 tdm_func_output *func_output;
1337 OUTPUT_FUNC_ENTRY();
1339 if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1340 dpms_value = TDM_OUTPUT_DPMS_OFF;
1342 _pthread_mutex_lock(&private_display->lock);
1344 if (private_output->current_dpms_value == dpms_value) {
1345 _pthread_mutex_unlock(&private_display->lock);
1346 return TDM_ERROR_NONE;
1349 /** Use timer to call the output change callback of the sub-thread.
1350 * The output change callback of tdm_server and tdm_vblank was called
1351 * in the main thread. And it made the multi thread issue. If we use
1352 * the timer, we can call the sub-thread's output change callback in
1355 if (!private_output->dpms_changed_timer) {
1356 private_output->dpms_changed_timer =
1357 tdm_event_loop_add_timer_handler(private_output->private_display,
1358 _tdm_output_dpms_changed_timeout, private_output, NULL);
1359 if (!private_output->dpms_changed_timer) {
1360 TDM_ERR("can't create dpms timer!!");
1361 _pthread_mutex_unlock(&private_display->lock);
1362 return TDM_ERROR_OUT_OF_MEMORY;
1366 func_output = &private_display->func_output;
1368 if (!func_output->output_set_dpms) {
1369 _pthread_mutex_unlock(&private_display->lock);
1370 private_output->current_dpms_value = dpms_value;
1371 TDM_WRN("not implemented!!");
1372 return TDM_ERROR_NONE;
1375 if (func_output->output_set_dpms_handler) {
1376 if (!private_output->regist_dpms_cb) {
1377 private_output->regist_dpms_cb = 1;
1378 ret = func_output->output_set_dpms_handler(private_output->output_backend,
1379 tdm_output_cb_dpms, private_output);
1380 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1384 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1386 if (ret == TDM_ERROR_NONE && !func_output->output_set_dpms_handler) {
1389 private_output->current_dpms_value = dpms_value;
1391 value.u32 = dpms_value;
1392 tdm_output_call_change_handler_internal(private_output,
1393 &private_output->change_handler_list_main,
1394 TDM_OUTPUT_CHANGE_DPMS,
1397 if (!LIST_IS_EMPTY(&private_output->change_handler_list_sub)) {
1398 ret = tdm_event_loop_source_timer_update(private_output->dpms_changed_timer, 1);
1399 if (ret != TDM_ERROR_NONE)
1400 TDM_NEVER_GET_HERE();
1404 _pthread_mutex_unlock(&private_display->lock);
1410 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1412 tdm_func_output *func_output;
1413 OUTPUT_FUNC_ENTRY();
1415 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1417 _pthread_mutex_lock(&private_display->lock);
1419 func_output = &private_display->func_output;
1421 if (!func_output->output_get_dpms) {
1422 *dpms_value = private_output->current_dpms_value;
1423 _pthread_mutex_unlock(&private_display->lock);
1424 TDM_WRN("not implemented!!");
1425 return TDM_ERROR_NONE;
1428 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1430 _pthread_mutex_unlock(&private_display->lock);
1435 EXTERN tdm_capture *
1436 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1438 tdm_capture *capture = NULL;
1440 OUTPUT_FUNC_ENTRY_ERROR();
1442 _pthread_mutex_lock(&private_display->lock);
1444 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output, error);
1446 _pthread_mutex_unlock(&private_display->lock);
1452 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1453 struct list_head *change_handler_list,
1454 tdm_output_change_type type,
1456 int no_check_thread_id)
1458 tdm_private_display *private_display;
1459 tdm_private_change_handler *change_handler = NULL;
1461 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1462 TDM_RETURN_IF_FAIL(private_output);
1464 private_display = private_output->private_display;
1465 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1466 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1467 TDM_INFO("output(%d) changed: %s (%d)",
1468 private_output->pipe, tdm_status_str(value.u32), value.u32);
1469 if (type & TDM_OUTPUT_CHANGE_DPMS)
1470 TDM_INFO("output(%d) changed: dpms %s (%d)",
1471 private_output->pipe, tdm_dpms_str(value.u32), value.u32);
1474 if (LIST_IS_EMPTY(change_handler_list))
1477 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1478 if (!no_check_thread_id && change_handler->owner_tid != syscall(SYS_gettid))
1479 TDM_NEVER_GET_HERE();
1481 _pthread_mutex_unlock(&private_display->lock);
1482 change_handler->func(private_output, type,
1483 value, change_handler->user_data);
1484 _pthread_mutex_lock(&private_display->lock);
1489 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1493 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1495 _pthread_mutex_lock(&private_display->lock);
1497 *capabilities = private_layer->caps.capabilities;
1499 _pthread_mutex_unlock(&private_display->lock);
1505 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
1509 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1510 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1512 _pthread_mutex_lock(&private_display->lock);
1514 *formats = (const tbm_format *)private_layer->caps.formats;
1515 *count = private_layer->caps.format_count;
1517 _pthread_mutex_unlock(&private_display->lock);
1523 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
1527 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1528 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1530 _pthread_mutex_lock(&private_display->lock);
1532 *props = (const tdm_prop *)private_layer->caps.props;
1533 *count = private_layer->caps.prop_count;
1535 _pthread_mutex_unlock(&private_display->lock);
1541 tdm_layer_get_zpos(tdm_layer *layer, int *zpos)
1545 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1547 _pthread_mutex_lock(&private_display->lock);
1549 *zpos = private_layer->caps.zpos;
1551 _pthread_mutex_unlock(&private_display->lock);
1557 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1559 tdm_func_layer *func_layer;
1562 _pthread_mutex_lock(&private_display->lock);
1564 func_layer = &private_display->func_layer;
1566 if (private_layer->usable)
1567 TDM_INFO("layer(%d) not usable", private_layer->index);
1569 private_layer->usable = 0;
1571 if (!func_layer->layer_set_property) {
1572 _pthread_mutex_unlock(&private_display->lock);
1573 TDM_ERR("not implemented!!");
1574 return TDM_ERROR_NOT_IMPLEMENTED;
1577 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1579 _pthread_mutex_unlock(&private_display->lock);
1585 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1587 tdm_func_layer *func_layer;
1590 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1592 _pthread_mutex_lock(&private_display->lock);
1594 func_layer = &private_display->func_layer;
1596 if (!func_layer->layer_get_property) {
1597 _pthread_mutex_unlock(&private_display->lock);
1598 TDM_ERR("not implemented!!");
1599 return TDM_ERROR_NOT_IMPLEMENTED;
1602 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1604 _pthread_mutex_unlock(&private_display->lock);
1610 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1612 tdm_func_layer *func_layer;
1617 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1619 _pthread_mutex_lock(&private_display->lock);
1621 func_layer = &private_display->func_layer;
1623 if (private_layer->usable)
1624 TDM_INFO("layer(%p) not usable", private_layer);
1626 private_layer->usable = 0;
1628 if (!func_layer->layer_set_info) {
1629 _pthread_mutex_unlock(&private_display->lock);
1630 TDM_ERR("not implemented!!");
1631 return TDM_ERROR_NOT_IMPLEMENTED;
1634 if (info->src_config.format)
1635 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
1637 snprintf(fmtstr, 128, "NONE");
1639 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
1640 private_layer, info->src_config.size.h, info->src_config.size.v,
1641 info->src_config.pos.x, info->src_config.pos.y,
1642 info->src_config.pos.w, info->src_config.pos.h,
1644 info->dst_pos.x, info->dst_pos.y,
1645 info->dst_pos.w, info->dst_pos.h,
1648 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1649 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1651 _pthread_mutex_unlock(&private_display->lock);
1657 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1659 tdm_func_layer *func_layer;
1662 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1664 _pthread_mutex_lock(&private_display->lock);
1666 func_layer = &private_display->func_layer;
1668 if (!func_layer->layer_get_info) {
1669 _pthread_mutex_unlock(&private_display->lock);
1670 TDM_ERR("not implemented!!");
1671 return TDM_ERROR_NOT_IMPLEMENTED;
1674 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1676 _pthread_mutex_unlock(&private_display->lock);
1682 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1684 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1685 tdm_private_output *private_output = private_layer->private_output;
1688 char fname[PATH_MAX];
1690 pipe = private_output->pipe;
1691 zpos = private_layer->caps.zpos;
1693 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1695 tbm_surface_internal_dump_buffer(buffer, fname);
1696 TDM_DBG("%s dump excute", fname);
1702 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1704 tdm_func_layer *func_layer;
1708 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1710 _pthread_mutex_lock(&private_display->lock);
1712 if (tdm_debug_dump & TDM_DUMP_FLAG_LAYER &&
1713 !(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1714 char str[TDM_PATH_LEN];
1716 snprintf(str, TDM_PATH_LEN, "layer_%d_%d_%03d",
1717 private_output->index, private_layer->index, i++);
1718 tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str);
1721 func_layer = &private_display->func_layer;
1723 if (private_layer->usable)
1724 TDM_INFO("layer(%p) not usable", private_layer);
1726 private_layer->usable = 0;
1728 if (!func_layer->layer_set_buffer) {
1729 _pthread_mutex_unlock(&private_display->lock);
1730 TDM_ERR("not implemented!!");
1731 return TDM_ERROR_NOT_IMPLEMENTED;
1734 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1735 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1738 if (tdm_dump_enable && !(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO))
1739 _tdm_layer_dump_buffer(layer, buffer);
1741 if (ret == TDM_ERROR_NONE) {
1742 /* FIXME: should save to pending_buffer first. And after committing
1743 * successfully, need to move to waiting_buffer.
1745 if (private_layer->waiting_buffer) {
1746 _pthread_mutex_unlock(&private_display->lock);
1747 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1748 _pthread_mutex_lock(&private_display->lock);
1751 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1752 if (tdm_debug_module & TDM_DEBUG_BUFFER)
1753 TDM_INFO("layer(%p) waiting_buffer(%p)",
1754 private_layer, private_layer->waiting_buffer);
1757 _pthread_mutex_unlock(&private_display->lock);
1763 tdm_layer_unset_buffer(tdm_layer *layer)
1765 tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL;
1766 tdm_func_layer *func_layer;
1769 _pthread_mutex_lock(&private_display->lock);
1771 func_layer = &private_display->func_layer;
1773 if (private_layer->waiting_buffer) {
1774 _pthread_mutex_unlock(&private_display->lock);
1775 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1776 _pthread_mutex_lock(&private_display->lock);
1777 private_layer->waiting_buffer = NULL;
1779 if (tdm_debug_module & TDM_DEBUG_BUFFER)
1780 TDM_INFO("layer(%p) waiting_buffer(%p)",
1781 private_layer, private_layer->waiting_buffer);
1784 if (private_layer->showing_buffer) {
1785 _pthread_mutex_unlock(&private_display->lock);
1786 tdm_buffer_unref_backend(private_layer->showing_buffer);
1787 _pthread_mutex_lock(&private_display->lock);
1788 private_layer->showing_buffer = NULL;
1790 if (tdm_debug_module & TDM_DEBUG_BUFFER)
1791 TDM_INFO("layer(%p) showing_buffer(%p)",
1792 private_layer, private_layer->showing_buffer);
1795 LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) {
1796 if (lm->private_layer != private_layer)
1798 LIST_DEL(&lm->link);
1802 LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
1803 if (lm->private_layer != private_layer)
1805 LIST_DEL(&lm->link);
1809 private_layer->usable = 1;
1811 if (private_layer->usable)
1812 TDM_INFO("layer(%p) now usable", private_layer);
1814 if (!func_layer->layer_unset_buffer) {
1815 _pthread_mutex_unlock(&private_display->lock);
1816 TDM_ERR("not implemented!!");
1817 return TDM_ERROR_NOT_IMPLEMENTED;
1820 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1821 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1823 _pthread_mutex_unlock(&private_display->lock);
1829 _tdm_layer_committed(tdm_private_layer *private_layer)
1831 tdm_private_output *private_output = private_layer->private_output;
1832 tdm_private_display *private_display = private_output->private_display;
1834 private_layer->committing = 0;
1836 if (private_display->print_fps) {
1837 double curr = tdm_helper_get_time();
1838 private_layer->fps_count++;
1839 if (private_layer->fps_stamp == 0) {
1840 private_layer->fps_stamp = curr;
1841 } else if ((curr - private_layer->fps_stamp) > 1.0) {
1842 TDM_INFO("output(%d) layer(%d) fps: %d", private_output->index, private_layer->index, private_layer->fps_count - 1);
1843 private_layer->fps_count = 1;
1844 private_layer->fps_stamp = curr;
1846 } else if (private_layer->fps_stamp != 0) {
1847 private_layer->fps_stamp = 0;
1848 private_layer->fps_count = 0;
1851 if (!private_layer->waiting_buffer)
1854 if (private_layer->showing_buffer) {
1855 _pthread_mutex_unlock(&private_display->lock);
1856 tdm_buffer_unref_backend(private_layer->showing_buffer);
1857 _pthread_mutex_lock(&private_display->lock);
1859 if (private_layer->buffer_queue) {
1860 _pthread_mutex_unlock(&private_display->lock);
1861 tbm_surface_queue_release(private_layer->buffer_queue,
1862 private_layer->showing_buffer);
1863 _pthread_mutex_lock(&private_display->lock);
1867 private_layer->showing_buffer = private_layer->waiting_buffer;
1868 private_layer->waiting_buffer = NULL;
1870 if (tdm_debug_module & TDM_DEBUG_BUFFER)
1871 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
1872 private_layer, private_layer->waiting_buffer,
1873 private_layer->showing_buffer);
1877 _tdm_layer_got_output_vblank(tdm_private_output *private_output, unsigned int sequence,
1878 unsigned int tv_sec, unsigned int tv_usec)
1880 tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL;
1881 tdm_private_display *private_display;
1884 private_display = private_output->private_display;
1886 private_output->waiting_vblank = 0;
1888 LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) {
1889 _tdm_layer_committed(lm->private_layer);
1892 _pthread_mutex_unlock(&private_display->lock);
1893 lm->func(lm->private_layer, sequence, tv_sec, tv_usec, lm->user_data);
1894 _pthread_mutex_lock(&private_display->lock);
1897 LIST_DEL(&lm->link);
1901 if (LIST_IS_EMPTY(&private_output->pending_commit_handler_list))
1905 ret = _tdm_output_commit(private_output, 0, _tdm_layer_cb_output_commit, NULL);
1906 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
1908 if (tdm_debug_module & TDM_DEBUG_COMMIT)
1909 TDM_INFO("layer commit: output(%d) commit", private_output->pipe);
1911 private_output->waiting_vblank = 1;
1913 ret = _tdm_output_commit(private_output, 0, NULL, NULL);
1914 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
1916 if (tdm_debug_module & TDM_DEBUG_COMMIT)
1917 TDM_INFO("layer commit: output(%d) commit", private_output->pipe);
1919 TDM_RETURN_IF_FAIL(private_output->vblank != NULL);
1921 /* tdm_vblank APIs is for server. it should be called in unlock status*/
1922 _pthread_mutex_unlock(&private_display->lock);
1923 ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output);
1924 _pthread_mutex_lock(&private_display->lock);
1925 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed);
1926 private_output->waiting_vblank = 1;
1928 if (tdm_debug_module & TDM_DEBUG_COMMIT)
1929 TDM_INFO("layer commit: output(%d) wait vblank", private_output->pipe);
1932 LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
1933 LIST_DEL(&lm->link);
1934 LIST_ADD(&lm->link, &private_output->layer_commit_handler_list);
1939 LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) {
1940 LIST_DEL(&lm->link);
1947 _tdm_layer_cb_output_commit(tdm_output *output, unsigned int sequence,
1948 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
1950 tdm_private_layer_commit_handler *layer_commit_handler = user_data;
1951 tdm_private_display *private_display;
1952 tdm_private_output *private_output = output;
1953 tdm_private_layer *private_layer;
1955 private_display = private_output->private_display;
1957 _pthread_mutex_lock(&private_display->lock);
1959 if (layer_commit_handler) {
1960 tdm_private_layer_commit_handler *lm = NULL;
1963 LIST_FOR_EACH_ENTRY(lm, &private_output->layer_commit_handler_list, link) {
1964 if (layer_commit_handler == lm) {
1971 private_layer = layer_commit_handler->private_layer;
1973 if (tdm_debug_module & TDM_DEBUG_COMMIT)
1974 TDM_INFO("layer(%p) commit: output(%d) committed", private_layer, private_output->pipe);
1976 _tdm_layer_committed(private_layer);
1978 if (layer_commit_handler->func) {
1979 _pthread_mutex_unlock(&private_display->lock);
1980 layer_commit_handler->func(private_output, sequence,
1981 tv_sec, tv_usec, layer_commit_handler->user_data);
1982 _pthread_mutex_lock(&private_display->lock);
1985 LIST_DEL(&layer_commit_handler->link);
1986 free(layer_commit_handler);
1989 if (tdm_debug_module & TDM_DEBUG_COMMIT)
1990 TDM_INFO("layer commit: output(%d) committed", private_output->pipe);
1992 _tdm_layer_got_output_vblank(private_output, sequence, tv_sec, tv_usec);
1995 _pthread_mutex_unlock(&private_display->lock);
1999 _tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
2000 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
2002 tdm_private_output *private_output = user_data;
2003 tdm_private_display *private_display;
2005 TDM_RETURN_IF_FAIL(private_output != NULL);
2007 private_display = private_output->private_display;
2009 _pthread_mutex_lock(&private_display->lock);
2011 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2012 TDM_INFO("layer commit: output(%d) got vblank", private_output->pipe);
2014 _tdm_layer_got_output_vblank(private_output, sequence, tv_sec, tv_usec);
2016 _pthread_mutex_unlock(&private_display->lock);
2020 _tdm_layer_commit_possible(tdm_private_layer *private_layer)
2022 tdm_private_output *private_output = private_layer->private_output;
2023 tdm_private_display *private_display = private_output->private_display;
2025 if (!private_display->commit_per_vblank) {
2026 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2027 TDM_INFO("layer(%p) commit: commit_per_vblank false", private_layer);
2031 if (private_display->commit_per_vblank == 1 && _tdm_output_used_layer_count(private_output) == 1) {
2032 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2033 TDM_INFO("layer(%p) commit: 1 layer", private_layer);
2037 if (private_display->commit_per_vblank == 2 && LIST_IS_EMPTY(&private_output->layer_commit_handler_list)) {
2038 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2039 TDM_INFO("layer(%p) commit: non previous commit", private_layer);
2047 _tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
2049 tdm_private_layer_commit_handler *layer_commit_handler;
2052 layer_commit_handler = calloc(1, sizeof(tdm_private_layer_commit_handler));
2053 if (!layer_commit_handler) {
2054 TDM_ERR("failed: alloc memory");
2055 return TDM_ERROR_OUT_OF_MEMORY;
2058 LIST_INITHEAD(&layer_commit_handler->link);
2059 layer_commit_handler->private_layer = private_layer;
2060 layer_commit_handler->func = func;
2061 layer_commit_handler->user_data = user_data;
2063 if (_tdm_layer_commit_possible(private_layer)) {
2064 if (private_layer->committing)
2065 TDM_WRN("layer(%d) too many commit", private_layer->index);
2067 private_layer->committing = 1;
2069 LIST_ADD(&layer_commit_handler->link, &private_output->layer_commit_handler_list);
2070 ret = _tdm_output_commit(private_layer->private_output, 0, _tdm_layer_cb_output_commit, layer_commit_handler);
2071 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
2073 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2074 TDM_INFO("layer(%p) commit: output", private_layer);
2076 if (private_layer->committing)
2077 TDM_WRN("layer(%d) too many commit", private_layer->index);
2079 private_layer->committing = 1;
2081 LIST_ADD(&layer_commit_handler->link, &private_output->pending_commit_handler_list);
2083 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2084 TDM_INFO("layer(%p) commit: pending", private_layer);
2086 if (!private_output->vblank) {
2087 /* tdm_vblank APIs is for server. it should be called in unlock status*/
2088 _pthread_mutex_unlock(&private_display->lock);
2089 private_output->vblank = tdm_vblank_create(private_display, private_output, NULL);
2090 _pthread_mutex_lock(&private_display->lock);
2091 TDM_GOTO_IF_FAIL(private_output->vblank != NULL, commit_failed);
2094 if (!private_output->waiting_vblank) {
2095 /* tdm_vblank APIs is for server. it should be called in unlock status*/
2096 _pthread_mutex_unlock(&private_display->lock);
2097 ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output);
2098 _pthread_mutex_lock(&private_display->lock);
2099 TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
2100 private_output->waiting_vblank = 1;
2102 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2103 TDM_INFO("layer(%p) commit: wait vblank", private_layer);
2110 if (layer_commit_handler) {
2111 LIST_DEL(&layer_commit_handler->link);
2112 free(layer_commit_handler);
2118 tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
2122 _pthread_mutex_lock(&private_display->lock);
2124 if (private_display->commit_type == TDM_COMMIT_TYPE_NONE)
2125 private_display->commit_type = TDM_COMMIT_TYPE_LAYER;
2126 else if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
2127 TDM_ERR("Can't supported. Use tdm_output_commit");
2128 _pthread_mutex_unlock(&private_display->lock);
2129 return TDM_ERROR_BAD_REQUEST;
2132 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
2133 TDM_ERR("layer(%p)'s output(%d) dpms: %s", layer, private_output->pipe,
2134 tdm_dpms_str(private_output->current_dpms_value));
2135 _pthread_mutex_unlock(&private_display->lock);
2136 return TDM_ERROR_DPMS_OFF;
2139 if (tdm_debug_module & TDM_DEBUG_COMMIT)
2140 TDM_INFO("layer(%p) commit", private_layer);
2142 ret = _tdm_layer_commit(private_layer, func, user_data);
2144 _pthread_mutex_unlock(&private_display->lock);
2150 tdm_layer_is_committing(tdm_layer *layer, unsigned int *committing)
2154 TDM_RETURN_VAL_IF_FAIL(committing != NULL, TDM_ERROR_INVALID_PARAMETER);
2156 _pthread_mutex_lock(&private_display->lock);
2158 *committing = private_layer->committing;
2160 _pthread_mutex_unlock(&private_display->lock);
2165 EXTERN tbm_surface_h
2166 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
2168 tbm_surface_h buffer;
2169 LAYER_FUNC_ENTRY_ERROR();
2171 _pthread_mutex_lock(&private_display->lock);
2174 *error = TDM_ERROR_NONE;
2176 if (private_layer->showing_buffer) {
2177 buffer = private_layer->showing_buffer;
2180 *error = TDM_ERROR_OPERATION_FAILED;
2181 _pthread_mutex_unlock(&private_display->lock);
2182 TDM_DBG("layer(%p) showing_buffer is null", private_layer);
2185 _pthread_mutex_unlock(&private_display->lock);
2191 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
2193 TDM_RETURN_IF_FAIL(data != NULL);
2194 tdm_layer *layer = data;
2195 tdm_func_layer *func_layer;
2196 tbm_surface_h surface = NULL;
2197 LAYER_FUNC_ENTRY_VOID_RETURN();
2199 _pthread_mutex_lock(&private_display->lock);
2201 func_layer = &private_display->func_layer;
2202 if (!func_layer->layer_set_buffer) {
2203 _pthread_mutex_unlock(&private_display->lock);
2207 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
2209 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
2210 private_layer, surface);
2211 _pthread_mutex_unlock(&private_display->lock);
2215 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
2216 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
2218 if (ret == TDM_ERROR_NONE) {
2219 if (private_layer->waiting_buffer) {
2220 TDM_DBG("layer(%p) drop waiting_buffer(%p)", private_layer, private_layer->waiting_buffer);
2221 _pthread_mutex_unlock(&private_display->lock);
2222 tdm_buffer_unref_backend(private_layer->waiting_buffer);
2223 tbm_surface_queue_release(private_layer->buffer_queue,
2224 private_layer->waiting_buffer);
2225 _pthread_mutex_lock(&private_display->lock);
2228 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
2230 if (tdm_debug_module & TDM_DEBUG_BUFFER)
2231 TDM_INFO("layer(%p) waiting_buffer(%p)",
2232 private_layer, private_layer->waiting_buffer);
2234 if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
2235 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
2236 if (ret != TDM_ERROR_NONE)
2237 TDM_ERR("_tdm_output_commit() is fail");
2238 } else if (private_display->commit_type == TDM_COMMIT_TYPE_LAYER) {
2239 ret = _tdm_layer_commit(private_layer, NULL, NULL);
2240 if (ret != TDM_ERROR_NONE)
2241 TDM_ERR("layer(%p) _tdm_layer_commit() is fail", private_layer);
2243 TDM_NEVER_GET_HERE();
2247 _pthread_mutex_unlock(&private_display->lock);
2251 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
2253 TDM_RETURN_IF_FAIL(data != NULL);
2254 tdm_layer *layer = data;
2255 LAYER_FUNC_ENTRY_VOID_RETURN();
2256 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
2258 _pthread_mutex_lock(&private_display->lock);
2260 if (private_layer->waiting_buffer) {
2261 _pthread_mutex_unlock(&private_display->lock);
2262 tdm_buffer_unref_backend(private_layer->waiting_buffer);
2263 tbm_surface_queue_release(private_layer->buffer_queue,
2264 private_layer->waiting_buffer);
2265 _pthread_mutex_lock(&private_display->lock);
2268 private_layer->buffer_queue = NULL;
2270 _pthread_mutex_unlock(&private_display->lock);
2274 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
2276 tdm_func_layer *func_layer;
2279 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
2281 _pthread_mutex_lock(&private_display->lock);
2283 func_layer = &private_display->func_layer;
2285 if (private_layer->usable)
2286 TDM_INFO("layer(%p) not usable", private_layer);
2288 private_layer->usable = 0;
2290 if (!func_layer->layer_set_buffer) {
2291 _pthread_mutex_unlock(&private_display->lock);
2292 TDM_ERR("not implemented!!");
2293 return TDM_ERROR_NOT_IMPLEMENTED;
2296 if (buffer_queue == private_layer->buffer_queue) {
2297 _pthread_mutex_unlock(&private_display->lock);
2298 return TDM_ERROR_NONE;
2301 if (private_layer->waiting_buffer) {
2302 _pthread_mutex_unlock(&private_display->lock);
2303 tdm_buffer_unref_backend(private_layer->waiting_buffer);
2304 tbm_surface_queue_release(private_layer->buffer_queue,
2305 private_layer->waiting_buffer);
2306 private_layer->waiting_buffer = NULL;
2307 _pthread_mutex_lock(&private_display->lock);
2309 if (tdm_debug_module & TDM_DEBUG_BUFFER)
2310 TDM_INFO("layer(%p) waiting_buffer(%p)",
2311 private_layer, private_layer->waiting_buffer);
2314 private_layer->buffer_queue = buffer_queue;
2315 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
2316 _tbm_layer_queue_acquirable_cb,
2318 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
2319 _tbm_layer_queue_destroy_cb,
2321 _pthread_mutex_unlock(&private_display->lock);
2327 tdm_layer_unset_buffer_queue(tdm_layer *layer)
2329 tdm_func_layer *func_layer;
2332 _pthread_mutex_lock(&private_display->lock);
2334 func_layer = &private_display->func_layer;
2336 if (private_layer->waiting_buffer) {
2337 _pthread_mutex_unlock(&private_display->lock);
2338 tdm_buffer_unref_backend(private_layer->waiting_buffer);
2339 tbm_surface_queue_release(private_layer->buffer_queue,
2340 private_layer->waiting_buffer);
2341 private_layer->waiting_buffer = NULL;
2342 _pthread_mutex_lock(&private_display->lock);
2344 if (tdm_debug_module & TDM_DEBUG_BUFFER)
2345 TDM_INFO("layer(%p) waiting_buffer(%p)",
2346 private_layer, private_layer->waiting_buffer);
2349 if (private_layer->showing_buffer) {
2350 _pthread_mutex_unlock(&private_display->lock);
2351 tdm_buffer_unref_backend(private_layer->showing_buffer);
2352 tbm_surface_queue_release(private_layer->buffer_queue,
2353 private_layer->showing_buffer);
2354 _pthread_mutex_lock(&private_display->lock);
2355 private_layer->showing_buffer = NULL;
2357 if (tdm_debug_module & TDM_DEBUG_BUFFER)
2358 TDM_INFO("layer(%p) showing_buffer(%p)",
2359 private_layer, private_layer->showing_buffer);
2362 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
2363 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
2364 private_layer->buffer_queue = NULL;
2365 private_layer->usable = 1;
2367 if (private_layer->usable)
2368 TDM_INFO("layer(%p) now usable", private_layer);
2370 if (!func_layer->layer_unset_buffer) {
2371 _pthread_mutex_unlock(&private_display->lock);
2372 TDM_ERR("not implemented!!");
2373 return TDM_ERROR_NOT_IMPLEMENTED;
2376 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
2378 _pthread_mutex_unlock(&private_display->lock);
2384 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
2388 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
2390 _pthread_mutex_lock(&private_display->lock);
2392 *usable = private_layer->usable;
2394 _pthread_mutex_unlock(&private_display->lock);
2400 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
2402 tdm_func_layer *func_layer;
2405 _pthread_mutex_lock(&private_display->lock);
2407 func_layer = &private_display->func_layer;
2409 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
2410 TDM_ERR("layer(%p) is not video layer", private_layer);
2411 _pthread_mutex_unlock(&private_display->lock);
2412 return TDM_ERROR_INVALID_PARAMETER;
2415 if (!func_layer->layer_set_video_pos) {
2416 _pthread_mutex_unlock(&private_display->lock);
2417 TDM_ERR("not implemented!!");
2418 return TDM_ERROR_NOT_IMPLEMENTED;
2421 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
2423 _pthread_mutex_unlock(&private_display->lock);
2428 EXTERN tdm_capture *
2429 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
2431 tdm_capture *capture = NULL;
2433 LAYER_FUNC_ENTRY_ERROR();
2435 _pthread_mutex_lock(&private_display->lock);
2437 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer, error);
2439 _pthread_mutex_unlock(&private_display->lock);
2445 tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
2447 tdm_func_layer *func_layer;
2450 _pthread_mutex_lock(&private_display->lock);
2452 func_layer = &private_display->func_layer;
2454 if (!func_layer->layer_get_buffer_flags) {
2455 _pthread_mutex_unlock(&private_display->lock);
2456 TDM_ERR("not implemented!!");
2457 return TDM_ERROR_NOT_IMPLEMENTED;
2460 ret = func_layer->layer_get_buffer_flags(private_layer->layer_backend, flags);
2462 _pthread_mutex_unlock(&private_display->lock);