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
106 tdm_display_get_capabilities(tdm_display *dpy,
107 tdm_display_capability *capabilities)
109 DISPLAY_FUNC_ENTRY();
111 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
113 _pthread_mutex_lock(&private_display->lock);
115 *capabilities = private_display->capabilities;
117 _pthread_mutex_unlock(&private_display->lock);
123 tdm_display_get_pp_capabilities(tdm_display *dpy,
124 tdm_pp_capability *capabilities)
126 DISPLAY_FUNC_ENTRY();
128 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
130 _pthread_mutex_lock(&private_display->lock);
132 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
133 TDM_ERR("no pp capability");
134 _pthread_mutex_unlock(&private_display->lock);
135 return TDM_ERROR_NO_CAPABILITY;
138 *capabilities = private_display->caps_pp.capabilities;
140 _pthread_mutex_unlock(&private_display->lock);
146 tdm_display_get_pp_available_formats(tdm_display *dpy,
147 const tbm_format **formats, int *count)
149 DISPLAY_FUNC_ENTRY();
151 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
152 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
154 _pthread_mutex_lock(&private_display->lock);
156 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
157 TDM_ERR("no pp capability");
158 _pthread_mutex_unlock(&private_display->lock);
159 return TDM_ERROR_NO_CAPABILITY;
162 *formats = (const tbm_format *)private_display->caps_pp.formats;
163 *count = private_display->caps_pp.format_count;
165 _pthread_mutex_unlock(&private_display->lock);
171 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
172 int *max_w, int *max_h, int *preferred_align)
174 DISPLAY_FUNC_ENTRY();
176 _pthread_mutex_lock(&private_display->lock);
178 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
179 TDM_ERR("no pp capability");
180 _pthread_mutex_unlock(&private_display->lock);
181 return TDM_ERROR_NO_CAPABILITY;
185 *min_w = private_display->caps_pp.min_w;
187 *min_h = private_display->caps_pp.min_h;
189 *max_w = private_display->caps_pp.max_w;
191 *max_h = private_display->caps_pp.max_h;
193 *preferred_align = private_display->caps_pp.preferred_align;
195 _pthread_mutex_unlock(&private_display->lock);
201 tdm_display_get_capture_capabilities(tdm_display *dpy,
202 tdm_capture_capability *capabilities)
204 DISPLAY_FUNC_ENTRY();
206 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
208 _pthread_mutex_lock(&private_display->lock);
210 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
211 TDM_ERR("no capture capability");
212 _pthread_mutex_unlock(&private_display->lock);
213 return TDM_ERROR_NO_CAPABILITY;
216 *capabilities = private_display->caps_capture.capabilities;
218 _pthread_mutex_unlock(&private_display->lock);
224 tdm_display_get_catpure_available_formats(tdm_display *dpy,
225 const tbm_format **formats, int *count)
227 DISPLAY_FUNC_ENTRY();
229 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
230 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
232 _pthread_mutex_lock(&private_display->lock);
234 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
235 TDM_ERR("no capture capability");
236 _pthread_mutex_unlock(&private_display->lock);
237 return TDM_ERROR_NO_CAPABILITY;
240 *formats = (const tbm_format *)private_display->caps_capture.formats;
241 *count = private_display->caps_capture.format_count;
243 _pthread_mutex_unlock(&private_display->lock);
249 tdm_display_get_output_count(tdm_display *dpy, int *count)
251 tdm_private_output *private_output = NULL;
253 DISPLAY_FUNC_ENTRY();
255 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
257 _pthread_mutex_lock(&private_display->lock);
260 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
264 _pthread_mutex_unlock(&private_display->lock);
265 return TDM_ERROR_NONE;
268 _pthread_mutex_unlock(&private_display->lock);
275 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
277 tdm_private_output *private_output = NULL;
280 DISPLAY_FUNC_ENTRY_ERROR();
282 _pthread_mutex_lock(&private_display->lock);
285 *error = TDM_ERROR_NONE;
288 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
290 _pthread_mutex_unlock(&private_display->lock);
291 return private_output;
296 _pthread_mutex_unlock(&private_display->lock);
302 tdm_display_get_fd(tdm_display *dpy, int *fd)
304 DISPLAY_FUNC_ENTRY();
306 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
308 _pthread_mutex_lock(&private_display->lock);
310 if (tdm_thread_is_running())
311 *fd = tdm_thread_get_fd(private_display->private_loop);
313 *fd = tdm_event_loop_get_fd(private_display);
315 _pthread_mutex_unlock(&private_display->lock);
321 tdm_display_handle_events(tdm_display *dpy)
326 DISPLAY_FUNC_ENTRY();
328 ret = tdm_display_get_fd(dpy, &fd);
329 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
335 if (tdm_debug_thread)
336 TDM_INFO("fd(%d) polling in", fd);
338 while (poll(&fds, 1, -1) < 0) {
339 if (errno == EINTR || errno == EAGAIN) /* normal case */
342 TDM_ERR("poll failed: %m");
343 return TDM_ERROR_OPERATION_FAILED;
347 if (tdm_debug_thread)
348 TDM_INFO("fd(%d) polling out", fd);
350 if (tdm_thread_is_running())
351 ret = tdm_thread_handle_cb(private_display->private_loop);
353 ret = tdm_event_loop_dispatch(private_display);
359 tdm_display_get_backend_info(tdm_display *dpy, const char **name,
360 const char **vendor, int *major, int *minor)
362 tdm_backend_module *module_data;
364 DISPLAY_FUNC_ENTRY();
366 _pthread_mutex_lock(&private_display->lock);
368 module_data = private_display->module_data;
371 *name = module_data->name;
373 *vendor = module_data->vendor;
375 *major = TDM_BACKEND_GET_ABI_MAJOR(module_data->abi_version);
377 *minor = TDM_BACKEND_GET_ABI_MINOR(module_data->abi_version);
379 _pthread_mutex_unlock(&private_display->lock);
385 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
389 DISPLAY_FUNC_ENTRY_ERROR();
391 _pthread_mutex_lock(&private_display->lock);
393 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
395 _pthread_mutex_unlock(&private_display->lock);
401 tdm_output_get_model_info(tdm_output *output, const char **maker,
402 const char **model, const char **name)
406 _pthread_mutex_lock(&private_display->lock);
409 *maker = private_output->caps.maker;
411 *model = private_output->caps.model;
413 *name = private_output->caps.name;
415 _pthread_mutex_unlock(&private_display->lock);
421 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
425 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
427 _pthread_mutex_lock(&private_display->lock);
429 *status = private_output->caps.status;
431 _pthread_mutex_unlock(&private_display->lock);
437 _tdm_output_update(tdm_output *output_backend, void *user_data)
439 tdm_private_display *private_display;
440 tdm_private_output *private_output = user_data;
443 TDM_RETURN_IF_FAIL(private_output);
445 private_display = private_output->private_display;
447 ret = tdm_display_update_output(private_display, output_backend, private_output->pipe);
448 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
452 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
455 tdm_private_display *private_display;
456 tdm_private_output *private_output = user_data;
459 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
460 TDM_RETURN_IF_FAIL(private_output);
462 private_display = private_output->private_display;
464 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
465 tdm_thread_cb_output_status output_status;
468 _tdm_output_update(output_backend, user_data);
470 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
471 output_status.base.length = sizeof output_status;
472 output_status.output_stamp = private_output->stamp;
473 output_status.status = status;
474 output_status.user_data = user_data;
477 tdm_output_call_change_handler_internal(private_output,
478 &private_output->change_handler_list_sub,
479 TDM_OUTPUT_CHANGE_CONNECTION,
482 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
483 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
488 if (!tdm_thread_is_running())
489 _tdm_output_update(output_backend, user_data);
492 tdm_output_call_change_handler_internal(private_output,
493 &private_output->change_handler_list_main,
494 TDM_OUTPUT_CHANGE_CONNECTION,
499 tdm_output_add_change_handler(tdm_output *output,
500 tdm_output_change_handler func,
503 tdm_private_change_handler *change_handler;
506 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
508 pthread_mutex_lock(&private_display->lock);
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 _pthread_mutex_unlock(&private_display->lock);
892 tbm_surface_queue_release(private_layer->buffer_queue,
893 private_layer->showing_buffer);
894 _pthread_mutex_lock(&private_display->lock);
898 private_layer->showing_buffer = private_layer->waiting_buffer;
899 private_layer->waiting_buffer = NULL;
901 if (tdm_debug_buffer)
902 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
903 private_layer, private_layer->waiting_buffer,
904 private_layer->showing_buffer);
907 if (commit_handler->func) {
908 _pthread_mutex_unlock(&private_display->lock);
909 commit_handler->func(private_output, sequence,
910 tv_sec, tv_usec, commit_handler->user_data);
911 _pthread_mutex_lock(&private_display->lock);
914 LIST_DEL(&commit_handler->link);
915 free(commit_handler);
919 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
920 tdm_output_vblank_handler func, void *user_data)
922 tdm_func_output *func_output;
923 tdm_private_vblank_handler *vblank_handler;
926 _pthread_mutex_lock(&private_display->lock);
928 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
929 TDM_WRN("output(%d) dpms: %s", private_output->pipe,
930 tdm_dpms_str(private_output->current_dpms_value));
931 _pthread_mutex_unlock(&private_display->lock);
932 return TDM_ERROR_DPMS_OFF;
935 func_output = &private_display->func_output;
937 if (!func_output->output_wait_vblank) {
938 _pthread_mutex_unlock(&private_display->lock);
939 TDM_ERR("not implemented!!");
940 return TDM_ERROR_NOT_IMPLEMENTED;
943 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
944 if (!vblank_handler) {
945 TDM_ERR("failed: alloc memory");
946 _pthread_mutex_unlock(&private_display->lock);
947 return TDM_ERROR_OUT_OF_MEMORY;
950 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
951 vblank_handler->private_output = private_output;
952 vblank_handler->func = func;
953 vblank_handler->user_data = user_data;
954 vblank_handler->owner_tid = syscall(SYS_gettid);
956 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
957 sync, vblank_handler);
958 if (ret != TDM_ERROR_NONE) {
959 _pthread_mutex_unlock(&private_display->lock);
963 if (!private_output->regist_vblank_cb) {
964 private_output->regist_vblank_cb = 1;
965 ret = func_output->output_set_vblank_handler(private_output->output_backend,
966 tdm_output_cb_vblank);
969 _pthread_mutex_unlock(&private_display->lock);
975 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
978 tdm_func_output *func_output;
979 tdm_private_commit_handler *commit_handler;
982 func_output = &private_display->func_output;
984 if (!func_output->output_commit) {
985 TDM_ERR("not implemented!!");
986 return TDM_ERROR_NOT_IMPLEMENTED;
989 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
990 if (!commit_handler) {
991 TDM_ERR("failed: alloc memory");
992 return TDM_ERROR_OUT_OF_MEMORY;
995 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
996 commit_handler->private_output = private_output;
997 commit_handler->func = func;
998 commit_handler->user_data = user_data;
999 commit_handler->owner_tid = syscall(SYS_gettid);
1001 if (!private_output->regist_commit_cb) {
1002 private_output->regist_commit_cb = 1;
1003 ret = func_output->output_set_commit_handler(private_output->output_backend,
1004 tdm_output_cb_commit);
1007 ret = func_output->output_commit(private_output->output_backend, sync,
1009 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1015 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1018 OUTPUT_FUNC_ENTRY();
1020 _pthread_mutex_lock(&private_display->lock);
1022 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1023 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1024 tdm_dpms_str(private_output->current_dpms_value));
1025 _pthread_mutex_unlock(&private_display->lock);
1026 return TDM_ERROR_DPMS_OFF;
1029 ret = _tdm_output_commit(output, sync, func, user_data);
1031 _pthread_mutex_unlock(&private_display->lock);
1037 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1039 tdm_func_output *func_output;
1040 OUTPUT_FUNC_ENTRY();
1042 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1044 _pthread_mutex_lock(&private_display->lock);
1046 func_output = &private_display->func_output;
1048 if (!func_output->output_set_mode) {
1049 _pthread_mutex_unlock(&private_display->lock);
1050 TDM_ERR("not implemented!!");
1051 return TDM_ERROR_NOT_IMPLEMENTED;
1054 ret = func_output->output_set_mode(private_output->output_backend, mode);
1056 _pthread_mutex_unlock(&private_display->lock);
1062 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1064 tdm_func_output *func_output;
1065 OUTPUT_FUNC_ENTRY();
1067 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1069 _pthread_mutex_lock(&private_display->lock);
1071 func_output = &private_display->func_output;
1073 if (!func_output->output_get_mode) {
1074 _pthread_mutex_unlock(&private_display->lock);
1075 TDM_ERR("not implemented!!");
1076 return TDM_ERROR_NOT_IMPLEMENTED;
1079 ret = func_output->output_get_mode(private_output->output_backend, mode);
1081 _pthread_mutex_unlock(&private_display->lock);
1087 _tdm_output_dpms_changed_timeout(void *user_data)
1089 tdm_private_output *private_output = user_data;
1092 value.u32 = private_output->current_dpms_value;
1093 tdm_output_call_change_handler_internal(private_output,
1094 &private_output->change_handler_list_sub,
1095 TDM_OUTPUT_CHANGE_DPMS,
1098 return TDM_ERROR_NONE;
1102 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1104 tdm_func_output *func_output;
1105 OUTPUT_FUNC_ENTRY();
1107 if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1108 dpms_value = TDM_OUTPUT_DPMS_OFF;
1110 _pthread_mutex_lock(&private_display->lock);
1112 if (private_output->current_dpms_value == dpms_value) {
1113 _pthread_mutex_unlock(&private_display->lock);
1114 return TDM_ERROR_NONE;
1117 if (!private_output->dpms_changed_timer) {
1118 private_output->dpms_changed_timer =
1119 tdm_event_loop_add_timer_handler(private_output->private_display,
1120 _tdm_output_dpms_changed_timeout, private_output, NULL);
1121 if (!private_output->dpms_changed_timer) {
1122 TDM_ERR("can't create dpms timer!!");
1123 _pthread_mutex_unlock(&private_display->lock);
1124 return TDM_ERROR_OUT_OF_MEMORY;
1128 func_output = &private_display->func_output;
1130 if (!func_output->output_set_dpms) {
1131 _pthread_mutex_unlock(&private_display->lock);
1132 private_output->current_dpms_value = dpms_value;
1133 TDM_WRN("not implemented!!");
1134 return TDM_ERROR_NONE;
1137 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1138 if (ret == TDM_ERROR_NONE) {
1141 private_output->current_dpms_value = dpms_value;
1143 value.u32 = dpms_value;
1144 tdm_output_call_change_handler_internal(private_output,
1145 &private_output->change_handler_list_main,
1146 TDM_OUTPUT_CHANGE_DPMS,
1149 if (!LIST_IS_EMPTY(&private_output->change_handler_list_sub)) {
1150 ret = tdm_event_loop_source_timer_update(private_output->dpms_changed_timer, 1);
1151 if (ret != TDM_ERROR_NONE)
1152 TDM_NEVER_GET_HERE();
1156 _pthread_mutex_unlock(&private_display->lock);
1162 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1164 tdm_func_output *func_output;
1165 OUTPUT_FUNC_ENTRY();
1167 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1169 _pthread_mutex_lock(&private_display->lock);
1171 func_output = &private_display->func_output;
1173 if (!func_output->output_get_dpms) {
1174 *dpms_value = private_output->current_dpms_value;
1175 _pthread_mutex_unlock(&private_display->lock);
1176 TDM_WRN("not implemented!!");
1177 return TDM_ERROR_NONE;
1180 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1182 _pthread_mutex_unlock(&private_display->lock);
1187 EXTERN tdm_capture *
1188 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1190 tdm_capture *capture = NULL;
1192 OUTPUT_FUNC_ENTRY_ERROR();
1194 _pthread_mutex_lock(&private_display->lock);
1196 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output, error);
1198 _pthread_mutex_unlock(&private_display->lock);
1204 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1205 struct list_head *change_handler_list,
1206 tdm_output_change_type type,
1208 int no_check_thread_id)
1210 tdm_private_display *private_display;
1211 tdm_private_change_handler *change_handler = NULL;
1213 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1214 TDM_RETURN_IF_FAIL(private_output);
1216 private_display = private_output->private_display;
1217 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1218 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1219 TDM_INFO("output(%d) changed: %s (%d)",
1220 private_output->pipe, tdm_status_str(value.u32), value.u32);
1221 if (type & TDM_OUTPUT_CHANGE_DPMS)
1222 TDM_INFO("output(%d) changed: dpms %s (%d)",
1223 private_output->pipe, tdm_dpms_str(value.u32), value.u32);
1226 if (LIST_IS_EMPTY(change_handler_list))
1229 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1230 if (!no_check_thread_id && change_handler->owner_tid != syscall(SYS_gettid))
1231 TDM_NEVER_GET_HERE();
1233 _pthread_mutex_unlock(&private_display->lock);
1234 change_handler->func(private_output, type,
1235 value, change_handler->user_data);
1236 _pthread_mutex_lock(&private_display->lock);
1241 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1245 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1247 _pthread_mutex_lock(&private_display->lock);
1249 *capabilities = private_layer->caps.capabilities;
1251 _pthread_mutex_unlock(&private_display->lock);
1257 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
1261 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1262 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1264 _pthread_mutex_lock(&private_display->lock);
1266 *formats = (const tbm_format *)private_layer->caps.formats;
1267 *count = private_layer->caps.format_count;
1269 _pthread_mutex_unlock(&private_display->lock);
1275 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
1279 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1280 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1282 _pthread_mutex_lock(&private_display->lock);
1284 *props = (const tdm_prop *)private_layer->caps.props;
1285 *count = private_layer->caps.prop_count;
1287 _pthread_mutex_unlock(&private_display->lock);
1293 tdm_layer_get_zpos(tdm_layer *layer, int *zpos)
1297 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1299 _pthread_mutex_lock(&private_display->lock);
1301 *zpos = private_layer->caps.zpos;
1303 _pthread_mutex_unlock(&private_display->lock);
1309 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1311 tdm_func_layer *func_layer;
1314 _pthread_mutex_lock(&private_display->lock);
1316 func_layer = &private_display->func_layer;
1318 if (!func_layer->layer_set_property) {
1319 _pthread_mutex_unlock(&private_display->lock);
1320 TDM_ERR("not implemented!!");
1321 return TDM_ERROR_NOT_IMPLEMENTED;
1324 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1326 _pthread_mutex_unlock(&private_display->lock);
1332 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1334 tdm_func_layer *func_layer;
1337 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1339 _pthread_mutex_lock(&private_display->lock);
1341 func_layer = &private_display->func_layer;
1343 if (!func_layer->layer_get_property) {
1344 _pthread_mutex_unlock(&private_display->lock);
1345 TDM_ERR("not implemented!!");
1346 return TDM_ERROR_NOT_IMPLEMENTED;
1349 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1351 _pthread_mutex_unlock(&private_display->lock);
1357 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1359 tdm_func_layer *func_layer;
1364 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1366 _pthread_mutex_lock(&private_display->lock);
1368 func_layer = &private_display->func_layer;
1370 if (private_layer->usable)
1371 TDM_INFO("layer(%p) not usable", private_layer);
1373 private_layer->usable = 0;
1375 if (!func_layer->layer_set_info) {
1376 _pthread_mutex_unlock(&private_display->lock);
1377 TDM_ERR("not implemented!!");
1378 return TDM_ERROR_NOT_IMPLEMENTED;
1381 if (info->src_config.format)
1382 snprintf(fmtstr, 128, "%c%c%c%c", FOURCC_STR(info->src_config.format));
1384 snprintf(fmtstr, 128, "NONE");
1386 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %s) dst(%d,%d %dx%d) trans(%d)",
1387 private_layer, info->src_config.size.h, info->src_config.size.v,
1388 info->src_config.pos.x, info->src_config.pos.y,
1389 info->src_config.pos.w, info->src_config.pos.h,
1391 info->dst_pos.x, info->dst_pos.y,
1392 info->dst_pos.w, info->dst_pos.h,
1395 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1396 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1398 _pthread_mutex_unlock(&private_display->lock);
1404 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1406 tdm_func_layer *func_layer;
1409 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1411 _pthread_mutex_lock(&private_display->lock);
1413 func_layer = &private_display->func_layer;
1415 if (!func_layer->layer_get_info) {
1416 _pthread_mutex_unlock(&private_display->lock);
1417 TDM_ERR("not implemented!!");
1418 return TDM_ERROR_NOT_IMPLEMENTED;
1421 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1423 _pthread_mutex_unlock(&private_display->lock);
1429 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1431 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1432 tdm_private_output *private_output = private_layer->private_output;
1435 char fname[PATH_MAX];
1437 pipe = private_output->pipe;
1438 zpos = private_layer->caps.zpos;
1440 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1442 tbm_surface_internal_dump_buffer(buffer, fname);
1443 TDM_DBG("%s dump excute", fname);
1449 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1451 tdm_func_layer *func_layer;
1455 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1457 _pthread_mutex_lock(&private_display->lock);
1459 if (tdm_debug_dump & TDM_DUMP_FLAG_LAYER &&
1460 !(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1461 char str[TDM_PATH_LEN];
1463 snprintf(str, TDM_PATH_LEN, "layer_%d_%d_%03d",
1464 private_output->pipe, private_layer->caps.zpos, i++);
1465 tdm_helper_dump_buffer_str(buffer, str);
1468 func_layer = &private_display->func_layer;
1470 if (private_layer->usable)
1471 TDM_INFO("layer(%p) not usable", private_layer);
1473 private_layer->usable = 0;
1475 if (!func_layer->layer_set_buffer) {
1476 _pthread_mutex_unlock(&private_display->lock);
1477 TDM_ERR("not implemented!!");
1478 return TDM_ERROR_NOT_IMPLEMENTED;
1481 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1482 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1485 if (tdm_dump_enable && !(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO))
1486 _tdm_layer_dump_buffer(layer, buffer);
1488 if (ret == TDM_ERROR_NONE) {
1489 /* FIXME: should save to pending_buffer first. And after committing
1490 * successfully, need to move to waiting_buffer.
1492 if (private_layer->waiting_buffer) {
1493 _pthread_mutex_unlock(&private_display->lock);
1494 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1495 _pthread_mutex_lock(&private_display->lock);
1498 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1499 if (tdm_debug_buffer)
1500 TDM_INFO("layer(%p) waiting_buffer(%p)",
1501 private_layer, private_layer->waiting_buffer);
1504 _pthread_mutex_unlock(&private_display->lock);
1510 tdm_layer_unset_buffer(tdm_layer *layer)
1512 tdm_func_layer *func_layer;
1515 _pthread_mutex_lock(&private_display->lock);
1517 func_layer = &private_display->func_layer;
1519 if (private_layer->waiting_buffer) {
1520 _pthread_mutex_unlock(&private_display->lock);
1521 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1522 _pthread_mutex_lock(&private_display->lock);
1523 private_layer->waiting_buffer = NULL;
1525 if (tdm_debug_buffer)
1526 TDM_INFO("layer(%p) waiting_buffer(%p)",
1527 private_layer, private_layer->waiting_buffer);
1530 if (private_layer->showing_buffer) {
1531 _pthread_mutex_unlock(&private_display->lock);
1532 tdm_buffer_unref_backend(private_layer->showing_buffer);
1533 _pthread_mutex_lock(&private_display->lock);
1534 private_layer->showing_buffer = NULL;
1536 if (tdm_debug_buffer)
1537 TDM_INFO("layer(%p) showing_buffer(%p)",
1538 private_layer, private_layer->showing_buffer);
1541 private_layer->usable = 1;
1543 if (private_layer->usable)
1544 TDM_INFO("layer(%p) now usable", private_layer);
1546 if (!func_layer->layer_unset_buffer) {
1547 _pthread_mutex_unlock(&private_display->lock);
1548 TDM_ERR("not implemented!!");
1549 return TDM_ERROR_NOT_IMPLEMENTED;
1552 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1553 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1555 _pthread_mutex_unlock(&private_display->lock);
1560 EXTERN tbm_surface_h
1561 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1563 tbm_surface_h buffer;
1564 LAYER_FUNC_ENTRY_ERROR();
1566 _pthread_mutex_lock(&private_display->lock);
1569 *error = TDM_ERROR_NONE;
1571 if (private_layer->showing_buffer) {
1572 buffer = private_layer->showing_buffer;
1575 *error = TDM_ERROR_OPERATION_FAILED;
1576 _pthread_mutex_unlock(&private_display->lock);
1577 TDM_DBG("layer(%p) showing_buffer is null", private_layer);
1580 _pthread_mutex_unlock(&private_display->lock);
1586 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1588 TDM_RETURN_IF_FAIL(data != NULL);
1589 tdm_layer *layer = data;
1590 tdm_func_layer *func_layer;
1591 tbm_surface_h surface = NULL;
1592 LAYER_FUNC_ENTRY_VOID_RETURN();
1594 _pthread_mutex_lock(&private_display->lock);
1596 func_layer = &private_display->func_layer;
1597 if (!func_layer->layer_set_buffer) {
1598 _pthread_mutex_unlock(&private_display->lock);
1602 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
1604 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1605 private_layer, surface);
1606 _pthread_mutex_unlock(&private_display->lock);
1610 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1611 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1613 if (ret == TDM_ERROR_NONE) {
1614 if (private_layer->waiting_buffer) {
1615 TDM_DBG("layer(%p) drop waiting_buffer(%p)", private_layer, private_layer->waiting_buffer);
1616 _pthread_mutex_unlock(&private_display->lock);
1617 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1618 tbm_surface_queue_release(private_layer->buffer_queue,
1619 private_layer->waiting_buffer);
1620 _pthread_mutex_lock(&private_display->lock);
1623 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1625 if (tdm_debug_buffer)
1626 TDM_INFO("layer(%p) waiting_buffer(%p)",
1627 private_layer, private_layer->waiting_buffer);
1629 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1630 if (ret != TDM_ERROR_NONE)
1631 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1634 _pthread_mutex_unlock(&private_display->lock);
1638 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1640 TDM_RETURN_IF_FAIL(data != NULL);
1641 tdm_layer *layer = data;
1642 LAYER_FUNC_ENTRY_VOID_RETURN();
1643 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1645 _pthread_mutex_lock(&private_display->lock);
1647 if (private_layer->waiting_buffer) {
1648 _pthread_mutex_unlock(&private_display->lock);
1649 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1650 tbm_surface_queue_release(private_layer->buffer_queue,
1651 private_layer->waiting_buffer);
1652 _pthread_mutex_lock(&private_display->lock);
1655 private_layer->buffer_queue = NULL;
1657 _pthread_mutex_unlock(&private_display->lock);
1661 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1663 tdm_func_layer *func_layer;
1666 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1668 _pthread_mutex_lock(&private_display->lock);
1670 func_layer = &private_display->func_layer;
1672 if (private_layer->usable)
1673 TDM_INFO("layer(%p) not usable", private_layer);
1675 private_layer->usable = 0;
1677 if (!func_layer->layer_set_buffer) {
1678 _pthread_mutex_unlock(&private_display->lock);
1679 TDM_ERR("not implemented!!");
1680 return TDM_ERROR_NOT_IMPLEMENTED;
1683 if (buffer_queue == private_layer->buffer_queue) {
1684 _pthread_mutex_unlock(&private_display->lock);
1685 return TDM_ERROR_NONE;
1688 if (private_layer->waiting_buffer) {
1689 _pthread_mutex_unlock(&private_display->lock);
1690 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1691 tbm_surface_queue_release(private_layer->buffer_queue,
1692 private_layer->waiting_buffer);
1693 private_layer->waiting_buffer = NULL;
1694 _pthread_mutex_lock(&private_display->lock);
1696 if (tdm_debug_buffer)
1697 TDM_INFO("layer(%p) waiting_buffer(%p)",
1698 private_layer, private_layer->waiting_buffer);
1701 private_layer->buffer_queue = buffer_queue;
1702 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1703 _tbm_layer_queue_acquirable_cb,
1705 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1706 _tbm_layer_queue_destroy_cb,
1708 _pthread_mutex_unlock(&private_display->lock);
1714 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1716 tdm_func_layer *func_layer;
1719 _pthread_mutex_lock(&private_display->lock);
1721 func_layer = &private_display->func_layer;
1723 if (private_layer->waiting_buffer) {
1724 _pthread_mutex_unlock(&private_display->lock);
1725 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1726 tbm_surface_queue_release(private_layer->buffer_queue,
1727 private_layer->waiting_buffer);
1728 private_layer->waiting_buffer = NULL;
1729 _pthread_mutex_lock(&private_display->lock);
1731 if (tdm_debug_buffer)
1732 TDM_INFO("layer(%p) waiting_buffer(%p)",
1733 private_layer, private_layer->waiting_buffer);
1736 if (private_layer->showing_buffer) {
1737 _pthread_mutex_unlock(&private_display->lock);
1738 tdm_buffer_unref_backend(private_layer->showing_buffer);
1739 tbm_surface_queue_release(private_layer->buffer_queue,
1740 private_layer->showing_buffer);
1741 _pthread_mutex_lock(&private_display->lock);
1742 private_layer->showing_buffer = NULL;
1744 if (tdm_debug_buffer)
1745 TDM_INFO("layer(%p) showing_buffer(%p)",
1746 private_layer, private_layer->showing_buffer);
1749 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1750 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1751 private_layer->buffer_queue = NULL;
1752 private_layer->usable = 1;
1754 if (private_layer->usable)
1755 TDM_INFO("layer(%p) now usable", private_layer);
1757 if (!func_layer->layer_unset_buffer) {
1758 _pthread_mutex_unlock(&private_display->lock);
1759 TDM_ERR("not implemented!!");
1760 return TDM_ERROR_NOT_IMPLEMENTED;
1763 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1765 _pthread_mutex_unlock(&private_display->lock);
1771 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1775 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1777 _pthread_mutex_lock(&private_display->lock);
1779 *usable = private_layer->usable;
1781 _pthread_mutex_unlock(&private_display->lock);
1787 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1789 tdm_func_layer *func_layer;
1792 _pthread_mutex_lock(&private_display->lock);
1794 func_layer = &private_display->func_layer;
1796 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1797 TDM_ERR("layer(%p) is not video layer", private_layer);
1798 _pthread_mutex_unlock(&private_display->lock);
1799 return TDM_ERROR_INVALID_PARAMETER;
1802 if (!func_layer->layer_set_video_pos) {
1803 _pthread_mutex_unlock(&private_display->lock);
1804 TDM_ERR("not implemented!!");
1805 return TDM_ERROR_NOT_IMPLEMENTED;
1808 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1810 _pthread_mutex_unlock(&private_display->lock);
1815 EXTERN tdm_capture *
1816 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1818 tdm_capture *capture = NULL;
1820 LAYER_FUNC_ENTRY_ERROR();
1822 _pthread_mutex_lock(&private_display->lock);
1824 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer, error);
1826 _pthread_mutex_unlock(&private_display->lock);
1832 tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
1834 tdm_func_layer *func_layer;
1837 _pthread_mutex_lock(&private_display->lock);
1839 func_layer = &private_display->func_layer;
1841 if (!func_layer->layer_get_buffer_flags) {
1842 _pthread_mutex_unlock(&private_display->lock);
1843 TDM_ERR("not implemented!!");
1844 return TDM_ERROR_NOT_IMPLEMENTED;
1847 ret = func_layer->layer_get_buffer_flags(private_layer->layer_backend, flags);
1849 _pthread_mutex_unlock(&private_display->lock);