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) \
116 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
117 if (res##_names[i].type == type) \
118 return res##_names[i].name; \
120 return "(invalid)"; \
123 struct type_name dpms_names[] = {
124 { TDM_OUTPUT_DPMS_ON, "on" },
125 { TDM_OUTPUT_DPMS_STANDBY, "standby" },
126 { TDM_OUTPUT_DPMS_SUSPEND, "suspend" },
127 { TDM_OUTPUT_DPMS_OFF, "off" },
130 INTERN type_name_fn(dpms)
132 struct type_name status_names[] = {
133 { TDM_OUTPUT_CONN_STATUS_DISCONNECTED, "disconnected" },
134 { TDM_OUTPUT_CONN_STATUS_CONNECTED, "connected" },
135 { TDM_OUTPUT_CONN_STATUS_MODE_SETTED, "mode_setted" },
138 INTERN type_name_fn(status)
141 tdm_get_dpms_str(tdm_output_dpms dpms_value)
143 return dpms_str(dpms_value);
147 _tdm_display_lock(tdm_display *dpy, const char *func)
149 tdm_private_display *private_display = (tdm_private_display*)dpy;
153 TDM_INFO("mutex lock: %s", func);
155 ret = pthread_mutex_trylock(&private_display->lock);
158 TDM_ERR("mutex lock busy: %s", func);
160 TDM_ERR("mutex lock failed: %s(%m)", func);
161 return TDM_ERROR_OPERATION_FAILED;
164 pthread_mutex_lock(&tdm_mutex_check_lock);
165 tdm_mutex_locked = 1;
166 pthread_mutex_unlock(&tdm_mutex_check_lock);
168 return TDM_ERROR_NONE;
172 _tdm_display_unlock(tdm_display *dpy, const char *func)
174 tdm_private_display *private_display = (tdm_private_display*)dpy;
177 TDM_INFO("mutex unlock: %s", func);
179 pthread_mutex_lock(&tdm_mutex_check_lock);
180 tdm_mutex_locked = 0;
181 pthread_mutex_unlock(&tdm_mutex_check_lock);
183 pthread_mutex_unlock(&private_display->lock);
187 tdm_display_get_capabilities(tdm_display *dpy,
188 tdm_display_capability *capabilities)
190 DISPLAY_FUNC_ENTRY();
192 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
194 _pthread_mutex_lock(&private_display->lock);
196 *capabilities = private_display->capabilities;
198 _pthread_mutex_unlock(&private_display->lock);
204 tdm_display_get_pp_capabilities(tdm_display *dpy,
205 tdm_pp_capability *capabilities)
207 DISPLAY_FUNC_ENTRY();
209 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
211 _pthread_mutex_lock(&private_display->lock);
213 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
214 TDM_ERR("no pp capability");
215 _pthread_mutex_unlock(&private_display->lock);
216 return TDM_ERROR_NO_CAPABILITY;
219 *capabilities = private_display->caps_pp.capabilities;
221 _pthread_mutex_unlock(&private_display->lock);
227 tdm_display_get_pp_available_formats(tdm_display *dpy,
228 const tbm_format **formats, int *count)
230 DISPLAY_FUNC_ENTRY();
232 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
233 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
235 _pthread_mutex_lock(&private_display->lock);
237 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
238 TDM_ERR("no pp capability");
239 _pthread_mutex_unlock(&private_display->lock);
240 return TDM_ERROR_NO_CAPABILITY;
243 *formats = (const tbm_format *)private_display->caps_pp.formats;
244 *count = private_display->caps_pp.format_count;
246 _pthread_mutex_unlock(&private_display->lock);
252 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
253 int *max_w, int *max_h, int *preferred_align)
255 DISPLAY_FUNC_ENTRY();
257 _pthread_mutex_lock(&private_display->lock);
259 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
260 TDM_ERR("no pp capability");
261 _pthread_mutex_unlock(&private_display->lock);
262 return TDM_ERROR_NO_CAPABILITY;
266 *min_w = private_display->caps_pp.min_w;
268 *min_h = private_display->caps_pp.min_h;
270 *max_w = private_display->caps_pp.max_w;
272 *max_h = private_display->caps_pp.max_h;
274 *preferred_align = private_display->caps_pp.preferred_align;
276 _pthread_mutex_unlock(&private_display->lock);
282 tdm_display_get_capture_capabilities(tdm_display *dpy,
283 tdm_capture_capability *capabilities)
285 DISPLAY_FUNC_ENTRY();
287 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
289 _pthread_mutex_lock(&private_display->lock);
291 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
292 TDM_ERR("no capture capability");
293 _pthread_mutex_unlock(&private_display->lock);
294 return TDM_ERROR_NO_CAPABILITY;
297 *capabilities = private_display->caps_capture.capabilities;
299 _pthread_mutex_unlock(&private_display->lock);
305 tdm_display_get_catpure_available_formats(tdm_display *dpy,
306 const tbm_format **formats, int *count)
308 DISPLAY_FUNC_ENTRY();
310 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
311 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
313 _pthread_mutex_lock(&private_display->lock);
315 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
316 TDM_ERR("no capture capability");
317 _pthread_mutex_unlock(&private_display->lock);
318 return TDM_ERROR_NO_CAPABILITY;
321 *formats = (const tbm_format *)private_display->caps_capture.formats;
322 *count = private_display->caps_capture.format_count;
324 _pthread_mutex_unlock(&private_display->lock);
330 tdm_display_get_output_count(tdm_display *dpy, int *count)
332 tdm_private_output *private_output = NULL;
334 DISPLAY_FUNC_ENTRY();
336 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
338 _pthread_mutex_lock(&private_display->lock);
341 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
345 _pthread_mutex_unlock(&private_display->lock);
346 return TDM_ERROR_NONE;
349 _pthread_mutex_unlock(&private_display->lock);
356 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
358 tdm_private_output *private_output = NULL;
361 DISPLAY_FUNC_ENTRY_ERROR();
363 _pthread_mutex_lock(&private_display->lock);
366 *error = TDM_ERROR_NONE;
369 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
371 _pthread_mutex_unlock(&private_display->lock);
372 return private_output;
377 _pthread_mutex_unlock(&private_display->lock);
383 tdm_display_get_fd(tdm_display *dpy, int *fd)
385 DISPLAY_FUNC_ENTRY();
387 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
389 _pthread_mutex_lock(&private_display->lock);
391 if (tdm_thread_is_running())
392 *fd = tdm_thread_get_fd(private_display->private_loop);
394 *fd = tdm_event_loop_get_fd(private_display);
396 _pthread_mutex_unlock(&private_display->lock);
402 tdm_display_handle_events(tdm_display *dpy)
407 DISPLAY_FUNC_ENTRY();
409 ret = tdm_display_get_fd(dpy, &fd);
410 TDM_RETURN_VAL_IF_FAIL(fd >= 0, ret);
416 if (tdm_debug_thread)
417 TDM_INFO("fd(%d) polling in", fd);
419 while (poll(&fds, 1, -1) < 0) {
420 if (errno == EBUSY) /* normal case */
423 TDM_ERR("poll failed: %m");
424 return TDM_ERROR_OPERATION_FAILED;
428 if (tdm_debug_thread)
429 TDM_INFO("fd(%d) polling out", fd);
431 if (tdm_thread_is_running())
432 ret = tdm_thread_handle_cb(private_display->private_loop);
434 ret = tdm_event_loop_dispatch(private_display);
440 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
444 DISPLAY_FUNC_ENTRY_ERROR();
446 _pthread_mutex_lock(&private_display->lock);
448 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
450 _pthread_mutex_unlock(&private_display->lock);
456 tdm_output_get_model_info(tdm_output *output, const char **maker,
457 const char **model, const char **name)
461 _pthread_mutex_lock(&private_display->lock);
464 *maker = private_output->caps.maker;
466 *model = private_output->caps.model;
468 *name = private_output->caps.name;
470 _pthread_mutex_unlock(&private_display->lock);
476 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
480 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
482 _pthread_mutex_lock(&private_display->lock);
484 *status = private_output->caps.status;
486 _pthread_mutex_unlock(&private_display->lock);
492 _tdm_output_update(tdm_output *output_backend, void *user_data)
494 tdm_private_display *private_display;
495 tdm_private_output *private_output = user_data;
498 TDM_RETURN_IF_FAIL(private_output);
500 private_display = private_output->private_display;
502 ret = tdm_display_update_output(private_display, output_backend, private_output->pipe);
503 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
507 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
510 tdm_private_display *private_display;
511 tdm_private_output *private_output = user_data;
514 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
515 TDM_RETURN_IF_FAIL(private_output);
517 private_display = private_output->private_display;
519 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
520 tdm_thread_cb_output_status output_status;
523 _tdm_output_update(output_backend, user_data);
525 output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS;
526 output_status.base.length = sizeof output_status;
527 output_status.output_stamp = private_output->stamp;
528 output_status.status = status;
529 output_status.user_data = user_data;
532 tdm_output_call_change_handler_internal(private_output,
533 &private_output->change_handler_list_sub,
534 TDM_OUTPUT_CHANGE_CONNECTION,
537 ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base);
538 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
543 if (!tdm_thread_is_running())
544 _tdm_output_update(output_backend, user_data);
547 tdm_output_call_change_handler_internal(private_output,
548 &private_output->change_handler_list_main,
549 TDM_OUTPUT_CHANGE_CONNECTION,
554 tdm_output_add_change_handler(tdm_output *output,
555 tdm_output_change_handler func,
558 tdm_private_change_handler *change_handler;
561 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER);
563 pthread_mutex_lock(&private_display->lock);
565 if (!private_output->regist_change_cb) {
566 _pthread_mutex_unlock(&private_display->lock);
567 TDM_ERR("not implemented!!");
568 return TDM_ERROR_NOT_IMPLEMENTED;
571 change_handler = calloc(1, sizeof(tdm_private_change_handler));
572 if (!change_handler) {
573 TDM_ERR("failed: alloc memory");
574 _pthread_mutex_unlock(&private_display->lock);
575 return TDM_ERROR_OUT_OF_MEMORY;
578 change_handler->private_output = private_output;
579 change_handler->func = func;
580 change_handler->user_data = user_data;
581 change_handler->owner_tid = syscall(SYS_gettid);
583 if (!tdm_thread_in_display_thread(change_handler->owner_tid))
584 LIST_ADD(&change_handler->link, &private_output->change_handler_list_sub);
586 LIST_ADD(&change_handler->link, &private_output->change_handler_list_main);
588 _pthread_mutex_unlock(&private_display->lock);
594 tdm_output_remove_change_handler(tdm_output *output,
595 tdm_output_change_handler func,
598 tdm_private_display *private_display;
599 tdm_private_output *private_output;
600 tdm_private_change_handler *h = NULL, *hh = NULL;
602 TDM_RETURN_IF_FAIL(output != NULL);
603 TDM_RETURN_IF_FAIL(func != NULL);
605 private_output = (tdm_private_output*)output;
606 private_display = private_output->private_display;
608 _pthread_mutex_lock(&private_display->lock);
610 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) {
611 if (h->func != func || h->user_data != user_data)
617 _pthread_mutex_unlock(&private_display->lock);
622 LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) {
623 if (h->func != func || h->user_data != user_data)
629 _pthread_mutex_unlock(&private_display->lock);
634 _pthread_mutex_unlock(&private_display->lock);
638 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
642 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
644 _pthread_mutex_lock(&private_display->lock);
646 *type = private_output->caps.type;
648 _pthread_mutex_unlock(&private_display->lock);
654 tdm_output_get_layer_count(tdm_output *output, int *count)
656 tdm_private_layer *private_layer = NULL;
660 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
662 _pthread_mutex_lock(&private_display->lock);
665 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
668 _pthread_mutex_unlock(&private_display->lock);
669 return TDM_ERROR_NONE;
672 _pthread_mutex_unlock(&private_display->lock);
679 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
681 tdm_private_layer *private_layer = NULL;
684 OUTPUT_FUNC_ENTRY_ERROR();
686 _pthread_mutex_lock(&private_display->lock);
689 *error = TDM_ERROR_NONE;
691 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
693 _pthread_mutex_unlock(&private_display->lock);
694 return private_layer;
699 _pthread_mutex_unlock(&private_display->lock);
705 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
710 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
711 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
713 _pthread_mutex_lock(&private_display->lock);
715 *props = (const tdm_prop *)private_output->caps.props;
716 *count = private_output->caps.prop_count;
718 _pthread_mutex_unlock(&private_display->lock);
724 tdm_output_get_available_modes(tdm_output *output,
725 const tdm_output_mode **modes, int *count)
729 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
730 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
732 _pthread_mutex_lock(&private_display->lock);
734 *modes = (const tdm_output_mode *)private_output->caps.modes;
735 *count = private_output->caps.mode_count;
737 _pthread_mutex_unlock(&private_display->lock);
743 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
744 int *max_w, int *max_h, int *preferred_align)
748 _pthread_mutex_lock(&private_display->lock);
751 *min_w = private_output->caps.min_w;
753 *min_h = private_output->caps.min_h;
755 *max_w = private_output->caps.max_w;
757 *max_h = private_output->caps.max_h;
759 *preferred_align = private_output->caps.preferred_align;
761 _pthread_mutex_unlock(&private_display->lock);
767 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
768 unsigned int *mmHeight)
772 _pthread_mutex_lock(&private_display->lock);
775 *mmWidth = private_output->caps.mmWidth;
777 *mmHeight = private_output->caps.mmHeight;
779 _pthread_mutex_unlock(&private_display->lock);
785 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
788 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
790 _pthread_mutex_lock(&private_display->lock);
792 *subpixel = private_output->caps.subpixel;
794 _pthread_mutex_unlock(&private_display->lock);
800 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
803 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
805 _pthread_mutex_lock(&private_display->lock);
807 *pipe = private_output->pipe;
809 _pthread_mutex_unlock(&private_display->lock);
816 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
818 tdm_func_output *func_output;
821 _pthread_mutex_lock(&private_display->lock);
823 func_output = &private_display->func_output;
825 if (!func_output->output_set_property) {
826 _pthread_mutex_unlock(&private_display->lock);
827 TDM_ERR("not implemented!!");
828 return TDM_ERROR_NOT_IMPLEMENTED;
831 ret = func_output->output_set_property(private_output->output_backend, id,
834 _pthread_mutex_unlock(&private_display->lock);
840 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
842 tdm_func_output *func_output;
845 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
847 _pthread_mutex_lock(&private_display->lock);
849 func_output = &private_display->func_output;
851 if (!func_output->output_get_property) {
852 _pthread_mutex_unlock(&private_display->lock);
853 TDM_ERR("not implemented!!");
854 return TDM_ERROR_NOT_IMPLEMENTED;
857 ret = func_output->output_get_property(private_output->output_backend, id,
860 _pthread_mutex_unlock(&private_display->lock);
866 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
867 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
869 tdm_private_vblank_handler *vblank_handler = user_data;
870 tdm_private_display *private_display;
872 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
873 TDM_RETURN_IF_FAIL(vblank_handler);
875 private_display = vblank_handler->private_output->private_display;
877 if (vblank_handler->owner_tid != syscall(SYS_gettid)) {
878 tdm_thread_cb_output_vblank output_vblank;
881 output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK;
882 output_vblank.base.length = sizeof output_vblank;
883 output_vblank.output_stamp = vblank_handler->private_output->stamp;
884 output_vblank.sequence = sequence;
885 output_vblank.tv_sec = tv_sec;
886 output_vblank.tv_usec = tv_usec;
887 output_vblank.user_data = user_data;
889 ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base);
890 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
895 if (vblank_handler->owner_tid != syscall(SYS_gettid))
896 TDM_NEVER_GET_HERE();
898 if (vblank_handler->func) {
899 _pthread_mutex_unlock(&private_display->lock);
900 vblank_handler->func(vblank_handler->private_output, sequence,
901 tv_sec, tv_usec, vblank_handler->user_data);
902 _pthread_mutex_lock(&private_display->lock);
905 LIST_DEL(&vblank_handler->link);
906 free(vblank_handler);
910 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
911 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
913 tdm_private_commit_handler *commit_handler = user_data;
914 tdm_private_display *private_display;
915 tdm_private_output *private_output;
916 tdm_private_layer *private_layer = NULL;
918 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
919 TDM_RETURN_IF_FAIL(commit_handler);
921 private_output = commit_handler->private_output;
922 private_display = private_output->private_display;
924 if (commit_handler->owner_tid != syscall(SYS_gettid)) {
925 tdm_thread_cb_output_commit output_commit;
928 output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT;
929 output_commit.base.length = sizeof output_commit;
930 output_commit.output_stamp = private_output->stamp;
931 output_commit.sequence = sequence;
932 output_commit.tv_sec = tv_sec;
933 output_commit.tv_usec = tv_usec;
934 output_commit.user_data = user_data;
936 ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base);
937 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
942 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
943 if (!private_layer->waiting_buffer)
946 if (private_layer->showing_buffer) {
947 _pthread_mutex_unlock(&private_display->lock);
948 tdm_buffer_unref_backend(private_layer->showing_buffer);
949 _pthread_mutex_lock(&private_display->lock);
951 if (private_layer->buffer_queue) {
952 _pthread_mutex_unlock(&private_display->lock);
953 tbm_surface_queue_release(private_layer->buffer_queue,
954 private_layer->showing_buffer);
955 _pthread_mutex_lock(&private_display->lock);
959 private_layer->showing_buffer = private_layer->waiting_buffer;
960 private_layer->waiting_buffer = NULL;
962 if (tdm_debug_buffer)
963 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
964 private_layer, private_layer->waiting_buffer,
965 private_layer->showing_buffer);
968 if (commit_handler->func) {
969 _pthread_mutex_unlock(&private_display->lock);
970 commit_handler->func(private_output, sequence,
971 tv_sec, tv_usec, commit_handler->user_data);
972 _pthread_mutex_lock(&private_display->lock);
975 LIST_DEL(&commit_handler->link);
976 free(commit_handler);
980 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
981 tdm_output_vblank_handler func, void *user_data)
983 tdm_func_output *func_output;
984 tdm_private_vblank_handler *vblank_handler;
987 _pthread_mutex_lock(&private_display->lock);
989 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
990 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
991 dpms_str(private_output->current_dpms_value));
992 _pthread_mutex_unlock(&private_display->lock);
993 return TDM_ERROR_BAD_REQUEST;
996 func_output = &private_display->func_output;
998 if (!func_output->output_wait_vblank) {
999 _pthread_mutex_unlock(&private_display->lock);
1000 TDM_ERR("not implemented!!");
1001 return TDM_ERROR_NOT_IMPLEMENTED;
1004 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
1005 if (!vblank_handler) {
1006 TDM_ERR("failed: alloc memory");
1007 _pthread_mutex_unlock(&private_display->lock);
1008 return TDM_ERROR_OUT_OF_MEMORY;
1011 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
1012 vblank_handler->private_output = private_output;
1013 vblank_handler->func = func;
1014 vblank_handler->user_data = user_data;
1015 vblank_handler->owner_tid = syscall(SYS_gettid);
1017 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
1018 sync, vblank_handler);
1019 if (ret != TDM_ERROR_NONE) {
1020 _pthread_mutex_unlock(&private_display->lock);
1024 if (!private_output->regist_vblank_cb) {
1025 private_output->regist_vblank_cb = 1;
1026 ret = func_output->output_set_vblank_handler(private_output->output_backend,
1027 tdm_output_cb_vblank);
1030 _pthread_mutex_unlock(&private_display->lock);
1036 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1039 tdm_func_output *func_output;
1040 tdm_private_commit_handler *commit_handler;
1041 OUTPUT_FUNC_ENTRY();
1043 func_output = &private_display->func_output;
1045 if (!func_output->output_commit) {
1046 TDM_ERR("not implemented!!");
1047 return TDM_ERROR_NOT_IMPLEMENTED;
1050 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1051 if (!commit_handler) {
1052 TDM_ERR("failed: alloc memory");
1053 return TDM_ERROR_OUT_OF_MEMORY;
1056 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1057 commit_handler->private_output = private_output;
1058 commit_handler->func = func;
1059 commit_handler->user_data = user_data;
1060 commit_handler->owner_tid = syscall(SYS_gettid);
1062 if (!private_output->regist_commit_cb) {
1063 private_output->regist_commit_cb = 1;
1064 ret = func_output->output_set_commit_handler(private_output->output_backend,
1065 tdm_output_cb_commit);
1068 ret = func_output->output_commit(private_output->output_backend, sync,
1070 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1076 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1079 OUTPUT_FUNC_ENTRY();
1081 _pthread_mutex_lock(&private_display->lock);
1083 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1084 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1085 dpms_str(private_output->current_dpms_value));
1086 _pthread_mutex_unlock(&private_display->lock);
1087 return TDM_ERROR_BAD_REQUEST;
1090 ret = _tdm_output_commit(output, sync, func, user_data);
1092 _pthread_mutex_unlock(&private_display->lock);
1098 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1100 tdm_func_output *func_output;
1101 OUTPUT_FUNC_ENTRY();
1103 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1105 _pthread_mutex_lock(&private_display->lock);
1107 func_output = &private_display->func_output;
1109 if (!func_output->output_set_mode) {
1110 _pthread_mutex_unlock(&private_display->lock);
1111 TDM_ERR("not implemented!!");
1112 return TDM_ERROR_NOT_IMPLEMENTED;
1115 ret = func_output->output_set_mode(private_output->output_backend, mode);
1117 _pthread_mutex_unlock(&private_display->lock);
1123 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1125 tdm_func_output *func_output;
1126 OUTPUT_FUNC_ENTRY();
1128 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1130 _pthread_mutex_lock(&private_display->lock);
1132 func_output = &private_display->func_output;
1134 if (!func_output->output_get_mode) {
1135 _pthread_mutex_unlock(&private_display->lock);
1136 TDM_ERR("not implemented!!");
1137 return TDM_ERROR_NOT_IMPLEMENTED;
1140 ret = func_output->output_get_mode(private_output->output_backend, mode);
1142 _pthread_mutex_unlock(&private_display->lock);
1148 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1150 tdm_func_output *func_output;
1151 OUTPUT_FUNC_ENTRY();
1153 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1154 dpms_value = TDM_OUTPUT_DPMS_ON;
1155 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1156 dpms_value = TDM_OUTPUT_DPMS_OFF;
1158 _pthread_mutex_lock(&private_display->lock);
1160 if (private_output->current_dpms_value == dpms_value) {
1161 _pthread_mutex_unlock(&private_display->lock);
1162 return TDM_ERROR_NONE;
1165 func_output = &private_display->func_output;
1167 if (!func_output->output_set_dpms) {
1168 _pthread_mutex_unlock(&private_display->lock);
1169 private_output->current_dpms_value = dpms_value;
1170 TDM_WRN("not implemented!!");
1171 return TDM_ERROR_NONE;
1174 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1175 if (ret == TDM_ERROR_NONE) {
1178 private_output->current_dpms_value = dpms_value;
1180 value.u32 = dpms_value;
1181 tdm_output_call_change_handler_internal(private_output,
1182 &private_output->change_handler_list_main,
1183 TDM_OUTPUT_CHANGE_DPMS,
1187 _pthread_mutex_unlock(&private_display->lock);
1193 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1195 tdm_func_output *func_output;
1196 OUTPUT_FUNC_ENTRY();
1198 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1200 _pthread_mutex_lock(&private_display->lock);
1202 func_output = &private_display->func_output;
1204 if (!func_output->output_get_dpms) {
1205 *dpms_value = private_output->current_dpms_value;
1206 _pthread_mutex_unlock(&private_display->lock);
1207 TDM_WRN("not implemented!!");
1208 return TDM_ERROR_NONE;
1211 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1213 _pthread_mutex_unlock(&private_display->lock);
1218 EXTERN tdm_capture *
1219 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1221 tdm_capture *capture = NULL;
1223 OUTPUT_FUNC_ENTRY_ERROR();
1225 _pthread_mutex_lock(&private_display->lock);
1227 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output, error);
1229 _pthread_mutex_unlock(&private_display->lock);
1235 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1236 struct list_head *change_handler_list,
1237 tdm_output_change_type type,
1240 tdm_private_display *private_display;
1241 tdm_private_change_handler *change_handler;
1243 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1244 TDM_RETURN_IF_FAIL(private_output);
1246 private_display = private_output->private_display;
1247 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1248 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1249 TDM_INFO("output(%d) changed: %s (%d)",
1250 private_output->pipe, status_str(value.u32), value.u32);
1251 if (type & TDM_OUTPUT_CHANGE_DPMS)
1252 TDM_INFO("output(%d) changed: dpms %s (%d)",
1253 private_output->pipe, dpms_str(value.u32), value.u32);
1256 if (LIST_IS_EMPTY(change_handler_list))
1259 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1260 if (change_handler->owner_tid != syscall(SYS_gettid))
1261 TDM_NEVER_GET_HERE();
1263 _pthread_mutex_unlock(&private_display->lock);
1264 change_handler->func(private_output, type,
1265 value, change_handler->user_data);
1266 _pthread_mutex_lock(&private_display->lock);
1271 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1275 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1277 _pthread_mutex_lock(&private_display->lock);
1279 *capabilities = private_layer->caps.capabilities;
1281 _pthread_mutex_unlock(&private_display->lock);
1287 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
1291 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1292 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1294 _pthread_mutex_lock(&private_display->lock);
1296 *formats = (const tbm_format *)private_layer->caps.formats;
1297 *count = private_layer->caps.format_count;
1299 _pthread_mutex_unlock(&private_display->lock);
1305 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
1309 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1310 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1312 _pthread_mutex_lock(&private_display->lock);
1314 *props = (const tdm_prop *)private_layer->caps.props;
1315 *count = private_layer->caps.prop_count;
1317 _pthread_mutex_unlock(&private_display->lock);
1323 tdm_layer_get_zpos(tdm_layer *layer, int *zpos)
1327 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1329 _pthread_mutex_lock(&private_display->lock);
1331 *zpos = private_layer->caps.zpos;
1333 _pthread_mutex_unlock(&private_display->lock);
1339 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1341 tdm_func_layer *func_layer;
1344 _pthread_mutex_lock(&private_display->lock);
1346 func_layer = &private_display->func_layer;
1348 if (!func_layer->layer_set_property) {
1349 _pthread_mutex_unlock(&private_display->lock);
1350 TDM_ERR("not implemented!!");
1351 return TDM_ERROR_NOT_IMPLEMENTED;
1354 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1356 _pthread_mutex_unlock(&private_display->lock);
1362 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1364 tdm_func_layer *func_layer;
1367 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1369 _pthread_mutex_lock(&private_display->lock);
1371 func_layer = &private_display->func_layer;
1373 if (!func_layer->layer_get_property) {
1374 _pthread_mutex_unlock(&private_display->lock);
1375 TDM_ERR("not implemented!!");
1376 return TDM_ERROR_NOT_IMPLEMENTED;
1379 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1381 _pthread_mutex_unlock(&private_display->lock);
1387 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1389 tdm_func_layer *func_layer;
1392 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1394 _pthread_mutex_lock(&private_display->lock);
1396 func_layer = &private_display->func_layer;
1398 if (private_layer->usable)
1399 TDM_INFO("layer(%p) not usable", private_layer);
1401 private_layer->usable = 0;
1403 if (!func_layer->layer_set_info) {
1404 _pthread_mutex_unlock(&private_display->lock);
1405 TDM_ERR("not implemented!!");
1406 return TDM_ERROR_NOT_IMPLEMENTED;
1409 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1410 private_layer, info->src_config.size.h, info->src_config.size.v,
1411 info->src_config.pos.x, info->src_config.pos.y,
1412 info->src_config.pos.w, info->src_config.pos.h,
1413 FOURCC_STR(info->src_config.format),
1414 info->dst_pos.x, info->dst_pos.y,
1415 info->dst_pos.w, info->dst_pos.h,
1418 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1419 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1421 _pthread_mutex_unlock(&private_display->lock);
1427 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1429 tdm_func_layer *func_layer;
1432 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1434 _pthread_mutex_lock(&private_display->lock);
1436 func_layer = &private_display->func_layer;
1438 if (!func_layer->layer_get_info) {
1439 _pthread_mutex_unlock(&private_display->lock);
1440 TDM_ERR("not implemented!!");
1441 return TDM_ERROR_NOT_IMPLEMENTED;
1444 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1446 _pthread_mutex_unlock(&private_display->lock);
1452 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1454 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1455 tdm_private_output *private_output = private_layer->private_output;
1458 char fname[PATH_MAX];
1460 pipe = private_output->pipe;
1461 zpos = private_layer->caps.zpos;
1463 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1465 tbm_surface_internal_dump_buffer(buffer, fname);
1466 TDM_DBG("%s dump excute", fname);
1472 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1474 tdm_func_layer *func_layer;
1478 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1480 _pthread_mutex_lock(&private_display->lock);
1482 func_layer = &private_display->func_layer;
1484 if (private_layer->usable)
1485 TDM_INFO("layer(%p) not usable", private_layer);
1487 private_layer->usable = 0;
1489 if (!func_layer->layer_set_buffer) {
1490 _pthread_mutex_unlock(&private_display->lock);
1491 TDM_ERR("not implemented!!");
1492 return TDM_ERROR_NOT_IMPLEMENTED;
1495 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1496 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1499 if (tdm_dump_enable)
1500 _tdm_layer_dump_buffer(layer, buffer);
1502 if (ret == TDM_ERROR_NONE) {
1503 /* FIXME: should save to pending_buffer first. And after committing
1504 * successfully, need to move to waiting_buffer.
1506 if (private_layer->waiting_buffer) {
1507 _pthread_mutex_unlock(&private_display->lock);
1508 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1509 _pthread_mutex_lock(&private_display->lock);
1512 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1513 if (tdm_debug_buffer)
1514 TDM_INFO("layer(%p) waiting_buffer(%p)",
1515 private_layer, private_layer->waiting_buffer);
1518 _pthread_mutex_unlock(&private_display->lock);
1524 tdm_layer_unset_buffer(tdm_layer *layer)
1526 tdm_func_layer *func_layer;
1529 _pthread_mutex_lock(&private_display->lock);
1531 func_layer = &private_display->func_layer;
1533 if (private_layer->waiting_buffer) {
1534 _pthread_mutex_unlock(&private_display->lock);
1535 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1536 _pthread_mutex_lock(&private_display->lock);
1537 private_layer->waiting_buffer = NULL;
1539 if (tdm_debug_buffer)
1540 TDM_INFO("layer(%p) waiting_buffer(%p)",
1541 private_layer, private_layer->waiting_buffer);
1544 if (private_layer->showing_buffer) {
1545 _pthread_mutex_unlock(&private_display->lock);
1546 tdm_buffer_unref_backend(private_layer->showing_buffer);
1547 _pthread_mutex_lock(&private_display->lock);
1548 private_layer->showing_buffer = NULL;
1550 if (tdm_debug_buffer)
1551 TDM_INFO("layer(%p) showing_buffer(%p)",
1552 private_layer, private_layer->showing_buffer);
1555 private_layer->usable = 1;
1557 if (private_layer->usable)
1558 TDM_INFO("layer(%p) now usable", private_layer);
1560 if (!func_layer->layer_unset_buffer) {
1561 _pthread_mutex_unlock(&private_display->lock);
1562 TDM_ERR("not implemented!!");
1563 return TDM_ERROR_NOT_IMPLEMENTED;
1566 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1567 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1569 _pthread_mutex_unlock(&private_display->lock);
1574 EXTERN tbm_surface_h
1575 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1577 tbm_surface_h buffer;
1578 LAYER_FUNC_ENTRY_ERROR();
1580 _pthread_mutex_lock(&private_display->lock);
1583 *error = TDM_ERROR_NONE;
1585 if (private_layer->showing_buffer) {
1586 buffer = private_layer->showing_buffer;
1589 *error = TDM_ERROR_OPERATION_FAILED;
1590 _pthread_mutex_unlock(&private_display->lock);
1591 TDM_DBG("layer(%p) showing_buffer is null", private_layer);
1594 _pthread_mutex_unlock(&private_display->lock);
1600 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1602 TDM_RETURN_IF_FAIL(data != NULL);
1603 tdm_layer *layer = data;
1604 tdm_func_layer *func_layer;
1605 tbm_surface_h surface = NULL;
1606 LAYER_FUNC_ENTRY_VOID_RETURN();
1608 _pthread_mutex_lock(&private_display->lock);
1610 func_layer = &private_display->func_layer;
1611 if (!func_layer->layer_set_buffer) {
1612 _pthread_mutex_unlock(&private_display->lock);
1616 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
1618 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1619 private_layer, surface);
1620 _pthread_mutex_unlock(&private_display->lock);
1624 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1625 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1627 if (ret == TDM_ERROR_NONE) {
1628 if (private_layer->waiting_buffer) {
1629 TDM_DBG("layer(%p) drop waiting_buffer(%p)", private_layer, private_layer->waiting_buffer);
1630 _pthread_mutex_unlock(&private_display->lock);
1631 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1632 tbm_surface_queue_release(private_layer->buffer_queue,
1633 private_layer->waiting_buffer);
1634 _pthread_mutex_lock(&private_display->lock);
1637 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1639 if (tdm_debug_buffer)
1640 TDM_INFO("layer(%p) waiting_buffer(%p)",
1641 private_layer, private_layer->waiting_buffer);
1643 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1644 if (ret != TDM_ERROR_NONE)
1645 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1648 _pthread_mutex_unlock(&private_display->lock);
1652 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1654 TDM_RETURN_IF_FAIL(data != NULL);
1655 tdm_layer *layer = data;
1656 LAYER_FUNC_ENTRY_VOID_RETURN();
1657 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1659 _pthread_mutex_lock(&private_display->lock);
1661 if (private_layer->waiting_buffer) {
1662 _pthread_mutex_unlock(&private_display->lock);
1663 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1664 tbm_surface_queue_release(private_layer->buffer_queue,
1665 private_layer->waiting_buffer);
1666 _pthread_mutex_lock(&private_display->lock);
1669 private_layer->buffer_queue = NULL;
1671 _pthread_mutex_unlock(&private_display->lock);
1675 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1677 tdm_func_layer *func_layer;
1680 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1682 _pthread_mutex_lock(&private_display->lock);
1684 func_layer = &private_display->func_layer;
1686 if (private_layer->usable)
1687 TDM_INFO("layer(%p) not usable", private_layer);
1689 private_layer->usable = 0;
1691 if (!func_layer->layer_set_buffer) {
1692 _pthread_mutex_unlock(&private_display->lock);
1693 TDM_ERR("not implemented!!");
1694 return TDM_ERROR_NOT_IMPLEMENTED;
1697 if (buffer_queue == private_layer->buffer_queue) {
1698 _pthread_mutex_unlock(&private_display->lock);
1699 return TDM_ERROR_NONE;
1702 if (private_layer->waiting_buffer) {
1703 _pthread_mutex_unlock(&private_display->lock);
1704 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1705 tbm_surface_queue_release(private_layer->buffer_queue,
1706 private_layer->waiting_buffer);
1707 private_layer->waiting_buffer = NULL;
1708 _pthread_mutex_lock(&private_display->lock);
1710 if (tdm_debug_buffer)
1711 TDM_INFO("layer(%p) waiting_buffer(%p)",
1712 private_layer, private_layer->waiting_buffer);
1715 private_layer->buffer_queue = buffer_queue;
1716 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1717 _tbm_layer_queue_acquirable_cb,
1719 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1720 _tbm_layer_queue_destroy_cb,
1722 _pthread_mutex_unlock(&private_display->lock);
1728 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1730 tdm_func_layer *func_layer;
1733 _pthread_mutex_lock(&private_display->lock);
1735 func_layer = &private_display->func_layer;
1737 if (private_layer->waiting_buffer) {
1738 _pthread_mutex_unlock(&private_display->lock);
1739 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1740 tbm_surface_queue_release(private_layer->buffer_queue,
1741 private_layer->waiting_buffer);
1742 private_layer->waiting_buffer = NULL;
1743 _pthread_mutex_lock(&private_display->lock);
1745 if (tdm_debug_buffer)
1746 TDM_INFO("layer(%p) waiting_buffer(%p)",
1747 private_layer, private_layer->waiting_buffer);
1750 if (private_layer->showing_buffer) {
1751 _pthread_mutex_unlock(&private_display->lock);
1752 tdm_buffer_unref_backend(private_layer->showing_buffer);
1753 tbm_surface_queue_release(private_layer->buffer_queue,
1754 private_layer->showing_buffer);
1755 _pthread_mutex_lock(&private_display->lock);
1756 private_layer->showing_buffer = NULL;
1758 if (tdm_debug_buffer)
1759 TDM_INFO("layer(%p) showing_buffer(%p)",
1760 private_layer, private_layer->showing_buffer);
1763 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1764 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1765 private_layer->buffer_queue = NULL;
1766 private_layer->usable = 1;
1768 if (private_layer->usable)
1769 TDM_INFO("layer(%p) now usable", private_layer);
1771 if (!func_layer->layer_unset_buffer) {
1772 _pthread_mutex_unlock(&private_display->lock);
1773 TDM_ERR("not implemented!!");
1774 return TDM_ERROR_NOT_IMPLEMENTED;
1777 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1779 _pthread_mutex_unlock(&private_display->lock);
1785 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1789 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1791 _pthread_mutex_lock(&private_display->lock);
1793 *usable = private_layer->usable;
1795 _pthread_mutex_unlock(&private_display->lock);
1801 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1803 tdm_func_layer *func_layer;
1806 _pthread_mutex_lock(&private_display->lock);
1808 func_layer = &private_display->func_layer;
1810 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1811 TDM_ERR("layer(%p) is not video layer", private_layer);
1812 _pthread_mutex_unlock(&private_display->lock);
1813 return TDM_ERROR_INVALID_PARAMETER;
1816 if (!func_layer->layer_set_video_pos) {
1817 _pthread_mutex_unlock(&private_display->lock);
1818 TDM_ERR("not implemented!!");
1819 return TDM_ERROR_NOT_IMPLEMENTED;
1822 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1824 _pthread_mutex_unlock(&private_display->lock);
1829 EXTERN tdm_capture *
1830 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1832 tdm_capture *capture = NULL;
1834 LAYER_FUNC_ENTRY_ERROR();
1836 _pthread_mutex_lock(&private_display->lock);
1838 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer, error);
1840 _pthread_mutex_unlock(&private_display->lock);