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 tbm_surface_queue_release(private_layer->buffer_queue,
953 private_layer->showing_buffer);
957 private_layer->showing_buffer = private_layer->waiting_buffer;
958 private_layer->waiting_buffer = NULL;
960 if (tdm_debug_buffer)
961 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
962 private_layer, private_layer->waiting_buffer,
963 private_layer->showing_buffer);
966 if (commit_handler->func) {
967 _pthread_mutex_unlock(&private_display->lock);
968 commit_handler->func(private_output, sequence,
969 tv_sec, tv_usec, commit_handler->user_data);
970 _pthread_mutex_lock(&private_display->lock);
973 LIST_DEL(&commit_handler->link);
974 free(commit_handler);
978 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
979 tdm_output_vblank_handler func, void *user_data)
981 tdm_func_output *func_output;
982 tdm_private_vblank_handler *vblank_handler;
985 _pthread_mutex_lock(&private_display->lock);
987 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
988 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
989 dpms_str(private_output->current_dpms_value));
990 _pthread_mutex_unlock(&private_display->lock);
991 return TDM_ERROR_BAD_REQUEST;
994 func_output = &private_display->func_output;
996 if (!func_output->output_wait_vblank) {
997 _pthread_mutex_unlock(&private_display->lock);
998 TDM_ERR("not implemented!!");
999 return TDM_ERROR_NOT_IMPLEMENTED;
1002 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
1003 if (!vblank_handler) {
1004 TDM_ERR("failed: alloc memory");
1005 _pthread_mutex_unlock(&private_display->lock);
1006 return TDM_ERROR_OUT_OF_MEMORY;
1009 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
1010 vblank_handler->private_output = private_output;
1011 vblank_handler->func = func;
1012 vblank_handler->user_data = user_data;
1013 vblank_handler->owner_tid = syscall(SYS_gettid);
1015 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
1016 sync, vblank_handler);
1017 if (ret != TDM_ERROR_NONE) {
1018 _pthread_mutex_unlock(&private_display->lock);
1022 if (!private_output->regist_vblank_cb) {
1023 private_output->regist_vblank_cb = 1;
1024 ret = func_output->output_set_vblank_handler(private_output->output_backend,
1025 tdm_output_cb_vblank);
1028 _pthread_mutex_unlock(&private_display->lock);
1034 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1037 tdm_func_output *func_output;
1038 tdm_private_commit_handler *commit_handler;
1039 OUTPUT_FUNC_ENTRY();
1041 func_output = &private_display->func_output;
1043 if (!func_output->output_commit) {
1044 TDM_ERR("not implemented!!");
1045 return TDM_ERROR_NOT_IMPLEMENTED;
1048 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
1049 if (!commit_handler) {
1050 TDM_ERR("failed: alloc memory");
1051 return TDM_ERROR_OUT_OF_MEMORY;
1054 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
1055 commit_handler->private_output = private_output;
1056 commit_handler->func = func;
1057 commit_handler->user_data = user_data;
1058 commit_handler->owner_tid = syscall(SYS_gettid);
1060 if (!private_output->regist_commit_cb) {
1061 private_output->regist_commit_cb = 1;
1062 ret = func_output->output_set_commit_handler(private_output->output_backend,
1063 tdm_output_cb_commit);
1066 ret = func_output->output_commit(private_output->output_backend, sync,
1068 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1074 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
1077 OUTPUT_FUNC_ENTRY();
1079 _pthread_mutex_lock(&private_display->lock);
1081 if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {
1082 TDM_ERR("output(%d) dpms: %s", private_output->pipe,
1083 dpms_str(private_output->current_dpms_value));
1084 _pthread_mutex_unlock(&private_display->lock);
1085 return TDM_ERROR_BAD_REQUEST;
1088 ret = _tdm_output_commit(output, sync, func, user_data);
1090 _pthread_mutex_unlock(&private_display->lock);
1096 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
1098 tdm_func_output *func_output;
1099 OUTPUT_FUNC_ENTRY();
1101 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1103 _pthread_mutex_lock(&private_display->lock);
1105 func_output = &private_display->func_output;
1107 if (!func_output->output_set_mode) {
1108 _pthread_mutex_unlock(&private_display->lock);
1109 TDM_ERR("not implemented!!");
1110 return TDM_ERROR_NOT_IMPLEMENTED;
1113 ret = func_output->output_set_mode(private_output->output_backend, mode);
1115 _pthread_mutex_unlock(&private_display->lock);
1121 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
1123 tdm_func_output *func_output;
1124 OUTPUT_FUNC_ENTRY();
1126 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
1128 _pthread_mutex_lock(&private_display->lock);
1130 func_output = &private_display->func_output;
1132 if (!func_output->output_get_mode) {
1133 _pthread_mutex_unlock(&private_display->lock);
1134 TDM_ERR("not implemented!!");
1135 return TDM_ERROR_NOT_IMPLEMENTED;
1138 ret = func_output->output_get_mode(private_output->output_backend, mode);
1140 _pthread_mutex_unlock(&private_display->lock);
1146 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
1148 tdm_func_output *func_output;
1149 OUTPUT_FUNC_ENTRY();
1151 if (dpms_value < TDM_OUTPUT_DPMS_ON)
1152 dpms_value = TDM_OUTPUT_DPMS_ON;
1153 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
1154 dpms_value = TDM_OUTPUT_DPMS_OFF;
1156 _pthread_mutex_lock(&private_display->lock);
1158 if (private_output->current_dpms_value == dpms_value) {
1159 _pthread_mutex_unlock(&private_display->lock);
1160 return TDM_ERROR_NONE;
1163 func_output = &private_display->func_output;
1165 if (!func_output->output_set_dpms) {
1166 _pthread_mutex_unlock(&private_display->lock);
1167 private_output->current_dpms_value = dpms_value;
1168 TDM_WRN("not implemented!!");
1169 return TDM_ERROR_NONE;
1172 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
1173 if (ret == TDM_ERROR_NONE) {
1176 private_output->current_dpms_value = dpms_value;
1178 value.u32 = dpms_value;
1179 tdm_output_call_change_handler_internal(private_output,
1180 &private_output->change_handler_list_main,
1181 TDM_OUTPUT_CHANGE_DPMS,
1185 _pthread_mutex_unlock(&private_display->lock);
1191 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
1193 tdm_func_output *func_output;
1194 OUTPUT_FUNC_ENTRY();
1196 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
1198 _pthread_mutex_lock(&private_display->lock);
1200 func_output = &private_display->func_output;
1202 if (!func_output->output_get_dpms) {
1203 *dpms_value = private_output->current_dpms_value;
1204 _pthread_mutex_unlock(&private_display->lock);
1205 TDM_WRN("not implemented!!");
1206 return TDM_ERROR_NONE;
1209 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
1211 _pthread_mutex_unlock(&private_display->lock);
1216 EXTERN tdm_capture *
1217 tdm_output_create_capture(tdm_output *output, tdm_error *error)
1219 tdm_capture *capture = NULL;
1221 OUTPUT_FUNC_ENTRY_ERROR();
1223 _pthread_mutex_lock(&private_display->lock);
1225 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output, error);
1227 _pthread_mutex_unlock(&private_display->lock);
1233 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1234 struct list_head *change_handler_list,
1235 tdm_output_change_type type,
1238 tdm_private_display *private_display;
1239 tdm_private_change_handler *change_handler;
1241 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1242 TDM_RETURN_IF_FAIL(private_output);
1244 private_display = private_output->private_display;
1245 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1246 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1247 TDM_INFO("output(%d) changed: %s (%d)",
1248 private_output->pipe, status_str(value.u32), value.u32);
1249 if (type & TDM_OUTPUT_CHANGE_DPMS)
1250 TDM_INFO("output(%d) changed: dpms %s (%d)",
1251 private_output->pipe, dpms_str(value.u32), value.u32);
1254 if (LIST_IS_EMPTY(change_handler_list))
1257 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1258 if (change_handler->owner_tid != syscall(SYS_gettid))
1259 TDM_NEVER_GET_HERE();
1261 _pthread_mutex_unlock(&private_display->lock);
1262 change_handler->func(private_output, type,
1263 value, change_handler->user_data);
1264 _pthread_mutex_lock(&private_display->lock);
1269 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1273 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1275 _pthread_mutex_lock(&private_display->lock);
1277 *capabilities = private_layer->caps.capabilities;
1279 _pthread_mutex_unlock(&private_display->lock);
1285 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
1289 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
1290 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1292 _pthread_mutex_lock(&private_display->lock);
1294 *formats = (const tbm_format *)private_layer->caps.formats;
1295 *count = private_layer->caps.format_count;
1297 _pthread_mutex_unlock(&private_display->lock);
1303 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
1307 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1308 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1310 _pthread_mutex_lock(&private_display->lock);
1312 *props = (const tdm_prop *)private_layer->caps.props;
1313 *count = private_layer->caps.prop_count;
1315 _pthread_mutex_unlock(&private_display->lock);
1321 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1325 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1327 _pthread_mutex_lock(&private_display->lock);
1329 *zpos = private_layer->caps.zpos;
1331 _pthread_mutex_unlock(&private_display->lock);
1337 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1339 tdm_func_layer *func_layer;
1342 _pthread_mutex_lock(&private_display->lock);
1344 func_layer = &private_display->func_layer;
1346 if (!func_layer->layer_set_property) {
1347 _pthread_mutex_unlock(&private_display->lock);
1348 TDM_ERR("not implemented!!");
1349 return TDM_ERROR_NOT_IMPLEMENTED;
1352 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1354 _pthread_mutex_unlock(&private_display->lock);
1360 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1362 tdm_func_layer *func_layer;
1365 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1367 _pthread_mutex_lock(&private_display->lock);
1369 func_layer = &private_display->func_layer;
1371 if (!func_layer->layer_get_property) {
1372 _pthread_mutex_unlock(&private_display->lock);
1373 TDM_ERR("not implemented!!");
1374 return TDM_ERROR_NOT_IMPLEMENTED;
1377 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1379 _pthread_mutex_unlock(&private_display->lock);
1385 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1387 tdm_func_layer *func_layer;
1390 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1392 _pthread_mutex_lock(&private_display->lock);
1394 func_layer = &private_display->func_layer;
1396 private_layer->usable = 0;
1398 if (!func_layer->layer_set_info) {
1399 _pthread_mutex_unlock(&private_display->lock);
1400 TDM_ERR("not implemented!!");
1401 return TDM_ERROR_NOT_IMPLEMENTED;
1404 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1405 private_layer, info->src_config.size.h, info->src_config.size.v,
1406 info->src_config.pos.x, info->src_config.pos.y,
1407 info->src_config.pos.w, info->src_config.pos.h,
1408 FOURCC_STR(info->src_config.format),
1409 info->dst_pos.x, info->dst_pos.y,
1410 info->dst_pos.w, info->dst_pos.h,
1413 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1414 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1416 _pthread_mutex_unlock(&private_display->lock);
1422 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1424 tdm_func_layer *func_layer;
1427 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1429 _pthread_mutex_lock(&private_display->lock);
1431 func_layer = &private_display->func_layer;
1433 if (!func_layer->layer_get_info) {
1434 _pthread_mutex_unlock(&private_display->lock);
1435 TDM_ERR("not implemented!!");
1436 return TDM_ERROR_NOT_IMPLEMENTED;
1439 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1441 _pthread_mutex_unlock(&private_display->lock);
1447 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1449 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1450 tdm_private_output *private_output = private_layer->private_output;
1453 char fname[PATH_MAX];
1455 pipe = private_output->pipe;
1456 zpos = private_layer->caps.zpos;
1458 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1460 tbm_surface_internal_dump_buffer(buffer, fname);
1461 TDM_DBG("%s dump excute", fname);
1467 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1469 tdm_func_layer *func_layer;
1473 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1475 _pthread_mutex_lock(&private_display->lock);
1477 func_layer = &private_display->func_layer;
1479 private_layer->usable = 0;
1481 if (!func_layer->layer_set_buffer) {
1482 _pthread_mutex_unlock(&private_display->lock);
1483 TDM_ERR("not implemented!!");
1484 return TDM_ERROR_NOT_IMPLEMENTED;
1487 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1488 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1491 if (tdm_dump_enable)
1492 _tdm_layer_dump_buffer(layer, buffer);
1494 if (ret == TDM_ERROR_NONE) {
1495 /* FIXME: should save to pending_buffer first. And after committing
1496 * successfully, need to move to waiting_buffer.
1498 if (private_layer->waiting_buffer) {
1499 _pthread_mutex_unlock(&private_display->lock);
1500 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1501 _pthread_mutex_lock(&private_display->lock);
1504 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1505 if (tdm_debug_buffer)
1506 TDM_INFO("layer(%p) waiting_buffer(%p)",
1507 private_layer, private_layer->waiting_buffer);
1510 _pthread_mutex_unlock(&private_display->lock);
1516 tdm_layer_unset_buffer(tdm_layer *layer)
1518 tdm_func_layer *func_layer;
1521 _pthread_mutex_lock(&private_display->lock);
1523 func_layer = &private_display->func_layer;
1525 if (private_layer->waiting_buffer) {
1526 _pthread_mutex_unlock(&private_display->lock);
1527 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1528 _pthread_mutex_lock(&private_display->lock);
1529 private_layer->waiting_buffer = NULL;
1531 if (tdm_debug_buffer)
1532 TDM_INFO("layer(%p) waiting_buffer(%p)",
1533 private_layer, private_layer->waiting_buffer);
1536 if (private_layer->showing_buffer) {
1537 _pthread_mutex_unlock(&private_display->lock);
1538 tdm_buffer_unref_backend(private_layer->showing_buffer);
1539 _pthread_mutex_lock(&private_display->lock);
1540 private_layer->showing_buffer = NULL;
1542 if (tdm_debug_buffer)
1543 TDM_INFO("layer(%p) showing_buffer(%p)",
1544 private_layer, private_layer->showing_buffer);
1547 private_layer->usable = 1;
1549 if (!func_layer->layer_unset_buffer) {
1550 _pthread_mutex_unlock(&private_display->lock);
1551 TDM_ERR("not implemented!!");
1552 return TDM_ERROR_NOT_IMPLEMENTED;
1555 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1556 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1558 _pthread_mutex_unlock(&private_display->lock);
1563 EXTERN tbm_surface_h
1564 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1566 tbm_surface_h buffer;
1567 LAYER_FUNC_ENTRY_ERROR();
1569 _pthread_mutex_lock(&private_display->lock);
1572 *error = TDM_ERROR_NONE;
1574 if (private_layer->showing_buffer) {
1575 buffer = private_layer->showing_buffer;
1578 *error = TDM_ERROR_OPERATION_FAILED;
1579 _pthread_mutex_unlock(&private_display->lock);
1580 TDM_DBG("layer(%p) showing_buffer is null", private_layer);
1583 _pthread_mutex_unlock(&private_display->lock);
1589 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1591 TDM_RETURN_IF_FAIL(data != NULL);
1592 tdm_layer *layer = data;
1593 tdm_func_layer *func_layer;
1594 tbm_surface_h surface = NULL;
1595 LAYER_FUNC_ENTRY_VOID_RETURN();
1597 _pthread_mutex_lock(&private_display->lock);
1599 func_layer = &private_display->func_layer;
1600 if (!func_layer->layer_set_buffer) {
1601 _pthread_mutex_unlock(&private_display->lock);
1605 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) ||
1607 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1608 private_layer, surface);
1609 _pthread_mutex_unlock(&private_display->lock);
1613 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1614 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1616 if (ret == TDM_ERROR_NONE) {
1617 if (private_layer->waiting_buffer) {
1618 _pthread_mutex_unlock(&private_display->lock);
1619 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1620 tbm_surface_queue_release(private_layer->buffer_queue,
1621 private_layer->waiting_buffer);
1622 _pthread_mutex_lock(&private_display->lock);
1625 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1627 if (tdm_debug_buffer)
1628 TDM_INFO("layer(%p) waiting_buffer(%p)",
1629 private_layer, private_layer->waiting_buffer);
1631 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1632 if (ret != TDM_ERROR_NONE)
1633 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1636 _pthread_mutex_unlock(&private_display->lock);
1640 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1642 TDM_RETURN_IF_FAIL(data != NULL);
1643 tdm_layer *layer = data;
1644 LAYER_FUNC_ENTRY_VOID_RETURN();
1645 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1647 _pthread_mutex_lock(&private_display->lock);
1649 if (private_layer->waiting_buffer) {
1650 _pthread_mutex_unlock(&private_display->lock);
1651 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1652 tbm_surface_queue_release(private_layer->buffer_queue,
1653 private_layer->waiting_buffer);
1654 _pthread_mutex_lock(&private_display->lock);
1657 private_layer->buffer_queue = NULL;
1659 _pthread_mutex_unlock(&private_display->lock);
1663 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1665 tdm_func_layer *func_layer;
1668 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1670 _pthread_mutex_lock(&private_display->lock);
1672 func_layer = &private_display->func_layer;
1674 private_layer->usable = 0;
1676 if (!func_layer->layer_set_buffer) {
1677 _pthread_mutex_unlock(&private_display->lock);
1678 TDM_ERR("not implemented!!");
1679 return TDM_ERROR_NOT_IMPLEMENTED;
1682 if (buffer_queue == private_layer->buffer_queue) {
1683 _pthread_mutex_unlock(&private_display->lock);
1684 return TDM_ERROR_NONE;
1687 if (private_layer->waiting_buffer) {
1688 _pthread_mutex_unlock(&private_display->lock);
1689 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1690 tbm_surface_queue_release(private_layer->buffer_queue,
1691 private_layer->waiting_buffer);
1692 private_layer->waiting_buffer = NULL;
1693 _pthread_mutex_lock(&private_display->lock);
1695 if (tdm_debug_buffer)
1696 TDM_INFO("layer(%p) waiting_buffer(%p)",
1697 private_layer, private_layer->waiting_buffer);
1700 private_layer->buffer_queue = buffer_queue;
1701 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1702 _tbm_layer_queue_acquirable_cb,
1704 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1705 _tbm_layer_queue_destroy_cb,
1707 _pthread_mutex_unlock(&private_display->lock);
1713 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1715 tdm_func_layer *func_layer;
1718 _pthread_mutex_lock(&private_display->lock);
1720 func_layer = &private_display->func_layer;
1722 if (private_layer->waiting_buffer) {
1723 _pthread_mutex_unlock(&private_display->lock);
1724 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1725 tbm_surface_queue_release(private_layer->buffer_queue,
1726 private_layer->waiting_buffer);
1727 private_layer->waiting_buffer = NULL;
1728 _pthread_mutex_lock(&private_display->lock);
1730 if (tdm_debug_buffer)
1731 TDM_INFO("layer(%p) waiting_buffer(%p)",
1732 private_layer, private_layer->waiting_buffer);
1735 if (private_layer->showing_buffer) {
1736 _pthread_mutex_unlock(&private_display->lock);
1737 tdm_buffer_unref_backend(private_layer->showing_buffer);
1738 tbm_surface_queue_release(private_layer->buffer_queue,
1739 private_layer->showing_buffer);
1740 _pthread_mutex_lock(&private_display->lock);
1741 private_layer->showing_buffer = NULL;
1743 if (tdm_debug_buffer)
1744 TDM_INFO("layer(%p) showing_buffer(%p)",
1745 private_layer, private_layer->showing_buffer);
1748 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1749 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1750 private_layer->buffer_queue = NULL;
1751 private_layer->usable = 1;
1753 if (!func_layer->layer_unset_buffer) {
1754 _pthread_mutex_unlock(&private_display->lock);
1755 TDM_ERR("not implemented!!");
1756 return TDM_ERROR_NOT_IMPLEMENTED;
1759 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1761 _pthread_mutex_unlock(&private_display->lock);
1767 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1771 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1773 _pthread_mutex_lock(&private_display->lock);
1775 *usable = private_layer->usable;
1777 _pthread_mutex_unlock(&private_display->lock);
1783 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1785 tdm_func_layer *func_layer;
1788 _pthread_mutex_lock(&private_display->lock);
1790 func_layer = &private_display->func_layer;
1792 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1793 TDM_ERR("layer(%p) is not video layer", private_layer);
1794 _pthread_mutex_unlock(&private_display->lock);
1795 return TDM_ERROR_INVALID_PARAMETER;
1798 if (!func_layer->layer_set_video_pos) {
1799 _pthread_mutex_unlock(&private_display->lock);
1800 TDM_ERR("not implemented!!");
1801 return TDM_ERROR_NOT_IMPLEMENTED;
1804 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1806 _pthread_mutex_unlock(&private_display->lock);
1811 EXTERN tdm_capture *
1812 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1814 tdm_capture *capture = NULL;
1816 LAYER_FUNC_ENTRY_ERROR();
1818 _pthread_mutex_lock(&private_display->lock);
1820 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer, error);
1822 _pthread_mutex_unlock(&private_display->lock);