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;
1438 char fullpath[PATH_MAX];
1439 tbm_surface_info_s info;
1440 tbm_surface_error_e err;
1442 path = tdm_helper_get_dump_path();
1446 count = tdm_helper_get_dump_count();
1450 err = tbm_surface_map(buffer, TBM_SURF_OPTION_READ, &info);
1451 TDM_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
1453 pipe = private_output->pipe;
1454 zpos = private_layer->caps.zpos;
1456 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1457 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d.png",
1458 path, count, pipe, zpos);
1460 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d_%dx%d_%c%c%c%c.yuv",
1461 path, count, pipe, zpos, info.planes[0].stride, info.height, FOURCC_STR(info.format));
1463 tbm_surface_unmap(buffer);
1465 tdm_helper_dump_buffer(buffer, fullpath);
1466 TDM_DBG("%d, %s dump excute", count, fullpath);
1472 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1474 tdm_func_layer *func_layer;
1478 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1480 _pthread_mutex_lock(&private_display->lock);
1482 func_layer = &private_display->func_layer;
1484 private_layer->usable = 0;
1486 if (!func_layer->layer_set_buffer) {
1487 _pthread_mutex_unlock(&private_display->lock);
1488 TDM_ERR("not implemented!!");
1489 return TDM_ERROR_NOT_IMPLEMENTED;
1492 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1493 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1496 if (tdm_dump_enable)
1497 _tdm_layer_dump_buffer(layer, buffer);
1499 if (ret == TDM_ERROR_NONE) {
1500 /* FIXME: should save to pending_buffer first. And after committing
1501 * successfully, need to move to waiting_buffer.
1503 if (private_layer->waiting_buffer) {
1504 _pthread_mutex_unlock(&private_display->lock);
1505 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1506 _pthread_mutex_lock(&private_display->lock);
1509 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1510 if (tdm_debug_buffer)
1511 TDM_INFO("layer(%p) waiting_buffer(%p)",
1512 private_layer, private_layer->waiting_buffer);
1515 _pthread_mutex_unlock(&private_display->lock);
1521 tdm_layer_unset_buffer(tdm_layer *layer)
1523 tdm_func_layer *func_layer;
1526 _pthread_mutex_lock(&private_display->lock);
1528 func_layer = &private_display->func_layer;
1530 if (private_layer->waiting_buffer) {
1531 _pthread_mutex_unlock(&private_display->lock);
1532 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1533 _pthread_mutex_lock(&private_display->lock);
1534 private_layer->waiting_buffer = NULL;
1536 if (tdm_debug_buffer)
1537 TDM_INFO("layer(%p) waiting_buffer(%p)",
1538 private_layer, private_layer->waiting_buffer);
1541 if (private_layer->showing_buffer) {
1542 _pthread_mutex_unlock(&private_display->lock);
1543 tdm_buffer_unref_backend(private_layer->showing_buffer);
1544 _pthread_mutex_lock(&private_display->lock);
1545 private_layer->showing_buffer = NULL;
1547 if (tdm_debug_buffer)
1548 TDM_INFO("layer(%p) showing_buffer(%p)",
1549 private_layer, private_layer->showing_buffer);
1552 private_layer->usable = 1;
1554 if (!func_layer->layer_unset_buffer) {
1555 _pthread_mutex_unlock(&private_display->lock);
1556 TDM_ERR("not implemented!!");
1557 return TDM_ERROR_NOT_IMPLEMENTED;
1560 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1561 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1563 _pthread_mutex_unlock(&private_display->lock);
1569 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1571 TDM_RETURN_IF_FAIL(data != NULL);
1572 tdm_layer *layer = data;
1573 tdm_func_layer *func_layer;
1574 tbm_surface_h surface = NULL;
1575 LAYER_FUNC_ENTRY_VOID_RETURN();
1577 _pthread_mutex_lock(&private_display->lock);
1579 func_layer = &private_display->func_layer;
1580 if (!func_layer->layer_set_buffer) {
1581 _pthread_mutex_unlock(&private_display->lock);
1585 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1586 private_layer->buffer_queue, &surface) ||
1588 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1589 private_layer, surface);
1590 _pthread_mutex_unlock(&private_display->lock);
1594 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1595 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1597 if (ret == TDM_ERROR_NONE) {
1598 if (private_layer->waiting_buffer) {
1599 _pthread_mutex_unlock(&private_display->lock);
1600 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1601 tbm_surface_queue_release(private_layer->buffer_queue,
1602 private_layer->waiting_buffer);
1603 _pthread_mutex_lock(&private_display->lock);
1606 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1608 if (tdm_debug_buffer)
1609 TDM_INFO("layer(%p) waiting_buffer(%p)",
1610 private_layer, private_layer->waiting_buffer);
1612 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1613 if (ret != TDM_ERROR_NONE)
1614 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1617 _pthread_mutex_unlock(&private_display->lock);
1621 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1623 TDM_RETURN_IF_FAIL(data != NULL);
1624 tdm_layer *layer = data;
1625 LAYER_FUNC_ENTRY_VOID_RETURN();
1626 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1628 _pthread_mutex_lock(&private_display->lock);
1630 if (private_layer->waiting_buffer) {
1631 _pthread_mutex_unlock(&private_display->lock);
1632 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1633 tbm_surface_queue_release(private_layer->buffer_queue,
1634 private_layer->waiting_buffer);
1635 _pthread_mutex_lock(&private_display->lock);
1638 private_layer->buffer_queue = NULL;
1640 _pthread_mutex_unlock(&private_display->lock);
1644 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1646 tdm_func_layer *func_layer;
1649 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1651 _pthread_mutex_lock(&private_display->lock);
1653 func_layer = &private_display->func_layer;
1655 private_layer->usable = 0;
1657 if (!func_layer->layer_set_buffer) {
1658 _pthread_mutex_unlock(&private_display->lock);
1659 TDM_ERR("not implemented!!");
1660 return TDM_ERROR_NOT_IMPLEMENTED;
1663 if (buffer_queue == private_layer->buffer_queue) {
1664 _pthread_mutex_unlock(&private_display->lock);
1665 return TDM_ERROR_NONE;
1668 if (private_layer->waiting_buffer) {
1669 _pthread_mutex_unlock(&private_display->lock);
1670 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1671 tbm_surface_queue_release(private_layer->buffer_queue,
1672 private_layer->waiting_buffer);
1673 private_layer->waiting_buffer = NULL;
1674 _pthread_mutex_lock(&private_display->lock);
1676 if (tdm_debug_buffer)
1677 TDM_INFO("layer(%p) waiting_buffer(%p)",
1678 private_layer, private_layer->waiting_buffer);
1681 private_layer->buffer_queue = buffer_queue;
1682 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1683 _tbm_layer_queue_acquirable_cb,
1685 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1686 _tbm_layer_queue_destroy_cb,
1688 _pthread_mutex_unlock(&private_display->lock);
1694 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1696 tdm_func_layer *func_layer;
1699 _pthread_mutex_lock(&private_display->lock);
1701 func_layer = &private_display->func_layer;
1703 if (private_layer->waiting_buffer) {
1704 _pthread_mutex_unlock(&private_display->lock);
1705 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1706 tbm_surface_queue_release(private_layer->buffer_queue,
1707 private_layer->waiting_buffer);
1708 private_layer->waiting_buffer = NULL;
1709 _pthread_mutex_lock(&private_display->lock);
1711 if (tdm_debug_buffer)
1712 TDM_INFO("layer(%p) waiting_buffer(%p)",
1713 private_layer, private_layer->waiting_buffer);
1716 if (private_layer->showing_buffer) {
1717 _pthread_mutex_unlock(&private_display->lock);
1718 tdm_buffer_unref_backend(private_layer->showing_buffer);
1719 tbm_surface_queue_release(private_layer->buffer_queue,
1720 private_layer->showing_buffer);
1721 _pthread_mutex_lock(&private_display->lock);
1722 private_layer->showing_buffer = NULL;
1724 if (tdm_debug_buffer)
1725 TDM_INFO("layer(%p) showing_buffer(%p)",
1726 private_layer, private_layer->showing_buffer);
1729 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1730 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1731 private_layer->buffer_queue = NULL;
1732 private_layer->usable = 1;
1734 if (!func_layer->layer_unset_buffer) {
1735 _pthread_mutex_unlock(&private_display->lock);
1736 TDM_ERR("not implemented!!");
1737 return TDM_ERROR_NOT_IMPLEMENTED;
1740 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1742 _pthread_mutex_unlock(&private_display->lock);
1748 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1752 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1754 _pthread_mutex_lock(&private_display->lock);
1756 *usable = private_layer->usable;
1758 _pthread_mutex_unlock(&private_display->lock);
1764 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1766 tdm_func_layer *func_layer;
1769 _pthread_mutex_lock(&private_display->lock);
1771 func_layer = &private_display->func_layer;
1773 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1774 TDM_ERR("layer(%p) is not video layer", private_layer);
1775 _pthread_mutex_unlock(&private_display->lock);
1776 return TDM_ERROR_INVALID_PARAMETER;
1779 if (!func_layer->layer_set_video_pos) {
1780 _pthread_mutex_unlock(&private_display->lock);
1781 TDM_ERR("not implemented!!");
1782 return TDM_ERROR_NOT_IMPLEMENTED;
1785 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1787 _pthread_mutex_unlock(&private_display->lock);
1792 EXTERN tdm_capture *
1793 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1795 tdm_capture *capture = NULL;
1797 LAYER_FUNC_ENTRY_ERROR();
1799 _pthread_mutex_lock(&private_display->lock);
1801 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1804 _pthread_mutex_unlock(&private_display->lock);