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_ERR("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_ERR("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_ERR("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_ERR("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_ERR("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_ERR("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_ERR("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_ERR("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_ERR("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 private_output->current_dpms_value = dpms_value;
1101 TDM_WRN("not implemented!!");
1102 return TDM_ERROR_NONE;
1105 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1106 if (ret == TDM_ERROR_NONE) {
1109 private_output->current_dpms_value = dpms_value;
1111 value.u32 = dpms_value;
1112 tdm_output_call_change_handler_internal(private_output,
1113 &private_output->change_handler_list_main,
1114 TDM_OUTPUT_CHANGE_DPMS,
1118 _pthread_mutex_unlock(&private_display->lock);
1124 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1126 tdm_func_output *func_output;
1127 OUTPUT_FUNC_ENTRY();
1129 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1131 _pthread_mutex_lock(&private_display->lock);
1133 func_output = &private_display->func_output;
1135 if (!func_output->output_get_dpms) {
1136 *dpms_value = private_output->current_dpms_value;
1137 _pthread_mutex_unlock(&private_display->lock);
1138 TDM_WRN("not implemented!!");
1139 return TDM_ERROR_NONE;
1142 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1144 _pthread_mutex_unlock(&private_display->lock);
1149 EXTERN tdm_capture *
1150 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1152 tdm_capture *capture = NULL;
1154 OUTPUT_FUNC_ENTRY_ERROR();
1156 _pthread_mutex_lock(&private_display->lock);
1158 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
1161 _pthread_mutex_unlock(&private_display->lock);
1167 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1168 struct list_head *change_handler_list,
1169 tdm_output_change_type type,
1172 tdm_private_display *private_display;
1173 tdm_private_change_handler *change_handler;
1175 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1176 TDM_RETURN_IF_FAIL(private_output);
1178 private_display = private_output->private_display;
1179 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1180 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1181 TDM_INFO("output(%d) changed: %s (%d)",
1182 private_output->pipe, status_str(value.u32), value.u32);
1183 if (type & TDM_OUTPUT_CHANGE_DPMS)
1184 TDM_INFO("output(%d) changed: dpms %s (%d)",
1185 private_output->pipe, dpms_str(value.u32), value.u32);
1188 if (LIST_IS_EMPTY(change_handler_list))
1191 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1192 if (change_handler->owner_tid != syscall(SYS_gettid))
1193 TDM_NEVER_GET_HERE();
1195 _pthread_mutex_unlock(&private_display->lock);
1196 change_handler->func(private_output, type,
1197 value, change_handler->user_data);
1198 _pthread_mutex_lock(&private_display->lock);
1203 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1207 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1209 _pthread_mutex_lock(&private_display->lock);
1211 *capabilities = private_layer->caps.capabilities;
1213 _pthread_mutex_unlock(&private_display->lock);
1219 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
1224 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1225 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1227 _pthread_mutex_lock(&private_display->lock);
1229 *formats = (const tbm_format *)private_layer->caps.formats;
1230 *count = private_layer->caps.format_count;
1232 _pthread_mutex_unlock(&private_display->lock);
1238 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
1243 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1244 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1246 _pthread_mutex_lock(&private_display->lock);
1248 *props = (const tdm_prop *)private_layer->caps.props;
1249 *count = private_layer->caps.prop_count;
1251 _pthread_mutex_unlock(&private_display->lock);
1257 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1261 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1263 _pthread_mutex_lock(&private_display->lock);
1265 *zpos = private_layer->caps.zpos;
1267 _pthread_mutex_unlock(&private_display->lock);
1273 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1275 tdm_func_layer *func_layer;
1278 _pthread_mutex_lock(&private_display->lock);
1280 func_layer = &private_display->func_layer;
1282 if (!func_layer->layer_set_property) {
1283 _pthread_mutex_unlock(&private_display->lock);
1284 TDM_ERR("not implemented!!");
1285 return TDM_ERROR_NOT_IMPLEMENTED;
1288 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1290 _pthread_mutex_unlock(&private_display->lock);
1296 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1298 tdm_func_layer *func_layer;
1301 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1303 _pthread_mutex_lock(&private_display->lock);
1305 func_layer = &private_display->func_layer;
1307 if (!func_layer->layer_get_property) {
1308 _pthread_mutex_unlock(&private_display->lock);
1309 TDM_ERR("not implemented!!");
1310 return TDM_ERROR_NOT_IMPLEMENTED;
1313 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1315 _pthread_mutex_unlock(&private_display->lock);
1321 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1323 tdm_func_layer *func_layer;
1326 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1328 _pthread_mutex_lock(&private_display->lock);
1330 func_layer = &private_display->func_layer;
1332 private_layer->usable = 0;
1334 if (!func_layer->layer_set_info) {
1335 _pthread_mutex_unlock(&private_display->lock);
1336 TDM_ERR("not implemented!!");
1337 return TDM_ERROR_NOT_IMPLEMENTED;
1340 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1341 private_layer, info->src_config.size.h, info->src_config.size.v,
1342 info->src_config.pos.x, info->src_config.pos.y,
1343 info->src_config.pos.w, info->src_config.pos.h,
1344 FOURCC_STR(info->src_config.format),
1345 info->dst_pos.x, info->dst_pos.y,
1346 info->dst_pos.w, info->dst_pos.h,
1349 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1350 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1352 _pthread_mutex_unlock(&private_display->lock);
1358 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1360 tdm_func_layer *func_layer;
1363 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1365 _pthread_mutex_lock(&private_display->lock);
1367 func_layer = &private_display->func_layer;
1369 if (!func_layer->layer_get_info) {
1370 _pthread_mutex_unlock(&private_display->lock);
1371 TDM_ERR("not implemented!!");
1372 return TDM_ERROR_NOT_IMPLEMENTED;
1375 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1377 _pthread_mutex_unlock(&private_display->lock);
1383 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1385 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1386 tdm_private_output *private_output = private_layer->private_output;
1391 char fullpath[PATH_MAX];
1392 tbm_surface_info_s info;
1393 tbm_surface_error_e err;
1395 path = tdm_helper_get_dump_path();
1399 count = tdm_helper_get_dump_count();
1403 err = tbm_surface_map(buffer, TBM_SURF_OPTION_READ, &info);
1404 TDM_RETURN_IF_FAIL(err == TBM_SURFACE_ERROR_NONE);
1406 pipe = private_output->pipe;
1407 zpos = private_layer->caps.zpos;
1409 if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
1410 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d.png",
1411 path, count, pipe, zpos);
1413 snprintf(fullpath, sizeof(fullpath), "%s/%03d_out_%d_lyr_%d_%dx%d_%c%c%c%c.yuv",
1414 path, count, pipe, zpos, info.planes[0].stride, info.height, FOURCC_STR(info.format));
1416 tbm_surface_unmap(buffer);
1418 tdm_helper_dump_buffer(buffer, fullpath);
1419 TDM_DBG("%d, %s dump excute", count, fullpath);
1425 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1427 tdm_func_layer *func_layer;
1431 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1433 _pthread_mutex_lock(&private_display->lock);
1435 func_layer = &private_display->func_layer;
1437 private_layer->usable = 0;
1439 if (!func_layer->layer_set_buffer) {
1440 _pthread_mutex_unlock(&private_display->lock);
1441 TDM_ERR("not implemented!!");
1442 return TDM_ERROR_NOT_IMPLEMENTED;
1445 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1446 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1449 if (tdm_dump_enable)
1450 _tdm_layer_dump_buffer(layer, buffer);
1452 if (ret == TDM_ERROR_NONE) {
1453 /* FIXME: should save to pending_buffer first. And after committing
1454 * successfully, need to move to waiting_buffer.
1456 if (private_layer->waiting_buffer) {
1457 _pthread_mutex_unlock(&private_display->lock);
1458 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1459 _pthread_mutex_lock(&private_display->lock);
1462 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1463 if (tdm_debug_buffer)
1464 TDM_INFO("layer(%p) waiting_buffer(%p)",
1465 private_layer, private_layer->waiting_buffer);
1468 _pthread_mutex_unlock(&private_display->lock);
1474 tdm_layer_unset_buffer(tdm_layer *layer)
1476 tdm_func_layer *func_layer;
1479 _pthread_mutex_lock(&private_display->lock);
1481 func_layer = &private_display->func_layer;
1483 if (private_layer->waiting_buffer) {
1484 _pthread_mutex_unlock(&private_display->lock);
1485 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1486 _pthread_mutex_lock(&private_display->lock);
1487 private_layer->waiting_buffer = NULL;
1489 if (tdm_debug_buffer)
1490 TDM_INFO("layer(%p) waiting_buffer(%p)",
1491 private_layer, private_layer->waiting_buffer);
1494 if (private_layer->showing_buffer) {
1495 _pthread_mutex_unlock(&private_display->lock);
1496 tdm_buffer_unref_backend(private_layer->showing_buffer);
1497 _pthread_mutex_lock(&private_display->lock);
1498 private_layer->showing_buffer = NULL;
1500 if (tdm_debug_buffer)
1501 TDM_INFO("layer(%p) showing_buffer(%p)",
1502 private_layer, private_layer->showing_buffer);
1505 private_layer->usable = 1;
1507 if (!func_layer->layer_unset_buffer) {
1508 _pthread_mutex_unlock(&private_display->lock);
1509 TDM_ERR("not implemented!!");
1510 return TDM_ERROR_NOT_IMPLEMENTED;
1513 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1514 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1516 _pthread_mutex_unlock(&private_display->lock);
1522 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1524 TDM_RETURN_IF_FAIL(data != NULL);
1525 tdm_layer *layer = data;
1526 tdm_func_layer *func_layer;
1527 tbm_surface_h surface = NULL;
1528 LAYER_FUNC_ENTRY_VOID_RETURN();
1530 _pthread_mutex_lock(&private_display->lock);
1532 func_layer = &private_display->func_layer;
1533 if (!func_layer->layer_set_buffer) {
1534 _pthread_mutex_unlock(&private_display->lock);
1538 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1539 private_layer->buffer_queue, &surface) ||
1541 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1542 private_layer, surface);
1543 _pthread_mutex_unlock(&private_display->lock);
1547 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1548 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1550 if (ret == TDM_ERROR_NONE) {
1551 if (private_layer->waiting_buffer) {
1552 _pthread_mutex_unlock(&private_display->lock);
1553 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1554 tbm_surface_queue_release(private_layer->buffer_queue,
1555 private_layer->waiting_buffer);
1556 _pthread_mutex_lock(&private_display->lock);
1559 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1561 if (tdm_debug_buffer)
1562 TDM_INFO("layer(%p) waiting_buffer(%p)",
1563 private_layer, private_layer->waiting_buffer);
1565 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1566 if (ret != TDM_ERROR_NONE)
1567 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1570 _pthread_mutex_unlock(&private_display->lock);
1574 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1576 TDM_RETURN_IF_FAIL(data != NULL);
1577 tdm_layer *layer = data;
1578 LAYER_FUNC_ENTRY_VOID_RETURN();
1579 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1581 _pthread_mutex_lock(&private_display->lock);
1583 if (private_layer->waiting_buffer) {
1584 _pthread_mutex_unlock(&private_display->lock);
1585 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1586 tbm_surface_queue_release(private_layer->buffer_queue,
1587 private_layer->waiting_buffer);
1588 _pthread_mutex_lock(&private_display->lock);
1591 private_layer->buffer_queue = NULL;
1593 _pthread_mutex_unlock(&private_display->lock);
1597 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1599 tdm_func_layer *func_layer;
1602 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1604 _pthread_mutex_lock(&private_display->lock);
1606 func_layer = &private_display->func_layer;
1608 private_layer->usable = 0;
1610 if (!func_layer->layer_set_buffer) {
1611 _pthread_mutex_unlock(&private_display->lock);
1612 TDM_ERR("not implemented!!");
1613 return TDM_ERROR_NOT_IMPLEMENTED;
1616 if (buffer_queue == private_layer->buffer_queue) {
1617 _pthread_mutex_unlock(&private_display->lock);
1618 return TDM_ERROR_NONE;
1621 if (private_layer->waiting_buffer) {
1622 _pthread_mutex_unlock(&private_display->lock);
1623 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1624 tbm_surface_queue_release(private_layer->buffer_queue,
1625 private_layer->waiting_buffer);
1626 private_layer->waiting_buffer = NULL;
1627 _pthread_mutex_lock(&private_display->lock);
1629 if (tdm_debug_buffer)
1630 TDM_INFO("layer(%p) waiting_buffer(%p)",
1631 private_layer, private_layer->waiting_buffer);
1634 private_layer->buffer_queue = buffer_queue;
1635 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1636 _tbm_layer_queue_acquirable_cb,
1638 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1639 _tbm_layer_queue_destroy_cb,
1641 _pthread_mutex_unlock(&private_display->lock);
1647 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1649 tdm_func_layer *func_layer;
1652 _pthread_mutex_lock(&private_display->lock);
1654 func_layer = &private_display->func_layer;
1656 if (private_layer->waiting_buffer) {
1657 _pthread_mutex_unlock(&private_display->lock);
1658 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1659 tbm_surface_queue_release(private_layer->buffer_queue,
1660 private_layer->waiting_buffer);
1661 private_layer->waiting_buffer = NULL;
1662 _pthread_mutex_lock(&private_display->lock);
1664 if (tdm_debug_buffer)
1665 TDM_INFO("layer(%p) waiting_buffer(%p)",
1666 private_layer, private_layer->waiting_buffer);
1669 if (private_layer->showing_buffer) {
1670 _pthread_mutex_unlock(&private_display->lock);
1671 tdm_buffer_unref_backend(private_layer->showing_buffer);
1672 tbm_surface_queue_release(private_layer->buffer_queue,
1673 private_layer->showing_buffer);
1674 _pthread_mutex_lock(&private_display->lock);
1675 private_layer->showing_buffer = NULL;
1677 if (tdm_debug_buffer)
1678 TDM_INFO("layer(%p) showing_buffer(%p)",
1679 private_layer, private_layer->showing_buffer);
1682 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1683 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1684 private_layer->buffer_queue = NULL;
1685 private_layer->usable = 1;
1687 if (!func_layer->layer_unset_buffer) {
1688 _pthread_mutex_unlock(&private_display->lock);
1689 TDM_ERR("not implemented!!");
1690 return TDM_ERROR_NOT_IMPLEMENTED;
1693 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1695 _pthread_mutex_unlock(&private_display->lock);
1701 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1705 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1707 _pthread_mutex_lock(&private_display->lock);
1709 *usable = private_layer->usable;
1711 _pthread_mutex_unlock(&private_display->lock);
1717 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1719 tdm_func_layer *func_layer;
1722 _pthread_mutex_lock(&private_display->lock);
1724 func_layer = &private_display->func_layer;
1726 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1727 TDM_ERR("layer(%p) is not video layer", private_layer);
1728 _pthread_mutex_unlock(&private_display->lock);
1729 return TDM_ERROR_INVALID_PARAMETER;
1732 if (!func_layer->layer_set_video_pos) {
1733 _pthread_mutex_unlock(&private_display->lock);
1734 TDM_ERR("not implemented!!");
1735 return TDM_ERROR_NOT_IMPLEMENTED;
1738 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1740 _pthread_mutex_unlock(&private_display->lock);
1745 EXTERN tdm_capture *
1746 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1748 tdm_capture *capture = NULL;
1750 LAYER_FUNC_ENTRY_ERROR();
1752 _pthread_mutex_lock(&private_display->lock);
1754 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1757 _pthread_mutex_unlock(&private_display->lock);