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 TDM_DBG("failed: not implemented!!");
589 return TDM_ERROR_NOT_IMPLEMENTED;
592 ret = func_output->output_set_property(private_output->output_backend, id,
595 _pthread_mutex_unlock(&private_display->lock);
601 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
603 tdm_func_output *func_output;
606 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
608 _pthread_mutex_lock(&private_display->lock);
610 func_output = &private_display->func_output;
612 if (!func_output->output_get_property) {
613 _pthread_mutex_unlock(&private_display->lock);
614 TDM_DBG("failed: not implemented!!");
615 return TDM_ERROR_NOT_IMPLEMENTED;
618 ret = func_output->output_get_property(private_output->output_backend, id,
621 _pthread_mutex_unlock(&private_display->lock);
627 _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
628 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
630 tdm_private_vblank_handler *vblank_handler = user_data;
631 tdm_private_display *private_display;
633 TDM_RETURN_IF_FAIL(vblank_handler);
635 private_display = vblank_handler->private_output->private_display;
637 if (vblank_handler->func) {
638 _pthread_mutex_unlock(&private_display->lock);
639 vblank_handler->func(vblank_handler->private_output, sequence,
640 tv_sec, tv_usec, vblank_handler->user_data);
641 _pthread_mutex_lock(&private_display->lock);
644 LIST_DEL(&vblank_handler->link);
645 free(vblank_handler);
649 _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
650 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
652 tdm_private_commit_handler *commit_handler = user_data;
653 tdm_private_display *private_display;
654 tdm_private_output *private_output;
655 tdm_private_layer *private_layer = NULL;
657 TDM_RETURN_IF_FAIL(commit_handler);
659 private_output = commit_handler->private_output;
660 private_display = private_output->private_display;
662 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
663 if (!private_layer->waiting_buffer)
666 if (private_layer->showing_buffer) {
667 _pthread_mutex_unlock(&private_display->lock);
668 tdm_buffer_unref_backend(private_layer->showing_buffer);
669 _pthread_mutex_lock(&private_display->lock);
671 if (private_layer->buffer_queue) {
672 _pthread_mutex_unlock(&private_display->lock);
673 tbm_surface_queue_release(private_layer->buffer_queue,
674 private_layer->showing_buffer);
675 _pthread_mutex_lock(&private_display->lock);
679 private_layer->showing_buffer = private_layer->waiting_buffer;
680 private_layer->waiting_buffer = NULL;
682 if (tdm_debug_buffer)
683 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
684 private_layer, private_layer->waiting_buffer,
685 private_layer->showing_buffer);
688 if (commit_handler->func) {
689 _pthread_mutex_unlock(&private_display->lock);
690 commit_handler->func(private_output, sequence,
691 tv_sec, tv_usec, commit_handler->user_data);
692 _pthread_mutex_lock(&private_display->lock);
695 LIST_DEL(&commit_handler->link);
696 free(commit_handler);
700 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
701 tdm_output_vblank_handler func, void *user_data)
703 tdm_func_output *func_output;
704 tdm_private_vblank_handler *vblank_handler;
707 _pthread_mutex_lock(&private_display->lock);
709 func_output = &private_display->func_output;
711 if (!func_output->output_wait_vblank) {
712 _pthread_mutex_unlock(&private_display->lock);
713 TDM_DBG("failed: not implemented!!");
714 return TDM_ERROR_NOT_IMPLEMENTED;
717 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
718 if (!vblank_handler) {
719 TDM_ERR("failed: alloc memory");
720 _pthread_mutex_unlock(&private_display->lock);
721 return TDM_ERROR_OUT_OF_MEMORY;
724 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
725 vblank_handler->private_output = private_output;
726 vblank_handler->func = func;
727 vblank_handler->user_data = user_data;
729 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
730 sync, vblank_handler);
731 if (ret != TDM_ERROR_NONE) {
732 _pthread_mutex_unlock(&private_display->lock);
736 if (!private_output->regist_vblank_cb) {
737 private_output->regist_vblank_cb = 1;
738 ret = func_output->output_set_vblank_handler(private_output->output_backend,
739 _tdm_output_cb_vblank);
742 _pthread_mutex_unlock(&private_display->lock);
748 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
751 tdm_func_output *func_output;
752 tdm_private_commit_handler *commit_handler;
755 func_output = &private_display->func_output;
757 if (!func_output->output_commit) {
758 TDM_DBG("failed: not implemented!!");
759 return TDM_ERROR_NOT_IMPLEMENTED;
762 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
763 if (!commit_handler) {
764 TDM_ERR("failed: alloc memory");
765 return TDM_ERROR_OUT_OF_MEMORY;
768 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
769 commit_handler->private_output = private_output;
770 commit_handler->func = func;
771 commit_handler->user_data = user_data;
773 ret = func_output->output_commit(private_output->output_backend, sync,
775 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
777 if (!private_output->regist_commit_cb) {
778 private_output->regist_commit_cb = 1;
779 ret = func_output->output_set_commit_handler(private_output->output_backend,
780 _tdm_output_cb_commit);
787 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
792 _pthread_mutex_lock(&private_display->lock);
794 ret = _tdm_output_commit(output, sync, func, user_data);
796 _pthread_mutex_unlock(&private_display->lock);
802 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
804 tdm_func_output *func_output;
807 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
809 _pthread_mutex_lock(&private_display->lock);
811 func_output = &private_display->func_output;
813 if (!func_output->output_set_mode) {
814 _pthread_mutex_unlock(&private_display->lock);
815 TDM_DBG("failed: not implemented!!");
816 return TDM_ERROR_NOT_IMPLEMENTED;
819 ret = func_output->output_set_mode(private_output->output_backend, mode);
821 _pthread_mutex_unlock(&private_display->lock);
827 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
829 tdm_func_output *func_output;
832 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
834 _pthread_mutex_lock(&private_display->lock);
836 func_output = &private_display->func_output;
838 if (!func_output->output_get_mode) {
839 _pthread_mutex_unlock(&private_display->lock);
840 TDM_DBG("failed: not implemented!!");
841 return TDM_ERROR_NOT_IMPLEMENTED;
844 ret = func_output->output_get_mode(private_output->output_backend, mode);
846 _pthread_mutex_unlock(&private_display->lock);
852 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
854 tdm_func_output *func_output;
857 if (dpms_value < TDM_OUTPUT_DPMS_ON)
858 dpms_value = TDM_OUTPUT_DPMS_ON;
859 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
860 dpms_value = TDM_OUTPUT_DPMS_OFF;
862 _pthread_mutex_lock(&private_display->lock);
864 func_output = &private_display->func_output;
866 if (!func_output->output_set_dpms) {
867 _pthread_mutex_unlock(&private_display->lock);
868 TDM_DBG("failed: not implemented!!");
869 return TDM_ERROR_NOT_IMPLEMENTED;
872 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
874 _pthread_mutex_unlock(&private_display->lock);
880 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
882 tdm_func_output *func_output;
885 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
887 _pthread_mutex_lock(&private_display->lock);
889 func_output = &private_display->func_output;
891 if (!func_output->output_get_dpms) {
892 _pthread_mutex_unlock(&private_display->lock);
893 TDM_DBG("failed: not implemented!!");
894 return TDM_ERROR_NOT_IMPLEMENTED;
897 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
899 _pthread_mutex_unlock(&private_display->lock);
905 tdm_output_create_capture(tdm_output *output, tdm_error *error)
907 tdm_capture *capture = NULL;
909 OUTPUT_FUNC_ENTRY_ERROR();
911 _pthread_mutex_lock(&private_display->lock);
913 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
916 _pthread_mutex_unlock(&private_display->lock);
922 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
926 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
928 _pthread_mutex_lock(&private_display->lock);
930 *capabilities = private_layer->caps.capabilities;
932 _pthread_mutex_unlock(&private_display->lock);
938 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
943 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
944 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
946 _pthread_mutex_lock(&private_display->lock);
948 *formats = (const tbm_format *)private_layer->caps.formats;
949 *count = private_layer->caps.format_count;
951 _pthread_mutex_unlock(&private_display->lock);
957 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
962 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
963 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
965 _pthread_mutex_lock(&private_display->lock);
967 *props = (const tdm_prop *)private_layer->caps.props;
968 *count = private_layer->caps.prop_count;
970 _pthread_mutex_unlock(&private_display->lock);
976 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
980 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
982 _pthread_mutex_lock(&private_display->lock);
984 *zpos = private_layer->caps.zpos;
986 _pthread_mutex_unlock(&private_display->lock);
992 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
994 tdm_func_layer *func_layer;
997 _pthread_mutex_lock(&private_display->lock);
999 func_layer = &private_display->func_layer;
1001 if (!func_layer->layer_set_property) {
1002 _pthread_mutex_unlock(&private_display->lock);
1003 TDM_DBG("failed: not implemented!!");
1004 return TDM_ERROR_NOT_IMPLEMENTED;
1007 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
1009 _pthread_mutex_unlock(&private_display->lock);
1015 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1017 tdm_func_layer *func_layer;
1020 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1022 _pthread_mutex_lock(&private_display->lock);
1024 func_layer = &private_display->func_layer;
1026 if (!func_layer->layer_get_property) {
1027 _pthread_mutex_unlock(&private_display->lock);
1028 TDM_DBG("failed: not implemented!!");
1029 return TDM_ERROR_NOT_IMPLEMENTED;
1032 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1034 _pthread_mutex_unlock(&private_display->lock);
1040 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1042 tdm_func_layer *func_layer;
1045 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1047 _pthread_mutex_lock(&private_display->lock);
1049 func_layer = &private_display->func_layer;
1051 private_layer->usable = 0;
1053 if (!func_layer->layer_set_info) {
1054 _pthread_mutex_unlock(&private_display->lock);
1055 TDM_DBG("failed: not implemented!!");
1056 return TDM_ERROR_NOT_IMPLEMENTED;
1059 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1060 private_layer, info->src_config.size.h, info->src_config.size.v,
1061 info->src_config.pos.x, info->src_config.pos.y,
1062 info->src_config.pos.w, info->src_config.pos.h,
1063 FOURCC_STR(info->src_config.format),
1064 info->dst_pos.x, info->dst_pos.y,
1065 info->dst_pos.w, info->dst_pos.h,
1068 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1069 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1071 _pthread_mutex_unlock(&private_display->lock);
1077 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1079 tdm_func_layer *func_layer;
1082 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1084 _pthread_mutex_lock(&private_display->lock);
1086 func_layer = &private_display->func_layer;
1088 if (!func_layer->layer_get_info) {
1089 _pthread_mutex_unlock(&private_display->lock);
1090 TDM_DBG("failed: not implemented!!");
1091 return TDM_ERROR_NOT_IMPLEMENTED;
1094 ret = func_layer->layer_get_info(private_layer->layer_backend, info);
1096 _pthread_mutex_unlock(&private_display->lock);
1102 tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
1104 tdm_func_layer *func_layer;
1108 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1110 _pthread_mutex_lock(&private_display->lock);
1112 func_layer = &private_display->func_layer;
1114 private_layer->usable = 0;
1116 if (!func_layer->layer_set_buffer) {
1117 _pthread_mutex_unlock(&private_display->lock);
1118 TDM_DBG("failed: not implemented!!");
1119 return TDM_ERROR_NOT_IMPLEMENTED;
1122 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1123 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1125 if (ret == TDM_ERROR_NONE) {
1126 /* FIXME: should save to pending_buffer first. And after committing
1127 * successfully, need to move to waiting_buffer.
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);
1135 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1136 if (tdm_debug_buffer)
1137 TDM_INFO("layer(%p) waiting_buffer(%p)",
1138 private_layer, private_layer->waiting_buffer);
1141 _pthread_mutex_unlock(&private_display->lock);
1147 tdm_layer_unset_buffer(tdm_layer *layer)
1149 tdm_func_layer *func_layer;
1152 _pthread_mutex_lock(&private_display->lock);
1154 func_layer = &private_display->func_layer;
1156 if (private_layer->waiting_buffer) {
1157 _pthread_mutex_unlock(&private_display->lock);
1158 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1159 _pthread_mutex_lock(&private_display->lock);
1160 private_layer->waiting_buffer = NULL;
1162 if (tdm_debug_buffer)
1163 TDM_INFO("layer(%p) waiting_buffer(%p)",
1164 private_layer, private_layer->waiting_buffer);
1167 if (private_layer->showing_buffer) {
1168 _pthread_mutex_unlock(&private_display->lock);
1169 tdm_buffer_unref_backend(private_layer->showing_buffer);
1170 _pthread_mutex_lock(&private_display->lock);
1171 private_layer->showing_buffer = NULL;
1173 if (tdm_debug_buffer)
1174 TDM_INFO("layer(%p) showing_buffer(%p)",
1175 private_layer, private_layer->showing_buffer);
1178 private_layer->usable = 1;
1180 if (!func_layer->layer_unset_buffer) {
1181 _pthread_mutex_unlock(&private_display->lock);
1182 TDM_DBG("failed: not implemented!!");
1183 return TDM_ERROR_NOT_IMPLEMENTED;
1186 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1187 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1189 _pthread_mutex_unlock(&private_display->lock);
1195 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1197 TDM_RETURN_IF_FAIL(data != NULL);
1198 tdm_layer *layer = data;
1199 tdm_func_layer *func_layer;
1200 tbm_surface_h surface = NULL;
1201 LAYER_FUNC_ENTRY_VOID_RETURN();
1203 _pthread_mutex_lock(&private_display->lock);
1205 func_layer = &private_display->func_layer;
1206 if (!func_layer->layer_set_buffer) {
1207 _pthread_mutex_unlock(&private_display->lock);
1211 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1212 private_layer->buffer_queue, &surface) ||
1214 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1215 private_layer, surface);
1216 _pthread_mutex_unlock(&private_display->lock);
1220 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1221 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1223 if (ret == TDM_ERROR_NONE) {
1224 if (private_layer->waiting_buffer) {
1225 _pthread_mutex_unlock(&private_display->lock);
1226 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1227 tbm_surface_queue_release(private_layer->buffer_queue,
1228 private_layer->waiting_buffer);
1229 _pthread_mutex_lock(&private_display->lock);
1232 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1234 if (tdm_debug_buffer)
1235 TDM_INFO("layer(%p) waiting_buffer(%p)",
1236 private_layer, private_layer->waiting_buffer);
1238 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1239 if (ret != TDM_ERROR_NONE)
1240 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1243 _pthread_mutex_unlock(&private_display->lock);
1247 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1249 TDM_RETURN_IF_FAIL(data != NULL);
1250 tdm_layer *layer = data;
1251 LAYER_FUNC_ENTRY_VOID_RETURN();
1252 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1254 _pthread_mutex_lock(&private_display->lock);
1256 if (private_layer->waiting_buffer) {
1257 _pthread_mutex_unlock(&private_display->lock);
1258 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1259 tbm_surface_queue_release(private_layer->buffer_queue,
1260 private_layer->waiting_buffer);
1261 _pthread_mutex_lock(&private_display->lock);
1264 private_layer->buffer_queue = NULL;
1266 _pthread_mutex_unlock(&private_display->lock);
1270 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1272 tdm_func_layer *func_layer;
1275 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1277 _pthread_mutex_lock(&private_display->lock);
1279 func_layer = &private_display->func_layer;
1281 private_layer->usable = 0;
1283 if (!func_layer->layer_set_buffer) {
1284 _pthread_mutex_unlock(&private_display->lock);
1285 TDM_DBG("failed: not implemented!!");
1286 return TDM_ERROR_NOT_IMPLEMENTED;
1289 if (buffer_queue == private_layer->buffer_queue) {
1290 _pthread_mutex_unlock(&private_display->lock);
1291 return TDM_ERROR_NONE;
1294 if (private_layer->waiting_buffer) {
1295 _pthread_mutex_unlock(&private_display->lock);
1296 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1297 tbm_surface_queue_release(private_layer->buffer_queue,
1298 private_layer->waiting_buffer);
1299 private_layer->waiting_buffer = NULL;
1300 _pthread_mutex_lock(&private_display->lock);
1302 if (tdm_debug_buffer)
1303 TDM_INFO("layer(%p) waiting_buffer(%p)",
1304 private_layer, private_layer->waiting_buffer);
1307 private_layer->buffer_queue = buffer_queue;
1308 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1309 _tbm_layer_queue_acquirable_cb,
1311 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1312 _tbm_layer_queue_destroy_cb,
1314 _pthread_mutex_unlock(&private_display->lock);
1320 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1322 tdm_func_layer *func_layer;
1325 _pthread_mutex_lock(&private_display->lock);
1327 func_layer = &private_display->func_layer;
1329 if (private_layer->waiting_buffer) {
1330 _pthread_mutex_unlock(&private_display->lock);
1331 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1332 tbm_surface_queue_release(private_layer->buffer_queue,
1333 private_layer->waiting_buffer);
1334 private_layer->waiting_buffer = NULL;
1335 _pthread_mutex_lock(&private_display->lock);
1337 if (tdm_debug_buffer)
1338 TDM_INFO("layer(%p) waiting_buffer(%p)",
1339 private_layer, private_layer->waiting_buffer);
1342 if (private_layer->showing_buffer) {
1343 _pthread_mutex_unlock(&private_display->lock);
1344 tdm_buffer_unref_backend(private_layer->showing_buffer);
1345 tbm_surface_queue_release(private_layer->buffer_queue,
1346 private_layer->showing_buffer);
1347 _pthread_mutex_lock(&private_display->lock);
1348 private_layer->showing_buffer = NULL;
1350 if (tdm_debug_buffer)
1351 TDM_INFO("layer(%p) showing_buffer(%p)",
1352 private_layer, private_layer->showing_buffer);
1355 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1356 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1357 private_layer->buffer_queue = NULL;
1358 private_layer->usable = 1;
1360 if (!func_layer->layer_unset_buffer) {
1361 _pthread_mutex_unlock(&private_display->lock);
1362 TDM_DBG("failed: not implemented!!");
1363 return TDM_ERROR_NOT_IMPLEMENTED;
1366 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1368 _pthread_mutex_unlock(&private_display->lock);
1374 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1378 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1380 _pthread_mutex_lock(&private_display->lock);
1382 *usable = private_layer->usable;
1384 _pthread_mutex_unlock(&private_display->lock);
1390 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1392 tdm_func_layer *func_layer;
1395 _pthread_mutex_lock(&private_display->lock);
1397 func_layer = &private_display->func_layer;
1399 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1400 TDM_ERR("layer(%p) is not video layer", private_layer);
1401 _pthread_mutex_unlock(&private_display->lock);
1402 return TDM_ERROR_INVALID_PARAMETER;
1405 if (!func_layer->layer_set_video_pos) {
1406 _pthread_mutex_unlock(&private_display->lock);
1407 TDM_DBG("failed: not implemented!!");
1408 return TDM_ERROR_NOT_IMPLEMENTED;
1411 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1413 _pthread_mutex_unlock(&private_display->lock);
1418 EXTERN tdm_capture *
1419 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1421 tdm_capture *capture = NULL;
1423 LAYER_FUNC_ENTRY_ERROR();
1425 _pthread_mutex_lock(&private_display->lock);
1427 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1430 _pthread_mutex_unlock(&private_display->lock);