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 DISPLAY_FUNC_ENTRY();
305 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
307 _pthread_mutex_lock(&private_display->lock);
309 *fd = tdm_event_get_fd(private_display);
311 _pthread_mutex_unlock(&private_display->lock);
317 tdm_display_handle_events(tdm_display *dpy)
319 DISPLAY_FUNC_ENTRY();
321 _pthread_mutex_lock(&private_display->lock);
323 ret = tdm_event_dispatch(private_display);
325 _pthread_mutex_unlock(&private_display->lock);
331 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
335 DISPLAY_FUNC_ENTRY_ERROR();
337 _pthread_mutex_lock(&private_display->lock);
339 pp = (tdm_pp *)tdm_pp_create_internal(private_display, error);
341 _pthread_mutex_unlock(&private_display->lock);
347 tdm_output_get_model_info(tdm_output *output, const char **maker,
348 const char **model, const char **name)
352 _pthread_mutex_lock(&private_display->lock);
355 *maker = private_output->caps.maker;
357 *model = private_output->caps.model;
359 *name = private_output->caps.name;
361 _pthread_mutex_unlock(&private_display->lock);
367 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
371 TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
373 _pthread_mutex_lock(&private_display->lock);
375 *status = private_output->caps.status;
377 _pthread_mutex_unlock(&private_display->lock);
383 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
387 TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
389 _pthread_mutex_lock(&private_display->lock);
391 *type = private_output->caps.type;
393 _pthread_mutex_unlock(&private_display->lock);
399 tdm_output_get_layer_count(tdm_output *output, int *count)
401 tdm_private_layer *private_layer = NULL;
405 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
407 _pthread_mutex_lock(&private_display->lock);
410 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
413 _pthread_mutex_unlock(&private_display->lock);
414 return TDM_ERROR_NONE;
417 _pthread_mutex_unlock(&private_display->lock);
424 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
426 tdm_private_layer *private_layer = NULL;
429 OUTPUT_FUNC_ENTRY_ERROR();
431 _pthread_mutex_lock(&private_display->lock);
434 *error = TDM_ERROR_NONE;
436 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
438 _pthread_mutex_unlock(&private_display->lock);
439 return private_layer;
444 _pthread_mutex_unlock(&private_display->lock);
450 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props,
455 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
456 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
458 _pthread_mutex_lock(&private_display->lock);
460 *props = (const tdm_prop *)private_output->caps.props;
461 *count = private_output->caps.prop_count;
463 _pthread_mutex_unlock(&private_display->lock);
469 tdm_output_get_available_modes(tdm_output *output,
470 const tdm_output_mode **modes, int *count)
474 TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
475 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
477 _pthread_mutex_lock(&private_display->lock);
479 *modes = (const tdm_output_mode *)private_output->caps.modes;
480 *count = private_output->caps.mode_count;
482 _pthread_mutex_unlock(&private_display->lock);
488 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
489 int *max_w, int *max_h, int *preferred_align)
493 _pthread_mutex_lock(&private_display->lock);
496 *min_w = private_output->caps.min_w;
498 *min_h = private_output->caps.min_h;
500 *max_w = private_output->caps.max_w;
502 *max_h = private_output->caps.max_h;
504 *preferred_align = private_output->caps.preferred_align;
506 _pthread_mutex_unlock(&private_display->lock);
512 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth,
513 unsigned int *mmHeight)
517 _pthread_mutex_lock(&private_display->lock);
520 *mmWidth = private_output->caps.mmWidth;
522 *mmHeight = private_output->caps.mmHeight;
524 _pthread_mutex_unlock(&private_display->lock);
530 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
533 TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
535 _pthread_mutex_lock(&private_display->lock);
537 *subpixel = private_output->caps.subpixel;
539 _pthread_mutex_unlock(&private_display->lock);
545 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
548 TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
550 _pthread_mutex_lock(&private_display->lock);
552 *pipe = private_output->pipe;
554 _pthread_mutex_unlock(&private_display->lock);
561 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
563 tdm_func_output *func_output;
566 _pthread_mutex_lock(&private_display->lock);
568 func_output = &private_display->func_output;
570 if (!func_output->output_set_property) {
571 _pthread_mutex_unlock(&private_display->lock);
572 TDM_DBG("failed: not implemented!!");
573 return TDM_ERROR_NOT_IMPLEMENTED;
576 ret = func_output->output_set_property(private_output->output_backend, id,
579 _pthread_mutex_unlock(&private_display->lock);
585 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
587 tdm_func_output *func_output;
590 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
592 _pthread_mutex_lock(&private_display->lock);
594 func_output = &private_display->func_output;
596 if (!func_output->output_get_property) {
597 _pthread_mutex_unlock(&private_display->lock);
598 TDM_DBG("failed: not implemented!!");
599 return TDM_ERROR_NOT_IMPLEMENTED;
602 ret = func_output->output_get_property(private_output->output_backend, id,
605 _pthread_mutex_unlock(&private_display->lock);
611 _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
612 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
614 tdm_private_vblank_handler *vblank_handler = user_data;
615 tdm_private_display *private_display;
617 TDM_RETURN_IF_FAIL(vblank_handler);
619 private_display = vblank_handler->private_output->private_display;
621 if (vblank_handler->func) {
622 _pthread_mutex_unlock(&private_display->lock);
623 vblank_handler->func(vblank_handler->private_output, sequence,
624 tv_sec, tv_usec, vblank_handler->user_data);
625 _pthread_mutex_lock(&private_display->lock);
628 LIST_DEL(&vblank_handler->link);
629 free(vblank_handler);
633 _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
634 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
636 tdm_private_commit_handler *commit_handler = user_data;
637 tdm_private_display *private_display;
638 tdm_private_output *private_output;
639 tdm_private_layer *private_layer = NULL;
641 TDM_RETURN_IF_FAIL(commit_handler);
643 private_output = commit_handler->private_output;
644 private_display = private_output->private_display;
646 LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) {
647 if (!private_layer->waiting_buffer)
650 if (private_layer->showing_buffer) {
651 _pthread_mutex_unlock(&private_display->lock);
652 tdm_buffer_unref_backend(private_layer->showing_buffer);
653 _pthread_mutex_lock(&private_display->lock);
655 if (private_layer->buffer_queue) {
656 _pthread_mutex_unlock(&private_display->lock);
657 tbm_surface_queue_release(private_layer->buffer_queue,
658 private_layer->showing_buffer);
659 _pthread_mutex_lock(&private_display->lock);
663 private_layer->showing_buffer = private_layer->waiting_buffer;
664 private_layer->waiting_buffer = NULL;
666 if (tdm_debug_buffer)
667 TDM_INFO("layer(%p) waiting_buffer(%p) showing_buffer(%p)",
668 private_layer, private_layer->waiting_buffer,
669 private_layer->showing_buffer);
672 if (commit_handler->func) {
673 _pthread_mutex_unlock(&private_display->lock);
674 commit_handler->func(private_output, sequence,
675 tv_sec, tv_usec, commit_handler->user_data);
676 _pthread_mutex_lock(&private_display->lock);
679 LIST_DEL(&commit_handler->link);
680 free(commit_handler);
684 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
685 tdm_output_vblank_handler func, void *user_data)
687 tdm_func_output *func_output;
688 tdm_private_vblank_handler *vblank_handler;
691 _pthread_mutex_lock(&private_display->lock);
693 func_output = &private_display->func_output;
695 if (!func_output->output_wait_vblank) {
696 _pthread_mutex_unlock(&private_display->lock);
697 TDM_DBG("failed: not implemented!!");
698 return TDM_ERROR_NOT_IMPLEMENTED;
701 vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
702 if (!vblank_handler) {
703 TDM_ERR("failed: alloc memory");
704 _pthread_mutex_unlock(&private_display->lock);
705 return TDM_ERROR_OUT_OF_MEMORY;
708 LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
709 vblank_handler->private_output = private_output;
710 vblank_handler->func = func;
711 vblank_handler->user_data = user_data;
713 ret = func_output->output_wait_vblank(private_output->output_backend, interval,
714 sync, vblank_handler);
715 if (ret != TDM_ERROR_NONE) {
716 _pthread_mutex_unlock(&private_display->lock);
720 if (!private_output->regist_vblank_cb) {
721 private_output->regist_vblank_cb = 1;
722 ret = func_output->output_set_vblank_handler(private_output->output_backend,
723 _tdm_output_cb_vblank);
726 _pthread_mutex_unlock(&private_display->lock);
732 _tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
735 tdm_func_output *func_output;
736 tdm_private_commit_handler *commit_handler;
739 func_output = &private_display->func_output;
741 if (!func_output->output_commit) {
742 TDM_DBG("failed: not implemented!!");
743 return TDM_ERROR_NOT_IMPLEMENTED;
746 commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
747 if (!commit_handler) {
748 TDM_ERR("failed: alloc memory");
749 return TDM_ERROR_OUT_OF_MEMORY;
752 LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
753 commit_handler->private_output = private_output;
754 commit_handler->func = func;
755 commit_handler->user_data = user_data;
757 ret = func_output->output_commit(private_output->output_backend, sync,
759 TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
761 if (!private_output->regist_commit_cb) {
762 private_output->regist_commit_cb = 1;
763 ret = func_output->output_set_commit_handler(private_output->output_backend,
764 _tdm_output_cb_commit);
771 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func,
776 _pthread_mutex_lock(&private_display->lock);
778 ret = _tdm_output_commit(output, sync, func, user_data);
780 _pthread_mutex_unlock(&private_display->lock);
786 tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
788 tdm_func_output *func_output;
791 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
793 _pthread_mutex_lock(&private_display->lock);
795 func_output = &private_display->func_output;
797 if (!func_output->output_set_mode) {
798 _pthread_mutex_unlock(&private_display->lock);
799 TDM_DBG("failed: not implemented!!");
800 return TDM_ERROR_NOT_IMPLEMENTED;
803 ret = func_output->output_set_mode(private_output->output_backend, mode);
805 _pthread_mutex_unlock(&private_display->lock);
811 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
813 tdm_func_output *func_output;
816 TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
818 _pthread_mutex_lock(&private_display->lock);
820 func_output = &private_display->func_output;
822 if (!func_output->output_get_mode) {
823 _pthread_mutex_unlock(&private_display->lock);
824 TDM_DBG("failed: not implemented!!");
825 return TDM_ERROR_NOT_IMPLEMENTED;
828 ret = func_output->output_get_mode(private_output->output_backend, mode);
830 _pthread_mutex_unlock(&private_display->lock);
836 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
838 tdm_func_output *func_output;
841 if (dpms_value < TDM_OUTPUT_DPMS_ON)
842 dpms_value = TDM_OUTPUT_DPMS_ON;
843 else if (dpms_value > TDM_OUTPUT_DPMS_OFF)
844 dpms_value = TDM_OUTPUT_DPMS_OFF;
846 _pthread_mutex_lock(&private_display->lock);
848 func_output = &private_display->func_output;
850 if (!func_output->output_set_dpms) {
851 _pthread_mutex_unlock(&private_display->lock);
852 TDM_DBG("failed: not implemented!!");
853 return TDM_ERROR_NOT_IMPLEMENTED;
856 ret = func_output->output_set_dpms(private_output->output_backend, dpms_value);
858 _pthread_mutex_unlock(&private_display->lock);
864 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
866 tdm_func_output *func_output;
869 TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
871 _pthread_mutex_lock(&private_display->lock);
873 func_output = &private_display->func_output;
875 if (!func_output->output_get_dpms) {
876 _pthread_mutex_unlock(&private_display->lock);
877 TDM_DBG("failed: not implemented!!");
878 return TDM_ERROR_NOT_IMPLEMENTED;
881 ret = func_output->output_get_dpms(private_output->output_backend, dpms_value);
883 _pthread_mutex_unlock(&private_display->lock);
889 tdm_output_create_capture(tdm_output *output, tdm_error *error)
891 tdm_capture *capture = NULL;
893 OUTPUT_FUNC_ENTRY_ERROR();
895 _pthread_mutex_lock(&private_display->lock);
897 capture = (tdm_capture *)tdm_capture_create_output_internal(private_output,
900 _pthread_mutex_unlock(&private_display->lock);
906 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
910 TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
912 _pthread_mutex_lock(&private_display->lock);
914 *capabilities = private_layer->caps.capabilities;
916 _pthread_mutex_unlock(&private_display->lock);
922 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats,
927 TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
928 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
930 _pthread_mutex_lock(&private_display->lock);
932 *formats = (const tbm_format *)private_layer->caps.formats;
933 *count = private_layer->caps.format_count;
935 _pthread_mutex_unlock(&private_display->lock);
941 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props,
946 TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
947 TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
949 _pthread_mutex_lock(&private_display->lock);
951 *props = (const tdm_prop *)private_layer->caps.props;
952 *count = private_layer->caps.prop_count;
954 _pthread_mutex_unlock(&private_display->lock);
960 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
964 TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
966 _pthread_mutex_lock(&private_display->lock);
968 *zpos = private_layer->caps.zpos;
970 _pthread_mutex_unlock(&private_display->lock);
976 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
978 tdm_func_layer *func_layer;
981 _pthread_mutex_lock(&private_display->lock);
983 func_layer = &private_display->func_layer;
985 if (!func_layer->layer_set_property) {
986 _pthread_mutex_unlock(&private_display->lock);
987 TDM_DBG("failed: not implemented!!");
988 return TDM_ERROR_NOT_IMPLEMENTED;
991 ret = func_layer->layer_set_property(private_layer->layer_backend, id, value);
993 _pthread_mutex_unlock(&private_display->lock);
999 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
1001 tdm_func_layer *func_layer;
1004 TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
1006 _pthread_mutex_lock(&private_display->lock);
1008 func_layer = &private_display->func_layer;
1010 if (!func_layer->layer_get_property) {
1011 _pthread_mutex_unlock(&private_display->lock);
1012 TDM_DBG("failed: not implemented!!");
1013 return TDM_ERROR_NOT_IMPLEMENTED;
1016 ret = func_layer->layer_get_property(private_layer->layer_backend, id, value);
1018 _pthread_mutex_unlock(&private_display->lock);
1024 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
1026 tdm_func_layer *func_layer;
1029 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1031 _pthread_mutex_lock(&private_display->lock);
1033 func_layer = &private_display->func_layer;
1035 private_layer->usable = 0;
1037 if (!func_layer->layer_set_info) {
1038 _pthread_mutex_unlock(&private_display->lock);
1039 TDM_DBG("failed: not implemented!!");
1040 return TDM_ERROR_NOT_IMPLEMENTED;
1043 TDM_INFO("layer(%p) info: src(%dx%d %d,%d %dx%d %c%c%c%c) dst(%d,%d %dx%d) trans(%d)",
1044 private_layer, info->src_config.size.h, info->src_config.size.v,
1045 info->src_config.pos.x, info->src_config.pos.y,
1046 info->src_config.pos.w, info->src_config.pos.h,
1047 FOURCC_STR(info->src_config.format),
1048 info->dst_pos.x, info->dst_pos.y,
1049 info->dst_pos.w, info->dst_pos.h,
1052 ret = func_layer->layer_set_info(private_layer->layer_backend, info);
1053 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1055 _pthread_mutex_unlock(&private_display->lock);
1061 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
1063 tdm_func_layer *func_layer;
1066 TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
1068 _pthread_mutex_lock(&private_display->lock);
1070 func_layer = &private_display->func_layer;
1072 if (!func_layer->layer_get_info) {
1073 _pthread_mutex_unlock(&private_display->lock);
1074 TDM_DBG("failed: not implemented!!");
1075 return TDM_ERROR_NOT_IMPLEMENTED;
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;
1092 TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1094 _pthread_mutex_lock(&private_display->lock);
1096 func_layer = &private_display->func_layer;
1098 private_layer->usable = 0;
1100 if (!func_layer->layer_set_buffer) {
1101 _pthread_mutex_unlock(&private_display->lock);
1102 TDM_DBG("failed: not implemented!!");
1103 return TDM_ERROR_NOT_IMPLEMENTED;
1106 ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer);
1107 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1109 if (ret == TDM_ERROR_NONE) {
1110 /* FIXME: should save to pending_buffer first. And after committing
1111 * successfully, need to move to waiting_buffer.
1113 if (private_layer->waiting_buffer) {
1114 _pthread_mutex_unlock(&private_display->lock);
1115 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1116 _pthread_mutex_lock(&private_display->lock);
1119 private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer);
1120 if (tdm_debug_buffer)
1121 TDM_INFO("layer(%p) waiting_buffer(%p)",
1122 private_layer, private_layer->waiting_buffer);
1125 _pthread_mutex_unlock(&private_display->lock);
1131 tdm_layer_unset_buffer(tdm_layer *layer)
1133 tdm_func_layer *func_layer;
1136 _pthread_mutex_lock(&private_display->lock);
1138 func_layer = &private_display->func_layer;
1140 if (private_layer->waiting_buffer) {
1141 _pthread_mutex_unlock(&private_display->lock);
1142 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1143 _pthread_mutex_lock(&private_display->lock);
1144 private_layer->waiting_buffer = NULL;
1146 if (tdm_debug_buffer)
1147 TDM_INFO("layer(%p) waiting_buffer(%p)",
1148 private_layer, private_layer->waiting_buffer);
1151 if (private_layer->showing_buffer) {
1152 _pthread_mutex_unlock(&private_display->lock);
1153 tdm_buffer_unref_backend(private_layer->showing_buffer);
1154 _pthread_mutex_lock(&private_display->lock);
1155 private_layer->showing_buffer = NULL;
1157 if (tdm_debug_buffer)
1158 TDM_INFO("layer(%p) showing_buffer(%p)",
1159 private_layer, private_layer->showing_buffer);
1162 private_layer->usable = 1;
1164 if (!func_layer->layer_unset_buffer) {
1165 _pthread_mutex_unlock(&private_display->lock);
1166 TDM_DBG("failed: not implemented!!");
1167 return TDM_ERROR_NOT_IMPLEMENTED;
1170 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1171 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1173 _pthread_mutex_unlock(&private_display->lock);
1179 _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data)
1181 TDM_RETURN_IF_FAIL(data != NULL);
1182 tdm_layer *layer = data;
1183 tdm_func_layer *func_layer;
1184 tbm_surface_h surface = NULL;
1185 LAYER_FUNC_ENTRY_VOID_RETURN();
1187 _pthread_mutex_lock(&private_display->lock);
1189 func_layer = &private_display->func_layer;
1190 if (!func_layer->layer_set_buffer) {
1191 _pthread_mutex_unlock(&private_display->lock);
1195 if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(
1196 private_layer->buffer_queue, &surface) ||
1198 TDM_ERR("layer(%p) tbm_surface_queue_acquire() failed surface:%p",
1199 private_layer, surface);
1200 _pthread_mutex_unlock(&private_display->lock);
1204 ret = func_layer->layer_set_buffer(private_layer->layer_backend, surface);
1205 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1207 if (ret == TDM_ERROR_NONE) {
1208 if (private_layer->waiting_buffer) {
1209 _pthread_mutex_unlock(&private_display->lock);
1210 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1211 tbm_surface_queue_release(private_layer->buffer_queue,
1212 private_layer->waiting_buffer);
1213 _pthread_mutex_lock(&private_display->lock);
1216 private_layer->waiting_buffer = tdm_buffer_ref_backend(surface);
1218 if (tdm_debug_buffer)
1219 TDM_INFO("layer(%p) waiting_buffer(%p)",
1220 private_layer, private_layer->waiting_buffer);
1222 ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
1223 if (ret != TDM_ERROR_NONE)
1224 TDM_ERR("layer(%p) _tdm_output_commit() is fail", private_layer);
1227 _pthread_mutex_unlock(&private_display->lock);
1231 _tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data)
1233 TDM_RETURN_IF_FAIL(data != NULL);
1234 tdm_layer *layer = data;
1235 LAYER_FUNC_ENTRY_VOID_RETURN();
1236 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1238 _pthread_mutex_lock(&private_display->lock);
1240 if (private_layer->waiting_buffer) {
1241 _pthread_mutex_unlock(&private_display->lock);
1242 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1243 tbm_surface_queue_release(private_layer->buffer_queue,
1244 private_layer->waiting_buffer);
1245 _pthread_mutex_lock(&private_display->lock);
1248 private_layer->buffer_queue = NULL;
1250 _pthread_mutex_unlock(&private_display->lock);
1254 tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue)
1256 tdm_func_layer *func_layer;
1259 TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER);
1261 _pthread_mutex_lock(&private_display->lock);
1263 func_layer = &private_display->func_layer;
1265 private_layer->usable = 0;
1267 if (!func_layer->layer_set_buffer) {
1268 _pthread_mutex_unlock(&private_display->lock);
1269 TDM_DBG("failed: not implemented!!");
1270 return TDM_ERROR_NOT_IMPLEMENTED;
1273 if (buffer_queue == private_layer->buffer_queue) {
1274 _pthread_mutex_unlock(&private_display->lock);
1275 return TDM_ERROR_NONE;
1278 if (private_layer->waiting_buffer) {
1279 _pthread_mutex_unlock(&private_display->lock);
1280 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1281 tbm_surface_queue_release(private_layer->buffer_queue,
1282 private_layer->waiting_buffer);
1283 private_layer->waiting_buffer = NULL;
1284 _pthread_mutex_lock(&private_display->lock);
1286 if (tdm_debug_buffer)
1287 TDM_INFO("layer(%p) waiting_buffer(%p)",
1288 private_layer, private_layer->waiting_buffer);
1291 private_layer->buffer_queue = buffer_queue;
1292 tbm_surface_queue_add_acquirable_cb(private_layer->buffer_queue,
1293 _tbm_layer_queue_acquirable_cb,
1295 tbm_surface_queue_add_destroy_cb(private_layer->buffer_queue,
1296 _tbm_layer_queue_destroy_cb,
1298 _pthread_mutex_unlock(&private_display->lock);
1304 tdm_layer_unset_buffer_queue(tdm_layer *layer)
1306 tdm_func_layer *func_layer;
1309 _pthread_mutex_lock(&private_display->lock);
1311 func_layer = &private_display->func_layer;
1313 if (private_layer->waiting_buffer) {
1314 _pthread_mutex_unlock(&private_display->lock);
1315 tdm_buffer_unref_backend(private_layer->waiting_buffer);
1316 tbm_surface_queue_release(private_layer->buffer_queue,
1317 private_layer->waiting_buffer);
1318 private_layer->waiting_buffer = NULL;
1319 _pthread_mutex_lock(&private_display->lock);
1321 if (tdm_debug_buffer)
1322 TDM_INFO("layer(%p) waiting_buffer(%p)",
1323 private_layer, private_layer->waiting_buffer);
1326 if (private_layer->showing_buffer) {
1327 _pthread_mutex_unlock(&private_display->lock);
1328 tdm_buffer_unref_backend(private_layer->showing_buffer);
1329 tbm_surface_queue_release(private_layer->buffer_queue,
1330 private_layer->showing_buffer);
1331 _pthread_mutex_lock(&private_display->lock);
1332 private_layer->showing_buffer = NULL;
1334 if (tdm_debug_buffer)
1335 TDM_INFO("layer(%p) showing_buffer(%p)",
1336 private_layer, private_layer->showing_buffer);
1339 tbm_surface_queue_remove_acquirable_cb(private_layer->buffer_queue, _tbm_layer_queue_acquirable_cb, layer);
1340 tbm_surface_queue_remove_destroy_cb(private_layer->buffer_queue, _tbm_layer_queue_destroy_cb, layer);
1341 private_layer->buffer_queue = NULL;
1342 private_layer->usable = 1;
1344 if (!func_layer->layer_unset_buffer) {
1345 _pthread_mutex_unlock(&private_display->lock);
1346 TDM_DBG("failed: not implemented!!");
1347 return TDM_ERROR_NOT_IMPLEMENTED;
1350 ret = func_layer->layer_unset_buffer(private_layer->layer_backend);
1352 _pthread_mutex_unlock(&private_display->lock);
1358 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1362 TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1364 _pthread_mutex_lock(&private_display->lock);
1366 *usable = private_layer->usable;
1368 _pthread_mutex_unlock(&private_display->lock);
1374 tdm_layer_set_video_pos(tdm_layer *layer, int zpos)
1376 tdm_func_layer *func_layer;
1379 _pthread_mutex_lock(&private_display->lock);
1381 func_layer = &private_display->func_layer;
1383 if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) {
1384 TDM_ERR("layer(%p) is not video layer", private_layer);
1385 _pthread_mutex_unlock(&private_display->lock);
1386 return TDM_ERROR_INVALID_PARAMETER;
1389 if (!func_layer->layer_set_video_pos) {
1390 _pthread_mutex_unlock(&private_display->lock);
1391 TDM_DBG("failed: not implemented!!");
1392 return TDM_ERROR_NOT_IMPLEMENTED;
1395 ret = func_layer->layer_set_video_pos(private_layer->layer_backend, zpos);
1397 _pthread_mutex_unlock(&private_display->lock);
1402 EXTERN tdm_capture *
1403 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1405 tdm_capture *capture = NULL;
1407 LAYER_FUNC_ENTRY_ERROR();
1409 _pthread_mutex_lock(&private_display->lock);
1411 capture = (tdm_capture *)tdm_capture_create_layer_internal(private_layer,
1414 _pthread_mutex_unlock(&private_display->lock);