1 /**************************************************************************
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8 JinYoung Jeon <jy0.jeon@samsung.com>,
9 Taeheon Kim <th908.kim@samsung.com>,
10 YoungJun Cho <yj44.cho@samsung.com>,
11 SooChan Lim <sc1.lim@samsung.com>,
12 Boram Park <sc1.lim@samsung.com>
14 Permission is hereby granted, free of charge, to any person obtaining a
15 copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sub license, and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following conditions:
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 **************************************************************************/
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
43 #include "tdm_helper.h"
47 #define DISPLAY_FUNC_ENTRY() \
48 tdm_private_display *private_display; \
49 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50 TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
51 private_display = (tdm_private_display*)dpy;
53 #define DISPLAY_FUNC_ENTRY_ERROR() \
54 tdm_private_display *private_display; \
55 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
56 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
57 private_display = (tdm_private_display*)dpy;
59 #define OUTPUT_FUNC_ENTRY() \
60 tdm_private_display *private_display; \
61 tdm_private_output *private_output; \
62 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
63 TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
64 private_output = (tdm_private_output*)output; \
65 private_display = private_output->private_display
67 #define OUTPUT_FUNC_ENTRY_ERROR() \
68 tdm_private_display *private_display; \
69 tdm_private_output *private_output; \
70 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
71 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
72 private_output = (tdm_private_output*)output; \
73 private_display = private_output->private_display
75 #define LAYER_FUNC_ENTRY() \
76 tdm_private_display *private_display; \
77 tdm_private_output *private_output; \
78 tdm_private_layer *private_layer; \
79 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
80 TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
81 private_layer = (tdm_private_layer*)layer; \
82 private_output = private_layer->private_output; \
83 private_display = private_output->private_display
85 #define LAYER_FUNC_ENTRY_ERROR() \
86 tdm_private_display *private_display; \
87 tdm_private_output *private_output; \
88 tdm_private_layer *private_layer; \
89 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
90 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
91 private_layer = (tdm_private_layer*)layer; \
92 private_output = private_layer->private_output; \
93 private_display = private_output->private_display
95 #define LAYER_FUNC_ENTRY_VOID_RETURN() \
96 tdm_private_display *private_display; \
97 tdm_private_output *private_output; \
98 tdm_private_layer *private_layer; \
99 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
100 TDM_RETURN_IF_FAIL(layer != NULL); \
101 private_layer = (tdm_private_layer*)layer; \
102 private_output = private_layer->private_output; \
103 private_display = private_output->private_display
105 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
112 #define type_name_fn(res) \
113 const char * res##_str(int type) { \
115 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
116 if (res##_names[i].type == type) \
117 return res##_names[i].name; \
119 return "(invalid)"; \
122 struct type_name dpms_names[] = {
123 { TDM_OUTPUT_DPMS_ON, "on" },
124 { TDM_OUTPUT_DPMS_STANDBY, "standby" },
125 { TDM_OUTPUT_DPMS_SUSPEND, "suspend" },
126 { TDM_OUTPUT_DPMS_OFF, "off" },
129 INTERN type_name_fn(dpms)
131 struct type_name status_names[] = {
132 { TDM_OUTPUT_CONN_STATUS_DISCONNECTED, "disconnected" },
133 { TDM_OUTPUT_CONN_STATUS_CONNECTED, "connected" },
134 { TDM_OUTPUT_CONN_STATUS_MODE_SETTED, "mode_setted" },
137 INTERN type_name_fn(status)
140 tdm_get_dpms_str(tdm_output_dpms dpms_value)
142 return dpms_str(dpms_value);
146 _tdm_display_lock(tdm_display *dpy, const char *func)
148 tdm_private_display *private_display = (tdm_private_display*)dpy;
152 TDM_INFO("mutex lock: %s", func);
154 ret = pthread_mutex_trylock(&private_display->lock);
157 TDM_ERR("mutex lock busy: %s", func);
159 TDM_ERR("mutex lock failed: %s(%m)", func);
161 return TDM_ERROR_OPERATION_FAILED;
164 pthread_mutex_lock(&tdm_mutex_check_lock);
165 tdm_mutex_locked = 1;
166 pthread_mutex_unlock(&tdm_mutex_check_lock);
168 return TDM_ERROR_NONE;
172 _tdm_display_unlock(tdm_display *dpy, const char *func)
174 tdm_private_display *private_display = (tdm_private_display*)dpy;
177 TDM_INFO("mutex unlock: %s", func);
179 pthread_mutex_lock(&tdm_mutex_check_lock);
180 tdm_mutex_locked = 0;
181 pthread_mutex_unlock(&tdm_mutex_check_lock);
183 pthread_mutex_unlock(&private_display->lock);
187 tdm_display_get_capabilities(tdm_display *dpy,
188 tdm_display_capability *capabilities)
190 DISPLAY_FUNC_ENTRY();
192 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
194 _pthread_mutex_lock(&private_display->lock);
196 *capabilities = private_display->capabilities;
198 _pthread_mutex_unlock(&private_display->lock);
204 tdm_display_get_pp_capabilities(tdm_display *dpy,
205 tdm_pp_capability *capabilities)
207 DISPLAY_FUNC_ENTRY();
209 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
211 _pthread_mutex_lock(&private_display->lock);
213 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
214 TDM_ERR("no pp capability");
215 _pthread_mutex_unlock(&private_display->lock);
216 return TDM_ERROR_NO_CAPABILITY;
219 *capabilities = private_display->caps_pp.capabilities;
221 _pthread_mutex_unlock(&private_display->lock);
227 tdm_display_get_pp_available_formats(tdm_display *dpy,
228 const tbm_format **formats, int *count)
230 DISPLAY_FUNC_ENTRY();
232 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
233 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
235 _pthread_mutex_lock(&private_display->lock);
237 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
238 TDM_ERR("no pp capability");
239 _pthread_mutex_unlock(&private_display->lock);
240 return TDM_ERROR_NO_CAPABILITY;
243 *formats = (const tbm_format *)private_display->caps_pp.formats;
244 *count = private_display->caps_pp.format_count;
246 _pthread_mutex_unlock(&private_display->lock);
252 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
253 int *max_w, int *max_h, int *preferred_align)
255 DISPLAY_FUNC_ENTRY();
257 _pthread_mutex_lock(&private_display->lock);
259 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
260 TDM_ERR("no pp capability");
261 _pthread_mutex_unlock(&private_display->lock);
262 return TDM_ERROR_NO_CAPABILITY;
266 *min_w = private_display->caps_pp.min_w;
268 *min_h = private_display->caps_pp.min_h;
270 *max_w = private_display->caps_pp.max_w;
272 *max_h = private_display->caps_pp.max_h;
274 *preferred_align = private_display->caps_pp.preferred_align;
276 _pthread_mutex_unlock(&private_display->lock);
282 tdm_display_get_capture_capabilities(tdm_display *dpy,
283 tdm_capture_capability *capabilities)
285 DISPLAY_FUNC_ENTRY();
287 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
289 _pthread_mutex_lock(&private_display->lock);
291 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
292 TDM_ERR("no capture capability");
293 _pthread_mutex_unlock(&private_display->lock);
294 return TDM_ERROR_NO_CAPABILITY;
297 *capabilities = private_display->caps_capture.capabilities;
299 _pthread_mutex_unlock(&private_display->lock);
305 tdm_display_get_catpure_available_formats(tdm_display *dpy,
306 const tbm_format **formats, int *count)
308 DISPLAY_FUNC_ENTRY();
310 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
311 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
313 _pthread_mutex_lock(&private_display->lock);
315 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
316 TDM_ERR("no capture capability");
317 _pthread_mutex_unlock(&private_display->lock);
318 return TDM_ERROR_NO_CAPABILITY;
321 *formats = (const tbm_format *)private_display->caps_capture.formats;
322 *count = private_display->caps_capture.format_count;
324 _pthread_mutex_unlock(&private_display->lock);
330 tdm_display_get_output_count(tdm_display *dpy, int *count)
332 tdm_private_output *private_output = NULL;
334 DISPLAY_FUNC_ENTRY();
336 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
338 _pthread_mutex_lock(&private_display->lock);
341 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
345 _pthread_mutex_unlock(&private_display->lock);
346 return TDM_ERROR_NONE;
349 _pthread_mutex_unlock(&private_display->lock);
356 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
358 tdm_private_output *private_output = NULL;
361 DISPLAY_FUNC_ENTRY_ERROR();
363 _pthread_mutex_lock(&private_display->lock);
366 *error = TDM_ERROR_NONE;
369 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
371 _pthread_mutex_unlock(&private_display->lock);
372 return private_output;
377 _pthread_mutex_unlock(&private_display->lock);
383 tdm_display_get_fd(tdm_display *dpy, int *fd)
385 DISPLAY_FUNC_ENTRY();
387 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
389 _pthread_mutex_lock(&private_display->lock);
391 if (tdm_thread_is_running())
392 *fd = tdm_thread_get_fd(private_display->private_loop);
394 *fd = tdm_event_loop_get_fd(private_display);
396 _pthread_mutex_unlock(&private_display->lock);
402 tdm_display_handle_events(tdm_display *dpy)
407 DISPLAY_FUNC_ENTRY();
409 ret = tdm_display_get_fd(dpy, &fd);
410 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
416 if (tdm_debug_thread)
417 TDM_INFO("fd(%d) polling in", fd);
419 while (poll(&fds, 1, -1) < 0) {
420 if (errno == EBUSY) /* normal case */
423 TDM_ERR("poll failed: %m");
424 return TDM_ERROR_OPERATION_FAILED;
428 if (tdm_debug_thread)
429 TDM_INFO("fd(%d) polling out", fd);
431 if (tdm_thread_is_running())
432 ret = tdm_thread_handle_cb(private_display->private_loop);
434 ret = tdm_event_loop_dispatch(private_display);
440 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
444 DISPLAY_FUNC_ENTRY_ERROR();
446 _pthread_mutex_lock(&private_display->lock);
448 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
450 _pthread_mutex_unlock(&private_display->lock);
456 tdm_output_get_model_info(tdm_output *output, const char **maker,
457 const char **model, const char **name)
461 _pthread_mutex_lock(&private_display->lock);
464 *maker = private_output->caps.maker;
466 *model = private_output->caps.model;
468 *name = private_output->caps.name;
470 _pthread_mutex_unlock(&private_display->lock);
476 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
480 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
482 _pthread_mutex_lock(&private_display->lock);
484 *status = private_output->caps.status;
486 _pthread_mutex_unlock(&private_display->lock);
492 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
495 tdm_private_display *private_display;
496 tdm_private_output *private_output = user_data;
499 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
500 TDM_RETURN_IF_FAIL(private_output);
502 private_display = private_output->private_display;
504 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
505 tdm_thread_cb_output_status output_status;
508 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
509 output_status.base.length = sizeof output_status;
510 output_status.output_stamp = private_output->stamp;
511 output_status.status = status;
512 output_status.user_data = user_data;
515 tdm_output_call_change_handler_internal(private_output,
516 &private_output->change_handler_list_sub,
517 TDM_OUTPUT_CHANGE_CONNECTION,
520 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
521 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
527 tdm_output_call_change_handler_internal(private_output,
528 &private_output->change_handler_list_main,
529 TDM_OUTPUT_CHANGE_CONNECTION,
534 tdm_output_add_change_handler(tdm_output *output,
535 tdm_output_change_handler func,
538 tdm_private_change_handler *change_handler;
541 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
543 pthread_mutex_lock(&private_display->lock);
545 if (!private_output->regist_change_cb) {
546 _pthread_mutex_unlock(&private_display->lock);
547 TDM_ERR("not implemented!!");
548 return TDM_ERROR_NOT_IMPLEMENTED;
551 change_handler = calloc(1, sizeof(tdm_private_change_handler));
552 if (!change_handler) {
553 TDM_ERR("failed: alloc memory");
554 _pthread_mutex_unlock(&private_display->lock);
555 return TDM_ERROR_OUT_OF_MEMORY;
558 change_handler->private_output = private_output;
559 change_handler->func = func;
560 change_handler->user_data = user_data;
561 change_handler->owner_tid = syscall(SYS_gettid);
563 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
564 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
566 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
568 _pthread_mutex_unlock(&private_display->lock);
574 tdm_output_remove_change_handler(tdm_output *output,
575 tdm_output_change_handler func,
578 tdm_private_display *private_display;
579 tdm_private_output *private_output;
580 tdm_private_change_handler *h = NULL, *hh = NULL;
582 TDM_RETURN_IF_FAIL(output != NULL);
583 TDM_RETURN_IF_FAIL(func != NULL);
585 private_output = (tdm_private_output*)output;
586 private_display = private_output->private_display;
588 _pthread_mutex_lock(&private_display->lock);
590 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
591 if (h->func != func || h->user_data != user_data)
597 _pthread_mutex_unlock(&private_display->lock);
602 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
603 if (h->func != func || h->user_data != user_data)
609 _pthread_mutex_unlock(&private_display->lock);
614 _pthread_mutex_unlock(&private_display->lock);
618 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
622 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
624 _pthread_mutex_lock(&private_display->lock);
626 *type = private_output->caps.type;
628 _pthread_mutex_unlock(&private_display->lock);
634 tdm_output_get_layer_count(tdm_output *output, int *count)
636 tdm_private_layer *private_layer = NULL;
640 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
642 _pthread_mutex_lock(&private_display->lock);
645 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
648 _pthread_mutex_unlock(&private_display->lock);
649 return TDM_ERROR_NONE;
652 _pthread_mutex_unlock(&private_display->lock);
659 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
661 tdm_private_layer *private_layer = NULL;
664 OUTPUT_FUNC_ENTRY_ERROR();
666 _pthread_mutex_lock(&private_display->lock);
669 *error = TDM_ERROR_NONE;
671 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
673 _pthread_mutex_unlock(&private_display->lock);
674 return private_layer;
679 _pthread_mutex_unlock(&private_display->lock);
685 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
690 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
691 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
693 _pthread_mutex_lock(&private_display->lock);
695 *props = (const tdm_prop *)private_output->caps.props;
696 *count = private_output->caps.prop_count;
698 _pthread_mutex_unlock(&private_display->lock);
704 tdm_output_get_available_modes(tdm_output *output,
705 const tdm_output_mode **modes, int *count)
709 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
710 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
712 _pthread_mutex_lock(&private_display->lock);
714 *modes = (const tdm_output_mode *)private_output->caps.modes;
715 *count = private_output->caps.mode_count;
717 _pthread_mutex_unlock(&private_display->lock);
723 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
724 int *max_w, int *max_h, int *preferred_align)
728 _pthread_mutex_lock(&private_display->lock);
731 *min_w = private_output->caps.min_w;
733 *min_h = private_output->caps.min_h;
735 *max_w = private_output->caps.max_w;
737 *max_h = private_output->caps.max_h;
739 *preferred_align = private_output->caps.preferred_align;
741 _pthread_mutex_unlock(&private_display->lock);
747 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
748 unsigned int *mmHeight)
752 _pthread_mutex_lock(&private_display->lock);
755 *mmWidth = private_output->caps.mmWidth;
757 *mmHeight = private_output->caps.mmHeight;
759 _pthread_mutex_unlock(&private_display->lock);
765 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
768 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
770 _pthread_mutex_lock(&private_display->lock);
772 *subpixel = private_output->caps.subpixel;
774 _pthread_mutex_unlock(&private_display->lock);
780 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
783 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
785 _pthread_mutex_lock(&private_display->lock);
787 *pipe = private_output->pipe;
789 _pthread_mutex_unlock(&private_display->lock);
796 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
798 tdm_func_output *func_output;
801 _pthread_mutex_lock(&private_display->lock);
803 func_output = &private_display->func_output;
805 if (!func_output->output_set_property) {
806 _pthread_mutex_unlock(&private_display->lock);
807 TDM_ERR("not implemented!!");
808 return TDM_ERROR_NOT_IMPLEMENTED;
811 ret = func_output->output_set_property(private_output->output_backend, id,
814 _pthread_mutex_unlock(&private_display->lock);
820 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
822 tdm_func_output *func_output;
825 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
827 _pthread_mutex_lock(&private_display->lock);
829 func_output = &private_display->func_output;
831 if (!func_output->output_get_property) {
832 _pthread_mutex_unlock(&private_display->lock);
833 TDM_ERR("not implemented!!");
834 return TDM_ERROR_NOT_IMPLEMENTED;
837 ret = func_output->output_get_property(private_output->output_backend, id,
840 _pthread_mutex_unlock(&private_display->lock);
846 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
847 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
849 tdm_private_vblank_handler *vblank_handler = user_data;
850 tdm_private_display *private_display;
852 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
853 TDM_RETURN_IF_FAIL(vblank_handler);
855 private_display = vblank_handler->private_output->private_display;
857 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
858 tdm_thread_cb_output_vblank output_vblank;
861 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
862 output_vblank.base.length = sizeof output_vblank;
863 output_vblank.output_stamp = vblank_handler->private_output->stamp;
864 output_vblank.sequence = sequence;
865 output_vblank.tv_sec = tv_sec;
866 output_vblank.tv_usec = tv_usec;
867 output_vblank.user_data = user_data;
869 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
870 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
875 if (vblank_handler->owner_tid != syscall(SYS_gettid))
876 TDM_NEVER_GET_HERE();
878 if (vblank_handler->func) {
879 _pthread_mutex_unlock(&private_display->lock);
880 vblank_handler->func(vblank_handler->private_output, sequence,
881 tv_sec, tv_usec, vblank_handler->user_data);
882 _pthread_mutex_lock(&private_display->lock);
885 LIST_DEL(&vblank_handler->link);
886 free(vblank_handler);
890 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
891 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
893 tdm_private_commit_handler *commit_handler = user_data;
894 tdm_private_display *private_display;
895 tdm_private_output *private_output;
896 tdm_private_layer *private_layer = NULL;
898 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
899 TDM_RETURN_IF_FAIL(commit_handler);
901 private_output = commit_handler->private_output;
902 private_display = private_output->private_display;
904 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
905 tdm_thread_cb_output_commit output_commit;
908 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
909 output_commit.base.length = sizeof output_commit;
910 output_commit.output_stamp = private_output->stamp;
911 output_commit.sequence = sequence;
912 output_commit.tv_sec = tv_sec;
913 output_commit.tv_usec = tv_usec;
914 output_commit.user_data = user_data;
916 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
917 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
922 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
923 if (!private_layer->waiting_buffer)
926 if (private_layer->showing_buffer) {
927 _pthread_mutex_unlock(&private_display->lock);
928 tdm_buffer_unref_backend(private_layer->showing_buffer);
929 _pthread_mutex_lock(&private_display->lock);
931 if (private_layer->buffer_queue) {
932 tbm_surface_queue_release(private_layer->buffer_queue,
933 private_layer->showing_buffer);
937 private_layer->showing_buffer = private_layer->waiting_buffer;
938 private_layer->waiting_buffer = NULL;
940 if (tdm_debug_buffer)
941 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
942 private_layer, private_layer->waiting_buffer,
943 private_layer->showing_buffer);
946 if (commit_handler->func) {
947 _pthread_mutex_unlock(&private_display->lock);
948 commit_handler->func(private_output, sequence,
949 tv_sec, tv_usec, commit_handler->user_data);
950 _pthread_mutex_lock(&private_display->lock);
953 LIST_DEL(&commit_handler->link);
954 free(commit_handler);
958 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
959 tdm_output_vblank_handler func, void *user_data)
961 tdm_func_output *func_output;
962 tdm_private_vblank_handler *vblank_handler;
965 _pthread_mutex_lock(&private_display->lock);
967 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
968 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
969 dpms_str(private_output->current_dpms_value));
970 _pthread_mutex_unlock(&private_display->lock);
971 return TDM_ERROR_BAD_REQUEST;
974 func_output = &private_display->func_output;
976 if (!func_output->output_wait_vblank) {
977 _pthread_mutex_unlock(&private_display->lock);
978 TDM_ERR("not implemented!!");
979 return TDM_ERROR_NOT_IMPLEMENTED;
982 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
983 if (!vblank_handler) {
984 TDM_ERR("failed: alloc memory");
985 _pthread_mutex_unlock(&private_display->lock);
986 return TDM_ERROR_OUT_OF_MEMORY;
989 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
990 vblank_handler->private_output = private_output;
991 vblank_handler->func = func;
992 vblank_handler->user_data = user_data;
993 vblank_handler->owner_tid = syscall(SYS_gettid);
995 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
996 sync, vblank_handler);
997 if (ret != TDM_ERROR_NONE) {
998 _pthread_mutex_unlock(&private_display->lock);
1002 if (!private_output->regist_vblank_cb) {
1003 private_output->regist_vblank_cb = 1;
1004 ret = func_output->output_set_vblank_handler(private_output->output_backend,
1005 tdm_output_cb_vblank);
1008 _pthread_mutex_unlock(&private_display->lock);
1014 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1017 tdm_func_output *func_output;
1018 tdm_private_commit_handler *commit_handler;
1019 OUTPUT_FUNC_ENTRY();
1021 func_output = &private_display->func_output;
1023 if (!func_output->output_commit) {
1024 TDM_ERR("not implemented!!");
1025 return TDM_ERROR_NOT_IMPLEMENTED;
1028 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1029 if (!commit_handler) {
1030 TDM_ERR("failed: alloc memory");
1031 return TDM_ERROR_OUT_OF_MEMORY;
1034 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1035 commit_handler->private_output = private_output;
1036 commit_handler->func = func;
1037 commit_handler->user_data = user_data;
1038 commit_handler->owner_tid = syscall(SYS_gettid);
1040 ret = func_output->output_commit(private_output->output_backend, sync,
1042 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1044 if (!private_output->regist_commit_cb) {
1045 private_output->regist_commit_cb = 1;
1046 ret = func_output->output_set_commit_handler(private_output->output_backend,
1047 tdm_output_cb_commit);
1054 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1057 OUTPUT_FUNC_ENTRY();
1059 _pthread_mutex_lock(&private_display->lock);
1061 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1062 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1063 dpms_str(private_output->current_dpms_value));
1064 _pthread_mutex_unlock(&private_display->lock);
1065 return TDM_ERROR_BAD_REQUEST;
1068 ret = _tdm_output_commit(output, sync, func, user_data);
1070 _pthread_mutex_unlock(&private_display->lock);
1076 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1078 tdm_func_output *func_output;
1079 OUTPUT_FUNC_ENTRY();
1081 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1083 _pthread_mutex_lock(&private_display->lock);
1085 func_output = &private_display->func_output;
1087 if (!func_output->output_set_mode) {
1088 _pthread_mutex_unlock(&private_display->lock);
1089 TDM_ERR("not implemented!!");
1090 return TDM_ERROR_NOT_IMPLEMENTED;
1093 ret = func_output->output_set_mode(private_output->output_backend, mode);
1095 _pthread_mutex_unlock(&private_display->lock);
1101 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1103 tdm_func_output *func_output;
1104 OUTPUT_FUNC_ENTRY();
1106 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1108 _pthread_mutex_lock(&private_display->lock);
1110 func_output = &private_display->func_output;
1112 if (!func_output->output_get_mode) {
1113 _pthread_mutex_unlock(&private_display->lock);
1114 TDM_ERR("not implemented!!");
1115 return TDM_ERROR_NOT_IMPLEMENTED;
1118 ret = func_output->output_get_mode(private_output->output_backend, mode);
1120 _pthread_mutex_unlock(&private_display->lock);
1126 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1128 tdm_func_output *func_output;
1129 OUTPUT_FUNC_ENTRY();
1131 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1132 dpms_value = TDM_OUTPUT_DPMS_ON;
1133 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1134 dpms_value = TDM_OUTPUT_DPMS_OFF;
1136 _pthread_mutex_lock(&private_display->lock);
1138 if (private_output->current_dpms_value == dpms_value) {
1139 _pthread_mutex_unlock(&private_display->lock);
1140 return TDM_ERROR_NONE;
1143 func_output = &private_display->func_output;
1145 if (!func_output->output_set_dpms) {
1146 _pthread_mutex_unlock(&private_display->lock);
1147 private_output->current_dpms_value = dpms_value;
1148 TDM_WRN("not implemented!!");
1149 return TDM_ERROR_NONE;
1152 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1153 if (ret == TDM_ERROR_NONE) {
1156 private_output->current_dpms_value = dpms_value;
1158 value.u32 = dpms_value;
1159 tdm_output_call_change_handler_internal(private_output,
1160 &private_output->change_handler_list_main,
1161 TDM_OUTPUT_CHANGE_DPMS,
1165 _pthread_mutex_unlock(&private_display->lock);
1171 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1173 tdm_func_output *func_output;
1174 OUTPUT_FUNC_ENTRY();
1176 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1178 _pthread_mutex_lock(&private_display->lock);
1180 func_output = &private_display->func_output;
1182 if (!func_output->output_get_dpms) {
1183 *dpms_value = private_output->current_dpms_value;
1184 _pthread_mutex_unlock(&private_display->lock);
1185 TDM_WRN("not implemented!!");
1186 return TDM_ERROR_NONE;
1189 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1191 _pthread_mutex_unlock(&private_display->lock);
1196 EXTERN tdm_capture *
1197 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1199 tdm_capture *capture = NULL;
1201 OUTPUT_FUNC_ENTRY_ERROR();
1203 _pthread_mutex_lock(&private_display->lock);
1205 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1208 _pthread_mutex_unlock(&private_display->lock);
1214 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1215 struct list_head *change_handler_list,
1216 tdm_output_change_type type,
1219 tdm_private_display *private_display;
1220 tdm_private_change_handler *change_handler;
1222 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1223 TDM_RETURN_IF_FAIL(private_output);
1225 private_display = private_output->private_display;
1226 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1227 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1228 TDM_INFO("output(%d) changed: %s (%d)",
1229 private_output->pipe, status_str(value.u32), value.u32);
1230 if (type & TDM_OUTPUT_CHANGE_DPMS)
1231 TDM_INFO("output(%d) changed: dpms %s (%d)",
1232 private_output->pipe, dpms_str(value.u32), value.u32);
1235 if (LIST_IS_EMPTY(change_handler_list))
1238 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1239 if (change_handler->owner_tid != syscall(SYS_gettid))
1240 TDM_NEVER_GET_HERE();
1242 _pthread_mutex_unlock(&private_display->lock);
1243 change_handler->func(private_output, type,
1244 value, change_handler->user_data);
1245 _pthread_mutex_lock(&private_display->lock);
1250 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1254 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1256 _pthread_mutex_lock(&private_display->lock);
1258 *capabilities = private_layer->caps.capabilities;
1260 _pthread_mutex_unlock(&private_display->lock);
1266 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1271 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1272 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1274 _pthread_mutex_lock(&private_display->lock);
1276 *formats = (const tbm_format *)private_layer->caps.formats;
1277 *count = private_layer->caps.format_count;
1279 _pthread_mutex_unlock(&private_display->lock);
1285 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1290 TDM_RETURN_VAL_IF_FAIL(props != 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 *props = (const tdm_prop *)private_layer->caps.props;
1296 *count = private_layer->caps.prop_count;
1298 _pthread_mutex_unlock(&private_display->lock);
1304 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1308 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1310 _pthread_mutex_lock(&private_display->lock);
1312 *zpos = private_layer->caps.zpos;
1314 _pthread_mutex_unlock(&private_display->lock);
1320 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1322 tdm_func_layer *func_layer;
1325 _pthread_mutex_lock(&private_display->lock);
1327 func_layer = &private_display->func_layer;
1329 if (!func_layer->layer_set_property) {
1330 _pthread_mutex_unlock(&private_display->lock);
1331 TDM_ERR("not implemented!!");
1332 return TDM_ERROR_NOT_IMPLEMENTED;
1335 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1337 _pthread_mutex_unlock(&private_display->lock);
1343 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1345 tdm_func_layer *func_layer;
1348 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1350 _pthread_mutex_lock(&private_display->lock);
1352 func_layer = &private_display->func_layer;
1354 if (!func_layer->layer_get_property) {
1355 _pthread_mutex_unlock(&private_display->lock);
1356 TDM_ERR("not implemented!!");
1357 return TDM_ERROR_NOT_IMPLEMENTED;
1360 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1362 _pthread_mutex_unlock(&private_display->lock);
1368 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1370 tdm_func_layer *func_layer;
1373 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1375 _pthread_mutex_lock(&private_display->lock);
1377 func_layer = &private_display->func_layer;
1379 private_layer->usable = 0;
1381 if (!func_layer->layer_set_info) {
1382 _pthread_mutex_unlock(&private_display->lock);
1383 TDM_ERR("not implemented!!");
1384 return TDM_ERROR_NOT_IMPLEMENTED;
1387 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1388 private_layer, info->src_config.size.h, info->src_config.size.v,
1389 info->src_config.pos.x, info->src_config.pos.y,
1390 info->src_config.pos.w, info->src_config.pos.h,
1391 FOURCC_STR(info->src_config.format),
1392 info->dst_pos.x, info->dst_pos.y,
1393 info->dst_pos.w, info->dst_pos.h,
1396 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1397 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1399 _pthread_mutex_unlock(&private_display->lock);
1405 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1407 tdm_func_layer *func_layer;
1410 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1412 _pthread_mutex_lock(&private_display->lock);
1414 func_layer = &private_display->func_layer;
1416 if (!func_layer->layer_get_info) {
1417 _pthread_mutex_unlock(&private_display->lock);
1418 TDM_ERR("not implemented!!");
1419 return TDM_ERROR_NOT_IMPLEMENTED;
1422 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1424 _pthread_mutex_unlock(&private_display->lock);
1430 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1432 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1433 tdm_private_output *private_output = private_layer->private_output;
1436 char fname[PATH_MAX];
1438 pipe = private_output->pipe;
1439 zpos = private_layer->caps.zpos;
1441 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1443 tbm_surface_internal_dump_buffer(buffer, fname);
1444 TDM_DBG("%s dump excute", fname);
1450 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1452 tdm_func_layer *func_layer;
1456 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1458 _pthread_mutex_lock(&private_display->lock);
1460 func_layer = &private_display->func_layer;
1462 private_layer->usable = 0;
1464 if (!func_layer->layer_set_buffer) {
1465 _pthread_mutex_unlock(&private_display->lock);
1466 TDM_ERR("not implemented!!");
1467 return TDM_ERROR_NOT_IMPLEMENTED;
1470 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1471 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1474 if (tdm_dump_enable)
1475 _tdm_layer_dump_buffer(layer, buffer);
1477 if (ret == TDM_ERROR_NONE) {
1478 /* FIXME: should save to pending_buffer first. And after committing
1479 * successfully, need to move to waiting_buffer.
1481 if (private_layer->waiting_buffer) {
1482 _pthread_mutex_unlock(&private_display->lock);
1483 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1484 _pthread_mutex_lock(&private_display->lock);
1487 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1488 if (tdm_debug_buffer)
1489 TDM_INFO("layer(%p) waiting_buffer(%p)",
1490 private_layer, private_layer->waiting_buffer);
1493 _pthread_mutex_unlock(&private_display->lock);
1499 tdm_layer_unset_buffer(tdm_layer *layer)
1501 tdm_func_layer *func_layer;
1504 _pthread_mutex_lock(&private_display->lock);
1506 func_layer = &private_display->func_layer;
1508 if (private_layer->waiting_buffer) {
1509 _pthread_mutex_unlock(&private_display->lock);
1510 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1511 _pthread_mutex_lock(&private_display->lock);
1512 private_layer->waiting_buffer = NULL;
1514 if (tdm_debug_buffer)
1515 TDM_INFO("layer(%p) waiting_buffer(%p)",
1516 private_layer, private_layer->waiting_buffer);
1519 if (private_layer->showing_buffer) {
1520 _pthread_mutex_unlock(&private_display->lock);
1521 tdm_buffer_unref_backend(private_layer->showing_buffer);
1522 _pthread_mutex_lock(&private_display->lock);
1523 private_layer->showing_buffer = NULL;
1525 if (tdm_debug_buffer)
1526 TDM_INFO("layer(%p) showing_buffer(%p)",
1527 private_layer, private_layer->showing_buffer);
1530 private_layer->usable = 1;
1532 if (!func_layer->layer_unset_buffer) {
1533 _pthread_mutex_unlock(&private_display->lock);
1534 TDM_ERR("not implemented!!");
1535 return TDM_ERROR_NOT_IMPLEMENTED;
1538 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1539 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1541 _pthread_mutex_unlock(&private_display->lock);
1546 EXTERN tbm_surface_h
1547 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1549 tbm_surface_h buffer;
1550 LAYER_FUNC_ENTRY_ERROR();
1552 _pthread_mutex_lock(&private_display->lock);
1555 *error = TDM_ERROR_NONE;
1557 if (private_layer->showing_buffer) {
1558 buffer = private_layer->showing_buffer;
1561 *error = TDM_ERROR_OPERATION_FAILED;
1562 _pthread_mutex_unlock(&private_display->lock);
1563 TDM_ERR("layer(%p) showing_buffer is null",
1567 _pthread_mutex_unlock(&private_display->lock);
1573 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1575 TDM_RETURN_IF_FAIL(data != NULL);
1576 tdm_layer *layer = data;
1577 tdm_func_layer *func_layer;
1578 tbm_surface_h surface = NULL;
1579 LAYER_FUNC_ENTRY_VOID_RETURN();
1581 _pthread_mutex_lock(&private_display->lock);
1583 func_layer = &private_display->func_layer;
1584 if (!func_layer->layer_set_buffer) {
1585 _pthread_mutex_unlock(&private_display->lock);
1589 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1590 private_layer->buffer_queue, &surface) ||
1592 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1593 private_layer, surface);
1594 _pthread_mutex_unlock(&private_display->lock);
1598 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1599 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1601 if (ret == TDM_ERROR_NONE) {
1602 if (private_layer->waiting_buffer) {
1603 _pthread_mutex_unlock(&private_display->lock);
1604 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1605 tbm_surface_queue_release(private_layer->buffer_queue,
1606 private_layer->waiting_buffer);
1607 _pthread_mutex_lock(&private_display->lock);
1610 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1612 if (tdm_debug_buffer)
1613 TDM_INFO("layer(%p) waiting_buffer(%p)",
1614 private_layer, private_layer->waiting_buffer);
1616 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1617 if (ret != TDM_ERROR_NONE)
1618 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1621 _pthread_mutex_unlock(&private_display->lock);
1625 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1627 TDM_RETURN_IF_FAIL(data != NULL);
1628 tdm_layer *layer = data;
1629 LAYER_FUNC_ENTRY_VOID_RETURN();
1630 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1632 _pthread_mutex_lock(&private_display->lock);
1634 if (private_layer->waiting_buffer) {
1635 _pthread_mutex_unlock(&private_display->lock);
1636 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1637 tbm_surface_queue_release(private_layer->buffer_queue,
1638 private_layer->waiting_buffer);
1639 _pthread_mutex_lock(&private_display->lock);
1642 private_layer->buffer_queue = NULL;
1644 _pthread_mutex_unlock(&private_display->lock);
1648 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1650 tdm_func_layer *func_layer;
1653 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1655 _pthread_mutex_lock(&private_display->lock);
1657 func_layer = &private_display->func_layer;
1659 private_layer->usable = 0;
1661 if (!func_layer->layer_set_buffer) {
1662 _pthread_mutex_unlock(&private_display->lock);
1663 TDM_ERR("not implemented!!");
1664 return TDM_ERROR_NOT_IMPLEMENTED;
1667 if (buffer_queue == private_layer->buffer_queue) {
1668 _pthread_mutex_unlock(&private_display->lock);
1669 return TDM_ERROR_NONE;
1672 if (private_layer->waiting_buffer) {
1673 _pthread_mutex_unlock(&private_display->lock);
1674 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1675 tbm_surface_queue_release(private_layer->buffer_queue,
1676 private_layer->waiting_buffer);
1677 private_layer->waiting_buffer = NULL;
1678 _pthread_mutex_lock(&private_display->lock);
1680 if (tdm_debug_buffer)
1681 TDM_INFO("layer(%p) waiting_buffer(%p)",
1682 private_layer, private_layer->waiting_buffer);
1685 private_layer->buffer_queue = buffer_queue;
1686 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1687 _tbm_layer_queue_acquirable_cb,
1689 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1690 _tbm_layer_queue_destroy_cb,
1692 _pthread_mutex_unlock(&private_display->lock);
1698 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1700 tdm_func_layer *func_layer;
1703 _pthread_mutex_lock(&private_display->lock);
1705 func_layer = &private_display->func_layer;
1707 if (private_layer->waiting_buffer) {
1708 _pthread_mutex_unlock(&private_display->lock);
1709 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1710 tbm_surface_queue_release(private_layer->buffer_queue,
1711 private_layer->waiting_buffer);
1712 private_layer->waiting_buffer = NULL;
1713 _pthread_mutex_lock(&private_display->lock);
1715 if (tdm_debug_buffer)
1716 TDM_INFO("layer(%p) waiting_buffer(%p)",
1717 private_layer, private_layer->waiting_buffer);
1720 if (private_layer->showing_buffer) {
1721 _pthread_mutex_unlock(&private_display->lock);
1722 tdm_buffer_unref_backend(private_layer->showing_buffer);
1723 tbm_surface_queue_release(private_layer->buffer_queue,
1724 private_layer->showing_buffer);
1725 _pthread_mutex_lock(&private_display->lock);
1726 private_layer->showing_buffer = NULL;
1728 if (tdm_debug_buffer)
1729 TDM_INFO("layer(%p) showing_buffer(%p)",
1730 private_layer, private_layer->showing_buffer);
1733 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1734 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1735 private_layer->buffer_queue = NULL;
1736 private_layer->usable = 1;
1738 if (!func_layer->layer_unset_buffer) {
1739 _pthread_mutex_unlock(&private_display->lock);
1740 TDM_ERR("not implemented!!");
1741 return TDM_ERROR_NOT_IMPLEMENTED;
1744 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1746 _pthread_mutex_unlock(&private_display->lock);
1752 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1756 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1758 _pthread_mutex_lock(&private_display->lock);
1760 *usable = private_layer->usable;
1762 _pthread_mutex_unlock(&private_display->lock);
1768 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1770 tdm_func_layer *func_layer;
1773 _pthread_mutex_lock(&private_display->lock);
1775 func_layer = &private_display->func_layer;
1777 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1778 TDM_ERR("layer(%p) is not video layer", private_layer);
1779 _pthread_mutex_unlock(&private_display->lock);
1780 return TDM_ERROR_INVALID_PARAMETER;
1783 if (!func_layer->layer_set_video_pos) {
1784 _pthread_mutex_unlock(&private_display->lock);
1785 TDM_ERR("not implemented!!");
1786 return TDM_ERROR_NOT_IMPLEMENTED;
1789 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1791 _pthread_mutex_unlock(&private_display->lock);
1796 EXTERN tdm_capture *
1797 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1799 tdm_capture *capture = NULL;
1801 LAYER_FUNC_ENTRY_ERROR();
1803 _pthread_mutex_lock(&private_display->lock);
1805 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1808 _pthread_mutex_unlock(&private_display->lock);