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"
46 #define DISPLAY_FUNC_ENTRY() \
47 tdm_private_display *private_display; \
48 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
49 TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
50 private_display = (tdm_private_display*)dpy;
52 #define DISPLAY_FUNC_ENTRY_ERROR() \
53 tdm_private_display *private_display; \
54 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
55 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
56 private_display = (tdm_private_display*)dpy;
58 #define OUTPUT_FUNC_ENTRY() \
59 tdm_private_display *private_display; \
60 tdm_private_output *private_output; \
61 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
62 TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
63 private_output = (tdm_private_output*)output; \
64 private_display = private_output->private_display
66 #define OUTPUT_FUNC_ENTRY_ERROR() \
67 tdm_private_display *private_display; \
68 tdm_private_output *private_output; \
69 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
70 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
71 private_output = (tdm_private_output*)output; \
72 private_display = private_output->private_display
74 #define LAYER_FUNC_ENTRY() \
75 tdm_private_display *private_display; \
76 tdm_private_output *private_output; \
77 tdm_private_layer *private_layer; \
78 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
79 TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
80 private_layer = (tdm_private_layer*)layer; \
81 private_output = private_layer->private_output; \
82 private_display = private_output->private_display
84 #define LAYER_FUNC_ENTRY_ERROR() \
85 tdm_private_display *private_display; \
86 tdm_private_output *private_output; \
87 tdm_private_layer *private_layer; \
88 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
89 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
90 private_layer = (tdm_private_layer*)layer; \
91 private_output = private_layer->private_output; \
92 private_display = private_output->private_display
94 #define LAYER_FUNC_ENTRY_VOID_RETURN() \
95 tdm_private_display *private_display; \
96 tdm_private_output *private_output; \
97 tdm_private_layer *private_layer; \
98 tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
99 TDM_RETURN_IF_FAIL(layer != NULL); \
100 private_layer = (tdm_private_layer*)layer; \
101 private_output = private_layer->private_output; \
102 private_display = private_output->private_display
105 tdm_display_get_capabilities(tdm_display *dpy,
106 tdm_display_capability *capabilities)
108 DISPLAY_FUNC_ENTRY();
110 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
112 pthread_mutex_lock(&private_display->lock);
114 *capabilities = private_display->capabilities;
116 pthread_mutex_unlock(&private_display->lock);
122 tdm_display_get_pp_capabilities(tdm_display *dpy,
123 tdm_pp_capability *capabilities)
125 DISPLAY_FUNC_ENTRY();
127 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
129 pthread_mutex_lock(&private_display->lock);
131 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
132 TDM_ERR("no pp capability");
133 pthread_mutex_unlock(&private_display->lock);
134 return TDM_ERROR_NO_CAPABILITY;
137 *capabilities = private_display->caps_pp.capabilities;
139 pthread_mutex_unlock(&private_display->lock);
145 tdm_display_get_pp_available_formats(tdm_display *dpy,
146 const tbm_format **formats, int *count)
148 DISPLAY_FUNC_ENTRY();
150 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
151 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
153 pthread_mutex_lock(&private_display->lock);
155 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
156 TDM_ERR("no pp capability");
157 pthread_mutex_unlock(&private_display->lock);
158 return TDM_ERROR_NO_CAPABILITY;
161 *formats = (const tbm_format *)private_display->caps_pp.formats;
162 *count = private_display->caps_pp.format_count;
164 pthread_mutex_unlock(&private_display->lock);
170 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h,
171 int *max_w, int *max_h, int *preferred_align)
173 DISPLAY_FUNC_ENTRY();
175 pthread_mutex_lock(&private_display->lock);
177 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) {
178 TDM_ERR("no pp capability");
179 pthread_mutex_unlock(&private_display->lock);
180 return TDM_ERROR_NO_CAPABILITY;
184 *min_w = private_display->caps_pp.min_w;
186 *min_h = private_display->caps_pp.min_h;
188 *max_w = private_display->caps_pp.max_w;
190 *max_h = private_display->caps_pp.max_h;
192 *preferred_align = private_display->caps_pp.preferred_align;
194 pthread_mutex_unlock(&private_display->lock);
200 tdm_display_get_capture_capabilities(tdm_display *dpy,
201 tdm_capture_capability *capabilities)
203 DISPLAY_FUNC_ENTRY();
205 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
207 pthread_mutex_lock(&private_display->lock);
209 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
210 TDM_ERR("no capture capability");
211 pthread_mutex_unlock(&private_display->lock);
212 return TDM_ERROR_NO_CAPABILITY;
215 *capabilities = private_display->caps_capture.capabilities;
217 pthread_mutex_unlock(&private_display->lock);
223 tdm_display_get_catpure_available_formats(tdm_display *dpy,
224 const tbm_format **formats, int *count)
226 DISPLAY_FUNC_ENTRY();
228 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
229 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
231 pthread_mutex_lock(&private_display->lock);
233 if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) {
234 TDM_ERR("no capture capability");
235 pthread_mutex_unlock(&private_display->lock);
236 return TDM_ERROR_NO_CAPABILITY;
239 *formats = (const tbm_format *)private_display->caps_capture.formats;
240 *count = private_display->caps_capture.format_count;
242 pthread_mutex_unlock(&private_display->lock);
248 tdm_display_get_output_count(tdm_display *dpy, int *count)
250 tdm_private_output *private_output = NULL;
252 DISPLAY_FUNC_ENTRY();
254 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
256 pthread_mutex_lock(&private_display->lock);
259 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
263 pthread_mutex_unlock(&private_display->lock);
264 return TDM_ERROR_NONE;
267 pthread_mutex_unlock(&private_display->lock);
274 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
276 tdm_private_output *private_output = NULL;
279 DISPLAY_FUNC_ENTRY_ERROR();
281 pthread_mutex_lock(&private_display->lock);
284 *error = TDM_ERROR_NONE;
287 LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) {
289 pthread_mutex_unlock(&private_display->lock);
290 return private_output;
295 pthread_mutex_unlock(&private_display->lock);
301 tdm_display_get_fd(tdm_display *dpy, int *fd)
303 tdm_func_display *func_display;
304 DISPLAY_FUNC_ENTRY();
306 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
308 pthread_mutex_lock(&private_display->lock);
310 func_display = &private_display->func_display;
312 if (!func_display->display_get_fd) {
313 pthread_mutex_unlock(&private_display->lock);
314 return TDM_ERROR_NONE;
317 ret = func_display->display_get_fd(private_display->bdata, fd);
319 pthread_mutex_unlock(&private_display->lock);
325 tdm_display_handle_events(tdm_display *dpy)
327 tdm_func_display *func_display;
328 DISPLAY_FUNC_ENTRY();
330 pthread_mutex_lock(&private_display->lock);
332 func_display = &private_display->func_display;
334 if (!func_display->display_handle_events) {
335 pthread_mutex_unlock(&private_display->lock);
336 return TDM_ERROR_NONE;
339 ret = func_display->display_handle_events(private_display->bdata);
341 pthread_mutex_unlock(&private_display->lock);
347 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
351 DISPLAY_FUNC_ENTRY_ERROR();
353 pthread_mutex_lock(&private_display->lock);
355 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
357 pthread_mutex_unlock(&private_display->lock);
363 tdm_output_get_model_info(tdm_output *output, const char **maker,
364 const char **model, const char **name)
368 pthread_mutex_lock(&private_display->lock);
371 *maker = private_output->caps.maker;
373 *model = private_output->caps.model;
375 *name = private_output->caps.name;
377 pthread_mutex_unlock(&private_display->lock);
383 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
387 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
389 pthread_mutex_lock(&private_display->lock);
391 *status = private_output->caps.status;
393 pthread_mutex_unlock(&private_display->lock);
399 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
403 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
405 pthread_mutex_lock(&private_display->lock);
407 *type = private_output->caps.type;
409 pthread_mutex_unlock(&private_display->lock);
415 tdm_output_get_layer_count(tdm_output *output, int *count)
417 tdm_private_layer *private_layer = NULL;
421 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
423 pthread_mutex_lock(&private_display->lock);
426 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
429 pthread_mutex_unlock(&private_display->lock);
430 return TDM_ERROR_NONE;
433 pthread_mutex_unlock(&private_display->lock);
440 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
442 tdm_private_layer *private_layer = NULL;
445 OUTPUT_FUNC_ENTRY_ERROR();
447 pthread_mutex_lock(&private_display->lock);
450 *error = TDM_ERROR_NONE;
452 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
454 pthread_mutex_unlock(&private_display->lock);
455 return private_layer;
460 pthread_mutex_unlock(&private_display->lock);
466 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
471 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
472 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
474 pthread_mutex_lock(&private_display->lock);
476 *props = (const tdm_prop *)private_output->caps.props;
477 *count = private_output->caps.prop_count;
479 pthread_mutex_unlock(&private_display->lock);
485 tdm_output_get_available_modes(tdm_output *output,
486 const tdm_output_mode **modes, int *count)
490 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
491 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
493 pthread_mutex_lock(&private_display->lock);
495 *modes = (const tdm_output_mode *)private_output->caps.modes;
496 *count = private_output->caps.mode_count;
498 pthread_mutex_unlock(&private_display->lock);
504 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
505 int *max_w, int *max_h, int *preferred_align)
509 pthread_mutex_lock(&private_display->lock);
512 *min_w = private_output->caps.min_w;
514 *min_h = private_output->caps.min_h;
516 *max_w = private_output->caps.max_w;
518 *max_h = private_output->caps.max_h;
520 *preferred_align = private_output->caps.preferred_align;
522 pthread_mutex_unlock(&private_display->lock);
528 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
529 unsigned int *mmHeight)
533 pthread_mutex_lock(&private_display->lock);
536 *mmWidth = private_output->caps.mmWidth;
538 *mmHeight = private_output->caps.mmHeight;
540 pthread_mutex_unlock(&private_display->lock);
546 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
549 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
551 pthread_mutex_lock(&private_display->lock);
553 *subpixel = private_output->caps.subpixel;
555 pthread_mutex_unlock(&private_display->lock);
561 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
564 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
566 pthread_mutex_lock(&private_display->lock);
568 *pipe = private_output->pipe;
570 pthread_mutex_unlock(&private_display->lock);
577 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
579 tdm_func_output *func_output;
582 pthread_mutex_lock(&private_display->lock);
584 func_output = &private_display->func_output;
586 if (!func_output->output_set_property) {
587 pthread_mutex_unlock(&private_display->lock);
588 return TDM_ERROR_NONE;
591 ret = func_output->output_set_property(private_output->output_backend, id,
594 pthread_mutex_unlock(&private_display->lock);
600 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
602 tdm_func_output *func_output;
605 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
607 pthread_mutex_lock(&private_display->lock);
609 func_output = &private_display->func_output;
611 if (!func_output->output_get_property) {
612 pthread_mutex_unlock(&private_display->lock);
613 return TDM_ERROR_NONE;
616 ret = func_output->output_get_property(private_output->output_backend, id,
619 pthread_mutex_unlock(&private_display->lock);
625 _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
626 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
628 tdm_private_vblank_handler *vblank_handler = user_data;
629 tdm_private_display *private_display;
631 TDM_RETURN_IF_FAIL(vblank_handler);
633 private_display = vblank_handler->private_output->private_display;
635 if (vblank_handler->func) {
636 pthread_mutex_unlock(&private_display->lock);
637 vblank_handler->func(vblank_handler->private_output, sequence,
638 tv_sec, tv_usec, vblank_handler->user_data);
639 pthread_mutex_lock(&private_display->lock);
642 LIST_DEL(&vblank_handler->link);
643 free(vblank_handler);
647 _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
648 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
650 tdm_private_commit_handler *commit_handler = user_data;
651 tdm_private_display *private_display;
652 tdm_private_output *private_output;
653 tdm_private_layer *private_layer = NULL;
655 TDM_RETURN_IF_FAIL(commit_handler);
657 private_output = commit_handler->private_output;
658 private_display = private_output->private_display;
660 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
661 if (!private_layer->waiting_buffer)
664 if (private_layer->showing_buffer) {
665 pthread_mutex_unlock(&private_display->lock);
666 tdm_buffer_unref_backend(private_layer->showing_buffer);
667 pthread_mutex_lock(&private_display->lock);
669 if (private_layer->buffer_queue) {
670 pthread_mutex_unlock(&private_display->lock);
671 tbm_surface_queue_release(private_layer->buffer_queue,
672 private_layer->showing_buffer);
673 pthread_mutex_lock(&private_display->lock);
677 private_layer->showing_buffer = private_layer->waiting_buffer;
678 private_layer->waiting_buffer = NULL;
681 if (commit_handler->func) {
682 pthread_mutex_unlock(&private_display->lock);
683 commit_handler->func(private_output, sequence,
684 tv_sec, tv_usec, commit_handler->user_data);
685 pthread_mutex_lock(&private_display->lock);
688 LIST_DEL(&commit_handler->link);
689 free(commit_handler);
693 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
694 tdm_output_vblank_handler func, void *user_data)
696 tdm_func_output *func_output;
697 tdm_private_vblank_handler *vblank_handler;
700 pthread_mutex_lock(&private_display->lock);
702 func_output = &private_display->func_output;
704 if (!func_output->output_wait_vblank) {
705 pthread_mutex_unlock(&private_display->lock);
706 return TDM_ERROR_NONE;
709 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
710 if (!vblank_handler) {
711 TDM_ERR("failed: alloc memory");
712 pthread_mutex_unlock(&private_display->lock);
713 return TDM_ERROR_OUT_OF_MEMORY;
716 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
717 vblank_handler->private_output = private_output;
718 vblank_handler->func = func;
719 vblank_handler->user_data = user_data;
721 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
722 sync, vblank_handler);
723 if (ret != TDM_ERROR_NONE) {
724 pthread_mutex_unlock(&private_display->lock);
728 if (!private_output->regist_vblank_cb) {
729 private_output->regist_vblank_cb = 1;
730 ret = func_output->output_set_vblank_handler(private_output->output_backend,
731 _tdm_output_cb_vblank);
734 pthread_mutex_unlock(&private_display->lock);
740 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
743 tdm_func_output *func_output;
744 tdm_private_commit_handler *commit_handler;
747 func_output = &private_display->func_output;
749 if (!func_output->output_commit) {
750 return TDM_ERROR_NONE;
753 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
754 if (!commit_handler) {
755 TDM_ERR("failed: alloc memory");
756 return TDM_ERROR_OUT_OF_MEMORY;
759 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
760 commit_handler->private_output = private_output;
761 commit_handler->func = func;
762 commit_handler->user_data = user_data;
764 ret = func_output->output_commit(private_output->output_backend, sync,
766 if (ret != TDM_ERROR_NONE) {
770 if (!private_output->regist_commit_cb) {
771 private_output->regist_commit_cb = 1;
772 ret = func_output->output_set_commit_handler(private_output->output_backend,
773 _tdm_output_cb_commit);
780 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
785 pthread_mutex_lock(&private_display->lock);
787 ret = _tdm_output_commit(output, sync, func, user_data);
789 pthread_mutex_unlock(&private_display->lock);
795 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
797 tdm_func_output *func_output;
800 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
802 pthread_mutex_lock(&private_display->lock);
804 func_output = &private_display->func_output;
806 if (!func_output->output_set_mode) {
807 pthread_mutex_unlock(&private_display->lock);
808 return TDM_ERROR_NONE;
811 ret = func_output->output_set_mode(private_output->output_backend, mode);
813 pthread_mutex_unlock(&private_display->lock);
819 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
821 tdm_func_output *func_output;
824 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
826 pthread_mutex_lock(&private_display->lock);
828 func_output = &private_display->func_output;
830 if (!func_output->output_get_mode) {
831 pthread_mutex_unlock(&private_display->lock);
832 return TDM_ERROR_NONE;
835 ret = func_output->output_get_mode(private_output->output_backend, mode);
837 pthread_mutex_unlock(&private_display->lock);
843 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
845 tdm_func_output *func_output;
848 if (dpms_value < TDM_OUTPUT_DPMS_ON)
849 dpms_value = TDM_OUTPUT_DPMS_ON;
850 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
851 dpms_value = TDM_OUTPUT_DPMS_OFF;
853 pthread_mutex_lock(&private_display->lock);
855 func_output = &private_display->func_output;
857 if (!func_output->output_set_dpms) {
858 pthread_mutex_unlock(&private_display->lock);
859 return TDM_ERROR_NONE;
862 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
864 pthread_mutex_unlock(&private_display->lock);
870 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
872 tdm_func_output *func_output;
875 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
877 pthread_mutex_lock(&private_display->lock);
879 func_output = &private_display->func_output;
881 if (!func_output->output_get_dpms) {
882 pthread_mutex_unlock(&private_display->lock);
883 return TDM_ERROR_NONE;
886 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
888 pthread_mutex_unlock(&private_display->lock);
894 tdm_output_create_capture(tdm_output *output, tdm_error *error)
896 tdm_capture *capture = NULL;
898 OUTPUT_FUNC_ENTRY_ERROR();
900 pthread_mutex_lock(&private_display->lock);
902 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
905 pthread_mutex_unlock(&private_display->lock);
911 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
915 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
917 pthread_mutex_lock(&private_display->lock);
919 *capabilities = private_layer->caps.capabilities;
921 pthread_mutex_unlock(&private_display->lock);
927 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
932 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
933 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
935 pthread_mutex_lock(&private_display->lock);
937 *formats = (const tbm_format *)private_layer->caps.formats;
938 *count = private_layer->caps.format_count;
940 pthread_mutex_unlock(&private_display->lock);
946 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
951 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
952 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
954 pthread_mutex_lock(&private_display->lock);
956 *props = (const tdm_prop *)private_layer->caps.props;
957 *count = private_layer->caps.prop_count;
959 pthread_mutex_unlock(&private_display->lock);
965 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
969 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
971 pthread_mutex_lock(&private_display->lock);
973 *zpos = private_layer->caps.zpos;
975 pthread_mutex_unlock(&private_display->lock);
981 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
983 tdm_func_layer *func_layer;
986 pthread_mutex_lock(&private_display->lock);
988 func_layer = &private_display->func_layer;
990 if (!func_layer->layer_set_property) {
991 pthread_mutex_unlock(&private_display->lock);
992 return TDM_ERROR_NONE;
995 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
997 pthread_mutex_unlock(&private_display->lock);
1003 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1005 tdm_func_layer *func_layer;
1008 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1010 pthread_mutex_lock(&private_display->lock);
1012 func_layer = &private_display->func_layer;
1014 if (!func_layer->layer_get_property) {
1015 pthread_mutex_unlock(&private_display->lock);
1016 return TDM_ERROR_NONE;
1019 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1021 pthread_mutex_unlock(&private_display->lock);
1027 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1029 tdm_func_layer *func_layer;
1032 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1034 pthread_mutex_lock(&private_display->lock);
1036 func_layer = &private_display->func_layer;
1038 private_layer->usable = 0;
1040 if (!func_layer->layer_set_info) {
1041 pthread_mutex_unlock(&private_display->lock);
1042 return TDM_ERROR_NONE;
1045 TDM_INFO("layer info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1046 info->src_config.size.h, info->src_config.size.v,
1047 info->src_config.pos.x, info->src_config.pos.y,
1048 info->src_config.pos.w, info->src_config.pos.h,
1049 FOURCC_STR(info->src_config.format),
1050 info->dst_pos.x, info->dst_pos.y,
1051 info->dst_pos.w, info->dst_pos.h,
1054 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1056 pthread_mutex_unlock(&private_display->lock);
1062 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1064 tdm_func_layer *func_layer;
1067 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1069 pthread_mutex_lock(&private_display->lock);
1071 func_layer = &private_display->func_layer;
1073 if (!func_layer->layer_get_info) {
1074 pthread_mutex_unlock(&private_display->lock);
1075 return TDM_ERROR_NONE;
1078 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1080 pthread_mutex_unlock(&private_display->lock);
1086 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1088 tdm_func_layer *func_layer;
1091 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1093 pthread_mutex_lock(&private_display->lock);
1095 func_layer = &private_display->func_layer;
1097 private_layer->usable = 0;
1099 if (!func_layer->layer_set_buffer) {
1100 pthread_mutex_unlock(&private_display->lock);
1101 return TDM_ERROR_NONE;
1104 if (private_layer->waiting_buffer) {
1105 pthread_mutex_unlock(&private_display->lock);
1106 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1107 pthread_mutex_lock(&private_display->lock);
1110 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1112 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1114 pthread_mutex_unlock(&private_display->lock);
1120 tdm_layer_unset_buffer(tdm_layer *layer)
1122 tdm_func_layer *func_layer;
1125 pthread_mutex_lock(&private_display->lock);
1127 func_layer = &private_display->func_layer;
1129 if (private_layer->waiting_buffer) {
1130 pthread_mutex_unlock(&private_display->lock);
1131 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1132 pthread_mutex_lock(&private_display->lock);
1133 private_layer->waiting_buffer = NULL;
1136 if (private_layer->showing_buffer) {
1137 pthread_mutex_unlock(&private_display->lock);
1138 tdm_buffer_unref_backend(private_layer->showing_buffer);
1139 pthread_mutex_lock(&private_display->lock);
1140 private_layer->showing_buffer = NULL;
1143 private_layer->usable = 1;
1145 if (!func_layer->layer_unset_buffer) {
1146 pthread_mutex_unlock(&private_display->lock);
1147 return TDM_ERROR_NONE;
1150 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1152 pthread_mutex_unlock(&private_display->lock);
1158 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1160 TDM_RETURN_IF_FAIL(data != NULL);
1161 tdm_layer *layer = data;
1162 tdm_func_layer *func_layer;
1163 tbm_surface_h surface = NULL;
1164 LAYER_FUNC_ENTRY_VOID_RETURN();
1166 pthread_mutex_lock(&private_display->lock);
1168 func_layer = &private_display->func_layer;
1169 if (!func_layer->layer_set_buffer) {
1170 pthread_mutex_unlock(&private_display->lock);
1174 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1175 private_layer->buffer_queue, &surface) ||
1177 TDM_ERR("tbm_surface_queue_acquire() failed surface:%p", surface);
1178 pthread_mutex_unlock(&private_display->lock);
1182 if (private_layer->waiting_buffer) {
1183 pthread_mutex_unlock(&private_display->lock);
1184 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1185 tbm_surface_queue_release(private_layer->buffer_queue,
1186 private_layer->waiting_buffer);
1187 pthread_mutex_lock(&private_display->lock);
1190 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1192 func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1194 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1195 if (ret != TDM_ERROR_NONE)
1196 TDM_ERR("_tdm_output_commit() is fail");
1198 pthread_mutex_unlock(&private_display->lock);
1202 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1204 TDM_RETURN_IF_FAIL(data != NULL);
1205 tdm_layer *layer = data;
1206 LAYER_FUNC_ENTRY_VOID_RETURN();
1207 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1209 pthread_mutex_lock(&private_display->lock);
1211 if (private_layer->waiting_buffer) {
1212 pthread_mutex_unlock(&private_display->lock);
1213 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1214 tbm_surface_queue_release(private_layer->buffer_queue,
1215 private_layer->waiting_buffer);
1216 pthread_mutex_lock(&private_display->lock);
1219 private_layer->buffer_queue = NULL;
1221 pthread_mutex_unlock(&private_display->lock);
1225 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1227 tdm_func_layer *func_layer;
1230 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1232 pthread_mutex_lock(&private_display->lock);
1234 func_layer = &private_display->func_layer;
1236 private_layer->usable = 0;
1238 if (!func_layer->layer_set_buffer) {
1239 pthread_mutex_unlock(&private_display->lock);
1240 return TDM_ERROR_NONE;
1243 if (buffer_queue == private_layer->buffer_queue) {
1244 pthread_mutex_unlock(&private_display->lock);
1245 return TDM_ERROR_NONE;
1248 if (private_layer->waiting_buffer) {
1249 pthread_mutex_unlock(&private_display->lock);
1250 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1251 tbm_surface_queue_release(private_layer->buffer_queue,
1252 private_layer->waiting_buffer);
1253 private_layer->waiting_buffer = NULL;
1254 pthread_mutex_lock(&private_display->lock);
1257 private_layer->buffer_queue = buffer_queue;
1258 tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue,
1259 _tbm_layer_queue_acquirable_cb,
1261 tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue,
1262 _tbm_layer_queue_destroy_cb,
1264 pthread_mutex_unlock(&private_display->lock);
1270 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1272 tdm_func_layer *func_layer;
1275 pthread_mutex_lock(&private_display->lock);
1277 func_layer = &private_display->func_layer;
1279 if (private_layer->waiting_buffer) {
1280 pthread_mutex_unlock(&private_display->lock);
1281 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1282 tbm_surface_queue_release(private_layer->buffer_queue,
1283 private_layer->waiting_buffer);
1284 private_layer->waiting_buffer = NULL;
1285 pthread_mutex_lock(&private_display->lock);
1288 if (private_layer->showing_buffer) {
1289 pthread_mutex_unlock(&private_display->lock);
1290 tdm_buffer_unref_backend(private_layer->showing_buffer);
1291 tbm_surface_queue_release(private_layer->buffer_queue,
1292 private_layer->showing_buffer);
1293 pthread_mutex_lock(&private_display->lock);
1294 private_layer->showing_buffer = NULL;
1297 tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, NULL, NULL);
1298 tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue, NULL, NULL);
1299 private_layer->buffer_queue = NULL;
1300 private_layer->usable = 1;
1302 if (!func_layer->layer_unset_buffer) {
1303 pthread_mutex_unlock(&private_display->lock);
1304 return TDM_ERROR_NONE;
1307 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1309 pthread_mutex_unlock(&private_display->lock);
1315 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1319 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1321 pthread_mutex_lock(&private_display->lock);
1323 *usable = private_layer->usable;
1325 pthread_mutex_unlock(&private_display->lock);
1331 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1333 tdm_func_layer *func_layer;
1336 pthread_mutex_lock(&private_display->lock);
1338 func_layer = &private_display->func_layer;
1340 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1341 TDM_ERR("layer is not video layer");
1342 pthread_mutex_unlock(&private_display->lock);
1343 return TDM_ERROR_INVALID_PARAMETER;
1346 if (!func_layer->layer_set_video_pos) {
1347 pthread_mutex_unlock(&private_display->lock);
1348 return TDM_ERROR_NONE;
1351 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1353 pthread_mutex_unlock(&private_display->lock);
1358 EXTERN tdm_capture *
1359 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1361 tdm_capture *capture = NULL;
1363 LAYER_FUNC_ENTRY_ERROR();
1365 pthread_mutex_lock(&private_display->lock);
1367 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1370 pthread_mutex_unlock(&private_display->lock);