1 /**************************************************************************
5 * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
7 * Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8 * JinYoung Jeon <jy0.jeon@samsung.com>,
9 * Taeheon Kim <th908.kim@samsung.com>,
10 * YoungJun Cho <yj44.cho@samsung.com>,
11 * SooChan Lim <sc1.lim@samsung.com>,
12 * Boram Park <sc1.lim@samsung.com>
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the
16 * "Software"), to deal in the Software without restriction, including
17 * without limitation the rights to use, copy, modify, merge, publish,
18 * distribute, sub license, and/or sell copies of the Software, and to
19 * permit persons to whom the Software is furnished to do so, subject to
20 * the following conditions:
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 **************************************************************************/
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
43 #include "tdm_helper.h"
47 #define DISPLAY_FUNC_ENTRY() \
48 tdm_private_display *private_display; \
49 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50 TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
51 private_display = (tdm_private_display*)dpy;
53 #define DISPLAY_FUNC_ENTRY_ERROR() \
54 tdm_private_display *private_display; \
55 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
56 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
57 private_display = (tdm_private_display*)dpy;
59 #define OUTPUT_FUNC_ENTRY() \
60 tdm_private_display *private_display; \
61 tdm_private_output *private_output; \
62 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
63 TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
64 private_output = (tdm_private_output*)output; \
65 private_display = private_output->private_display
67 #define OUTPUT_FUNC_ENTRY_ERROR() \
68 tdm_private_display *private_display; \
69 tdm_private_output *private_output; \
70 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
71 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
72 private_output = (tdm_private_output*)output; \
73 private_display = private_output->private_display
75 #define LAYER_FUNC_ENTRY() \
76 tdm_private_display *private_display; \
77 tdm_private_output *private_output; \
78 tdm_private_layer *private_layer; \
79 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
80 TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
81 private_layer = (tdm_private_layer*)layer; \
82 private_output = private_layer->private_output; \
83 private_display = private_output->private_display
85 #define LAYER_FUNC_ENTRY_ERROR() \
86 tdm_private_display *private_display; \
87 tdm_private_output *private_output; \
88 tdm_private_layer *private_layer; \
89 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
90 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
91 private_layer = (tdm_private_layer*)layer; \
92 private_output = private_layer->private_output; \
93 private_display = private_output->private_display
95 #define LAYER_FUNC_ENTRY_VOID_RETURN() \
96 tdm_private_display *private_display; \
97 tdm_private_output *private_output; \
98 tdm_private_layer *private_layer; \
99 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
100 TDM_RETURN_IF_FAIL(layer != NULL); \
101 private_layer = (tdm_private_layer*)layer; \
102 private_output = private_layer->private_output; \
103 private_display = private_output->private_display
105 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
112 #define type_name_fn(res) \
113 const char * res##_str(int type) \
116 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
117 if (res##_names[i].type == type) \
118 return res##_names[i].name; \
120 return "(invalid)"; \
123 struct type_name dpms_names[] = {
124 { TDM_OUTPUT_DPMS_ON, "on" },
125 { TDM_OUTPUT_DPMS_STANDBY, "standby" },
126 { TDM_OUTPUT_DPMS_SUSPEND, "suspend" },
127 { TDM_OUTPUT_DPMS_OFF, "off" },
130 INTERN type_name_fn(dpms)
132 struct type_name status_names[] = {
133 { TDM_OUTPUT_CONN_STATUS_DISCONNECTED, "disconnected" },
134 { TDM_OUTPUT_CONN_STATUS_CONNECTED, "connected" },
135 { TDM_OUTPUT_CONN_STATUS_MODE_SETTED, "mode_setted" },
138 INTERN type_name_fn(status)
141 tdm_get_dpms_str(tdm_output_dpms dpms_value)
143 return dpms_str(dpms_value);
147 _tdm_display_lock(tdm_display *dpy, const char *func)
149 tdm_private_display *private_display = (tdm_private_display*)dpy;
153 TDM_INFO("mutex lock: %s", func);
155 ret = pthread_mutex_trylock(&private_display->lock);
158 TDM_ERR("mutex lock busy: %s", func);
160 TDM_ERR("mutex lock failed: %s(%m)", func);
162 return TDM_ERROR_OPERATION_FAILED;
165 pthread_mutex_lock(&tdm_mutex_check_lock);
166 tdm_mutex_locked = 1;
167 pthread_mutex_unlock(&tdm_mutex_check_lock);
169 return TDM_ERROR_NONE;
173 _tdm_display_unlock(tdm_display *dpy, const char *func)
175 tdm_private_display *private_display = (tdm_private_display*)dpy;
178 TDM_INFO("mutex unlock: %s", func);
180 pthread_mutex_lock(&tdm_mutex_check_lock);
181 tdm_mutex_locked = 0;
182 pthread_mutex_unlock(&tdm_mutex_check_lock);
184 pthread_mutex_unlock(&private_display->lock);
188 tdm_display_get_capabilities(tdm_display *dpy,
189 tdm_display_capability *capabilities)
191 DISPLAY_FUNC_ENTRY();
193 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
195 _pthread_mutex_lock(&private_display->lock);
197 *capabilities = private_display->capabilities;
199 _pthread_mutex_unlock(&private_display->lock);
205 tdm_display_get_pp_capabilities(tdm_display *dpy,
206 tdm_pp_capability *capabilities)
208 DISPLAY_FUNC_ENTRY();
210 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
212 _pthread_mutex_lock(&private_display->lock);
214 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
215 TDM_ERR("no pp capability");
216 _pthread_mutex_unlock(&private_display->lock);
217 return TDM_ERROR_NO_CAPABILITY;
220 *capabilities = private_display->caps_pp.capabilities;
222 _pthread_mutex_unlock(&private_display->lock);
228 tdm_display_get_pp_available_formats(tdm_display *dpy,
229 const tbm_format **formats, int *count)
231 DISPLAY_FUNC_ENTRY();
233 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
234 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
236 _pthread_mutex_lock(&private_display->lock);
238 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
239 TDM_ERR("no pp capability");
240 _pthread_mutex_unlock(&private_display->lock);
241 return TDM_ERROR_NO_CAPABILITY;
244 *formats = (const tbm_format *)private_display->caps_pp.formats;
245 *count = private_display->caps_pp.format_count;
247 _pthread_mutex_unlock(&private_display->lock);
253 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
254 int *max_w, int *max_h, int *preferred_align)
256 DISPLAY_FUNC_ENTRY();
258 _pthread_mutex_lock(&private_display->lock);
260 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
261 TDM_ERR("no pp capability");
262 _pthread_mutex_unlock(&private_display->lock);
263 return TDM_ERROR_NO_CAPABILITY;
267 *min_w = private_display->caps_pp.min_w;
269 *min_h = private_display->caps_pp.min_h;
271 *max_w = private_display->caps_pp.max_w;
273 *max_h = private_display->caps_pp.max_h;
275 *preferred_align = private_display->caps_pp.preferred_align;
277 _pthread_mutex_unlock(&private_display->lock);
283 tdm_display_get_capture_capabilities(tdm_display *dpy,
284 tdm_capture_capability *capabilities)
286 DISPLAY_FUNC_ENTRY();
288 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
290 _pthread_mutex_lock(&private_display->lock);
292 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
293 TDM_ERR("no capture capability");
294 _pthread_mutex_unlock(&private_display->lock);
295 return TDM_ERROR_NO_CAPABILITY;
298 *capabilities = private_display->caps_capture.capabilities;
300 _pthread_mutex_unlock(&private_display->lock);
306 tdm_display_get_catpure_available_formats(tdm_display *dpy,
307 const tbm_format **formats, int *count)
309 DISPLAY_FUNC_ENTRY();
311 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
312 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
314 _pthread_mutex_lock(&private_display->lock);
316 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
317 TDM_ERR("no capture capability");
318 _pthread_mutex_unlock(&private_display->lock);
319 return TDM_ERROR_NO_CAPABILITY;
322 *formats = (const tbm_format *)private_display->caps_capture.formats;
323 *count = private_display->caps_capture.format_count;
325 _pthread_mutex_unlock(&private_display->lock);
331 tdm_display_get_output_count(tdm_display *dpy, int *count)
333 tdm_private_output *private_output = NULL;
335 DISPLAY_FUNC_ENTRY();
337 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
339 _pthread_mutex_lock(&private_display->lock);
342 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
346 _pthread_mutex_unlock(&private_display->lock);
347 return TDM_ERROR_NONE;
350 _pthread_mutex_unlock(&private_display->lock);
357 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
359 tdm_private_output *private_output = NULL;
362 DISPLAY_FUNC_ENTRY_ERROR();
364 _pthread_mutex_lock(&private_display->lock);
367 *error = TDM_ERROR_NONE;
370 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
372 _pthread_mutex_unlock(&private_display->lock);
373 return private_output;
378 _pthread_mutex_unlock(&private_display->lock);
384 tdm_display_get_fd(tdm_display *dpy, int *fd)
386 DISPLAY_FUNC_ENTRY();
388 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
390 _pthread_mutex_lock(&private_display->lock);
392 if (tdm_thread_is_running())
393 *fd = tdm_thread_get_fd(private_display->private_loop);
395 *fd = tdm_event_loop_get_fd(private_display);
397 _pthread_mutex_unlock(&private_display->lock);
403 tdm_display_handle_events(tdm_display *dpy)
408 DISPLAY_FUNC_ENTRY();
410 ret = tdm_display_get_fd(dpy, &fd);
411 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
417 if (tdm_debug_thread)
418 TDM_INFO("fd(%d) polling in", fd);
420 while (poll(&fds, 1, -1) < 0) {
421 if (errno == EBUSY) /* normal case */
424 TDM_ERR("poll failed: %m");
425 return TDM_ERROR_OPERATION_FAILED;
429 if (tdm_debug_thread)
430 TDM_INFO("fd(%d) polling out", fd);
432 if (tdm_thread_is_running())
433 ret = tdm_thread_handle_cb(private_display->private_loop);
435 ret = tdm_event_loop_dispatch(private_display);
441 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
445 DISPLAY_FUNC_ENTRY_ERROR();
447 _pthread_mutex_lock(&private_display->lock);
449 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
451 _pthread_mutex_unlock(&private_display->lock);
457 tdm_output_get_model_info(tdm_output *output, const char **maker,
458 const char **model, const char **name)
462 _pthread_mutex_lock(&private_display->lock);
465 *maker = private_output->caps.maker;
467 *model = private_output->caps.model;
469 *name = private_output->caps.name;
471 _pthread_mutex_unlock(&private_display->lock);
477 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
481 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
483 _pthread_mutex_lock(&private_display->lock);
485 *status = private_output->caps.status;
487 _pthread_mutex_unlock(&private_display->lock);
493 _tdm_output_update(tdm_output *output_backend, void *user_data)
495 tdm_private_display *private_display;
496 tdm_private_output *private_output = user_data;
499 TDM_RETURN_IF_FAIL(private_output);
501 private_display = private_output->private_display;
503 ret = tdm_display_update_output(private_display, output_backend, private_output->pipe);
504 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
508 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
511 tdm_private_display *private_display;
512 tdm_private_output *private_output = user_data;
515 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
516 TDM_RETURN_IF_FAIL(private_output);
518 private_display = private_output->private_display;
520 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
521 tdm_thread_cb_output_status output_status;
524 _tdm_output_update(output_backend, user_data);
526 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
527 output_status.base.length = sizeof output_status;
528 output_status.output_stamp = private_output->stamp;
529 output_status.status = status;
530 output_status.user_data = user_data;
533 tdm_output_call_change_handler_internal(private_output,
534 &private_output->change_handler_list_sub,
535 TDM_OUTPUT_CHANGE_CONNECTION,
538 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
539 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
544 if (!tdm_thread_is_running())
545 _tdm_output_update(output_backend, user_data);
548 tdm_output_call_change_handler_internal(private_output,
549 &private_output->change_handler_list_main,
550 TDM_OUTPUT_CHANGE_CONNECTION,
555 tdm_output_add_change_handler(tdm_output *output,
556 tdm_output_change_handler func,
559 tdm_private_change_handler *change_handler;
562 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
564 pthread_mutex_lock(&private_display->lock);
566 if (!private_output->regist_change_cb) {
567 _pthread_mutex_unlock(&private_display->lock);
568 TDM_ERR("not implemented!!");
569 return TDM_ERROR_NOT_IMPLEMENTED;
572 change_handler = calloc(1, sizeof(tdm_private_change_handler));
573 if (!change_handler) {
574 TDM_ERR("failed: alloc memory");
575 _pthread_mutex_unlock(&private_display->lock);
576 return TDM_ERROR_OUT_OF_MEMORY;
579 change_handler->private_output = private_output;
580 change_handler->func = func;
581 change_handler->user_data = user_data;
582 change_handler->owner_tid = syscall(SYS_gettid);
584 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
585 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
587 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
589 _pthread_mutex_unlock(&private_display->lock);
595 tdm_output_remove_change_handler(tdm_output *output,
596 tdm_output_change_handler func,
599 tdm_private_display *private_display;
600 tdm_private_output *private_output;
601 tdm_private_change_handler *h = NULL, *hh = NULL;
603 TDM_RETURN_IF_FAIL(output != NULL);
604 TDM_RETURN_IF_FAIL(func != NULL);
606 private_output = (tdm_private_output*)output;
607 private_display = private_output->private_display;
609 _pthread_mutex_lock(&private_display->lock);
611 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
612 if (h->func != func || h->user_data != user_data)
618 _pthread_mutex_unlock(&private_display->lock);
623 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
624 if (h->func != func || h->user_data != user_data)
630 _pthread_mutex_unlock(&private_display->lock);
635 _pthread_mutex_unlock(&private_display->lock);
639 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
643 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
645 _pthread_mutex_lock(&private_display->lock);
647 *type = private_output->caps.type;
649 _pthread_mutex_unlock(&private_display->lock);
655 tdm_output_get_layer_count(tdm_output *output, int *count)
657 tdm_private_layer *private_layer = NULL;
661 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
663 _pthread_mutex_lock(&private_display->lock);
666 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
669 _pthread_mutex_unlock(&private_display->lock);
670 return TDM_ERROR_NONE;
673 _pthread_mutex_unlock(&private_display->lock);
680 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
682 tdm_private_layer *private_layer = NULL;
685 OUTPUT_FUNC_ENTRY_ERROR();
687 _pthread_mutex_lock(&private_display->lock);
690 *error = TDM_ERROR_NONE;
692 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
694 _pthread_mutex_unlock(&private_display->lock);
695 return private_layer;
700 _pthread_mutex_unlock(&private_display->lock);
706 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
711 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
712 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
714 _pthread_mutex_lock(&private_display->lock);
716 *props = (const tdm_prop *)private_output->caps.props;
717 *count = private_output->caps.prop_count;
719 _pthread_mutex_unlock(&private_display->lock);
725 tdm_output_get_available_modes(tdm_output *output,
726 const tdm_output_mode **modes, int *count)
730 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
731 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
733 _pthread_mutex_lock(&private_display->lock);
735 *modes = (const tdm_output_mode *)private_output->caps.modes;
736 *count = private_output->caps.mode_count;
738 _pthread_mutex_unlock(&private_display->lock);
744 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
745 int *max_w, int *max_h, int *preferred_align)
749 _pthread_mutex_lock(&private_display->lock);
752 *min_w = private_output->caps.min_w;
754 *min_h = private_output->caps.min_h;
756 *max_w = private_output->caps.max_w;
758 *max_h = private_output->caps.max_h;
760 *preferred_align = private_output->caps.preferred_align;
762 _pthread_mutex_unlock(&private_display->lock);
768 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
769 unsigned int *mmHeight)
773 _pthread_mutex_lock(&private_display->lock);
776 *mmWidth = private_output->caps.mmWidth;
778 *mmHeight = private_output->caps.mmHeight;
780 _pthread_mutex_unlock(&private_display->lock);
786 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
789 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
791 _pthread_mutex_lock(&private_display->lock);
793 *subpixel = private_output->caps.subpixel;
795 _pthread_mutex_unlock(&private_display->lock);
801 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
804 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
806 _pthread_mutex_lock(&private_display->lock);
808 *pipe = private_output->pipe;
810 _pthread_mutex_unlock(&private_display->lock);
817 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
819 tdm_func_output *func_output;
822 _pthread_mutex_lock(&private_display->lock);
824 func_output = &private_display->func_output;
826 if (!func_output->output_set_property) {
827 _pthread_mutex_unlock(&private_display->lock);
828 TDM_ERR("not implemented!!");
829 return TDM_ERROR_NOT_IMPLEMENTED;
832 ret = func_output->output_set_property(private_output->output_backend, id,
835 _pthread_mutex_unlock(&private_display->lock);
841 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
843 tdm_func_output *func_output;
846 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
848 _pthread_mutex_lock(&private_display->lock);
850 func_output = &private_display->func_output;
852 if (!func_output->output_get_property) {
853 _pthread_mutex_unlock(&private_display->lock);
854 TDM_ERR("not implemented!!");
855 return TDM_ERROR_NOT_IMPLEMENTED;
858 ret = func_output->output_get_property(private_output->output_backend, id,
861 _pthread_mutex_unlock(&private_display->lock);
867 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
868 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
870 tdm_private_vblank_handler *vblank_handler = user_data;
871 tdm_private_display *private_display;
873 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
874 TDM_RETURN_IF_FAIL(vblank_handler);
876 private_display = vblank_handler->private_output->private_display;
878 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
879 tdm_thread_cb_output_vblank output_vblank;
882 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
883 output_vblank.base.length = sizeof output_vblank;
884 output_vblank.output_stamp = vblank_handler->private_output->stamp;
885 output_vblank.sequence = sequence;
886 output_vblank.tv_sec = tv_sec;
887 output_vblank.tv_usec = tv_usec;
888 output_vblank.user_data = user_data;
890 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
891 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
896 if (vblank_handler->owner_tid != syscall(SYS_gettid))
897 TDM_NEVER_GET_HERE();
899 if (vblank_handler->func) {
900 _pthread_mutex_unlock(&private_display->lock);
901 vblank_handler->func(vblank_handler->private_output, sequence,
902 tv_sec, tv_usec, vblank_handler->user_data);
903 _pthread_mutex_lock(&private_display->lock);
906 LIST_DEL(&vblank_handler->link);
907 free(vblank_handler);
911 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
912 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
914 tdm_private_commit_handler *commit_handler = user_data;
915 tdm_private_display *private_display;
916 tdm_private_output *private_output;
917 tdm_private_layer *private_layer = NULL;
919 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
920 TDM_RETURN_IF_FAIL(commit_handler);
922 private_output = commit_handler->private_output;
923 private_display = private_output->private_display;
925 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
926 tdm_thread_cb_output_commit output_commit;
929 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
930 output_commit.base.length = sizeof output_commit;
931 output_commit.output_stamp = private_output->stamp;
932 output_commit.sequence = sequence;
933 output_commit.tv_sec = tv_sec;
934 output_commit.tv_usec = tv_usec;
935 output_commit.user_data = user_data;
937 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
938 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
943 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
944 if (!private_layer->waiting_buffer)
947 if (private_layer->showing_buffer) {
948 _pthread_mutex_unlock(&private_display->lock);
949 tdm_buffer_unref_backend(private_layer->showing_buffer);
950 _pthread_mutex_lock(&private_display->lock);
952 if (private_layer->buffer_queue) {
953 tbm_surface_queue_release(private_layer->buffer_queue,
954 private_layer->showing_buffer);
958 private_layer->showing_buffer = private_layer->waiting_buffer;
959 private_layer->waiting_buffer = NULL;
961 if (tdm_debug_buffer)
962 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
963 private_layer, private_layer->waiting_buffer,
964 private_layer->showing_buffer);
967 if (commit_handler->func) {
968 _pthread_mutex_unlock(&private_display->lock);
969 commit_handler->func(private_output, sequence,
970 tv_sec, tv_usec, commit_handler->user_data);
971 _pthread_mutex_lock(&private_display->lock);
974 LIST_DEL(&commit_handler->link);
975 free(commit_handler);
979 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
980 tdm_output_vblank_handler func, void *user_data)
982 tdm_func_output *func_output;
983 tdm_private_vblank_handler *vblank_handler;
986 _pthread_mutex_lock(&private_display->lock);
988 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
989 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
990 dpms_str(private_output->current_dpms_value));
991 _pthread_mutex_unlock(&private_display->lock);
992 return TDM_ERROR_BAD_REQUEST;
995 func_output = &private_display->func_output;
997 if (!func_output->output_wait_vblank) {
998 _pthread_mutex_unlock(&private_display->lock);
999 TDM_ERR("not implemented!!");
1000 return TDM_ERROR_NOT_IMPLEMENTED;
1003 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
1004 if (!vblank_handler) {
1005 TDM_ERR("failed: alloc memory");
1006 _pthread_mutex_unlock(&private_display->lock);
1007 return TDM_ERROR_OUT_OF_MEMORY;
1010 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
1011 vblank_handler->private_output = private_output;
1012 vblank_handler->func = func;
1013 vblank_handler->user_data = user_data;
1014 vblank_handler->owner_tid = syscall(SYS_gettid);
1016 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
1017 sync, vblank_handler);
1018 if (ret != TDM_ERROR_NONE) {
1019 _pthread_mutex_unlock(&private_display->lock);
1023 if (!private_output->regist_vblank_cb) {
1024 private_output->regist_vblank_cb = 1;
1025 ret = func_output->output_set_vblank_handler(private_output->output_backend,
1026 tdm_output_cb_vblank);
1029 _pthread_mutex_unlock(&private_display->lock);
1035 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1038 tdm_func_output *func_output;
1039 tdm_private_commit_handler *commit_handler;
1040 OUTPUT_FUNC_ENTRY();
1042 func_output = &private_display->func_output;
1044 if (!func_output->output_commit) {
1045 TDM_ERR("not implemented!!");
1046 return TDM_ERROR_NOT_IMPLEMENTED;
1049 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1050 if (!commit_handler) {
1051 TDM_ERR("failed: alloc memory");
1052 return TDM_ERROR_OUT_OF_MEMORY;
1055 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1056 commit_handler->private_output = private_output;
1057 commit_handler->func = func;
1058 commit_handler->user_data = user_data;
1059 commit_handler->owner_tid = syscall(SYS_gettid);
1061 if (!private_output->regist_commit_cb) {
1062 private_output->regist_commit_cb = 1;
1063 ret = func_output->output_set_commit_handler(private_output->output_backend,
1064 tdm_output_cb_commit);
1067 ret = func_output->output_commit(private_output->output_backend, sync,
1069 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1075 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1078 OUTPUT_FUNC_ENTRY();
1080 _pthread_mutex_lock(&private_display->lock);
1082 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1083 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1084 dpms_str(private_output->current_dpms_value));
1085 _pthread_mutex_unlock(&private_display->lock);
1086 return TDM_ERROR_BAD_REQUEST;
1089 ret = _tdm_output_commit(output, sync, func, user_data);
1091 _pthread_mutex_unlock(&private_display->lock);
1097 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1099 tdm_func_output *func_output;
1100 OUTPUT_FUNC_ENTRY();
1102 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1104 _pthread_mutex_lock(&private_display->lock);
1106 func_output = &private_display->func_output;
1108 if (!func_output->output_set_mode) {
1109 _pthread_mutex_unlock(&private_display->lock);
1110 TDM_ERR("not implemented!!");
1111 return TDM_ERROR_NOT_IMPLEMENTED;
1114 ret = func_output->output_set_mode(private_output->output_backend, mode);
1116 _pthread_mutex_unlock(&private_display->lock);
1122 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1124 tdm_func_output *func_output;
1125 OUTPUT_FUNC_ENTRY();
1127 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1129 _pthread_mutex_lock(&private_display->lock);
1131 func_output = &private_display->func_output;
1133 if (!func_output->output_get_mode) {
1134 _pthread_mutex_unlock(&private_display->lock);
1135 TDM_ERR("not implemented!!");
1136 return TDM_ERROR_NOT_IMPLEMENTED;
1139 ret = func_output->output_get_mode(private_output->output_backend, mode);
1141 _pthread_mutex_unlock(&private_display->lock);
1147 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1149 tdm_func_output *func_output;
1150 OUTPUT_FUNC_ENTRY();
1152 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1153 dpms_value = TDM_OUTPUT_DPMS_ON;
1154 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1155 dpms_value = TDM_OUTPUT_DPMS_OFF;
1157 _pthread_mutex_lock(&private_display->lock);
1159 if (private_output->current_dpms_value == dpms_value) {
1160 _pthread_mutex_unlock(&private_display->lock);
1161 return TDM_ERROR_NONE;
1164 func_output = &private_display->func_output;
1166 if (!func_output->output_set_dpms) {
1167 _pthread_mutex_unlock(&private_display->lock);
1168 private_output->current_dpms_value = dpms_value;
1169 TDM_WRN("not implemented!!");
1170 return TDM_ERROR_NONE;
1173 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1174 if (ret == TDM_ERROR_NONE) {
1177 private_output->current_dpms_value = dpms_value;
1179 value.u32 = dpms_value;
1180 tdm_output_call_change_handler_internal(private_output,
1181 &private_output->change_handler_list_main,
1182 TDM_OUTPUT_CHANGE_DPMS,
1186 _pthread_mutex_unlock(&private_display->lock);
1192 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1194 tdm_func_output *func_output;
1195 OUTPUT_FUNC_ENTRY();
1197 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1199 _pthread_mutex_lock(&private_display->lock);
1201 func_output = &private_display->func_output;
1203 if (!func_output->output_get_dpms) {
1204 *dpms_value = private_output->current_dpms_value;
1205 _pthread_mutex_unlock(&private_display->lock);
1206 TDM_WRN("not implemented!!");
1207 return TDM_ERROR_NONE;
1210 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1212 _pthread_mutex_unlock(&private_display->lock);
1217 EXTERN tdm_capture *
1218 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1220 tdm_capture *capture = NULL;
1222 OUTPUT_FUNC_ENTRY_ERROR();
1224 _pthread_mutex_lock(&private_display->lock);
1226 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output, error);
1228 _pthread_mutex_unlock(&private_display->lock);
1234 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1235 struct list_head *change_handler_list,
1236 tdm_output_change_type type,
1239 tdm_private_display *private_display;
1240 tdm_private_change_handler *change_handler;
1242 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1243 TDM_RETURN_IF_FAIL(private_output);
1245 private_display = private_output->private_display;
1246 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1247 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1248 TDM_INFO("output(%d) changed: %s (%d)",
1249 private_output->pipe, status_str(value.u32), value.u32);
1250 if (type & TDM_OUTPUT_CHANGE_DPMS)
1251 TDM_INFO("output(%d) changed: dpms %s (%d)",
1252 private_output->pipe, dpms_str(value.u32), value.u32);
1255 if (LIST_IS_EMPTY(change_handler_list))
1258 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1259 if (change_handler->owner_tid != syscall(SYS_gettid))
1260 TDM_NEVER_GET_HERE();
1262 _pthread_mutex_unlock(&private_display->lock);
1263 change_handler->func(private_output, type,
1264 value, change_handler->user_data);
1265 _pthread_mutex_lock(&private_display->lock);
1270 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1274 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1276 _pthread_mutex_lock(&private_display->lock);
1278 *capabilities = private_layer->caps.capabilities;
1280 _pthread_mutex_unlock(&private_display->lock);
1286 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
1290 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1291 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1293 _pthread_mutex_lock(&private_display->lock);
1295 *formats = (const tbm_format *)private_layer->caps.formats;
1296 *count = private_layer->caps.format_count;
1298 _pthread_mutex_unlock(&private_display->lock);
1304 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
1308 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1309 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1311 _pthread_mutex_lock(&private_display->lock);
1313 *props = (const tdm_prop *)private_layer->caps.props;
1314 *count = private_layer->caps.prop_count;
1316 _pthread_mutex_unlock(&private_display->lock);
1322 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1326 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1328 _pthread_mutex_lock(&private_display->lock);
1330 *zpos = private_layer->caps.zpos;
1332 _pthread_mutex_unlock(&private_display->lock);
1338 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1340 tdm_func_layer *func_layer;
1343 _pthread_mutex_lock(&private_display->lock);
1345 func_layer = &private_display->func_layer;
1347 if (!func_layer->layer_set_property) {
1348 _pthread_mutex_unlock(&private_display->lock);
1349 TDM_ERR("not implemented!!");
1350 return TDM_ERROR_NOT_IMPLEMENTED;
1353 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1355 _pthread_mutex_unlock(&private_display->lock);
1361 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1363 tdm_func_layer *func_layer;
1366 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1368 _pthread_mutex_lock(&private_display->lock);
1370 func_layer = &private_display->func_layer;
1372 if (!func_layer->layer_get_property) {
1373 _pthread_mutex_unlock(&private_display->lock);
1374 TDM_ERR("not implemented!!");
1375 return TDM_ERROR_NOT_IMPLEMENTED;
1378 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1380 _pthread_mutex_unlock(&private_display->lock);
1386 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1388 tdm_func_layer *func_layer;
1391 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1393 _pthread_mutex_lock(&private_display->lock);
1395 func_layer = &private_display->func_layer;
1397 private_layer->usable = 0;
1399 if (!func_layer->layer_set_info) {
1400 _pthread_mutex_unlock(&private_display->lock);
1401 TDM_ERR("not implemented!!");
1402 return TDM_ERROR_NOT_IMPLEMENTED;
1405 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1406 private_layer, info->src_config.size.h, info->src_config.size.v,
1407 info->src_config.pos.x, info->src_config.pos.y,
1408 info->src_config.pos.w, info->src_config.pos.h,
1409 FOURCC_STR(info->src_config.format),
1410 info->dst_pos.x, info->dst_pos.y,
1411 info->dst_pos.w, info->dst_pos.h,
1414 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1415 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1417 _pthread_mutex_unlock(&private_display->lock);
1423 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1425 tdm_func_layer *func_layer;
1428 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1430 _pthread_mutex_lock(&private_display->lock);
1432 func_layer = &private_display->func_layer;
1434 if (!func_layer->layer_get_info) {
1435 _pthread_mutex_unlock(&private_display->lock);
1436 TDM_ERR("not implemented!!");
1437 return TDM_ERROR_NOT_IMPLEMENTED;
1440 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1442 _pthread_mutex_unlock(&private_display->lock);
1448 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1450 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1451 tdm_private_output *private_output = private_layer->private_output;
1454 char fname[PATH_MAX];
1456 pipe = private_output->pipe;
1457 zpos = private_layer->caps.zpos;
1459 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1461 tbm_surface_internal_dump_buffer(buffer, fname);
1462 TDM_DBG("%s dump excute", fname);
1468 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1470 tdm_func_layer *func_layer;
1474 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1476 _pthread_mutex_lock(&private_display->lock);
1478 func_layer = &private_display->func_layer;
1480 private_layer->usable = 0;
1482 if (!func_layer->layer_set_buffer) {
1483 _pthread_mutex_unlock(&private_display->lock);
1484 TDM_ERR("not implemented!!");
1485 return TDM_ERROR_NOT_IMPLEMENTED;
1488 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1489 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1492 if (tdm_dump_enable)
1493 _tdm_layer_dump_buffer(layer, buffer);
1495 if (ret == TDM_ERROR_NONE) {
1496 /* FIXME: should save to pending_buffer first. And after committing
1497 * successfully, need to move to waiting_buffer.
1499 if (private_layer->waiting_buffer) {
1500 _pthread_mutex_unlock(&private_display->lock);
1501 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1502 _pthread_mutex_lock(&private_display->lock);
1505 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1506 if (tdm_debug_buffer)
1507 TDM_INFO("layer(%p) waiting_buffer(%p)",
1508 private_layer, private_layer->waiting_buffer);
1511 _pthread_mutex_unlock(&private_display->lock);
1517 tdm_layer_unset_buffer(tdm_layer *layer)
1519 tdm_func_layer *func_layer;
1522 _pthread_mutex_lock(&private_display->lock);
1524 func_layer = &private_display->func_layer;
1526 if (private_layer->waiting_buffer) {
1527 _pthread_mutex_unlock(&private_display->lock);
1528 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1529 _pthread_mutex_lock(&private_display->lock);
1530 private_layer->waiting_buffer = NULL;
1532 if (tdm_debug_buffer)
1533 TDM_INFO("layer(%p) waiting_buffer(%p)",
1534 private_layer, private_layer->waiting_buffer);
1537 if (private_layer->showing_buffer) {
1538 _pthread_mutex_unlock(&private_display->lock);
1539 tdm_buffer_unref_backend(private_layer->showing_buffer);
1540 _pthread_mutex_lock(&private_display->lock);
1541 private_layer->showing_buffer = NULL;
1543 if (tdm_debug_buffer)
1544 TDM_INFO("layer(%p) showing_buffer(%p)",
1545 private_layer, private_layer->showing_buffer);
1548 private_layer->usable = 1;
1550 if (!func_layer->layer_unset_buffer) {
1551 _pthread_mutex_unlock(&private_display->lock);
1552 TDM_ERR("not implemented!!");
1553 return TDM_ERROR_NOT_IMPLEMENTED;
1556 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1557 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1559 _pthread_mutex_unlock(&private_display->lock);
1564 EXTERN tbm_surface_h
1565 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1567 tbm_surface_h buffer;
1568 LAYER_FUNC_ENTRY_ERROR();
1570 _pthread_mutex_lock(&private_display->lock);
1573 *error = TDM_ERROR_NONE;
1575 if (private_layer->showing_buffer) {
1576 buffer = private_layer->showing_buffer;
1579 *error = TDM_ERROR_OPERATION_FAILED;
1580 _pthread_mutex_unlock(&private_display->lock);
1581 TDM_ERR("layer(%p) showing_buffer is null", private_layer);
1584 _pthread_mutex_unlock(&private_display->lock);
1590 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1592 TDM_RETURN_IF_FAIL(data != NULL);
1593 tdm_layer *layer = data;
1594 tdm_func_layer *func_layer;
1595 tbm_surface_h surface = NULL;
1596 LAYER_FUNC_ENTRY_VOID_RETURN();
1598 _pthread_mutex_lock(&private_display->lock);
1600 func_layer = &private_display->func_layer;
1601 if (!func_layer->layer_set_buffer) {
1602 _pthread_mutex_unlock(&private_display->lock);
1606 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
1608 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1609 private_layer, surface);
1610 _pthread_mutex_unlock(&private_display->lock);
1614 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1615 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1617 if (ret == TDM_ERROR_NONE) {
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->waiting_buffer = tdm_buffer_ref_backend(surface);
1628 if (tdm_debug_buffer)
1629 TDM_INFO("layer(%p) waiting_buffer(%p)",
1630 private_layer, private_layer->waiting_buffer);
1632 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1633 if (ret != TDM_ERROR_NONE)
1634 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1637 _pthread_mutex_unlock(&private_display->lock);
1641 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1643 TDM_RETURN_IF_FAIL(data != NULL);
1644 tdm_layer *layer = data;
1645 LAYER_FUNC_ENTRY_VOID_RETURN();
1646 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1648 _pthread_mutex_lock(&private_display->lock);
1650 if (private_layer->waiting_buffer) {
1651 _pthread_mutex_unlock(&private_display->lock);
1652 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1653 tbm_surface_queue_release(private_layer->buffer_queue,
1654 private_layer->waiting_buffer);
1655 _pthread_mutex_lock(&private_display->lock);
1658 private_layer->buffer_queue = NULL;
1660 _pthread_mutex_unlock(&private_display->lock);
1664 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1666 tdm_func_layer *func_layer;
1669 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1671 _pthread_mutex_lock(&private_display->lock);
1673 func_layer = &private_display->func_layer;
1675 private_layer->usable = 0;
1677 if (!func_layer->layer_set_buffer) {
1678 _pthread_mutex_unlock(&private_display->lock);
1679 TDM_ERR("not implemented!!");
1680 return TDM_ERROR_NOT_IMPLEMENTED;
1683 if (buffer_queue == private_layer->buffer_queue) {
1684 _pthread_mutex_unlock(&private_display->lock);
1685 return TDM_ERROR_NONE;
1688 if (private_layer->waiting_buffer) {
1689 _pthread_mutex_unlock(&private_display->lock);
1690 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1691 tbm_surface_queue_release(private_layer->buffer_queue,
1692 private_layer->waiting_buffer);
1693 private_layer->waiting_buffer = NULL;
1694 _pthread_mutex_lock(&private_display->lock);
1696 if (tdm_debug_buffer)
1697 TDM_INFO("layer(%p) waiting_buffer(%p)",
1698 private_layer, private_layer->waiting_buffer);
1701 private_layer->buffer_queue = buffer_queue;
1702 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1703 _tbm_layer_queue_acquirable_cb,
1705 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1706 _tbm_layer_queue_destroy_cb,
1708 _pthread_mutex_unlock(&private_display->lock);
1714 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1716 tdm_func_layer *func_layer;
1719 _pthread_mutex_lock(&private_display->lock);
1721 func_layer = &private_display->func_layer;
1723 if (private_layer->waiting_buffer) {
1724 _pthread_mutex_unlock(&private_display->lock);
1725 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1726 tbm_surface_queue_release(private_layer->buffer_queue,
1727 private_layer->waiting_buffer);
1728 private_layer->waiting_buffer = NULL;
1729 _pthread_mutex_lock(&private_display->lock);
1731 if (tdm_debug_buffer)
1732 TDM_INFO("layer(%p) waiting_buffer(%p)",
1733 private_layer, private_layer->waiting_buffer);
1736 if (private_layer->showing_buffer) {
1737 _pthread_mutex_unlock(&private_display->lock);
1738 tdm_buffer_unref_backend(private_layer->showing_buffer);
1739 tbm_surface_queue_release(private_layer->buffer_queue,
1740 private_layer->showing_buffer);
1741 _pthread_mutex_lock(&private_display->lock);
1742 private_layer->showing_buffer = NULL;
1744 if (tdm_debug_buffer)
1745 TDM_INFO("layer(%p) showing_buffer(%p)",
1746 private_layer, private_layer->showing_buffer);
1749 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1750 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1751 private_layer->buffer_queue = NULL;
1752 private_layer->usable = 1;
1754 if (!func_layer->layer_unset_buffer) {
1755 _pthread_mutex_unlock(&private_display->lock);
1756 TDM_ERR("not implemented!!");
1757 return TDM_ERROR_NOT_IMPLEMENTED;
1760 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1762 _pthread_mutex_unlock(&private_display->lock);
1768 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1772 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1774 _pthread_mutex_lock(&private_display->lock);
1776 *usable = private_layer->usable;
1778 _pthread_mutex_unlock(&private_display->lock);
1784 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1786 tdm_func_layer *func_layer;
1789 _pthread_mutex_lock(&private_display->lock);
1791 func_layer = &private_display->func_layer;
1793 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1794 TDM_ERR("layer(%p) is not video layer", private_layer);
1795 _pthread_mutex_unlock(&private_display->lock);
1796 return TDM_ERROR_INVALID_PARAMETER;
1799 if (!func_layer->layer_set_video_pos) {
1800 _pthread_mutex_unlock(&private_display->lock);
1801 TDM_ERR("not implemented!!");
1802 return TDM_ERROR_NOT_IMPLEMENTED;
1805 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1807 _pthread_mutex_unlock(&private_display->lock);
1812 EXTERN tdm_capture *
1813 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1815 tdm_capture *capture = NULL;
1817 LAYER_FUNC_ENTRY_ERROR();
1819 _pthread_mutex_lock(&private_display->lock);
1821 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer, error);
1823 _pthread_mutex_unlock(&private_display->lock);