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;
1560 *error = TDM_ERROR_OPERATION_FAILED;
1561 _pthread_mutex_unlock(&private_display->lock);
1562 TDM_ERR("layer(%p) showing_buffer is null",
1566 _pthread_mutex_unlock(&private_display->lock);
1572 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1574 TDM_RETURN_IF_FAIL(data != NULL);
1575 tdm_layer *layer = data;
1576 tdm_func_layer *func_layer;
1577 tbm_surface_h surface = NULL;
1578 LAYER_FUNC_ENTRY_VOID_RETURN();
1580 _pthread_mutex_lock(&private_display->lock);
1582 func_layer = &private_display->func_layer;
1583 if (!func_layer->layer_set_buffer) {
1584 _pthread_mutex_unlock(&private_display->lock);
1588 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1589 private_layer->buffer_queue, &surface) ||
1591 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1592 private_layer, surface);
1593 _pthread_mutex_unlock(&private_display->lock);
1597 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1598 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1600 if (ret == TDM_ERROR_NONE) {
1601 if (private_layer->waiting_buffer) {
1602 _pthread_mutex_unlock(&private_display->lock);
1603 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1604 tbm_surface_queue_release(private_layer->buffer_queue,
1605 private_layer->waiting_buffer);
1606 _pthread_mutex_lock(&private_display->lock);
1609 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1611 if (tdm_debug_buffer)
1612 TDM_INFO("layer(%p) waiting_buffer(%p)",
1613 private_layer, private_layer->waiting_buffer);
1615 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1616 if (ret != TDM_ERROR_NONE)
1617 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1620 _pthread_mutex_unlock(&private_display->lock);
1624 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1626 TDM_RETURN_IF_FAIL(data != NULL);
1627 tdm_layer *layer = data;
1628 LAYER_FUNC_ENTRY_VOID_RETURN();
1629 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1631 _pthread_mutex_lock(&private_display->lock);
1633 if (private_layer->waiting_buffer) {
1634 _pthread_mutex_unlock(&private_display->lock);
1635 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1636 tbm_surface_queue_release(private_layer->buffer_queue,
1637 private_layer->waiting_buffer);
1638 _pthread_mutex_lock(&private_display->lock);
1641 private_layer->buffer_queue = NULL;
1643 _pthread_mutex_unlock(&private_display->lock);
1647 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1649 tdm_func_layer *func_layer;
1652 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1654 _pthread_mutex_lock(&private_display->lock);
1656 func_layer = &private_display->func_layer;
1658 private_layer->usable = 0;
1660 if (!func_layer->layer_set_buffer) {
1661 _pthread_mutex_unlock(&private_display->lock);
1662 TDM_ERR("not implemented!!");
1663 return TDM_ERROR_NOT_IMPLEMENTED;
1666 if (buffer_queue == private_layer->buffer_queue) {
1667 _pthread_mutex_unlock(&private_display->lock);
1668 return TDM_ERROR_NONE;
1671 if (private_layer->waiting_buffer) {
1672 _pthread_mutex_unlock(&private_display->lock);
1673 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1674 tbm_surface_queue_release(private_layer->buffer_queue,
1675 private_layer->waiting_buffer);
1676 private_layer->waiting_buffer = NULL;
1677 _pthread_mutex_lock(&private_display->lock);
1679 if (tdm_debug_buffer)
1680 TDM_INFO("layer(%p) waiting_buffer(%p)",
1681 private_layer, private_layer->waiting_buffer);
1684 private_layer->buffer_queue = buffer_queue;
1685 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1686 _tbm_layer_queue_acquirable_cb,
1688 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1689 _tbm_layer_queue_destroy_cb,
1691 _pthread_mutex_unlock(&private_display->lock);
1697 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1699 tdm_func_layer *func_layer;
1702 _pthread_mutex_lock(&private_display->lock);
1704 func_layer = &private_display->func_layer;
1706 if (private_layer->waiting_buffer) {
1707 _pthread_mutex_unlock(&private_display->lock);
1708 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1709 tbm_surface_queue_release(private_layer->buffer_queue,
1710 private_layer->waiting_buffer);
1711 private_layer->waiting_buffer = NULL;
1712 _pthread_mutex_lock(&private_display->lock);
1714 if (tdm_debug_buffer)
1715 TDM_INFO("layer(%p) waiting_buffer(%p)",
1716 private_layer, private_layer->waiting_buffer);
1719 if (private_layer->showing_buffer) {
1720 _pthread_mutex_unlock(&private_display->lock);
1721 tdm_buffer_unref_backend(private_layer->showing_buffer);
1722 tbm_surface_queue_release(private_layer->buffer_queue,
1723 private_layer->showing_buffer);
1724 _pthread_mutex_lock(&private_display->lock);
1725 private_layer->showing_buffer = NULL;
1727 if (tdm_debug_buffer)
1728 TDM_INFO("layer(%p) showing_buffer(%p)",
1729 private_layer, private_layer->showing_buffer);
1732 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1733 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1734 private_layer->buffer_queue = NULL;
1735 private_layer->usable = 1;
1737 if (!func_layer->layer_unset_buffer) {
1738 _pthread_mutex_unlock(&private_display->lock);
1739 TDM_ERR("not implemented!!");
1740 return TDM_ERROR_NOT_IMPLEMENTED;
1743 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1745 _pthread_mutex_unlock(&private_display->lock);
1751 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1755 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1757 _pthread_mutex_lock(&private_display->lock);
1759 *usable = private_layer->usable;
1761 _pthread_mutex_unlock(&private_display->lock);
1767 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1769 tdm_func_layer *func_layer;
1772 _pthread_mutex_lock(&private_display->lock);
1774 func_layer = &private_display->func_layer;
1776 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1777 TDM_ERR("layer(%p) is not video layer", private_layer);
1778 _pthread_mutex_unlock(&private_display->lock);
1779 return TDM_ERROR_INVALID_PARAMETER;
1782 if (!func_layer->layer_set_video_pos) {
1783 _pthread_mutex_unlock(&private_display->lock);
1784 TDM_ERR("not implemented!!");
1785 return TDM_ERROR_NOT_IMPLEMENTED;
1788 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1790 _pthread_mutex_unlock(&private_display->lock);
1795 EXTERN tdm_capture *
1796 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1798 tdm_capture *capture = NULL;
1800 LAYER_FUNC_ENTRY_ERROR();
1802 _pthread_mutex_lock(&private_display->lock);
1804 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1807 _pthread_mutex_unlock(&private_display->lock);