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_get_capabilities(tdm_display *dpy,
147 tdm_display_capability *capabilities)
149 DISPLAY_FUNC_ENTRY();
151 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
153 _pthread_mutex_lock(&private_display->lock);
155 *capabilities = private_display->capabilities;
157 _pthread_mutex_unlock(&private_display->lock);
163 tdm_display_get_pp_capabilities(tdm_display *dpy,
164 tdm_pp_capability *capabilities)
166 DISPLAY_FUNC_ENTRY();
168 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
170 _pthread_mutex_lock(&private_display->lock);
172 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
173 TDM_ERR("no pp capability");
174 _pthread_mutex_unlock(&private_display->lock);
175 return TDM_ERROR_NO_CAPABILITY;
178 *capabilities = private_display->caps_pp.capabilities;
180 _pthread_mutex_unlock(&private_display->lock);
186 tdm_display_get_pp_available_formats(tdm_display *dpy,
187 const tbm_format **formats, int *count)
189 DISPLAY_FUNC_ENTRY();
191 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
192 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
194 _pthread_mutex_lock(&private_display->lock);
196 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
197 TDM_ERR("no pp capability");
198 _pthread_mutex_unlock(&private_display->lock);
199 return TDM_ERROR_NO_CAPABILITY;
202 *formats = (const tbm_format *)private_display->caps_pp.formats;
203 *count = private_display->caps_pp.format_count;
205 _pthread_mutex_unlock(&private_display->lock);
211 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
212 int *max_w, int *max_h, int *preferred_align)
214 DISPLAY_FUNC_ENTRY();
216 _pthread_mutex_lock(&private_display->lock);
218 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
219 TDM_ERR("no pp capability");
220 _pthread_mutex_unlock(&private_display->lock);
221 return TDM_ERROR_NO_CAPABILITY;
225 *min_w = private_display->caps_pp.min_w;
227 *min_h = private_display->caps_pp.min_h;
229 *max_w = private_display->caps_pp.max_w;
231 *max_h = private_display->caps_pp.max_h;
233 *preferred_align = private_display->caps_pp.preferred_align;
235 _pthread_mutex_unlock(&private_display->lock);
241 tdm_display_get_capture_capabilities(tdm_display *dpy,
242 tdm_capture_capability *capabilities)
244 DISPLAY_FUNC_ENTRY();
246 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
248 _pthread_mutex_lock(&private_display->lock);
250 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
251 TDM_ERR("no capture capability");
252 _pthread_mutex_unlock(&private_display->lock);
253 return TDM_ERROR_NO_CAPABILITY;
256 *capabilities = private_display->caps_capture.capabilities;
258 _pthread_mutex_unlock(&private_display->lock);
264 tdm_display_get_catpure_available_formats(tdm_display *dpy,
265 const tbm_format **formats, int *count)
267 DISPLAY_FUNC_ENTRY();
269 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
270 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
272 _pthread_mutex_lock(&private_display->lock);
274 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
275 TDM_ERR("no capture capability");
276 _pthread_mutex_unlock(&private_display->lock);
277 return TDM_ERROR_NO_CAPABILITY;
280 *formats = (const tbm_format *)private_display->caps_capture.formats;
281 *count = private_display->caps_capture.format_count;
283 _pthread_mutex_unlock(&private_display->lock);
289 tdm_display_get_output_count(tdm_display *dpy, int *count)
291 tdm_private_output *private_output = NULL;
293 DISPLAY_FUNC_ENTRY();
295 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
297 _pthread_mutex_lock(&private_display->lock);
300 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
304 _pthread_mutex_unlock(&private_display->lock);
305 return TDM_ERROR_NONE;
308 _pthread_mutex_unlock(&private_display->lock);
315 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
317 tdm_private_output *private_output = NULL;
320 DISPLAY_FUNC_ENTRY_ERROR();
322 _pthread_mutex_lock(&private_display->lock);
325 *error = TDM_ERROR_NONE;
328 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
330 _pthread_mutex_unlock(&private_display->lock);
331 return private_output;
336 _pthread_mutex_unlock(&private_display->lock);
342 tdm_display_get_fd(tdm_display *dpy, int *fd)
344 DISPLAY_FUNC_ENTRY();
346 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
348 _pthread_mutex_lock(&private_display->lock);
350 if (tdm_thread_is_running())
351 *fd = tdm_thread_get_fd(private_display->private_loop);
353 *fd = tdm_event_loop_get_fd(private_display);
355 _pthread_mutex_unlock(&private_display->lock);
361 tdm_display_handle_events(tdm_display *dpy)
366 DISPLAY_FUNC_ENTRY();
368 ret = tdm_display_get_fd(dpy, &fd);
369 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
375 if (tdm_debug_thread)
376 TDM_INFO("fd(%d) polling in", fd);
378 while (poll(&fds, 1, -1) < 0) {
379 if (errno == EBUSY) /* normal case */
382 TDM_ERR("poll failed: %m");
383 return TDM_ERROR_OPERATION_FAILED;
387 if (tdm_debug_thread)
388 TDM_INFO("fd(%d) polling out", fd);
390 if (tdm_thread_is_running())
391 ret = tdm_thread_handle_cb(private_display->private_loop);
393 ret = tdm_event_loop_dispatch(private_display);
399 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
403 DISPLAY_FUNC_ENTRY_ERROR();
405 _pthread_mutex_lock(&private_display->lock);
407 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
409 _pthread_mutex_unlock(&private_display->lock);
415 tdm_output_get_model_info(tdm_output *output, const char **maker,
416 const char **model, const char **name)
420 _pthread_mutex_lock(&private_display->lock);
423 *maker = private_output->caps.maker;
425 *model = private_output->caps.model;
427 *name = private_output->caps.name;
429 _pthread_mutex_unlock(&private_display->lock);
435 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
439 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
441 _pthread_mutex_lock(&private_display->lock);
443 *status = private_output->caps.status;
445 _pthread_mutex_unlock(&private_display->lock);
451 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
454 tdm_private_display *private_display;
455 tdm_private_output *private_output = user_data;
458 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
459 TDM_RETURN_IF_FAIL(private_output);
461 private_display = private_output->private_display;
463 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
464 tdm_thread_cb_output_status output_status;
467 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
468 output_status.base.length = sizeof output_status;
469 output_status.output_stamp = private_output->stamp;
470 output_status.status = status;
471 output_status.user_data = user_data;
474 tdm_output_call_change_handler_internal(private_output,
475 &private_output->change_handler_list_sub,
476 TDM_OUTPUT_CHANGE_CONNECTION,
479 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
480 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
486 tdm_output_call_change_handler_internal(private_output,
487 &private_output->change_handler_list_main,
488 TDM_OUTPUT_CHANGE_CONNECTION,
493 tdm_output_add_change_handler(tdm_output *output,
494 tdm_output_change_handler func,
497 tdm_private_change_handler *change_handler;
500 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
502 pthread_mutex_lock(&private_display->lock);
504 if (!private_output->regist_change_cb) {
505 _pthread_mutex_unlock(&private_display->lock);
506 TDM_ERR("not implemented!!");
507 return TDM_ERROR_NOT_IMPLEMENTED;
510 change_handler = calloc(1, sizeof(tdm_private_change_handler));
511 if (!change_handler) {
512 TDM_ERR("failed: alloc memory");
513 _pthread_mutex_unlock(&private_display->lock);
514 return TDM_ERROR_OUT_OF_MEMORY;
517 change_handler->private_output = private_output;
518 change_handler->func = func;
519 change_handler->user_data = user_data;
520 change_handler->owner_tid = syscall(SYS_gettid);
522 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
523 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
525 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
527 _pthread_mutex_unlock(&private_display->lock);
533 tdm_output_remove_change_handler(tdm_output *output,
534 tdm_output_change_handler func,
537 tdm_private_display *private_display;
538 tdm_private_output *private_output;
539 tdm_private_change_handler *h = NULL, *hh = NULL;
541 TDM_RETURN_IF_FAIL(output != NULL);
542 TDM_RETURN_IF_FAIL(func != NULL);
544 private_output = (tdm_private_output*)output;
545 private_display = private_output->private_display;
547 _pthread_mutex_lock(&private_display->lock);
549 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
550 if (h->func != func || h->user_data != user_data)
556 _pthread_mutex_unlock(&private_display->lock);
561 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
562 if (h->func != func || h->user_data != user_data)
568 _pthread_mutex_unlock(&private_display->lock);
573 _pthread_mutex_unlock(&private_display->lock);
577 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
581 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
583 _pthread_mutex_lock(&private_display->lock);
585 *type = private_output->caps.type;
587 _pthread_mutex_unlock(&private_display->lock);
593 tdm_output_get_layer_count(tdm_output *output, int *count)
595 tdm_private_layer *private_layer = NULL;
599 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
601 _pthread_mutex_lock(&private_display->lock);
604 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
607 _pthread_mutex_unlock(&private_display->lock);
608 return TDM_ERROR_NONE;
611 _pthread_mutex_unlock(&private_display->lock);
618 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
620 tdm_private_layer *private_layer = NULL;
623 OUTPUT_FUNC_ENTRY_ERROR();
625 _pthread_mutex_lock(&private_display->lock);
628 *error = TDM_ERROR_NONE;
630 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
632 _pthread_mutex_unlock(&private_display->lock);
633 return private_layer;
638 _pthread_mutex_unlock(&private_display->lock);
644 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
649 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
650 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
652 _pthread_mutex_lock(&private_display->lock);
654 *props = (const tdm_prop *)private_output->caps.props;
655 *count = private_output->caps.prop_count;
657 _pthread_mutex_unlock(&private_display->lock);
663 tdm_output_get_available_modes(tdm_output *output,
664 const tdm_output_mode **modes, int *count)
668 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
669 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
671 _pthread_mutex_lock(&private_display->lock);
673 *modes = (const tdm_output_mode *)private_output->caps.modes;
674 *count = private_output->caps.mode_count;
676 _pthread_mutex_unlock(&private_display->lock);
682 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
683 int *max_w, int *max_h, int *preferred_align)
687 _pthread_mutex_lock(&private_display->lock);
690 *min_w = private_output->caps.min_w;
692 *min_h = private_output->caps.min_h;
694 *max_w = private_output->caps.max_w;
696 *max_h = private_output->caps.max_h;
698 *preferred_align = private_output->caps.preferred_align;
700 _pthread_mutex_unlock(&private_display->lock);
706 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
707 unsigned int *mmHeight)
711 _pthread_mutex_lock(&private_display->lock);
714 *mmWidth = private_output->caps.mmWidth;
716 *mmHeight = private_output->caps.mmHeight;
718 _pthread_mutex_unlock(&private_display->lock);
724 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
727 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
729 _pthread_mutex_lock(&private_display->lock);
731 *subpixel = private_output->caps.subpixel;
733 _pthread_mutex_unlock(&private_display->lock);
739 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
742 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
744 _pthread_mutex_lock(&private_display->lock);
746 *pipe = private_output->pipe;
748 _pthread_mutex_unlock(&private_display->lock);
755 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
757 tdm_func_output *func_output;
760 _pthread_mutex_lock(&private_display->lock);
762 func_output = &private_display->func_output;
764 if (!func_output->output_set_property) {
765 _pthread_mutex_unlock(&private_display->lock);
766 TDM_ERR("not implemented!!");
767 return TDM_ERROR_NOT_IMPLEMENTED;
770 ret = func_output->output_set_property(private_output->output_backend, id,
773 _pthread_mutex_unlock(&private_display->lock);
779 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
781 tdm_func_output *func_output;
784 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
786 _pthread_mutex_lock(&private_display->lock);
788 func_output = &private_display->func_output;
790 if (!func_output->output_get_property) {
791 _pthread_mutex_unlock(&private_display->lock);
792 TDM_ERR("not implemented!!");
793 return TDM_ERROR_NOT_IMPLEMENTED;
796 ret = func_output->output_get_property(private_output->output_backend, id,
799 _pthread_mutex_unlock(&private_display->lock);
805 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
806 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
808 tdm_private_vblank_handler *vblank_handler = user_data;
809 tdm_private_display *private_display;
811 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
812 TDM_RETURN_IF_FAIL(vblank_handler);
814 private_display = vblank_handler->private_output->private_display;
816 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
817 tdm_thread_cb_output_vblank output_vblank;
820 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
821 output_vblank.base.length = sizeof output_vblank;
822 output_vblank.output_stamp = vblank_handler->private_output->stamp;
823 output_vblank.sequence = sequence;
824 output_vblank.tv_sec = tv_sec;
825 output_vblank.tv_usec = tv_usec;
826 output_vblank.user_data = user_data;
828 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
829 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
834 if (vblank_handler->owner_tid != syscall(SYS_gettid))
835 TDM_NEVER_GET_HERE();
837 if (vblank_handler->func) {
838 _pthread_mutex_unlock(&private_display->lock);
839 vblank_handler->func(vblank_handler->private_output, sequence,
840 tv_sec, tv_usec, vblank_handler->user_data);
841 _pthread_mutex_lock(&private_display->lock);
844 LIST_DEL(&vblank_handler->link);
845 free(vblank_handler);
849 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
850 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
852 tdm_private_commit_handler *commit_handler = user_data;
853 tdm_private_display *private_display;
854 tdm_private_output *private_output;
855 tdm_private_layer *private_layer = NULL;
857 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
858 TDM_RETURN_IF_FAIL(commit_handler);
860 private_output = commit_handler->private_output;
861 private_display = private_output->private_display;
863 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
864 tdm_thread_cb_output_commit output_commit;
867 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
868 output_commit.base.length = sizeof output_commit;
869 output_commit.output_stamp = private_output->stamp;
870 output_commit.sequence = sequence;
871 output_commit.tv_sec = tv_sec;
872 output_commit.tv_usec = tv_usec;
873 output_commit.user_data = user_data;
875 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
876 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
881 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
882 if (!private_layer->waiting_buffer)
885 if (private_layer->showing_buffer) {
886 _pthread_mutex_unlock(&private_display->lock);
887 tdm_buffer_unref_backend(private_layer->showing_buffer);
888 _pthread_mutex_lock(&private_display->lock);
890 if (private_layer->buffer_queue) {
891 tbm_surface_queue_release(private_layer->buffer_queue,
892 private_layer->showing_buffer);
896 private_layer->showing_buffer = private_layer->waiting_buffer;
897 private_layer->waiting_buffer = NULL;
899 if (tdm_debug_buffer)
900 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
901 private_layer, private_layer->waiting_buffer,
902 private_layer->showing_buffer);
905 if (commit_handler->func) {
906 _pthread_mutex_unlock(&private_display->lock);
907 commit_handler->func(private_output, sequence,
908 tv_sec, tv_usec, commit_handler->user_data);
909 _pthread_mutex_lock(&private_display->lock);
912 LIST_DEL(&commit_handler->link);
913 free(commit_handler);
917 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
918 tdm_output_vblank_handler func, void *user_data)
920 tdm_func_output *func_output;
921 tdm_private_vblank_handler *vblank_handler;
924 _pthread_mutex_lock(&private_display->lock);
926 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
927 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
928 dpms_str(private_output->current_dpms_value));
929 _pthread_mutex_unlock(&private_display->lock);
930 return TDM_ERROR_BAD_REQUEST;
933 func_output = &private_display->func_output;
935 if (!func_output->output_wait_vblank) {
936 _pthread_mutex_unlock(&private_display->lock);
937 TDM_ERR("not implemented!!");
938 return TDM_ERROR_NOT_IMPLEMENTED;
941 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
942 if (!vblank_handler) {
943 TDM_ERR("failed: alloc memory");
944 _pthread_mutex_unlock(&private_display->lock);
945 return TDM_ERROR_OUT_OF_MEMORY;
948 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
949 vblank_handler->private_output = private_output;
950 vblank_handler->func = func;
951 vblank_handler->user_data = user_data;
952 vblank_handler->owner_tid = syscall(SYS_gettid);
954 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
955 sync, vblank_handler);
956 if (ret != TDM_ERROR_NONE) {
957 _pthread_mutex_unlock(&private_display->lock);
961 if (!private_output->regist_vblank_cb) {
962 private_output->regist_vblank_cb = 1;
963 ret = func_output->output_set_vblank_handler(private_output->output_backend,
964 tdm_output_cb_vblank);
967 _pthread_mutex_unlock(&private_display->lock);
973 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
976 tdm_func_output *func_output;
977 tdm_private_commit_handler *commit_handler;
980 func_output = &private_display->func_output;
982 if (!func_output->output_commit) {
983 TDM_ERR("not implemented!!");
984 return TDM_ERROR_NOT_IMPLEMENTED;
987 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
988 if (!commit_handler) {
989 TDM_ERR("failed: alloc memory");
990 return TDM_ERROR_OUT_OF_MEMORY;
993 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
994 commit_handler->private_output = private_output;
995 commit_handler->func = func;
996 commit_handler->user_data = user_data;
997 commit_handler->owner_tid = syscall(SYS_gettid);
999 ret = func_output->output_commit(private_output->output_backend, sync,
1001 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1003 if (!private_output->regist_commit_cb) {
1004 private_output->regist_commit_cb = 1;
1005 ret = func_output->output_set_commit_handler(private_output->output_backend,
1006 tdm_output_cb_commit);
1013 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1016 OUTPUT_FUNC_ENTRY();
1018 _pthread_mutex_lock(&private_display->lock);
1020 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1021 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1022 dpms_str(private_output->current_dpms_value));
1023 _pthread_mutex_unlock(&private_display->lock);
1024 return TDM_ERROR_BAD_REQUEST;
1027 ret = _tdm_output_commit(output, sync, func, user_data);
1029 _pthread_mutex_unlock(&private_display->lock);
1035 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1037 tdm_func_output *func_output;
1038 OUTPUT_FUNC_ENTRY();
1040 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1042 _pthread_mutex_lock(&private_display->lock);
1044 func_output = &private_display->func_output;
1046 if (!func_output->output_set_mode) {
1047 _pthread_mutex_unlock(&private_display->lock);
1048 TDM_ERR("not implemented!!");
1049 return TDM_ERROR_NOT_IMPLEMENTED;
1052 ret = func_output->output_set_mode(private_output->output_backend, mode);
1054 _pthread_mutex_unlock(&private_display->lock);
1060 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1062 tdm_func_output *func_output;
1063 OUTPUT_FUNC_ENTRY();
1065 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1067 _pthread_mutex_lock(&private_display->lock);
1069 func_output = &private_display->func_output;
1071 if (!func_output->output_get_mode) {
1072 _pthread_mutex_unlock(&private_display->lock);
1073 TDM_ERR("not implemented!!");
1074 return TDM_ERROR_NOT_IMPLEMENTED;
1077 ret = func_output->output_get_mode(private_output->output_backend, mode);
1079 _pthread_mutex_unlock(&private_display->lock);
1085 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1087 tdm_func_output *func_output;
1088 OUTPUT_FUNC_ENTRY();
1090 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1091 dpms_value = TDM_OUTPUT_DPMS_ON;
1092 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1093 dpms_value = TDM_OUTPUT_DPMS_OFF;
1095 _pthread_mutex_lock(&private_display->lock);
1097 if (private_output->current_dpms_value == dpms_value) {
1098 _pthread_mutex_unlock(&private_display->lock);
1099 return TDM_ERROR_NONE;
1102 func_output = &private_display->func_output;
1104 if (!func_output->output_set_dpms) {
1105 _pthread_mutex_unlock(&private_display->lock);
1106 private_output->current_dpms_value = dpms_value;
1107 TDM_WRN("not implemented!!");
1108 return TDM_ERROR_NONE;
1111 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1112 if (ret == TDM_ERROR_NONE) {
1115 private_output->current_dpms_value = dpms_value;
1117 value.u32 = dpms_value;
1118 tdm_output_call_change_handler_internal(private_output,
1119 &private_output->change_handler_list_main,
1120 TDM_OUTPUT_CHANGE_DPMS,
1124 _pthread_mutex_unlock(&private_display->lock);
1130 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1132 tdm_func_output *func_output;
1133 OUTPUT_FUNC_ENTRY();
1135 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1137 _pthread_mutex_lock(&private_display->lock);
1139 func_output = &private_display->func_output;
1141 if (!func_output->output_get_dpms) {
1142 *dpms_value = private_output->current_dpms_value;
1143 _pthread_mutex_unlock(&private_display->lock);
1144 TDM_WRN("not implemented!!");
1145 return TDM_ERROR_NONE;
1148 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1150 _pthread_mutex_unlock(&private_display->lock);
1155 EXTERN tdm_capture *
1156 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1158 tdm_capture *capture = NULL;
1160 OUTPUT_FUNC_ENTRY_ERROR();
1162 _pthread_mutex_lock(&private_display->lock);
1164 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1167 _pthread_mutex_unlock(&private_display->lock);
1173 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1174 struct list_head *change_handler_list,
1175 tdm_output_change_type type,
1178 tdm_private_display *private_display;
1179 tdm_private_change_handler *change_handler;
1181 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1182 TDM_RETURN_IF_FAIL(private_output);
1184 private_display = private_output->private_display;
1185 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1186 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1187 TDM_INFO("output(%d) changed: %s (%d)",
1188 private_output->pipe, status_str(value.u32), value.u32);
1189 if (type & TDM_OUTPUT_CHANGE_DPMS)
1190 TDM_INFO("output(%d) changed: dpms %s (%d)",
1191 private_output->pipe, dpms_str(value.u32), value.u32);
1194 if (LIST_IS_EMPTY(change_handler_list))
1197 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1198 if (change_handler->owner_tid != syscall(SYS_gettid))
1199 TDM_NEVER_GET_HERE();
1201 _pthread_mutex_unlock(&private_display->lock);
1202 change_handler->func(private_output, type,
1203 value, change_handler->user_data);
1204 _pthread_mutex_lock(&private_display->lock);
1209 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1213 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1215 _pthread_mutex_lock(&private_display->lock);
1217 *capabilities = private_layer->caps.capabilities;
1219 _pthread_mutex_unlock(&private_display->lock);
1225 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1230 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1231 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1233 _pthread_mutex_lock(&private_display->lock);
1235 *formats = (const tbm_format *)private_layer->caps.formats;
1236 *count = private_layer->caps.format_count;
1238 _pthread_mutex_unlock(&private_display->lock);
1244 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1249 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1250 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1252 _pthread_mutex_lock(&private_display->lock);
1254 *props = (const tdm_prop *)private_layer->caps.props;
1255 *count = private_layer->caps.prop_count;
1257 _pthread_mutex_unlock(&private_display->lock);
1263 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1267 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1269 _pthread_mutex_lock(&private_display->lock);
1271 *zpos = private_layer->caps.zpos;
1273 _pthread_mutex_unlock(&private_display->lock);
1279 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1281 tdm_func_layer *func_layer;
1284 _pthread_mutex_lock(&private_display->lock);
1286 func_layer = &private_display->func_layer;
1288 if (!func_layer->layer_set_property) {
1289 _pthread_mutex_unlock(&private_display->lock);
1290 TDM_ERR("not implemented!!");
1291 return TDM_ERROR_NOT_IMPLEMENTED;
1294 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1296 _pthread_mutex_unlock(&private_display->lock);
1302 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1304 tdm_func_layer *func_layer;
1307 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1309 _pthread_mutex_lock(&private_display->lock);
1311 func_layer = &private_display->func_layer;
1313 if (!func_layer->layer_get_property) {
1314 _pthread_mutex_unlock(&private_display->lock);
1315 TDM_ERR("not implemented!!");
1316 return TDM_ERROR_NOT_IMPLEMENTED;
1319 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1321 _pthread_mutex_unlock(&private_display->lock);
1327 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1329 tdm_func_layer *func_layer;
1332 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1334 _pthread_mutex_lock(&private_display->lock);
1336 func_layer = &private_display->func_layer;
1338 private_layer->usable = 0;
1340 if (!func_layer->layer_set_info) {
1341 _pthread_mutex_unlock(&private_display->lock);
1342 TDM_ERR("not implemented!!");
1343 return TDM_ERROR_NOT_IMPLEMENTED;
1346 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1347 private_layer, info->src_config.size.h, info->src_config.size.v,
1348 info->src_config.pos.x, info->src_config.pos.y,
1349 info->src_config.pos.w, info->src_config.pos.h,
1350 FOURCC_STR(info->src_config.format),
1351 info->dst_pos.x, info->dst_pos.y,
1352 info->dst_pos.w, info->dst_pos.h,
1355 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1356 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1358 _pthread_mutex_unlock(&private_display->lock);
1364 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1366 tdm_func_layer *func_layer;
1369 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1371 _pthread_mutex_lock(&private_display->lock);
1373 func_layer = &private_display->func_layer;
1375 if (!func_layer->layer_get_info) {
1376 _pthread_mutex_unlock(&private_display->lock);
1377 TDM_ERR("not implemented!!");
1378 return TDM_ERROR_NOT_IMPLEMENTED;
1381 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1383 _pthread_mutex_unlock(&private_display->lock);
1389 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1391 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1392 tdm_private_output *private_output = private_layer->private_output;
1397 char fullpath[PATH_MAX];
1398 tbm_surface_info_s info;
1399 tbm_surface_error_e err;
1401 path = tdm_helper_get_dump_path();
1405 count = tdm_helper_get_dump_count();
1409 err = tbm_surface_map(buffer, TBM_SURF_OPTION_READ, &info);
1410 TDM_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
1412 pipe = private_output->pipe;
1413 zpos = private_layer->caps.zpos;
1415 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1416 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d.png",
1417 path, count, pipe, zpos);
1419 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d_%dx%d_%c%c%c%c.yuv",
1420 path, count, pipe, zpos, info.planes[0].stride, info.height, FOURCC_STR(info.format));
1422 tbm_surface_unmap(buffer);
1424 tdm_helper_dump_buffer(buffer, fullpath);
1425 TDM_DBG("%d, %s dump excute", count, fullpath);
1431 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1433 tdm_func_layer *func_layer;
1437 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1439 _pthread_mutex_lock(&private_display->lock);
1441 func_layer = &private_display->func_layer;
1443 private_layer->usable = 0;
1445 if (!func_layer->layer_set_buffer) {
1446 _pthread_mutex_unlock(&private_display->lock);
1447 TDM_ERR("not implemented!!");
1448 return TDM_ERROR_NOT_IMPLEMENTED;
1451 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1452 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1455 if (tdm_dump_enable)
1456 _tdm_layer_dump_buffer(layer, buffer);
1458 if (ret == TDM_ERROR_NONE) {
1459 /* FIXME: should save to pending_buffer first. And after committing
1460 * successfully, need to move to waiting_buffer.
1462 if (private_layer->waiting_buffer) {
1463 _pthread_mutex_unlock(&private_display->lock);
1464 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1465 _pthread_mutex_lock(&private_display->lock);
1468 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1469 if (tdm_debug_buffer)
1470 TDM_INFO("layer(%p) waiting_buffer(%p)",
1471 private_layer, private_layer->waiting_buffer);
1474 _pthread_mutex_unlock(&private_display->lock);
1480 tdm_layer_unset_buffer(tdm_layer *layer)
1482 tdm_func_layer *func_layer;
1485 _pthread_mutex_lock(&private_display->lock);
1487 func_layer = &private_display->func_layer;
1489 if (private_layer->waiting_buffer) {
1490 _pthread_mutex_unlock(&private_display->lock);
1491 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1492 _pthread_mutex_lock(&private_display->lock);
1493 private_layer->waiting_buffer = NULL;
1495 if (tdm_debug_buffer)
1496 TDM_INFO("layer(%p) waiting_buffer(%p)",
1497 private_layer, private_layer->waiting_buffer);
1500 if (private_layer->showing_buffer) {
1501 _pthread_mutex_unlock(&private_display->lock);
1502 tdm_buffer_unref_backend(private_layer->showing_buffer);
1503 _pthread_mutex_lock(&private_display->lock);
1504 private_layer->showing_buffer = NULL;
1506 if (tdm_debug_buffer)
1507 TDM_INFO("layer(%p) showing_buffer(%p)",
1508 private_layer, private_layer->showing_buffer);
1511 private_layer->usable = 1;
1513 if (!func_layer->layer_unset_buffer) {
1514 _pthread_mutex_unlock(&private_display->lock);
1515 TDM_ERR("not implemented!!");
1516 return TDM_ERROR_NOT_IMPLEMENTED;
1519 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1520 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1522 _pthread_mutex_unlock(&private_display->lock);
1528 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1530 TDM_RETURN_IF_FAIL(data != NULL);
1531 tdm_layer *layer = data;
1532 tdm_func_layer *func_layer;
1533 tbm_surface_h surface = NULL;
1534 LAYER_FUNC_ENTRY_VOID_RETURN();
1536 _pthread_mutex_lock(&private_display->lock);
1538 func_layer = &private_display->func_layer;
1539 if (!func_layer->layer_set_buffer) {
1540 _pthread_mutex_unlock(&private_display->lock);
1544 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1545 private_layer->buffer_queue, &surface) ||
1547 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1548 private_layer, surface);
1549 _pthread_mutex_unlock(&private_display->lock);
1553 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1554 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1556 if (ret == TDM_ERROR_NONE) {
1557 if (private_layer->waiting_buffer) {
1558 _pthread_mutex_unlock(&private_display->lock);
1559 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1560 tbm_surface_queue_release(private_layer->buffer_queue,
1561 private_layer->waiting_buffer);
1562 _pthread_mutex_lock(&private_display->lock);
1565 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1567 if (tdm_debug_buffer)
1568 TDM_INFO("layer(%p) waiting_buffer(%p)",
1569 private_layer, private_layer->waiting_buffer);
1571 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1572 if (ret != TDM_ERROR_NONE)
1573 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1576 _pthread_mutex_unlock(&private_display->lock);
1580 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1582 TDM_RETURN_IF_FAIL(data != NULL);
1583 tdm_layer *layer = data;
1584 LAYER_FUNC_ENTRY_VOID_RETURN();
1585 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1587 _pthread_mutex_lock(&private_display->lock);
1589 if (private_layer->waiting_buffer) {
1590 _pthread_mutex_unlock(&private_display->lock);
1591 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1592 tbm_surface_queue_release(private_layer->buffer_queue,
1593 private_layer->waiting_buffer);
1594 _pthread_mutex_lock(&private_display->lock);
1597 private_layer->buffer_queue = NULL;
1599 _pthread_mutex_unlock(&private_display->lock);
1603 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1605 tdm_func_layer *func_layer;
1608 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1610 _pthread_mutex_lock(&private_display->lock);
1612 func_layer = &private_display->func_layer;
1614 private_layer->usable = 0;
1616 if (!func_layer->layer_set_buffer) {
1617 _pthread_mutex_unlock(&private_display->lock);
1618 TDM_ERR("not implemented!!");
1619 return TDM_ERROR_NOT_IMPLEMENTED;
1622 if (buffer_queue == private_layer->buffer_queue) {
1623 _pthread_mutex_unlock(&private_display->lock);
1624 return TDM_ERROR_NONE;
1627 if (private_layer->waiting_buffer) {
1628 _pthread_mutex_unlock(&private_display->lock);
1629 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1630 tbm_surface_queue_release(private_layer->buffer_queue,
1631 private_layer->waiting_buffer);
1632 private_layer->waiting_buffer = NULL;
1633 _pthread_mutex_lock(&private_display->lock);
1635 if (tdm_debug_buffer)
1636 TDM_INFO("layer(%p) waiting_buffer(%p)",
1637 private_layer, private_layer->waiting_buffer);
1640 private_layer->buffer_queue = buffer_queue;
1641 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1642 _tbm_layer_queue_acquirable_cb,
1644 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1645 _tbm_layer_queue_destroy_cb,
1647 _pthread_mutex_unlock(&private_display->lock);
1653 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1655 tdm_func_layer *func_layer;
1658 _pthread_mutex_lock(&private_display->lock);
1660 func_layer = &private_display->func_layer;
1662 if (private_layer->waiting_buffer) {
1663 _pthread_mutex_unlock(&private_display->lock);
1664 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1665 tbm_surface_queue_release(private_layer->buffer_queue,
1666 private_layer->waiting_buffer);
1667 private_layer->waiting_buffer = NULL;
1668 _pthread_mutex_lock(&private_display->lock);
1670 if (tdm_debug_buffer)
1671 TDM_INFO("layer(%p) waiting_buffer(%p)",
1672 private_layer, private_layer->waiting_buffer);
1675 if (private_layer->showing_buffer) {
1676 _pthread_mutex_unlock(&private_display->lock);
1677 tdm_buffer_unref_backend(private_layer->showing_buffer);
1678 tbm_surface_queue_release(private_layer->buffer_queue,
1679 private_layer->showing_buffer);
1680 _pthread_mutex_lock(&private_display->lock);
1681 private_layer->showing_buffer = NULL;
1683 if (tdm_debug_buffer)
1684 TDM_INFO("layer(%p) showing_buffer(%p)",
1685 private_layer, private_layer->showing_buffer);
1688 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1689 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1690 private_layer->buffer_queue = NULL;
1691 private_layer->usable = 1;
1693 if (!func_layer->layer_unset_buffer) {
1694 _pthread_mutex_unlock(&private_display->lock);
1695 TDM_ERR("not implemented!!");
1696 return TDM_ERROR_NOT_IMPLEMENTED;
1699 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1701 _pthread_mutex_unlock(&private_display->lock);
1707 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1711 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1713 _pthread_mutex_lock(&private_display->lock);
1715 *usable = private_layer->usable;
1717 _pthread_mutex_unlock(&private_display->lock);
1723 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1725 tdm_func_layer *func_layer;
1728 _pthread_mutex_lock(&private_display->lock);
1730 func_layer = &private_display->func_layer;
1732 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1733 TDM_ERR("layer(%p) is not video layer", private_layer);
1734 _pthread_mutex_unlock(&private_display->lock);
1735 return TDM_ERROR_INVALID_PARAMETER;
1738 if (!func_layer->layer_set_video_pos) {
1739 _pthread_mutex_unlock(&private_display->lock);
1740 TDM_ERR("not implemented!!");
1741 return TDM_ERROR_NOT_IMPLEMENTED;
1744 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1746 _pthread_mutex_unlock(&private_display->lock);
1751 EXTERN tdm_capture *
1752 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1754 tdm_capture *capture = NULL;
1756 LAYER_FUNC_ENTRY_ERROR();
1758 _pthread_mutex_lock(&private_display->lock);
1760 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1763 _pthread_mutex_unlock(&private_display->lock);