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_display_get_capabilities(tdm_display *dpy,
141 tdm_display_capability *capabilities)
143 DISPLAY_FUNC_ENTRY();
145 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
147 _pthread_mutex_lock(&private_display->lock);
149 *capabilities = private_display->capabilities;
151 _pthread_mutex_unlock(&private_display->lock);
157 tdm_display_get_pp_capabilities(tdm_display *dpy,
158 tdm_pp_capability *capabilities)
160 DISPLAY_FUNC_ENTRY();
162 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
164 _pthread_mutex_lock(&private_display->lock);
166 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
167 TDM_ERR("no pp capability");
168 _pthread_mutex_unlock(&private_display->lock);
169 return TDM_ERROR_NO_CAPABILITY;
172 *capabilities = private_display->caps_pp.capabilities;
174 _pthread_mutex_unlock(&private_display->lock);
180 tdm_display_get_pp_available_formats(tdm_display *dpy,
181 const tbm_format **formats, int *count)
183 DISPLAY_FUNC_ENTRY();
185 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
186 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
188 _pthread_mutex_lock(&private_display->lock);
190 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
191 TDM_ERR("no pp capability");
192 _pthread_mutex_unlock(&private_display->lock);
193 return TDM_ERROR_NO_CAPABILITY;
196 *formats = (const tbm_format *)private_display->caps_pp.formats;
197 *count = private_display->caps_pp.format_count;
199 _pthread_mutex_unlock(&private_display->lock);
205 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
206 int *max_w, int *max_h, int *preferred_align)
208 DISPLAY_FUNC_ENTRY();
210 _pthread_mutex_lock(&private_display->lock);
212 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
213 TDM_ERR("no pp capability");
214 _pthread_mutex_unlock(&private_display->lock);
215 return TDM_ERROR_NO_CAPABILITY;
219 *min_w = private_display->caps_pp.min_w;
221 *min_h = private_display->caps_pp.min_h;
223 *max_w = private_display->caps_pp.max_w;
225 *max_h = private_display->caps_pp.max_h;
227 *preferred_align = private_display->caps_pp.preferred_align;
229 _pthread_mutex_unlock(&private_display->lock);
235 tdm_display_get_capture_capabilities(tdm_display *dpy,
236 tdm_capture_capability *capabilities)
238 DISPLAY_FUNC_ENTRY();
240 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
242 _pthread_mutex_lock(&private_display->lock);
244 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
245 TDM_ERR("no capture capability");
246 _pthread_mutex_unlock(&private_display->lock);
247 return TDM_ERROR_NO_CAPABILITY;
250 *capabilities = private_display->caps_capture.capabilities;
252 _pthread_mutex_unlock(&private_display->lock);
258 tdm_display_get_catpure_available_formats(tdm_display *dpy,
259 const tbm_format **formats, int *count)
261 DISPLAY_FUNC_ENTRY();
263 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
264 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
266 _pthread_mutex_lock(&private_display->lock);
268 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
269 TDM_ERR("no capture capability");
270 _pthread_mutex_unlock(&private_display->lock);
271 return TDM_ERROR_NO_CAPABILITY;
274 *formats = (const tbm_format *)private_display->caps_capture.formats;
275 *count = private_display->caps_capture.format_count;
277 _pthread_mutex_unlock(&private_display->lock);
283 tdm_display_get_output_count(tdm_display *dpy, int *count)
285 tdm_private_output *private_output = NULL;
287 DISPLAY_FUNC_ENTRY();
289 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
291 _pthread_mutex_lock(&private_display->lock);
294 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
298 _pthread_mutex_unlock(&private_display->lock);
299 return TDM_ERROR_NONE;
302 _pthread_mutex_unlock(&private_display->lock);
309 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
311 tdm_private_output *private_output = NULL;
314 DISPLAY_FUNC_ENTRY_ERROR();
316 _pthread_mutex_lock(&private_display->lock);
319 *error = TDM_ERROR_NONE;
322 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
324 _pthread_mutex_unlock(&private_display->lock);
325 return private_output;
330 _pthread_mutex_unlock(&private_display->lock);
336 tdm_display_get_fd(tdm_display *dpy, int *fd)
338 DISPLAY_FUNC_ENTRY();
340 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
342 _pthread_mutex_lock(&private_display->lock);
344 if (tdm_thread_is_running())
345 *fd = tdm_thread_get_fd(private_display->private_loop);
347 *fd = tdm_event_loop_get_fd(private_display);
349 _pthread_mutex_unlock(&private_display->lock);
355 tdm_display_handle_events(tdm_display *dpy)
360 DISPLAY_FUNC_ENTRY();
362 ret = tdm_display_get_fd(dpy, &fd);
363 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
369 if (tdm_debug_thread)
370 TDM_INFO("fd(%d) polling in", fd);
372 while (poll(&fds, 1, -1) < 0) {
373 if (errno == EBUSY) /* normal case */
376 TDM_ERR("poll failed: %m");
377 return TDM_ERROR_OPERATION_FAILED;
381 if (tdm_debug_thread)
382 TDM_INFO("fd(%d) polling out", fd);
384 if (tdm_thread_is_running())
385 ret = tdm_thread_handle_cb(private_display->private_loop);
387 ret = tdm_event_loop_dispatch(private_display);
393 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
397 DISPLAY_FUNC_ENTRY_ERROR();
399 _pthread_mutex_lock(&private_display->lock);
401 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
403 _pthread_mutex_unlock(&private_display->lock);
409 tdm_output_get_model_info(tdm_output *output, const char **maker,
410 const char **model, const char **name)
414 _pthread_mutex_lock(&private_display->lock);
417 *maker = private_output->caps.maker;
419 *model = private_output->caps.model;
421 *name = private_output->caps.name;
423 _pthread_mutex_unlock(&private_display->lock);
429 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
433 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
435 _pthread_mutex_lock(&private_display->lock);
437 *status = private_output->caps.status;
439 _pthread_mutex_unlock(&private_display->lock);
445 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
448 tdm_private_display *private_display;
449 tdm_private_output *private_output = user_data;
452 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
453 TDM_RETURN_IF_FAIL(private_output);
455 private_display = private_output->private_display;
457 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
458 tdm_thread_cb_output_status output_status;
461 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
462 output_status.base.length = sizeof output_status;
463 output_status.output_stamp = private_output->stamp;
464 output_status.status = status;
465 output_status.user_data = user_data;
468 tdm_output_call_change_handler_internal(private_output,
469 &private_output->change_handler_list_sub,
470 TDM_OUTPUT_CHANGE_CONNECTION,
473 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
474 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
480 tdm_output_call_change_handler_internal(private_output,
481 &private_output->change_handler_list_main,
482 TDM_OUTPUT_CHANGE_CONNECTION,
487 tdm_output_add_change_handler(tdm_output *output,
488 tdm_output_change_handler func,
491 tdm_private_change_handler *change_handler;
494 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
496 pthread_mutex_lock(&private_display->lock);
498 if (!private_output->regist_change_cb) {
499 _pthread_mutex_unlock(&private_display->lock);
500 TDM_DBG("failed: not implemented!!");
501 return TDM_ERROR_NOT_IMPLEMENTED;
504 change_handler = calloc(1, sizeof(tdm_private_change_handler));
505 if (!change_handler) {
506 TDM_ERR("failed: alloc memory");
507 _pthread_mutex_unlock(&private_display->lock);
508 return TDM_ERROR_OUT_OF_MEMORY;
511 change_handler->private_output = private_output;
512 change_handler->func = func;
513 change_handler->user_data = user_data;
514 change_handler->owner_tid = syscall(SYS_gettid);
516 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
517 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
519 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
521 _pthread_mutex_unlock(&private_display->lock);
527 tdm_output_remove_change_handler(tdm_output *output,
528 tdm_output_change_handler func,
531 tdm_private_display *private_display;
532 tdm_private_output *private_output;
533 tdm_private_change_handler *h = NULL, *hh = NULL;
535 TDM_RETURN_IF_FAIL(output != NULL);
536 TDM_RETURN_IF_FAIL(func != NULL);
538 private_output = (tdm_private_output*)output;
539 private_display = private_output->private_display;
541 _pthread_mutex_lock(&private_display->lock);
543 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
544 if (h->func != func || h->user_data != user_data)
550 _pthread_mutex_unlock(&private_display->lock);
555 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
556 if (h->func != func || h->user_data != user_data)
562 _pthread_mutex_unlock(&private_display->lock);
567 _pthread_mutex_unlock(&private_display->lock);
571 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
575 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
577 _pthread_mutex_lock(&private_display->lock);
579 *type = private_output->caps.type;
581 _pthread_mutex_unlock(&private_display->lock);
587 tdm_output_get_layer_count(tdm_output *output, int *count)
589 tdm_private_layer *private_layer = NULL;
593 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
595 _pthread_mutex_lock(&private_display->lock);
598 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
601 _pthread_mutex_unlock(&private_display->lock);
602 return TDM_ERROR_NONE;
605 _pthread_mutex_unlock(&private_display->lock);
612 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
614 tdm_private_layer *private_layer = NULL;
617 OUTPUT_FUNC_ENTRY_ERROR();
619 _pthread_mutex_lock(&private_display->lock);
622 *error = TDM_ERROR_NONE;
624 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
626 _pthread_mutex_unlock(&private_display->lock);
627 return private_layer;
632 _pthread_mutex_unlock(&private_display->lock);
638 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
643 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
644 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
646 _pthread_mutex_lock(&private_display->lock);
648 *props = (const tdm_prop *)private_output->caps.props;
649 *count = private_output->caps.prop_count;
651 _pthread_mutex_unlock(&private_display->lock);
657 tdm_output_get_available_modes(tdm_output *output,
658 const tdm_output_mode **modes, int *count)
662 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
663 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
665 _pthread_mutex_lock(&private_display->lock);
667 *modes = (const tdm_output_mode *)private_output->caps.modes;
668 *count = private_output->caps.mode_count;
670 _pthread_mutex_unlock(&private_display->lock);
676 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
677 int *max_w, int *max_h, int *preferred_align)
681 _pthread_mutex_lock(&private_display->lock);
684 *min_w = private_output->caps.min_w;
686 *min_h = private_output->caps.min_h;
688 *max_w = private_output->caps.max_w;
690 *max_h = private_output->caps.max_h;
692 *preferred_align = private_output->caps.preferred_align;
694 _pthread_mutex_unlock(&private_display->lock);
700 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
701 unsigned int *mmHeight)
705 _pthread_mutex_lock(&private_display->lock);
708 *mmWidth = private_output->caps.mmWidth;
710 *mmHeight = private_output->caps.mmHeight;
712 _pthread_mutex_unlock(&private_display->lock);
718 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
721 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
723 _pthread_mutex_lock(&private_display->lock);
725 *subpixel = private_output->caps.subpixel;
727 _pthread_mutex_unlock(&private_display->lock);
733 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
736 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
738 _pthread_mutex_lock(&private_display->lock);
740 *pipe = private_output->pipe;
742 _pthread_mutex_unlock(&private_display->lock);
749 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
751 tdm_func_output *func_output;
754 _pthread_mutex_lock(&private_display->lock);
756 func_output = &private_display->func_output;
758 if (!func_output->output_set_property) {
759 _pthread_mutex_unlock(&private_display->lock);
760 TDM_DBG("failed: not implemented!!");
761 return TDM_ERROR_NOT_IMPLEMENTED;
764 ret = func_output->output_set_property(private_output->output_backend, id,
767 _pthread_mutex_unlock(&private_display->lock);
773 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
775 tdm_func_output *func_output;
778 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
780 _pthread_mutex_lock(&private_display->lock);
782 func_output = &private_display->func_output;
784 if (!func_output->output_get_property) {
785 _pthread_mutex_unlock(&private_display->lock);
786 TDM_DBG("failed: not implemented!!");
787 return TDM_ERROR_NOT_IMPLEMENTED;
790 ret = func_output->output_get_property(private_output->output_backend, id,
793 _pthread_mutex_unlock(&private_display->lock);
799 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
800 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
802 tdm_private_vblank_handler *vblank_handler = user_data;
803 tdm_private_display *private_display;
805 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
806 TDM_RETURN_IF_FAIL(vblank_handler);
808 private_display = vblank_handler->private_output->private_display;
810 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
811 tdm_thread_cb_output_vblank output_vblank;
814 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
815 output_vblank.base.length = sizeof output_vblank;
816 output_vblank.output_stamp = vblank_handler->private_output->stamp;
817 output_vblank.sequence = sequence;
818 output_vblank.tv_sec = tv_sec;
819 output_vblank.tv_usec = tv_usec;
820 output_vblank.user_data = user_data;
822 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
823 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
828 if (vblank_handler->owner_tid != syscall(SYS_gettid))
829 TDM_NEVER_GET_HERE();
831 if (vblank_handler->func) {
832 _pthread_mutex_unlock(&private_display->lock);
833 vblank_handler->func(vblank_handler->private_output, sequence,
834 tv_sec, tv_usec, vblank_handler->user_data);
835 _pthread_mutex_lock(&private_display->lock);
838 LIST_DEL(&vblank_handler->link);
839 free(vblank_handler);
843 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
844 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
846 tdm_private_commit_handler *commit_handler = user_data;
847 tdm_private_display *private_display;
848 tdm_private_output *private_output;
849 tdm_private_layer *private_layer = NULL;
851 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
852 TDM_RETURN_IF_FAIL(commit_handler);
854 private_output = commit_handler->private_output;
855 private_display = private_output->private_display;
857 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
858 tdm_thread_cb_output_commit output_commit;
861 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
862 output_commit.base.length = sizeof output_commit;
863 output_commit.output_stamp = private_output->stamp;
864 output_commit.sequence = sequence;
865 output_commit.tv_sec = tv_sec;
866 output_commit.tv_usec = tv_usec;
867 output_commit.user_data = user_data;
869 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
870 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
875 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
876 if (!private_layer->waiting_buffer)
879 if (private_layer->showing_buffer) {
880 _pthread_mutex_unlock(&private_display->lock);
881 tdm_buffer_unref_backend(private_layer->showing_buffer);
882 _pthread_mutex_lock(&private_display->lock);
884 if (private_layer->buffer_queue) {
885 tbm_surface_queue_release(private_layer->buffer_queue,
886 private_layer->showing_buffer);
890 private_layer->showing_buffer = private_layer->waiting_buffer;
891 private_layer->waiting_buffer = NULL;
893 if (tdm_debug_buffer)
894 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
895 private_layer, private_layer->waiting_buffer,
896 private_layer->showing_buffer);
899 if (commit_handler->func) {
900 _pthread_mutex_unlock(&private_display->lock);
901 commit_handler->func(private_output, sequence,
902 tv_sec, tv_usec, commit_handler->user_data);
903 _pthread_mutex_lock(&private_display->lock);
906 LIST_DEL(&commit_handler->link);
907 free(commit_handler);
911 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
912 tdm_output_vblank_handler func, void *user_data)
914 tdm_func_output *func_output;
915 tdm_private_vblank_handler *vblank_handler;
918 _pthread_mutex_lock(&private_display->lock);
920 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
921 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
922 dpms_str(private_output->current_dpms_value));
923 _pthread_mutex_unlock(&private_display->lock);
924 return TDM_ERROR_BAD_REQUEST;
927 func_output = &private_display->func_output;
929 if (!func_output->output_wait_vblank) {
930 _pthread_mutex_unlock(&private_display->lock);
931 TDM_DBG("failed: not implemented!!");
932 return TDM_ERROR_NOT_IMPLEMENTED;
935 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
936 if (!vblank_handler) {
937 TDM_ERR("failed: alloc memory");
938 _pthread_mutex_unlock(&private_display->lock);
939 return TDM_ERROR_OUT_OF_MEMORY;
942 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
943 vblank_handler->private_output = private_output;
944 vblank_handler->func = func;
945 vblank_handler->user_data = user_data;
946 vblank_handler->owner_tid = syscall(SYS_gettid);
948 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
949 sync, vblank_handler);
950 if (ret != TDM_ERROR_NONE) {
951 _pthread_mutex_unlock(&private_display->lock);
955 if (!private_output->regist_vblank_cb) {
956 private_output->regist_vblank_cb = 1;
957 ret = func_output->output_set_vblank_handler(private_output->output_backend,
958 tdm_output_cb_vblank);
961 _pthread_mutex_unlock(&private_display->lock);
967 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
970 tdm_func_output *func_output;
971 tdm_private_commit_handler *commit_handler;
974 func_output = &private_display->func_output;
976 if (!func_output->output_commit) {
977 TDM_DBG("failed: not implemented!!");
978 return TDM_ERROR_NOT_IMPLEMENTED;
981 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
982 if (!commit_handler) {
983 TDM_ERR("failed: alloc memory");
984 return TDM_ERROR_OUT_OF_MEMORY;
987 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
988 commit_handler->private_output = private_output;
989 commit_handler->func = func;
990 commit_handler->user_data = user_data;
991 commit_handler->owner_tid = syscall(SYS_gettid);
993 ret = func_output->output_commit(private_output->output_backend, sync,
995 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
997 if (!private_output->regist_commit_cb) {
998 private_output->regist_commit_cb = 1;
999 ret = func_output->output_set_commit_handler(private_output->output_backend,
1000 tdm_output_cb_commit);
1007 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1010 OUTPUT_FUNC_ENTRY();
1012 _pthread_mutex_lock(&private_display->lock);
1014 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1015 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
1016 dpms_str(private_output->current_dpms_value));
1017 _pthread_mutex_unlock(&private_display->lock);
1018 return TDM_ERROR_BAD_REQUEST;
1021 ret = _tdm_output_commit(output, sync, func, user_data);
1023 _pthread_mutex_unlock(&private_display->lock);
1029 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1031 tdm_func_output *func_output;
1032 OUTPUT_FUNC_ENTRY();
1034 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1036 _pthread_mutex_lock(&private_display->lock);
1038 func_output = &private_display->func_output;
1040 if (!func_output->output_set_mode) {
1041 _pthread_mutex_unlock(&private_display->lock);
1042 TDM_DBG("failed: not implemented!!");
1043 return TDM_ERROR_NOT_IMPLEMENTED;
1046 ret = func_output->output_set_mode(private_output->output_backend, mode);
1048 _pthread_mutex_unlock(&private_display->lock);
1054 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1056 tdm_func_output *func_output;
1057 OUTPUT_FUNC_ENTRY();
1059 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1061 _pthread_mutex_lock(&private_display->lock);
1063 func_output = &private_display->func_output;
1065 if (!func_output->output_get_mode) {
1066 _pthread_mutex_unlock(&private_display->lock);
1067 TDM_DBG("failed: not implemented!!");
1068 return TDM_ERROR_NOT_IMPLEMENTED;
1071 ret = func_output->output_get_mode(private_output->output_backend, mode);
1073 _pthread_mutex_unlock(&private_display->lock);
1079 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1081 tdm_func_output *func_output;
1082 OUTPUT_FUNC_ENTRY();
1084 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1085 dpms_value = TDM_OUTPUT_DPMS_ON;
1086 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1087 dpms_value = TDM_OUTPUT_DPMS_OFF;
1089 _pthread_mutex_lock(&private_display->lock);
1091 if (private_output->current_dpms_value == dpms_value) {
1092 _pthread_mutex_unlock(&private_display->lock);
1093 return TDM_ERROR_NONE;
1096 func_output = &private_display->func_output;
1098 if (!func_output->output_set_dpms) {
1099 _pthread_mutex_unlock(&private_display->lock);
1100 TDM_DBG("failed: not implemented!!");
1101 return TDM_ERROR_NOT_IMPLEMENTED;
1104 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1105 if (ret == TDM_ERROR_NONE) {
1108 private_output->current_dpms_value = dpms_value;
1110 value.u32 = dpms_value;
1111 tdm_output_call_change_handler_internal(private_output,
1112 &private_output->change_handler_list_main,
1113 TDM_OUTPUT_CHANGE_DPMS,
1117 _pthread_mutex_unlock(&private_display->lock);
1123 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1125 tdm_func_output *func_output;
1126 OUTPUT_FUNC_ENTRY();
1128 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1130 _pthread_mutex_lock(&private_display->lock);
1132 func_output = &private_display->func_output;
1134 if (!func_output->output_get_dpms) {
1135 _pthread_mutex_unlock(&private_display->lock);
1136 TDM_DBG("failed: not implemented!!");
1137 return TDM_ERROR_NOT_IMPLEMENTED;
1140 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1142 _pthread_mutex_unlock(&private_display->lock);
1147 EXTERN tdm_capture *
1148 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1150 tdm_capture *capture = NULL;
1152 OUTPUT_FUNC_ENTRY_ERROR();
1154 _pthread_mutex_lock(&private_display->lock);
1156 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1159 _pthread_mutex_unlock(&private_display->lock);
1165 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1166 struct list_head *change_handler_list,
1167 tdm_output_change_type type,
1170 tdm_private_display *private_display;
1171 tdm_private_change_handler *change_handler;
1173 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1174 TDM_RETURN_IF_FAIL(private_output);
1176 private_display = private_output->private_display;
1177 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1178 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1179 TDM_INFO("output(%d) changed: %s (%d)",
1180 private_output->pipe, status_str(value.u32), value.u32);
1181 if (type & TDM_OUTPUT_CHANGE_DPMS)
1182 TDM_INFO("output(%d) changed: dpms %s (%d)",
1183 private_output->pipe, dpms_str(value.u32), value.u32);
1186 if (LIST_IS_EMPTY(change_handler_list))
1189 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1190 if (change_handler->owner_tid != syscall(SYS_gettid))
1191 TDM_NEVER_GET_HERE();
1193 _pthread_mutex_unlock(&private_display->lock);
1194 change_handler->func(private_output, type,
1195 value, change_handler->user_data);
1196 _pthread_mutex_lock(&private_display->lock);
1201 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1205 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1207 _pthread_mutex_lock(&private_display->lock);
1209 *capabilities = private_layer->caps.capabilities;
1211 _pthread_mutex_unlock(&private_display->lock);
1217 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1222 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1223 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1225 _pthread_mutex_lock(&private_display->lock);
1227 *formats = (const tbm_format *)private_layer->caps.formats;
1228 *count = private_layer->caps.format_count;
1230 _pthread_mutex_unlock(&private_display->lock);
1236 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1241 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1242 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1244 _pthread_mutex_lock(&private_display->lock);
1246 *props = (const tdm_prop *)private_layer->caps.props;
1247 *count = private_layer->caps.prop_count;
1249 _pthread_mutex_unlock(&private_display->lock);
1255 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1259 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1261 _pthread_mutex_lock(&private_display->lock);
1263 *zpos = private_layer->caps.zpos;
1265 _pthread_mutex_unlock(&private_display->lock);
1271 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1273 tdm_func_layer *func_layer;
1276 _pthread_mutex_lock(&private_display->lock);
1278 func_layer = &private_display->func_layer;
1280 if (!func_layer->layer_set_property) {
1281 _pthread_mutex_unlock(&private_display->lock);
1282 TDM_DBG("failed: not implemented!!");
1283 return TDM_ERROR_NOT_IMPLEMENTED;
1286 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1288 _pthread_mutex_unlock(&private_display->lock);
1294 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1296 tdm_func_layer *func_layer;
1299 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1301 _pthread_mutex_lock(&private_display->lock);
1303 func_layer = &private_display->func_layer;
1305 if (!func_layer->layer_get_property) {
1306 _pthread_mutex_unlock(&private_display->lock);
1307 TDM_DBG("failed: not implemented!!");
1308 return TDM_ERROR_NOT_IMPLEMENTED;
1311 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1313 _pthread_mutex_unlock(&private_display->lock);
1319 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1321 tdm_func_layer *func_layer;
1324 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1326 _pthread_mutex_lock(&private_display->lock);
1328 func_layer = &private_display->func_layer;
1330 private_layer->usable = 0;
1332 if (!func_layer->layer_set_info) {
1333 _pthread_mutex_unlock(&private_display->lock);
1334 TDM_DBG("failed: not implemented!!");
1335 return TDM_ERROR_NOT_IMPLEMENTED;
1338 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1339 private_layer, info->src_config.size.h, info->src_config.size.v,
1340 info->src_config.pos.x, info->src_config.pos.y,
1341 info->src_config.pos.w, info->src_config.pos.h,
1342 FOURCC_STR(info->src_config.format),
1343 info->dst_pos.x, info->dst_pos.y,
1344 info->dst_pos.w, info->dst_pos.h,
1347 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1348 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1350 _pthread_mutex_unlock(&private_display->lock);
1356 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1358 tdm_func_layer *func_layer;
1361 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1363 _pthread_mutex_lock(&private_display->lock);
1365 func_layer = &private_display->func_layer;
1367 if (!func_layer->layer_get_info) {
1368 _pthread_mutex_unlock(&private_display->lock);
1369 TDM_DBG("failed: not implemented!!");
1370 return TDM_ERROR_NOT_IMPLEMENTED;
1373 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1375 _pthread_mutex_unlock(&private_display->lock);
1381 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1383 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1384 tdm_private_output *private_output = private_layer->private_output;
1389 tbm_surface_info_s info;
1390 tbm_surface_error_e err;
1392 path = tdm_helper_get_dump_path();
1393 TDM_RETURN_IF_FAIL(path != NULL);
1395 count = tdm_helper_get_dump_count();
1396 TDM_RETURN_IF_FAIL(count != 0);
1398 err = tbm_surface_map(buffer, TBM_SURF_OPTION_READ, &info);
1399 TDM_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
1401 char fullpath[PATH_MAX] = {0, };
1403 pipe = private_output->pipe;
1404 zpos = private_layer->caps.zpos;
1406 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1407 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d.png",
1408 path, count, pipe, zpos);
1410 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d_%dx%d_%c%c%c%c.yuv",
1411 path, count, pipe, zpos, info.planes[0].stride, info.height, FOURCC_STR(info.format));
1413 tbm_surface_unmap(buffer);
1415 tdm_helper_dump_buffer(buffer, fullpath);
1416 TDM_DBG("%d, %s dump excute", count, fullpath);
1422 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1424 tdm_func_layer *func_layer;
1428 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1430 _pthread_mutex_lock(&private_display->lock);
1432 func_layer = &private_display->func_layer;
1434 private_layer->usable = 0;
1436 if (!func_layer->layer_set_buffer) {
1437 _pthread_mutex_unlock(&private_display->lock);
1438 TDM_DBG("failed: not implemented!!");
1439 return TDM_ERROR_NOT_IMPLEMENTED;
1442 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1443 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1446 _tdm_layer_dump_buffer(layer, buffer);
1448 if (ret == TDM_ERROR_NONE) {
1449 /* FIXME: should save to pending_buffer first. And after committing
1450 * successfully, need to move to waiting_buffer.
1452 if (private_layer->waiting_buffer) {
1453 _pthread_mutex_unlock(&private_display->lock);
1454 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1455 _pthread_mutex_lock(&private_display->lock);
1458 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1459 if (tdm_debug_buffer)
1460 TDM_INFO("layer(%p) waiting_buffer(%p)",
1461 private_layer, private_layer->waiting_buffer);
1464 _pthread_mutex_unlock(&private_display->lock);
1470 tdm_layer_unset_buffer(tdm_layer *layer)
1472 tdm_func_layer *func_layer;
1475 _pthread_mutex_lock(&private_display->lock);
1477 func_layer = &private_display->func_layer;
1479 if (private_layer->waiting_buffer) {
1480 _pthread_mutex_unlock(&private_display->lock);
1481 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1482 _pthread_mutex_lock(&private_display->lock);
1483 private_layer->waiting_buffer = NULL;
1485 if (tdm_debug_buffer)
1486 TDM_INFO("layer(%p) waiting_buffer(%p)",
1487 private_layer, private_layer->waiting_buffer);
1490 if (private_layer->showing_buffer) {
1491 _pthread_mutex_unlock(&private_display->lock);
1492 tdm_buffer_unref_backend(private_layer->showing_buffer);
1493 _pthread_mutex_lock(&private_display->lock);
1494 private_layer->showing_buffer = NULL;
1496 if (tdm_debug_buffer)
1497 TDM_INFO("layer(%p) showing_buffer(%p)",
1498 private_layer, private_layer->showing_buffer);
1501 private_layer->usable = 1;
1503 if (!func_layer->layer_unset_buffer) {
1504 _pthread_mutex_unlock(&private_display->lock);
1505 TDM_DBG("failed: not implemented!!");
1506 return TDM_ERROR_NOT_IMPLEMENTED;
1509 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1510 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1512 _pthread_mutex_unlock(&private_display->lock);
1518 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1520 TDM_RETURN_IF_FAIL(data != NULL);
1521 tdm_layer *layer = data;
1522 tdm_func_layer *func_layer;
1523 tbm_surface_h surface = NULL;
1524 LAYER_FUNC_ENTRY_VOID_RETURN();
1526 _pthread_mutex_lock(&private_display->lock);
1528 func_layer = &private_display->func_layer;
1529 if (!func_layer->layer_set_buffer) {
1530 _pthread_mutex_unlock(&private_display->lock);
1534 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1535 private_layer->buffer_queue, &surface) ||
1537 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1538 private_layer, surface);
1539 _pthread_mutex_unlock(&private_display->lock);
1543 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1544 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1546 if (ret == TDM_ERROR_NONE) {
1547 if (private_layer->waiting_buffer) {
1548 _pthread_mutex_unlock(&private_display->lock);
1549 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1550 tbm_surface_queue_release(private_layer->buffer_queue,
1551 private_layer->waiting_buffer);
1552 _pthread_mutex_lock(&private_display->lock);
1555 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1557 if (tdm_debug_buffer)
1558 TDM_INFO("layer(%p) waiting_buffer(%p)",
1559 private_layer, private_layer->waiting_buffer);
1561 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1562 if (ret != TDM_ERROR_NONE)
1563 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1566 _pthread_mutex_unlock(&private_display->lock);
1570 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1572 TDM_RETURN_IF_FAIL(data != NULL);
1573 tdm_layer *layer = data;
1574 LAYER_FUNC_ENTRY_VOID_RETURN();
1575 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1577 _pthread_mutex_lock(&private_display->lock);
1579 if (private_layer->waiting_buffer) {
1580 _pthread_mutex_unlock(&private_display->lock);
1581 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1582 tbm_surface_queue_release(private_layer->buffer_queue,
1583 private_layer->waiting_buffer);
1584 _pthread_mutex_lock(&private_display->lock);
1587 private_layer->buffer_queue = NULL;
1589 _pthread_mutex_unlock(&private_display->lock);
1593 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1595 tdm_func_layer *func_layer;
1598 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1600 _pthread_mutex_lock(&private_display->lock);
1602 func_layer = &private_display->func_layer;
1604 private_layer->usable = 0;
1606 if (!func_layer->layer_set_buffer) {
1607 _pthread_mutex_unlock(&private_display->lock);
1608 TDM_DBG("failed: not implemented!!");
1609 return TDM_ERROR_NOT_IMPLEMENTED;
1612 if (buffer_queue == private_layer->buffer_queue) {
1613 _pthread_mutex_unlock(&private_display->lock);
1614 return TDM_ERROR_NONE;
1617 if (private_layer->waiting_buffer) {
1618 _pthread_mutex_unlock(&private_display->lock);
1619 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1620 tbm_surface_queue_release(private_layer->buffer_queue,
1621 private_layer->waiting_buffer);
1622 private_layer->waiting_buffer = NULL;
1623 _pthread_mutex_lock(&private_display->lock);
1625 if (tdm_debug_buffer)
1626 TDM_INFO("layer(%p) waiting_buffer(%p)",
1627 private_layer, private_layer->waiting_buffer);
1630 private_layer->buffer_queue = buffer_queue;
1631 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1632 _tbm_layer_queue_acquirable_cb,
1634 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1635 _tbm_layer_queue_destroy_cb,
1637 _pthread_mutex_unlock(&private_display->lock);
1643 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1645 tdm_func_layer *func_layer;
1648 _pthread_mutex_lock(&private_display->lock);
1650 func_layer = &private_display->func_layer;
1652 if (private_layer->waiting_buffer) {
1653 _pthread_mutex_unlock(&private_display->lock);
1654 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1655 tbm_surface_queue_release(private_layer->buffer_queue,
1656 private_layer->waiting_buffer);
1657 private_layer->waiting_buffer = NULL;
1658 _pthread_mutex_lock(&private_display->lock);
1660 if (tdm_debug_buffer)
1661 TDM_INFO("layer(%p) waiting_buffer(%p)",
1662 private_layer, private_layer->waiting_buffer);
1665 if (private_layer->showing_buffer) {
1666 _pthread_mutex_unlock(&private_display->lock);
1667 tdm_buffer_unref_backend(private_layer->showing_buffer);
1668 tbm_surface_queue_release(private_layer->buffer_queue,
1669 private_layer->showing_buffer);
1670 _pthread_mutex_lock(&private_display->lock);
1671 private_layer->showing_buffer = NULL;
1673 if (tdm_debug_buffer)
1674 TDM_INFO("layer(%p) showing_buffer(%p)",
1675 private_layer, private_layer->showing_buffer);
1678 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1679 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1680 private_layer->buffer_queue = NULL;
1681 private_layer->usable = 1;
1683 if (!func_layer->layer_unset_buffer) {
1684 _pthread_mutex_unlock(&private_display->lock);
1685 TDM_DBG("failed: not implemented!!");
1686 return TDM_ERROR_NOT_IMPLEMENTED;
1689 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1691 _pthread_mutex_unlock(&private_display->lock);
1697 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1701 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1703 _pthread_mutex_lock(&private_display->lock);
1705 *usable = private_layer->usable;
1707 _pthread_mutex_unlock(&private_display->lock);
1713 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1715 tdm_func_layer *func_layer;
1718 _pthread_mutex_lock(&private_display->lock);
1720 func_layer = &private_display->func_layer;
1722 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1723 TDM_ERR("layer(%p) is not video layer", private_layer);
1724 _pthread_mutex_unlock(&private_display->lock);
1725 return TDM_ERROR_INVALID_PARAMETER;
1728 if (!func_layer->layer_set_video_pos) {
1729 _pthread_mutex_unlock(&private_display->lock);
1730 TDM_DBG("failed: not implemented!!");
1731 return TDM_ERROR_NOT_IMPLEMENTED;
1734 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1736 _pthread_mutex_unlock(&private_display->lock);
1741 EXTERN tdm_capture *
1742 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1744 tdm_capture *capture = NULL;
1746 LAYER_FUNC_ENTRY_ERROR();
1748 _pthread_mutex_lock(&private_display->lock);
1750 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1753 _pthread_mutex_unlock(&private_display->lock);