1 /**************************************************************************
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8 JinYoung Jeon <jy0.jeon@samsung.com>,
9 Taeheon Kim <th908.kim@samsung.com>,
10 YoungJun Cho <yj44.cho@samsung.com>,
11 SooChan Lim <sc1.lim@samsung.com>,
12 Boram Park <sc1.lim@samsung.com>
14 Permission is hereby granted, free of charge, to any person obtaining a
15 copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sub license, and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following conditions:
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 **************************************************************************/
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
43 #include "tdm_helper.h"
47 #define DISPLAY_FUNC_ENTRY() \
48 tdm_private_display *private_display; \
49 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
50 TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
51 private_display = (tdm_private_display*)dpy;
53 #define DISPLAY_FUNC_ENTRY_ERROR() \
54 tdm_private_display *private_display; \
55 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
56 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
57 private_display = (tdm_private_display*)dpy;
59 #define OUTPUT_FUNC_ENTRY() \
60 tdm_private_display *private_display; \
61 tdm_private_output *private_output; \
62 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
63 TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
64 private_output = (tdm_private_output*)output; \
65 private_display = private_output->private_display
67 #define OUTPUT_FUNC_ENTRY_ERROR() \
68 tdm_private_display *private_display; \
69 tdm_private_output *private_output; \
70 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
71 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
72 private_output = (tdm_private_output*)output; \
73 private_display = private_output->private_display
75 #define LAYER_FUNC_ENTRY() \
76 tdm_private_display *private_display; \
77 tdm_private_output *private_output; \
78 tdm_private_layer *private_layer; \
79 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
80 TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
81 private_layer = (tdm_private_layer*)layer; \
82 private_output = private_layer->private_output; \
83 private_display = private_output->private_display
85 #define LAYER_FUNC_ENTRY_ERROR() \
86 tdm_private_display *private_display; \
87 tdm_private_output *private_output; \
88 tdm_private_layer *private_layer; \
89 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
90 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
91 private_layer = (tdm_private_layer*)layer; \
92 private_output = private_layer->private_output; \
93 private_display = private_output->private_display
95 #define LAYER_FUNC_ENTRY_VOID_RETURN() \
96 tdm_private_display *private_display; \
97 tdm_private_output *private_output; \
98 tdm_private_layer *private_layer; \
99 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
100 TDM_RETURN_IF_FAIL(layer != NULL); \
101 private_layer = (tdm_private_layer*)layer; \
102 private_output = private_layer->private_output; \
103 private_display = private_output->private_display
105 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
112 #define type_name_fn(res) \
113 const char * res##_str(int type) { \
115 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
116 if (res##_names[i].type == type) \
117 return res##_names[i].name; \
119 return "(invalid)"; \
122 struct type_name dpms_names[] = {
123 { TDM_OUTPUT_DPMS_ON, "on" },
124 { TDM_OUTPUT_DPMS_STANDBY, "standby" },
125 { TDM_OUTPUT_DPMS_SUSPEND, "suspend" },
126 { TDM_OUTPUT_DPMS_OFF, "off" },
129 INTERN type_name_fn(dpms)
131 struct type_name status_names[] = {
132 { TDM_OUTPUT_CONN_STATUS_DISCONNECTED, "disconnected" },
133 { TDM_OUTPUT_CONN_STATUS_CONNECTED, "connected" },
134 { TDM_OUTPUT_CONN_STATUS_MODE_SETTED, "mode_setted" },
137 INTERN type_name_fn(status)
140 tdm_get_dpms_str(tdm_output_dpms dpms_value)
142 return dpms_str(dpms_value);
146 _tdm_display_lock(tdm_display *dpy, const char *func)
148 tdm_private_display *private_display = (tdm_private_display*)dpy;
152 TDM_INFO("mutex lock: %s", func);
154 ret = pthread_mutex_trylock(&private_display->lock);
157 TDM_ERR("mutex lock busy: %s", func);
159 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 ret = func_output->output_commit(private_output->output_backend, sync,
1062 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
1064 if (!private_output->regist_commit_cb) {
1065 private_output->regist_commit_cb = 1;
1066 ret = func_output->output_set_commit_handler(private_output->output_backend,
1067 tdm_output_cb_commit);
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,
1228 _pthread_mutex_unlock(&private_display->lock);
1234 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
1235 struct list_head *change_handler_list,
1236 tdm_output_change_type type,
1239 tdm_private_display *private_display;
1240 tdm_private_change_handler *change_handler;
1242 TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
1243 TDM_RETURN_IF_FAIL(private_output);
1245 private_display = private_output->private_display;
1246 if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) {
1247 if (type & TDM_OUTPUT_CHANGE_CONNECTION)
1248 TDM_INFO("output(%d) changed: %s (%d)",
1249 private_output->pipe, status_str(value.u32), value.u32);
1250 if (type & TDM_OUTPUT_CHANGE_DPMS)
1251 TDM_INFO("output(%d) changed: dpms %s (%d)",
1252 private_output->pipe, dpms_str(value.u32), value.u32);
1255 if (LIST_IS_EMPTY(change_handler_list))
1258 LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) {
1259 if (change_handler->owner_tid != syscall(SYS_gettid))
1260 TDM_NEVER_GET_HERE();
1262 _pthread_mutex_unlock(&private_display->lock);
1263 change_handler->func(private_output, type,
1264 value, change_handler->user_data);
1265 _pthread_mutex_lock(&private_display->lock);
1270 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
1274 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
1276 _pthread_mutex_lock(&private_display->lock);
1278 *capabilities = private_layer->caps.capabilities;
1280 _pthread_mutex_unlock(&private_display->lock);
1286 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
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,
1310 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
1311 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
1313 _pthread_mutex_lock(&private_display->lock);
1315 *props = (const tdm_prop *)private_layer->caps.props;
1316 *count = private_layer->caps.prop_count;
1318 _pthread_mutex_unlock(&private_display->lock);
1324 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
1328 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
1330 _pthread_mutex_lock(&private_display->lock);
1332 *zpos = private_layer->caps.zpos;
1334 _pthread_mutex_unlock(&private_display->lock);
1340 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
1342 tdm_func_layer *func_layer;
1345 _pthread_mutex_lock(&private_display->lock);
1347 func_layer = &private_display->func_layer;
1349 if (!func_layer->layer_set_property) {
1350 _pthread_mutex_unlock(&private_display->lock);
1351 TDM_ERR("not implemented!!");
1352 return TDM_ERROR_NOT_IMPLEMENTED;
1355 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1357 _pthread_mutex_unlock(&private_display->lock);
1363 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1365 tdm_func_layer *func_layer;
1368 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1370 _pthread_mutex_lock(&private_display->lock);
1372 func_layer = &private_display->func_layer;
1374 if (!func_layer->layer_get_property) {
1375 _pthread_mutex_unlock(&private_display->lock);
1376 TDM_ERR("not implemented!!");
1377 return TDM_ERROR_NOT_IMPLEMENTED;
1380 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1382 _pthread_mutex_unlock(&private_display->lock);
1388 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1390 tdm_func_layer *func_layer;
1393 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1395 _pthread_mutex_lock(&private_display->lock);
1397 func_layer = &private_display->func_layer;
1399 private_layer->usable = 0;
1401 if (!func_layer->layer_set_info) {
1402 _pthread_mutex_unlock(&private_display->lock);
1403 TDM_ERR("not implemented!!");
1404 return TDM_ERROR_NOT_IMPLEMENTED;
1407 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1408 private_layer, info->src_config.size.h, info->src_config.size.v,
1409 info->src_config.pos.x, info->src_config.pos.y,
1410 info->src_config.pos.w, info->src_config.pos.h,
1411 FOURCC_STR(info->src_config.format),
1412 info->dst_pos.x, info->dst_pos.y,
1413 info->dst_pos.w, info->dst_pos.h,
1416 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1417 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1419 _pthread_mutex_unlock(&private_display->lock);
1425 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1427 tdm_func_layer *func_layer;
1430 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1432 _pthread_mutex_lock(&private_display->lock);
1434 func_layer = &private_display->func_layer;
1436 if (!func_layer->layer_get_info) {
1437 _pthread_mutex_unlock(&private_display->lock);
1438 TDM_ERR("not implemented!!");
1439 return TDM_ERROR_NOT_IMPLEMENTED;
1442 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1444 _pthread_mutex_unlock(&private_display->lock);
1450 _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer)
1452 tdm_private_layer *private_layer = (tdm_private_layer*)layer;
1453 tdm_private_output *private_output = private_layer->private_output;
1456 char fname[PATH_MAX];
1458 pipe = private_output->pipe;
1459 zpos = private_layer->caps.zpos;
1461 snprintf(fname, sizeof(fname), "tdm_%d_lyr_%d", pipe, zpos);
1463 tbm_surface_internal_dump_buffer(buffer, fname);
1464 TDM_DBG("%s dump excute", fname);
1470 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1472 tdm_func_layer *func_layer;
1476 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1478 _pthread_mutex_lock(&private_display->lock);
1480 func_layer = &private_display->func_layer;
1482 private_layer->usable = 0;
1484 if (!func_layer->layer_set_buffer) {
1485 _pthread_mutex_unlock(&private_display->lock);
1486 TDM_ERR("not implemented!!");
1487 return TDM_ERROR_NOT_IMPLEMENTED;
1490 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1491 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1494 if (tdm_dump_enable)
1495 _tdm_layer_dump_buffer(layer, buffer);
1497 if (ret == TDM_ERROR_NONE) {
1498 /* FIXME: should save to pending_buffer first. And after committing
1499 * successfully, need to move to waiting_buffer.
1501 if (private_layer->waiting_buffer) {
1502 _pthread_mutex_unlock(&private_display->lock);
1503 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1504 _pthread_mutex_lock(&private_display->lock);
1507 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1508 if (tdm_debug_buffer)
1509 TDM_INFO("layer(%p) waiting_buffer(%p)",
1510 private_layer, private_layer->waiting_buffer);
1513 _pthread_mutex_unlock(&private_display->lock);
1519 tdm_layer_unset_buffer(tdm_layer *layer)
1521 tdm_func_layer *func_layer;
1524 _pthread_mutex_lock(&private_display->lock);
1526 func_layer = &private_display->func_layer;
1528 if (private_layer->waiting_buffer) {
1529 _pthread_mutex_unlock(&private_display->lock);
1530 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1531 _pthread_mutex_lock(&private_display->lock);
1532 private_layer->waiting_buffer = NULL;
1534 if (tdm_debug_buffer)
1535 TDM_INFO("layer(%p) waiting_buffer(%p)",
1536 private_layer, private_layer->waiting_buffer);
1539 if (private_layer->showing_buffer) {
1540 _pthread_mutex_unlock(&private_display->lock);
1541 tdm_buffer_unref_backend(private_layer->showing_buffer);
1542 _pthread_mutex_lock(&private_display->lock);
1543 private_layer->showing_buffer = NULL;
1545 if (tdm_debug_buffer)
1546 TDM_INFO("layer(%p) showing_buffer(%p)",
1547 private_layer, private_layer->showing_buffer);
1550 private_layer->usable = 1;
1552 if (!func_layer->layer_unset_buffer) {
1553 _pthread_mutex_unlock(&private_display->lock);
1554 TDM_ERR("not implemented!!");
1555 return TDM_ERROR_NOT_IMPLEMENTED;
1558 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1559 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1561 _pthread_mutex_unlock(&private_display->lock);
1566 EXTERN tbm_surface_h
1567 tdm_layer_get_displaying_buffer(tdm_layer *layer, tdm_error *error)
1569 tbm_surface_h buffer;
1570 LAYER_FUNC_ENTRY_ERROR();
1572 _pthread_mutex_lock(&private_display->lock);
1575 *error = TDM_ERROR_NONE;
1577 if (private_layer->showing_buffer) {
1578 buffer = private_layer->showing_buffer;
1581 *error = TDM_ERROR_OPERATION_FAILED;
1582 _pthread_mutex_unlock(&private_display->lock);
1583 TDM_ERR("layer(%p) showing_buffer is null",
1587 _pthread_mutex_unlock(&private_display->lock);
1593 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1595 TDM_RETURN_IF_FAIL(data != NULL);
1596 tdm_layer *layer = data;
1597 tdm_func_layer *func_layer;
1598 tbm_surface_h surface = NULL;
1599 LAYER_FUNC_ENTRY_VOID_RETURN();
1601 _pthread_mutex_lock(&private_display->lock);
1603 func_layer = &private_display->func_layer;
1604 if (!func_layer->layer_set_buffer) {
1605 _pthread_mutex_unlock(&private_display->lock);
1609 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1610 private_layer->buffer_queue, &surface) ||
1612 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1613 private_layer, surface);
1614 _pthread_mutex_unlock(&private_display->lock);
1618 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1619 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1621 if (ret == TDM_ERROR_NONE) {
1622 if (private_layer->waiting_buffer) {
1623 _pthread_mutex_unlock(&private_display->lock);
1624 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1625 tbm_surface_queue_release(private_layer->buffer_queue,
1626 private_layer->waiting_buffer);
1627 _pthread_mutex_lock(&private_display->lock);
1630 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1632 if (tdm_debug_buffer)
1633 TDM_INFO("layer(%p) waiting_buffer(%p)",
1634 private_layer, private_layer->waiting_buffer);
1636 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1637 if (ret != TDM_ERROR_NONE)
1638 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1641 _pthread_mutex_unlock(&private_display->lock);
1645 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1647 TDM_RETURN_IF_FAIL(data != NULL);
1648 tdm_layer *layer = data;
1649 LAYER_FUNC_ENTRY_VOID_RETURN();
1650 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1652 _pthread_mutex_lock(&private_display->lock);
1654 if (private_layer->waiting_buffer) {
1655 _pthread_mutex_unlock(&private_display->lock);
1656 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1657 tbm_surface_queue_release(private_layer->buffer_queue,
1658 private_layer->waiting_buffer);
1659 _pthread_mutex_lock(&private_display->lock);
1662 private_layer->buffer_queue = NULL;
1664 _pthread_mutex_unlock(&private_display->lock);
1668 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1670 tdm_func_layer *func_layer;
1673 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1675 _pthread_mutex_lock(&private_display->lock);
1677 func_layer = &private_display->func_layer;
1679 private_layer->usable = 0;
1681 if (!func_layer->layer_set_buffer) {
1682 _pthread_mutex_unlock(&private_display->lock);
1683 TDM_ERR("not implemented!!");
1684 return TDM_ERROR_NOT_IMPLEMENTED;
1687 if (buffer_queue == private_layer->buffer_queue) {
1688 _pthread_mutex_unlock(&private_display->lock);
1689 return TDM_ERROR_NONE;
1692 if (private_layer->waiting_buffer) {
1693 _pthread_mutex_unlock(&private_display->lock);
1694 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1695 tbm_surface_queue_release(private_layer->buffer_queue,
1696 private_layer->waiting_buffer);
1697 private_layer->waiting_buffer = NULL;
1698 _pthread_mutex_lock(&private_display->lock);
1700 if (tdm_debug_buffer)
1701 TDM_INFO("layer(%p) waiting_buffer(%p)",
1702 private_layer, private_layer->waiting_buffer);
1705 private_layer->buffer_queue = buffer_queue;
1706 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1707 _tbm_layer_queue_acquirable_cb,
1709 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1710 _tbm_layer_queue_destroy_cb,
1712 _pthread_mutex_unlock(&private_display->lock);
1718 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1720 tdm_func_layer *func_layer;
1723 _pthread_mutex_lock(&private_display->lock);
1725 func_layer = &private_display->func_layer;
1727 if (private_layer->waiting_buffer) {
1728 _pthread_mutex_unlock(&private_display->lock);
1729 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1730 tbm_surface_queue_release(private_layer->buffer_queue,
1731 private_layer->waiting_buffer);
1732 private_layer->waiting_buffer = NULL;
1733 _pthread_mutex_lock(&private_display->lock);
1735 if (tdm_debug_buffer)
1736 TDM_INFO("layer(%p) waiting_buffer(%p)",
1737 private_layer, private_layer->waiting_buffer);
1740 if (private_layer->showing_buffer) {
1741 _pthread_mutex_unlock(&private_display->lock);
1742 tdm_buffer_unref_backend(private_layer->showing_buffer);
1743 tbm_surface_queue_release(private_layer->buffer_queue,
1744 private_layer->showing_buffer);
1745 _pthread_mutex_lock(&private_display->lock);
1746 private_layer->showing_buffer = NULL;
1748 if (tdm_debug_buffer)
1749 TDM_INFO("layer(%p) showing_buffer(%p)",
1750 private_layer, private_layer->showing_buffer);
1753 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1754 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1755 private_layer->buffer_queue = NULL;
1756 private_layer->usable = 1;
1758 if (!func_layer->layer_unset_buffer) {
1759 _pthread_mutex_unlock(&private_display->lock);
1760 TDM_ERR("not implemented!!");
1761 return TDM_ERROR_NOT_IMPLEMENTED;
1764 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1766 _pthread_mutex_unlock(&private_display->lock);
1772 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1776 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1778 _pthread_mutex_lock(&private_display->lock);
1780 *usable = private_layer->usable;
1782 _pthread_mutex_unlock(&private_display->lock);
1788 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1790 tdm_func_layer *func_layer;
1793 _pthread_mutex_lock(&private_display->lock);
1795 func_layer = &private_display->func_layer;
1797 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1798 TDM_ERR("layer(%p) is not video layer", private_layer);
1799 _pthread_mutex_unlock(&private_display->lock);
1800 return TDM_ERROR_INVALID_PARAMETER;
1803 if (!func_layer->layer_set_video_pos) {
1804 _pthread_mutex_unlock(&private_display->lock);
1805 TDM_ERR("not implemented!!");
1806 return TDM_ERROR_NOT_IMPLEMENTED;
1809 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1811 _pthread_mutex_unlock(&private_display->lock);
1816 EXTERN tdm_capture *
1817 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1819 tdm_capture *capture = NULL;
1821 LAYER_FUNC_ENTRY_ERROR();
1823 _pthread_mutex_lock(&private_display->lock);
1825 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1828 _pthread_mutex_unlock(&private_display->lock);