From a969ea6a705b8bc53375faffa310d002546f487f Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 3 Dec 2015 10:25:30 +0900 Subject: [PATCH 01/16] unref current_buffer after getting next buffer Change-Id: Iaf9b52276daf92e40754dce2fbba8a29a6702e40 --- src/tdm_display.c | 18 ++++++++++++++++-- src/tdm_private.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/tdm_display.c b/src/tdm_display.c index fcaca11..894b728 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -1010,11 +1010,18 @@ tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer) return TDM_ERROR_NONE; } - //TODO + if (private_layer->current_buffer) + { + /* TODO: need to unref after next buffer is showing on screen */ + tdm_buffer_unref_backend(private_layer->current_buffer); + tdm_buffer_unref(private_layer->current_buffer); + } + + private_layer->current_buffer = tdm_buffer_ref(buffer, NULL); tdm_buffer_ref_backend(buffer); + ret = func_display->layer_set_buffer(private_layer->layer, tdm_buffer_get_surface(buffer)); - tdm_buffer_unref_backend(buffer); pthread_mutex_unlock(&private_display->lock); @@ -1031,6 +1038,13 @@ tdm_layer_unset_buffer(tdm_layer *layer) func_display = &private_display->func_display; + if (private_layer->current_buffer) + { + tdm_buffer_unref(private_layer->current_buffer); + tdm_buffer_unref_backend(private_layer->current_buffer); + private_layer->current_buffer = NULL; + } + private_layer->usable = 1; if (!func_display->layer_unset_buffer) diff --git a/src/tdm_private.h b/src/tdm_private.h index 748385b..804db34 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -206,6 +206,8 @@ struct _tdm_private_layer tdm_caps_layer caps; tdm_layer *layer; + tdm_buffer *current_buffer; + struct list_head capture_list; unsigned int usable; -- 2.7.4 From e8016044fba558950625f837f8fbecadb6246074 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 3 Dec 2015 14:35:50 +0900 Subject: [PATCH 02/16] remove buffer from list when destroyed Change-Id: I98ee5fb7af54c30c4231c53dfd8f14f2045a9d79 --- src/tdm_buffer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 784c6ec..612b1ba 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -160,6 +160,8 @@ tdm_buffer_unref(tdm_buffer *buffer) free(func_info); } + LIST_DEL(&buf_info->link); + free(buf_info); } -- 2.7.4 From 174cae2f91f61e244ee9e8e088d663960d8606e3 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 3 Dec 2015 16:29:14 +0900 Subject: [PATCH 03/16] fix syntax error Change-Id: I3e591def832108dd44774b6173ceacc20868cf9c --- src/tdm_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tdm_display.c b/src/tdm_display.c index 894b728..abb5cb1 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -866,8 +866,8 @@ tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int pthread_mutex_lock(&private_display->lock); - *props = (const tdm_prop*)private_output->caps.props; - *count = private_output->caps.prop_count; + *props = (const tdm_prop*)private_layer->caps.props; + *count = private_layer->caps.prop_count; pthread_mutex_unlock(&private_display->lock); -- 2.7.4 From bee18909c8bfcb534a6c1696e14cb3902e4de7c3 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 4 Dec 2015 11:13:49 +0900 Subject: [PATCH 04/16] use pp flags instead of pp property Change-Id: I8476c1f89059e442787545b67a8da2f7eea1a8cb --- include/tdm.h | 3 --- include/tdm_backend.h | 5 ----- include/tdm_types.h | 2 ++ src/tdm_display.c | 18 ------------------ src/tdm_pp.c | 42 ------------------------------------------ 5 files changed, 2 insertions(+), 68 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index f8ccdca..b3812d7 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -68,7 +68,6 @@ tdm_error tdm_display_get_capabilities(tdm_display *dpy, tdm_display_capabili tdm_error tdm_display_get_pp_capabilities(tdm_display *dpy, tdm_pp_capability *capabilities); tdm_error tdm_display_get_pp_available_formats(tdm_display *dpy, const tbm_format **formats, int *count); tdm_error tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align); -tdm_error tdm_display_get_pp_available_properties(tdm_display *dpy, const tdm_prop **props, int *count); tdm_error tdm_display_get_capture_capabilities(tdm_display *dpy, tdm_capture_capability *capabilities); tdm_error tdm_display_get_catpure_available_formats(tdm_display *dpy, const tbm_format **formats, int *count); tdm_error tdm_display_get_output_count(tdm_display *dpy, int *count); @@ -122,8 +121,6 @@ tdm_capture *tdm_layer_create_capture(tdm_layer *layer, tdm_error *error); /////////////////////////////////////////////////////////////////////////////// void tdm_pp_destroy(tdm_pp *pp); -tdm_error tdm_pp_set_property(tdm_pp *pp, unsigned int id, tdm_value value); -tdm_error tdm_pp_get_property(tdm_pp *pp, unsigned int id, tdm_value *value); tdm_error tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info); tdm_error tdm_pp_attach(tdm_pp *pp, tdm_buffer *src, tdm_buffer *dst); tdm_error tdm_pp_commit(tdm_pp *pp); diff --git a/include/tdm_backend.h b/include/tdm_backend.h index d09e01f..1957987 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -95,9 +95,6 @@ typedef struct _tdm_caps_pp unsigned int format_count; tbm_format *formats; - unsigned int prop_count; - tdm_prop *props; - /* -1: not defined */ int min_w; int min_h; @@ -160,8 +157,6 @@ typedef void (*tdm_pp_done_handler)(tdm_pp *pp, tbm_surface_h src, tbm_surface_h typedef struct _tdm_func_pp { void (*pp_destroy)(tdm_pp *pp); /* init */ - tdm_error (*pp_set_property)(tdm_pp *pp, unsigned int id, tdm_value value); - tdm_error (*pp_get_property)(tdm_pp *pp, unsigned int id, tdm_value *value); tdm_error (*pp_set_info)(tdm_pp *pp, tdm_info_pp *info); tdm_error (*pp_attach)(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst); tdm_error (*pp_commit)(tdm_pp *pp); /* init */ diff --git a/include/tdm_types.h b/include/tdm_types.h index 7451c5a..e5e577b 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -227,6 +227,7 @@ typedef struct _tdm_info_pp tdm_info_config dst_config; tdm_transform transform; int sync; + int flags; } tdm_info_pp; typedef struct _tdm_info_capture @@ -235,6 +236,7 @@ typedef struct _tdm_info_capture tdm_transform transform; int oneshot; int frequency; + int flags; } tdm_info_capture; typedef void tdm_display; diff --git a/src/tdm_display.c b/src/tdm_display.c index abb5cb1..9e40cd6 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -165,24 +165,6 @@ tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, int } EXTERN tdm_error -tdm_display_get_pp_available_properties(tdm_display *dpy, const tdm_prop **props, int *count) -{ - DISPLAY_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - pthread_mutex_lock(&private_display->lock); - - *props = (const tdm_prop*)private_display->caps_pp.props; - *count = private_display->caps_pp.prop_count; - - pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error tdm_display_get_capture_capabilities(tdm_display *dpy, tdm_capture_capability *capabilities) { DISPLAY_FUNC_ENTRY(); diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 669b271..278e6e2 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -152,48 +152,6 @@ tdm_pp_destroy(tdm_pp *pp) } EXTERN tdm_error -tdm_pp_set_property(tdm_pp *pp, unsigned int id, tdm_value value) -{ - PP_FUNC_ENTRY(); - - pthread_mutex_lock(&private_display->lock); - - if (!func_pp->pp_set_property) - { - pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; - } - - ret = func_pp->pp_set_property(private_pp->pp, id, value); - - pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_pp_get_property(tdm_pp *pp, unsigned int id, tdm_value *value) -{ - PP_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER); - - pthread_mutex_lock(&private_display->lock); - - if (!func_pp->pp_get_property) - { - pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; - } - - ret = func_pp->pp_get_property(private_pp->pp, id, value); - - pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) { PP_FUNC_ENTRY(); -- 2.7.4 From 265cfb95e29898d1ffc515486d1331b7415eb83d Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Thu, 3 Dec 2015 21:50:52 +0900 Subject: [PATCH 05/16] eliminate race condition Change-Id: I9a76a4d631ad4a479bd59cdb487c99a79c3446d1 Signed-off-by: Junkyeong Kim --- src/tdm_display.c | 42 ++++++++++++++++++++++++++++++++++++------ src/tdm_private.h | 2 ++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/tdm_display.c b/src/tdm_display.c index 9e40cd6..52ae2e3 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -563,14 +563,28 @@ static void _tdm_output_cb_vblank(tdm_output *output, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - tdm_private_output *private_output = output; + tdm_private_output *private_output; + tdm_private_display *private_display; + tdm_private_display *private_display_backend; tdm_private_vblank_handler *vblank_handler = user_data; + TDM_RETURN_IF_FAIL(vblank_handler); + private_output = vblank_handler->private_output; TDM_RETURN_IF_FAIL(private_output); - TDM_RETURN_IF_FAIL(vblank_handler); + + private_display = private_output->private_display; + LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) + { + if (private_output->output == output) + private_display_backend = private_output->private_display; + } + + pthread_mutex_unlock(&private_display_backend->lock); if (vblank_handler->func) - vblank_handler->func(private_output, sequence, tv_sec, tv_usec, vblank_handler->user_data); + vblank_handler->func(vblank_handler->private_output, sequence, tv_sec, tv_usec, vblank_handler->user_data); + + pthread_mutex_lock(&private_display_backend->lock); LIST_DEL(&vblank_handler->link); free(vblank_handler); @@ -580,14 +594,28 @@ static void _tdm_output_cb_commit(tdm_output *output, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - tdm_private_output *private_output = output; + tdm_private_output *private_output; + tdm_private_display *private_display; + tdm_private_display *private_display_backend; tdm_private_commit_handler *commit_handler = user_data; + TDM_RETURN_IF_FAIL(commit_handler); + private_output = commit_handler->private_output; TDM_RETURN_IF_FAIL(private_output); - TDM_RETURN_IF_FAIL(commit_handler); + + private_display = private_output->private_display; + LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) + { + if (private_output->output == output) + private_display_backend = private_output->private_display; + } + + pthread_mutex_unlock(&private_display_backend->lock); if (commit_handler->func) - commit_handler->func(private_output, sequence, tv_sec, tv_usec, commit_handler->user_data); + commit_handler->func(commit_handler->private_output, sequence, tv_sec, tv_usec, commit_handler->user_data); + + pthread_mutex_lock(&private_display_backend->lock); LIST_DEL(&commit_handler->link); free(commit_handler); @@ -619,6 +647,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, tdm_output_vb } LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list); + vblank_handler->private_output = private_output; vblank_handler->func = func; vblank_handler->user_data = user_data; @@ -666,6 +695,7 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, } LIST_ADD(&commit_handler->link, &private_output->commit_handler_list); + commit_handler->private_output = private_output; commit_handler->func = func; commit_handler->user_data = user_data; diff --git a/src/tdm_private.h b/src/tdm_private.h index 804db34..3f0b733 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -241,6 +241,7 @@ struct _tdm_private_vblank_handler { struct list_head link; + tdm_private_output *private_output; tdm_output_vblank_handler func; void *user_data; }; @@ -249,6 +250,7 @@ struct _tdm_private_commit_handler { struct list_head link; + tdm_private_output *private_output; tdm_output_commit_handler func; void *user_data; }; -- 2.7.4 From 3ec2661d3dc88f4066351f951e37e1a9b3e28f7f Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 4 Dec 2015 12:58:10 +0900 Subject: [PATCH 06/16] fix syntax error Change-Id: I2a7aa2526254c72f8e325d9700d0f7387a1ff751 --- src/tdm_buffer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 612b1ba..3b8df91 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -162,6 +162,8 @@ tdm_buffer_unref(tdm_buffer *buffer) LIST_DEL(&buf_info->link); + tbm_surface_internal_unref(buf_info->buffer); + free(buf_info); } -- 2.7.4 From f4e7023468c96af088bbe1e43f3becfbe2a29d13 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 4 Dec 2015 19:47:15 +0900 Subject: [PATCH 07/16] change variable names Change-Id: I76b1add55684bcbe2d9ba483e1a9b3d81f1224b6 --- src/tdm.c | 37 +++++++++++++++++++---------------- src/tdm_capture.c | 35 ++++++++++++++++----------------- src/tdm_display.c | 58 +++++++++++++++++++++++++++++++------------------------ src/tdm_pp.c | 27 +++++++++++++------------- src/tdm_private.h | 8 ++++---- 5 files changed, 87 insertions(+), 78 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index fdb5834..7d5e16e 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -42,13 +42,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tdm_private.h" static tdm_private_layer* -_tdm_display_find_private_layer(tdm_private_output *private_output, tdm_layer *layer) +_tdm_display_find_private_layer(tdm_private_output *private_output, tdm_layer *layer_backend) { tdm_private_layer *private_layer = NULL; LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) { - if (private_layer->layer == layer) + if (private_layer->layer_backend == layer_backend) return private_layer; } @@ -56,13 +56,13 @@ _tdm_display_find_private_layer(tdm_private_output *private_output, tdm_layer *l } static tdm_private_output* -_tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output) +_tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend) { tdm_private_output *private_output = NULL; LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { - if (private_output->output == output) + if (private_output->output_backend == output_backend) return private_output; } @@ -245,7 +245,8 @@ _tdm_display_update_caps_capture(tdm_private_display *private_display, tdm_caps_ } static tdm_error -_tdm_display_update_caps_layer(tdm_private_display *private_display, tdm_layer *layer, tdm_caps_layer *caps) +_tdm_display_update_caps_layer(tdm_private_display *private_display, + tdm_layer *layer_backend, tdm_caps_layer *caps) { tdm_func_display *func_display = &private_display->func_display; char buf[1024]; @@ -261,7 +262,7 @@ _tdm_display_update_caps_layer(tdm_private_display *private_display, tdm_layer * return TDM_ERROR_BAD_MODULE; } - ret = func_display->layer_get_capability(layer, caps); + ret = func_display->layer_get_capability(layer_backend, caps); if (ret != TDM_ERROR_NONE) { TDM_ERR("layer_get_capability() failed"); @@ -281,7 +282,8 @@ _tdm_display_update_caps_layer(tdm_private_display *private_display, tdm_layer * } static tdm_error -_tdm_display_update_caps_output(tdm_private_display *private_display, tdm_output *output, tdm_caps_output *caps) +_tdm_display_update_caps_output(tdm_private_display *private_display, + tdm_output *output_backend, tdm_caps_output *caps) { tdm_func_display *func_display = &private_display->func_display; int i; @@ -293,7 +295,7 @@ _tdm_display_update_caps_output(tdm_private_display *private_display, tdm_output return TDM_ERROR_BAD_MODULE; } - ret = func_display->output_get_capability(output, caps); + ret = func_display->output_get_capability(output_backend, caps); if (ret != TDM_ERROR_NONE) { TDM_ERR("output_get_capability() failed"); @@ -318,12 +320,12 @@ _tdm_display_update_caps_output(tdm_private_display *private_display, tdm_output static tdm_error _tdm_display_update_layer(tdm_private_display *private_display, tdm_private_output *private_output, - tdm_layer *layer) + tdm_layer *layer_backend) { tdm_private_layer *private_layer; tdm_error ret; - private_layer = _tdm_display_find_private_layer(private_output, layer); + private_layer = _tdm_display_find_private_layer(private_output, layer_backend); if (!private_layer) { private_layer = calloc(1, sizeof(tdm_private_layer)); @@ -333,7 +335,7 @@ _tdm_display_update_layer(tdm_private_display *private_display, private_layer->func_display = &private_display->func_display; private_layer->private_display = private_display; private_layer->private_output = private_output; - private_layer->layer = layer; + private_layer->layer_backend = layer_backend; LIST_INITHEAD(&private_layer->capture_list); @@ -342,7 +344,7 @@ _tdm_display_update_layer(tdm_private_display *private_display, else _tdm_display_destroy_caps_layer(&private_layer->caps); - ret = _tdm_display_update_caps_layer(private_display, layer, &private_layer->caps); + ret = _tdm_display_update_caps_layer(private_display, layer_backend, &private_layer->caps); if (ret != TDM_ERROR_NONE) goto failed_update; @@ -353,7 +355,8 @@ failed_update: } static tdm_error -_tdm_display_update_output(tdm_private_display *private_display, tdm_output *output, int pipe) +_tdm_display_update_output(tdm_private_display *private_display, + tdm_output *output_backend, int pipe) { tdm_func_display *func_display = &private_display->func_display; tdm_private_output *private_output = NULL; @@ -361,7 +364,7 @@ _tdm_display_update_output(tdm_private_display *private_display, tdm_output *out int layer_count = 0, i; tdm_error ret; - private_output = _tdm_display_find_private_output(private_display, output); + private_output = _tdm_display_find_private_output(private_display, output_backend); if (!private_output) { private_output = calloc(1, sizeof(tdm_private_output)); @@ -370,7 +373,7 @@ _tdm_display_update_output(tdm_private_display *private_display, tdm_output *out LIST_ADD(&private_output->link, &private_display->output_list); private_output->func_display = func_display; private_output->private_display = private_display; - private_output->output = output; + private_output->output_backend = output_backend; private_output->pipe = pipe; LIST_INITHEAD(&private_output->layer_list); @@ -381,11 +384,11 @@ _tdm_display_update_output(tdm_private_display *private_display, tdm_output *out else _tdm_display_destroy_caps_output(&private_output->caps); - ret = _tdm_display_update_caps_output(private_display, output, &private_output->caps); + ret = _tdm_display_update_caps_output(private_display, output_backend, &private_output->caps); if (ret != TDM_ERROR_NONE) return ret; - layers = func_display->output_get_layers(output, &layer_count, &ret); + layers = func_display->output_get_layers(output_backend, &layer_count, &ret); if (ret != TDM_ERROR_NONE) goto failed_update; diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 0859f22..f63d2b8 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -52,7 +52,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. func_capture = private_capture->func_capture static void -_tdm_caputre_cb_done(tdm_capture *capture, tbm_surface_h buffer, void *user_data) +_tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data) { tdm_buffer_unref_backend(tdm_buffer_get(buffer)); } @@ -64,7 +64,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error tdm_func_display *func_display; tdm_func_capture *func_capture; tdm_private_capture *private_capture = NULL; - tdm_capture *capture = NULL; + tdm_capture *capture_backend = NULL; tdm_error ret = TDM_ERROR_NONE; private_display = private_output->private_display; @@ -79,7 +79,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error return NULL; } - capture = func_display->output_create_capture(private_output->output, &ret); + capture_backend = func_display->output_create_capture(private_output->output_backend, &ret); if (ret != TDM_ERROR_NONE) { if (error) @@ -91,17 +91,17 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error if (!private_capture) { TDM_ERR("failed: alloc memory"); - func_capture->capture_destroy(capture); + func_capture->capture_destroy(capture_backend); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; return NULL; } - ret = func_capture->capture_set_done_handler(capture, _tdm_caputre_cb_done, private_capture); + ret = func_capture->capture_set_done_handler(capture_backend, _tdm_caputre_cb_done, private_capture); if (ret != TDM_ERROR_NONE) { TDM_ERR("set capture_done_handler failed"); - func_capture->capture_destroy(capture); + func_capture->capture_destroy(capture_backend); if (error) *error = ret; return NULL; @@ -113,7 +113,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error private_capture->private_display = private_display; private_capture->private_output = private_output; private_capture->private_layer = NULL; - private_capture->capture = capture; + private_capture->capture_backend = capture_backend; if (error) *error = TDM_ERROR_NONE; @@ -129,7 +129,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, tdm_error *e tdm_func_display *func_display; tdm_func_capture *func_capture; tdm_private_capture *private_capture = NULL; - tdm_capture *capture = NULL; + tdm_capture *capture_backend = NULL; tdm_error ret = TDM_ERROR_NONE; private_output = private_layer->private_output; @@ -145,7 +145,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, tdm_error *e return NULL; } - capture = func_display->layer_create_capture(private_layer->layer, &ret); + capture_backend = func_display->layer_create_capture(private_layer->layer_backend, &ret); if (ret != TDM_ERROR_NONE) return NULL; @@ -153,7 +153,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, tdm_error *e if (!private_capture) { TDM_ERR("failed: alloc memory"); - func_capture->capture_destroy(capture); + func_capture->capture_destroy(capture_backend); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; return NULL; @@ -165,7 +165,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, tdm_error *e private_capture->private_display = private_display; private_capture->private_output = private_output; private_capture->private_layer = private_layer; - private_capture->capture = capture; + private_capture->capture_backend = capture_backend; if (error) *error = TDM_ERROR_NONE; @@ -184,7 +184,7 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) LIST_DEL(&private_capture->link); func_capture = private_capture->func_capture; - func_capture->capture_destroy(private_capture->capture); + func_capture->capture_destroy(private_capture->capture_backend); free(private_capture); } @@ -192,13 +192,12 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) EXTERN void tdm_capture_destroy(tdm_capture *capture) { + tdm_private_capture *private_capture = capture; tdm_private_display *private_display; - tdm_private_capture *private_capture; - if (!capture) + if (!private_capture) return; - private_capture = (tdm_private_capture*)capture; private_display = private_capture->private_display; pthread_mutex_lock(&private_display->lock); @@ -221,7 +220,7 @@ tdm_capture_set_info(tdm_capture *capture, tdm_info_capture *info) return TDM_ERROR_NONE; } - ret = func_capture->capture_set_info(private_capture->capture, info); + ret = func_capture->capture_set_info(private_capture->capture_backend, info); pthread_mutex_unlock(&private_display->lock); @@ -244,7 +243,7 @@ tdm_capture_attach(tdm_capture *capture, tdm_buffer *buffer) } tdm_buffer_ref_backend(buffer); - ret = func_capture->capture_attach(private_capture->capture, + ret = func_capture->capture_attach(private_capture->capture_backend, tdm_buffer_get_surface(buffer)); pthread_mutex_unlock(&private_display->lock); @@ -265,7 +264,7 @@ tdm_capture_commit(tdm_capture *capture) return TDM_ERROR_NONE; } - ret = func_capture->capture_commit(private_capture->capture); + ret = func_capture->capture_commit(private_capture->capture_backend); pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_display.c b/src/tdm_display.c index 52ae2e3..61e796a 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -142,7 +142,8 @@ tdm_display_get_pp_available_formats(tdm_display *dpy, const tbm_format **format } EXTERN tdm_error -tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align) +tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, + int *max_w, int *max_h, int *preferred_align) { DISPLAY_FUNC_ENTRY(); @@ -441,7 +442,8 @@ tdm_output_get_available_modes(tdm_output *output, const tdm_output_mode **modes } EXTERN tdm_error -tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align) +tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h, + int *max_w, int *max_h, int *preferred_align) { OUTPUT_FUNC_ENTRY(); @@ -527,7 +529,7 @@ tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) return TDM_ERROR_NONE; } - ret = func_display->output_set_property(private_output->output, id, value); + ret = func_display->output_set_property(private_output->output_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -552,7 +554,7 @@ tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) return TDM_ERROR_NONE; } - ret = func_display->output_get_property(private_output->output, id, value); + ret = func_display->output_get_property(private_output->output_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -560,7 +562,7 @@ tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) } static void -_tdm_output_cb_vblank(tdm_output *output, unsigned int sequence, +_tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { tdm_private_output *private_output; @@ -575,14 +577,15 @@ _tdm_output_cb_vblank(tdm_output *output, unsigned int sequence, private_display = private_output->private_display; LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { - if (private_output->output == output) + if (private_output->output_backend == output_backend) private_display_backend = private_output->private_display; } pthread_mutex_unlock(&private_display_backend->lock); if (vblank_handler->func) - vblank_handler->func(vblank_handler->private_output, sequence, tv_sec, tv_usec, vblank_handler->user_data); + vblank_handler->func(vblank_handler->private_output, sequence, + tv_sec, tv_usec, vblank_handler->user_data); pthread_mutex_lock(&private_display_backend->lock); @@ -591,7 +594,7 @@ _tdm_output_cb_vblank(tdm_output *output, unsigned int sequence, } static void -_tdm_output_cb_commit(tdm_output *output, unsigned int sequence, +_tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { tdm_private_output *private_output; @@ -606,14 +609,15 @@ _tdm_output_cb_commit(tdm_output *output, unsigned int sequence, private_display = private_output->private_display; LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) { - if (private_output->output == output) + if (private_output->output_backend == output_backend) private_display_backend = private_output->private_display; } pthread_mutex_unlock(&private_display_backend->lock); if (commit_handler->func) - commit_handler->func(commit_handler->private_output, sequence, tv_sec, tv_usec, commit_handler->user_data); + commit_handler->func(commit_handler->private_output, sequence, + tv_sec, tv_usec, commit_handler->user_data); pthread_mutex_lock(&private_display_backend->lock); @@ -622,7 +626,8 @@ _tdm_output_cb_commit(tdm_output *output, unsigned int sequence, } EXTERN tdm_error -tdm_output_wait_vblank(tdm_output *output, int interval, int sync, tdm_output_vblank_handler func, void *user_data) +tdm_output_wait_vblank(tdm_output *output, int interval, int sync, + tdm_output_vblank_handler func, void *user_data) { tdm_func_display *func_display; tdm_private_vblank_handler *vblank_handler; @@ -651,7 +656,8 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, tdm_output_vb vblank_handler->func = func; vblank_handler->user_data = user_data; - ret = func_display->output_wait_vblank(private_output->output, interval, sync, vblank_handler); + ret = func_display->output_wait_vblank(private_output->output_backend, interval, + sync, vblank_handler); if (ret != TDM_ERROR_NONE) { pthread_mutex_unlock(&private_display->lock); @@ -661,7 +667,8 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, tdm_output_vb if (!private_output->regist_vblank_cb) { private_output->regist_vblank_cb = 1; - ret = func_display->output_set_vblank_handler(private_output->output, _tdm_output_cb_vblank); + ret = func_display->output_set_vblank_handler(private_output->output_backend, + _tdm_output_cb_vblank); } pthread_mutex_unlock(&private_display->lock); @@ -699,7 +706,7 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, commit_handler->func = func; commit_handler->user_data = user_data; - ret = func_display->output_commit(private_output->output, sync, commit_handler); + ret = func_display->output_commit(private_output->output_backend, sync, commit_handler); if (ret != TDM_ERROR_NONE) { pthread_mutex_unlock(&private_display->lock); @@ -709,7 +716,8 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, if (!private_output->regist_commit_cb) { private_output->regist_commit_cb = 1; - ret = func_display->output_set_commit_handler(private_output->output, _tdm_output_cb_commit); + ret = func_display->output_set_commit_handler(private_output->output_backend, + _tdm_output_cb_commit); } pthread_mutex_unlock(&private_display->lock); @@ -735,7 +743,7 @@ tdm_output_set_mode(tdm_output *output, tdm_output_mode *mode) return TDM_ERROR_NONE; } - ret = func_display->output_set_mode(private_output->output, mode); + ret = func_display->output_set_mode(private_output->output_backend, mode); pthread_mutex_unlock(&private_display->lock); @@ -760,7 +768,7 @@ tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) return TDM_ERROR_NONE; } - ret = func_display->output_get_mode(private_output->output, mode); + ret = func_display->output_get_mode(private_output->output_backend, mode); pthread_mutex_unlock(&private_display->lock); @@ -786,7 +794,7 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) return TDM_ERROR_NONE; } - ret = func_display->output_set_dpms(private_output->output, dpms_value); + ret = func_display->output_set_dpms(private_output->output_backend, dpms_value); pthread_mutex_unlock(&private_display->lock); @@ -811,7 +819,7 @@ tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) return TDM_ERROR_NONE; } - ret = func_display->output_get_dpms(private_output->output, dpms_value); + ret = func_display->output_get_dpms(private_output->output_backend, dpms_value); pthread_mutex_unlock(&private_display->lock); @@ -918,7 +926,7 @@ tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) return TDM_ERROR_NONE; } - ret = func_display->layer_set_property(private_layer->layer, id, value); + ret = func_display->layer_set_property(private_layer->layer_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -943,7 +951,7 @@ tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) return TDM_ERROR_NONE; } - ret = func_display->layer_get_property(private_layer->layer, id, value); + ret = func_display->layer_get_property(private_layer->layer_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -970,7 +978,7 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) return TDM_ERROR_NONE; } - ret = func_display->layer_set_info(private_layer->layer, info); + ret = func_display->layer_set_info(private_layer->layer_backend, info); pthread_mutex_unlock(&private_display->lock); @@ -995,7 +1003,7 @@ tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) return TDM_ERROR_NONE; } - ret = func_display->layer_get_info(private_layer->layer, info); + ret = func_display->layer_get_info(private_layer->layer_backend, info); pthread_mutex_unlock(&private_display->lock); @@ -1032,7 +1040,7 @@ tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer) private_layer->current_buffer = tdm_buffer_ref(buffer, NULL); tdm_buffer_ref_backend(buffer); - ret = func_display->layer_set_buffer(private_layer->layer, + ret = func_display->layer_set_buffer(private_layer->layer_backend, tdm_buffer_get_surface(buffer)); pthread_mutex_unlock(&private_display->lock); @@ -1065,7 +1073,7 @@ tdm_layer_unset_buffer(tdm_layer *layer) return TDM_ERROR_NONE; } - ret = func_display->layer_unset_buffer(private_layer->layer); + ret = func_display->layer_unset_buffer(private_layer->layer_backend); pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 278e6e2..91642af 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -52,7 +52,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. func_pp = private_pp->func_pp static void -_tdm_pp_cb_done(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data) +_tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, void *user_data) { tdm_buffer_unref_backend(tdm_buffer_get(src)); tdm_buffer_unref_backend(tdm_buffer_get(dst)); @@ -64,7 +64,7 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) tdm_func_display *func_display; tdm_func_pp *func_pp; tdm_private_pp *private_pp = NULL; - tdm_pp *pp = NULL; + tdm_pp *pp_backend = NULL; tdm_error ret = TDM_ERROR_NONE; func_display = &private_display->func_display; @@ -78,7 +78,7 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) return NULL; } - pp = func_display->display_create_pp(private_display->bdata, &ret); + pp_backend = func_display->display_create_pp(private_display->bdata, &ret); if (ret != TDM_ERROR_NONE) { if (error) @@ -90,17 +90,17 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) if (!private_pp) { TDM_ERR("failed: alloc memory"); - func_pp->pp_destroy(pp); + func_pp->pp_destroy(pp_backend); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; return NULL; } - ret = func_pp->pp_set_done_handler(pp, _tdm_pp_cb_done, private_pp); + ret = func_pp->pp_set_done_handler(pp_backend, _tdm_pp_cb_done, private_pp); if (ret != TDM_ERROR_NONE) { TDM_ERR("set pp_done_handler failed"); - func_pp->pp_destroy(pp); + func_pp->pp_destroy(pp_backend); if (error) *error = ret; return NULL; @@ -109,7 +109,7 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) LIST_ADD(&private_pp->link, &private_display->pp_list); private_pp->func_pp = func_pp; private_pp->private_display = private_display; - private_pp->pp = pp; + private_pp->pp_backend = pp_backend; if (error) *error = TDM_ERROR_NONE; @@ -129,7 +129,7 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) LIST_DEL(&private_pp->link); - func_pp->pp_destroy(private_pp->pp); + func_pp->pp_destroy(private_pp->pp_backend); free(private_pp); } @@ -137,13 +137,12 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) EXTERN void tdm_pp_destroy(tdm_pp *pp) { + tdm_private_pp *private_pp = pp; tdm_private_display *private_display; - tdm_private_pp *private_pp; - if (!pp) + if (!private_pp) return; - private_pp = (tdm_private_pp*)pp; private_display = private_pp->private_display; pthread_mutex_lock(&private_display->lock); @@ -166,7 +165,7 @@ tdm_pp_set_info(tdm_pp *pp, tdm_info_pp *info) return TDM_ERROR_NONE; } - ret = func_pp->pp_set_info(private_pp->pp, info); + ret = func_pp->pp_set_info(private_pp->pp_backend, info); pthread_mutex_unlock(&private_display->lock); @@ -191,7 +190,7 @@ tdm_pp_attach(tdm_pp *pp, tdm_buffer *src, tdm_buffer *dst) tdm_buffer_ref_backend(src); tdm_buffer_ref_backend(dst); - ret = func_pp->pp_attach(private_pp->pp, + ret = func_pp->pp_attach(private_pp->pp_backend, tdm_buffer_get_surface(src), tdm_buffer_get_surface(dst)); @@ -213,7 +212,7 @@ tdm_pp_commit(tdm_pp *pp) return TDM_ERROR_NONE; } - ret = func_pp->pp_commit(private_pp->pp); + ret = func_pp->pp_commit(private_pp->pp_backend); pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_private.h b/src/tdm_private.h index 3f0b733..f9a727f 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -180,7 +180,7 @@ struct _tdm_private_output tdm_private_display *private_display; tdm_caps_output caps; - tdm_output *output; + tdm_output *output_backend; unsigned int pipe; @@ -204,7 +204,7 @@ struct _tdm_private_layer tdm_private_output *private_output; tdm_caps_layer caps; - tdm_layer *layer; + tdm_layer *layer_backend; tdm_buffer *current_buffer; @@ -220,7 +220,7 @@ struct _tdm_private_pp tdm_func_pp *func_pp; tdm_private_display *private_display; - tdm_pp *pp; + tdm_pp *pp_backend; }; struct _tdm_private_capture @@ -234,7 +234,7 @@ struct _tdm_private_capture tdm_private_output *private_output; tdm_private_layer *private_layer; - tdm_capture *capture; + tdm_capture *capture_backend; }; struct _tdm_private_vblank_handler -- 2.7.4 From b9335be165b9f48c462e3dd7f5f49faa0cc46370 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 4 Dec 2015 21:19:27 +0900 Subject: [PATCH 08/16] destroy tdm_buffer when ref_count and backend_ref_count == 0 Change-Id: I19592b24b0260a09cb6aa809471a30df4ad80030 --- src/tdm_buffer.c | 56 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 3b8df91..31b0d88 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -53,10 +53,10 @@ typedef struct _tdm_buffer_info { tbm_surface_h buffer; - /* frontend ref_count */ + /* ref_count for frontend */ int ref_count; - /* backend ref_count */ + /* ref_count for backend */ int backend_ref_count; struct list_head release_funcs; @@ -66,6 +66,26 @@ typedef struct _tdm_buffer_info static int buffer_list_init; static struct list_head buffer_list; +static void +_tdm_buffer_destroy(tdm_buffer_info *buf_info) +{ + tdm_buffer_func_info *func_info = NULL, *next = NULL; + + TDM_WARNING_IF_FAIL(buf_info->ref_count == 0); + TDM_WARNING_IF_FAIL(buf_info->backend_ref_count == 0); + + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) + { + LIST_DEL(&func_info->link); + free(func_info); + } + + LIST_DEL(&buf_info->link); + + tbm_surface_internal_unref(buf_info->buffer); + free(buf_info); +} + EXTERN tdm_buffer* tdm_buffer_create(tbm_surface_h buffer, tdm_error *error) { @@ -140,31 +160,20 @@ EXTERN void tdm_buffer_unref(tdm_buffer *buffer) { tdm_buffer_info *buf_info; - tdm_buffer_func_info *func_info = NULL, *next = NULL; if (!buffer) return; buf_info = buffer; + TDM_RETURN_IF_FAIL (buf_info->ref_count > 0); + buf_info->ref_count--; - if (buf_info->ref_count > 0) + /* destroy tdm_buffer when both ref_count and backend_ref_count are 0. */ + if (buf_info->ref_count > 0 || buf_info->backend_ref_count > 0) return; - /* Before ref_count become 0, all backend reference should be removed */ - TDM_WARNING_IF_FAIL(buf_info->backend_ref_count == 0); - - LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) - { - LIST_DEL(&func_info->link); - free(func_info); - } - - LIST_DEL(&buf_info->link); - - tbm_surface_internal_unref(buf_info->buffer); - - free(buf_info); + _tdm_buffer_destroy(buf_info); } EXTERN tdm_error @@ -230,6 +239,7 @@ tdm_buffer_unref_backend(tdm_buffer *buffer) { tdm_buffer_info *buf_info; tdm_buffer_func_info *func_info = NULL, *next = NULL; + int old_ref_count; TDM_RETURN_IF_FAIL(buffer != NULL); @@ -239,8 +249,18 @@ tdm_buffer_unref_backend(tdm_buffer *buffer) if (buf_info->backend_ref_count > 0) return; + /* ref_count can become 0 in user release function. In that case, buf_info + * will be destroyed in tbm_buffer_unref. So we destroy buf_info in this + * function only in case that old_ref_count is 0. + */ + old_ref_count = buf_info->ref_count; + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) func_info->func(buffer, func_info->user_data); + + /* finally, both ref_count and backend_ref_count are 0. destroy tdm_buffer */ + if (old_ref_count == 0 && buf_info->ref_count == 0) + _tdm_buffer_destroy(buf_info); } INTERN tbm_surface_h -- 2.7.4 From a3f04f163b1c7802fbd80c2edfa4909ec7058d5e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 4 Dec 2015 21:20:16 +0900 Subject: [PATCH 09/16] remove private_display_backend variable Change-Id: I2e6ae54deeee46c503d717bce7be45082db3979a --- src/tdm_display.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/src/tdm_display.c b/src/tdm_display.c index 61e796a..e4f8883 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -565,29 +565,20 @@ static void _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - tdm_private_output *private_output; - tdm_private_display *private_display; - tdm_private_display *private_display_backend; tdm_private_vblank_handler *vblank_handler = user_data; + tdm_private_display *private_display; + TDM_RETURN_IF_FAIL(vblank_handler); - private_output = vblank_handler->private_output; - TDM_RETURN_IF_FAIL(private_output); + private_display = vblank_handler->private_output->private_display; - private_display = private_output->private_display; - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) - { - if (private_output->output_backend == output_backend) - private_display_backend = private_output->private_display; - } - - pthread_mutex_unlock(&private_display_backend->lock); + pthread_mutex_unlock(&private_display->lock); if (vblank_handler->func) vblank_handler->func(vblank_handler->private_output, sequence, tv_sec, tv_usec, vblank_handler->user_data); - pthread_mutex_lock(&private_display_backend->lock); + pthread_mutex_lock(&private_display->lock); LIST_DEL(&vblank_handler->link); free(vblank_handler); @@ -597,29 +588,20 @@ static void _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - tdm_private_output *private_output; - tdm_private_display *private_display; - tdm_private_display *private_display_backend; tdm_private_commit_handler *commit_handler = user_data; + tdm_private_display *private_display; + TDM_RETURN_IF_FAIL(commit_handler); - private_output = commit_handler->private_output; - TDM_RETURN_IF_FAIL(private_output); + private_display = commit_handler->private_output->private_display; - private_display = private_output->private_display; - LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link) - { - if (private_output->output_backend == output_backend) - private_display_backend = private_output->private_display; - } - - pthread_mutex_unlock(&private_display_backend->lock); + pthread_mutex_unlock(&private_display->lock); if (commit_handler->func) commit_handler->func(commit_handler->private_output, sequence, tv_sec, tv_usec, commit_handler->user_data); - pthread_mutex_lock(&private_display_backend->lock); + pthread_mutex_lock(&private_display->lock); LIST_DEL(&commit_handler->link); free(commit_handler); -- 2.7.4 From 6007f89c41771889a97b8925b01967f0dcd3aeaa Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sat, 5 Dec 2015 10:41:55 +0900 Subject: [PATCH 10/16] add comments Change-Id: Ib98d898f5caac6fb4f0a429c2475e43ee5e4b558 --- include/tdm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/tdm.h b/include/tdm.h index b3812d7..23bcde8 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -136,6 +136,7 @@ tdm_error tdm_capture_commit(tdm_capture *capture); typedef void (*tdm_buffer_release_handler)(tdm_buffer *buffer, void *user_data); +/* not pthread safe */ tdm_buffer *tdm_buffer_create(tbm_surface_h buffer, tdm_error *error); tdm_buffer *tdm_buffer_ref(tdm_buffer *buffer, tdm_error *error); void tdm_buffer_unref(tdm_buffer *buffer); -- 2.7.4 From 2f3e0c774d17cbf21a6fa7a34c6f883ccce79731 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sat, 5 Dec 2015 10:42:43 +0900 Subject: [PATCH 11/16] buffer will be released when next buffer is showing Change-Id: I0db820a7d5b303b213040d1958badcdf6a925034 --- src/tdm_display.c | 65 +++++++++++++++++++++++++++++++++++++++---------------- src/tdm_private.h | 3 ++- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/tdm_display.c b/src/tdm_display.c index e4f8883..082e6b5 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -572,13 +572,13 @@ _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, private_display = vblank_handler->private_output->private_display; - pthread_mutex_unlock(&private_display->lock); - if (vblank_handler->func) + { + pthread_mutex_unlock(&private_display->lock); vblank_handler->func(vblank_handler->private_output, sequence, tv_sec, tv_usec, vblank_handler->user_data); - - pthread_mutex_lock(&private_display->lock); + pthread_mutex_lock(&private_display->lock); + } LIST_DEL(&vblank_handler->link); free(vblank_handler); @@ -590,18 +590,37 @@ _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, { tdm_private_commit_handler *commit_handler = user_data; tdm_private_display *private_display; + tdm_private_output *private_output; + tdm_private_layer *private_layer; TDM_RETURN_IF_FAIL(commit_handler); - private_display = commit_handler->private_output->private_display; - - pthread_mutex_unlock(&private_display->lock); + private_output = commit_handler->private_output; + private_display = private_output->private_display; if (commit_handler->func) - commit_handler->func(commit_handler->private_output, sequence, + { + pthread_mutex_unlock(&private_display->lock); + commit_handler->func(private_output, sequence, tv_sec, tv_usec, commit_handler->user_data); + pthread_mutex_lock(&private_display->lock); + } - pthread_mutex_lock(&private_display->lock); + LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link) + { + if (!private_layer->waiting_buffer) + continue; + + if (private_layer->showing_buffer) + { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->showing_buffer); + pthread_mutex_lock(&private_display->lock); + } + + private_layer->showing_buffer = private_layer->waiting_buffer; + private_layer->waiting_buffer = NULL; + } LIST_DEL(&commit_handler->link); free(commit_handler); @@ -1012,15 +1031,14 @@ tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer) return TDM_ERROR_NONE; } - if (private_layer->current_buffer) + if (private_layer->waiting_buffer) { - /* TODO: need to unref after next buffer is showing on screen */ - tdm_buffer_unref_backend(private_layer->current_buffer); - tdm_buffer_unref(private_layer->current_buffer); + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + pthread_mutex_lock(&private_display->lock); } - private_layer->current_buffer = tdm_buffer_ref(buffer, NULL); - tdm_buffer_ref_backend(buffer); + private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer); ret = func_display->layer_set_buffer(private_layer->layer_backend, tdm_buffer_get_surface(buffer)); @@ -1040,11 +1058,20 @@ tdm_layer_unset_buffer(tdm_layer *layer) func_display = &private_display->func_display; - if (private_layer->current_buffer) + if (private_layer->waiting_buffer) + { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + pthread_mutex_lock(&private_display->lock); + private_layer->waiting_buffer = NULL; + } + + if (private_layer->showing_buffer) { - tdm_buffer_unref(private_layer->current_buffer); - tdm_buffer_unref_backend(private_layer->current_buffer); - private_layer->current_buffer = NULL; + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->showing_buffer); + pthread_mutex_lock(&private_display->lock); + private_layer->showing_buffer = NULL; } private_layer->usable = 1; diff --git a/src/tdm_private.h b/src/tdm_private.h index f9a727f..635682f 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -206,7 +206,8 @@ struct _tdm_private_layer tdm_caps_layer caps; tdm_layer *layer_backend; - tdm_buffer *current_buffer; + tdm_buffer *waiting_buffer; + tdm_buffer *showing_buffer; struct list_head capture_list; -- 2.7.4 From 5e2e5f85345b29948876440e735c55d97c1e53d5 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Mon, 7 Dec 2015 17:13:09 +0900 Subject: [PATCH 12/16] elimiate race condition of pp callback Change-Id: Ie0599e2d7670ce2c31d2c8537c243a8e9d6f1fa7 Signed-off-by: Junkyeong Kim --- src/tdm_pp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 91642af..959674d 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -54,8 +54,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void _tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, void *user_data) { + tdm_private_pp *private_pp = user_data; + tdm_private_display *private_display = private_pp->private_display; + int lock_after_cb_done = 0; + + if (pthread_mutex_trylock(&private_display->lock)) + { + pthread_mutex_unlock(&private_display->lock); + lock_after_cb_done = 1; + } + tdm_buffer_unref_backend(tdm_buffer_get(src)); tdm_buffer_unref_backend(tdm_buffer_get(dst)); + + if (lock_after_cb_done) + pthread_mutex_lock(&private_display->lock); } INTERN tdm_private_pp* -- 2.7.4 From ec4c2c1a40f8e0f02683c7557f6f57c9db00b794 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 8 Dec 2015 20:35:50 +0900 Subject: [PATCH 13/16] elimiate race condition of capture callback Change-Id: I0eeeaac9b76474174272eba47ebfd7e23f0d14f6 --- src/tdm_capture.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index f63d2b8..fa592ec 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -54,7 +54,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. static void _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data) { + tdm_private_capture *private_capture = user_data; + tdm_private_display *private_display = private_capture->private_display; + int lock_after_cb_done = 0; + + if (pthread_mutex_trylock(&private_display->lock)) + { + pthread_mutex_unlock(&private_display->lock); + lock_after_cb_done = 1; + } + tdm_buffer_unref_backend(tdm_buffer_get(buffer)); + + if (lock_after_cb_done) + pthread_mutex_lock(&private_display->lock); } INTERN tdm_private_capture* -- 2.7.4 From 0528570f64e42d86e92d7edb5bd7a93e609f36dd Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 9 Dec 2015 12:45:00 +0900 Subject: [PATCH 14/16] change double pointer to one pointer in tdm_caps_output Change-Id: I81737bfacdf0423dce368d0dd6188ec71d41ad98 --- include/tdm_backend.h | 2 +- src/tdm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 1957987..bd4e9d7 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -59,7 +59,7 @@ typedef struct _tdm_caps_output unsigned int type_id; unsigned int mode_count; - tdm_output_mode **modes; + tdm_output_mode *modes; unsigned int prop_count; tdm_prop *props; diff --git a/src/tdm.c b/src/tdm.c index 7d5e16e..794540f 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -308,8 +308,8 @@ _tdm_display_update_caps_output(tdm_private_display *private_display, TDM_DBG("output props: %d, %s", caps->props[i].id, caps->props[i].name); for (i = 0; i < caps->mode_count; i++) TDM_DBG("output modes: name(%s), size(%dx%d), refresh(%d), flags(%d), type(%d)", - caps->modes[i]->name, caps->modes[i]->width, caps->modes[i]->height, - caps->modes[i]->refresh, caps->modes[i]->flags, caps->modes[i]->type); + caps->modes[i].name, caps->modes[i].width, caps->modes[i].height, + caps->modes[i].refresh, caps->modes[i].flags, caps->modes[i].type); TDM_DBG("output min : %dx%d", caps->min_w, caps->min_h); TDM_DBG("output max : %dx%d", caps->max_w, caps->max_h); TDM_DBG("output align: %d", caps->preferred_align); -- 2.7.4 From d61bb7194d28a31d9efad842e7eefde410eb3eac Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Fri, 11 Dec 2015 14:27:00 +0900 Subject: [PATCH 15/16] use tdm_buffer instead of tbm_surface for backend - add tdm buffer destroy handler Change-Id: I6edf927ded6c7e07cfcf396f279c5ab8fc49e4de Signed-off-by: Junkyeong Kim --- include/tdm_backend.h | 16 +++++++++--- src/tdm_buffer.c | 71 +++++++++++++++++++++++++++++++++++++++++++++------ src/tdm_capture.c | 4 +-- src/tdm_display.c | 3 +-- src/tdm_private.h | 5 ---- 5 files changed, 79 insertions(+), 20 deletions(-) diff --git a/include/tdm_backend.h b/include/tdm_backend.h index bd4e9d7..81eb89c 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -147,7 +147,7 @@ typedef struct _tdm_func_display tdm_error (*layer_get_property)(tdm_layer *layer, unsigned int id, tdm_value *value); tdm_error (*layer_set_info)(tdm_layer *layer, tdm_info_layer *info); tdm_error (*layer_get_info)(tdm_layer *layer, tdm_info_layer *info); - tdm_error (*layer_set_buffer)(tdm_layer *layer, tbm_surface_h buffer); + tdm_error (*layer_set_buffer)(tdm_layer *layer, tdm_buffer *buffer); tdm_error (*layer_unset_buffer)(tdm_layer *layer); tdm_capture *(*layer_create_capture)(tdm_layer *layer, tdm_error *error); } tdm_func_display; @@ -163,13 +163,13 @@ typedef struct _tdm_func_pp tdm_error (*pp_set_done_handler)(tdm_pp *pp, tdm_pp_done_handler func, void *user_data); } tdm_func_pp; -typedef void (*tdm_capture_done_handler)(tdm_capture *capture, tbm_surface_h buffer, void *user_data); +typedef void (*tdm_capture_done_handler)(tdm_capture *capture, tdm_buffer *buffer, void *user_data); typedef struct _tdm_func_capture { void (*capture_destroy)(tdm_capture *capture); /* init */ tdm_error (*capture_set_info)(tdm_capture *capture, tdm_info_capture *info); - tdm_error (*capture_attach)(tdm_capture *capture, tbm_surface_h buffer); + tdm_error (*capture_attach)(tdm_capture *capture, tdm_buffer *buffer); tdm_error (*capture_commit)(tdm_capture *capture); /* init */ tdm_error (*capture_set_done_handler)(tdm_capture *capture, tdm_capture_done_handler func, void *user_data); } tdm_func_capture; @@ -198,6 +198,16 @@ tdm_error tdm_backend_register_func_display(tdm_display *dpy, tdm_func_display * tdm_error tdm_backend_register_func_pp(tdm_display *dpy, tdm_func_pp *func_pp); tdm_error tdm_backend_register_func_capture(tdm_display *dpy, tdm_func_capture *func_capture); +typedef void (*tdm_buffer_destroy_handler)(tdm_buffer *buffer, void *user_data); + +tdm_buffer* tdm_buffer_ref_backend(tdm_buffer *buffer); +void tdm_buffer_unref_backend(tdm_buffer *buffer); +tbm_surface_h tdm_buffer_get_surface(tdm_buffer *buffer); +tdm_buffer* tdm_buffer_get(tbm_surface_h buffer); +tdm_error tdm_buffer_add_destroy_handler(tdm_buffer *buffer, tdm_buffer_destroy_handler func, void *user_data); +void tdm_buffer_remove_destroy_handler(tdm_buffer *buffer, tdm_buffer_destroy_handler func, void *user_data); + + #ifdef __cplusplus } #endif diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 31b0d88..508b9bd 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -43,7 +43,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typedef struct _tdm_buffer_func_info { - tdm_buffer_release_handler func; + tdm_buffer_release_handler release_func; + tdm_buffer_destroy_handler destroy_func; void *user_data; struct list_head link; @@ -60,6 +61,7 @@ typedef struct _tdm_buffer_info int backend_ref_count; struct list_head release_funcs; + struct list_head destroy_funcs; struct list_head link; } tdm_buffer_info; @@ -80,6 +82,15 @@ _tdm_buffer_destroy(tdm_buffer_info *buf_info) free(func_info); } + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) + func_info->destroy_func(buf_info, func_info->user_data); + + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) + { + LIST_DEL(&func_info->link); + free(func_info); + } + LIST_DEL(&buf_info->link); tbm_surface_internal_unref(buf_info->buffer); @@ -124,6 +135,7 @@ tdm_buffer_create(tbm_surface_h buffer, tdm_error *error) buf_info->buffer = buffer; LIST_INITHEAD(&buf_info->release_funcs); + LIST_INITHEAD(&buf_info->destroy_funcs); LIST_ADDTAIL(&buf_info->link, &buffer_list); if (error) @@ -189,7 +201,7 @@ tdm_buffer_add_release_handler(tdm_buffer *buffer, func_info = calloc(1, sizeof(tdm_buffer_func_info)); TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY); - func_info->func = func; + func_info->release_func = func; func_info->user_data = user_data; buf_info = buffer; @@ -210,7 +222,7 @@ tdm_buffer_remove_release_handler(tdm_buffer *buffer, tdm_buffer_release_handler buf_info = buffer; LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) { - if (func_info->func != func || func_info->user_data != user_data) + if (func_info->release_func != func || func_info->user_data != user_data) continue; LIST_DEL(&func_info->link); @@ -221,7 +233,7 @@ tdm_buffer_remove_release_handler(tdm_buffer *buffer, tdm_buffer_release_handler } -INTERN tdm_buffer* +EXTERN tdm_buffer* tdm_buffer_ref_backend(tdm_buffer *buffer) { tdm_buffer_info *buf_info; @@ -234,7 +246,7 @@ tdm_buffer_ref_backend(tdm_buffer *buffer) return buffer; } -INTERN void +EXTERN void tdm_buffer_unref_backend(tdm_buffer *buffer) { tdm_buffer_info *buf_info; @@ -256,14 +268,14 @@ tdm_buffer_unref_backend(tdm_buffer *buffer) old_ref_count = buf_info->ref_count; LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) - func_info->func(buffer, func_info->user_data); + func_info->release_func(buffer, func_info->user_data); /* finally, both ref_count and backend_ref_count are 0. destroy tdm_buffer */ if (old_ref_count == 0 && buf_info->ref_count == 0) _tdm_buffer_destroy(buf_info); } -INTERN tbm_surface_h +EXTERN tbm_surface_h tdm_buffer_get_surface(tdm_buffer *buffer) { tdm_buffer_info *buf_info = buffer; @@ -273,7 +285,7 @@ tdm_buffer_get_surface(tdm_buffer *buffer) return buf_info->buffer; } -INTERN tdm_buffer* +EXTERN tdm_buffer* tdm_buffer_get(tbm_surface_h buffer) { tdm_buffer_info *found; @@ -294,3 +306,46 @@ tdm_buffer_get(tbm_surface_h buffer) return NULL; } + +EXTERN tdm_error +tdm_buffer_add_destroy_handler(tdm_buffer *buffer, tdm_buffer_destroy_handler func, void *user_data) +{ + tdm_buffer_info *buf_info; + tdm_buffer_func_info *func_info; + + TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); + + func_info = calloc(1, sizeof(tdm_buffer_func_info)); + TDM_RETURN_VAL_IF_FAIL(func_info != NULL, TDM_ERROR_OUT_OF_MEMORY); + + func_info->destroy_func = func; + func_info->user_data = user_data; + + buf_info = buffer; + LIST_ADD(&func_info->link, &buf_info->destroy_funcs); + + return TDM_ERROR_NONE; +} + +EXTERN void +tdm_buffer_remove_destroy_handler(tdm_buffer *buffer, tdm_buffer_destroy_handler func, void *user_data) +{ + tdm_buffer_info *buf_info; + tdm_buffer_func_info *func_info = NULL, *next = NULL; + + TDM_RETURN_IF_FAIL(buffer != NULL); + TDM_RETURN_IF_FAIL(func != NULL); + + buf_info = buffer; + LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->destroy_funcs, link) + { + if (func_info->destroy_func != func || func_info->user_data != user_data) + continue; + + LIST_DEL(&func_info->link); + free(func_info); + + return; + } +} diff --git a/src/tdm_capture.c b/src/tdm_capture.c index fa592ec..46927c2 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -52,7 +52,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. func_capture = private_capture->func_capture static void -_tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data) +_tdm_caputre_cb_done(tdm_capture *capture_backend, tdm_buffer *buffer, void *user_data) { tdm_private_capture *private_capture = user_data; tdm_private_display *private_display = private_capture->private_display; @@ -64,7 +64,7 @@ _tdm_caputre_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *u lock_after_cb_done = 1; } - tdm_buffer_unref_backend(tdm_buffer_get(buffer)); + tdm_buffer_unref_backend(buffer); if (lock_after_cb_done) pthread_mutex_lock(&private_display->lock); diff --git a/src/tdm_display.c b/src/tdm_display.c index 082e6b5..0ae9bb5 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -1040,8 +1040,7 @@ tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer) private_layer->waiting_buffer = tdm_buffer_ref_backend(buffer); - ret = func_display->layer_set_buffer(private_layer->layer_backend, - tdm_buffer_get_surface(buffer)); + ret = func_display->layer_set_buffer(private_layer->layer_backend, buffer); pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_private.h b/src/tdm_private.h index 635682f..657ef4b 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -256,11 +256,6 @@ struct _tdm_private_commit_handler void *user_data; }; -tdm_buffer* tdm_buffer_ref_backend(tdm_buffer *buffer); -void tdm_buffer_unref_backend(tdm_buffer *buffer); -tbm_surface_h tdm_buffer_get_surface(tdm_buffer *buffer); -tdm_buffer* tdm_buffer_get(tbm_surface_h buffer); - tdm_private_pp* tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error); void tdm_pp_destroy_internal(tdm_private_pp *private_pp); -- 2.7.4 From 6f7e4d98706710265287efb05f23fe58a0686470 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 15 Dec 2015 19:01:11 +0900 Subject: [PATCH 16/16] add layer_set_video_pos to backend interface Change-Id: I80d1d31ab78f68f8859ce70b67d2e56a431e18b5 --- include/tdm.h | 1 + include/tdm_backend.h | 1 + src/tdm_display.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/include/tdm.h b/include/tdm.h index 23bcde8..da6a006 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -115,6 +115,7 @@ tdm_error tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info); tdm_error tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer); // layer has only one buffer tdm_error tdm_layer_unset_buffer(tdm_layer *layer); tdm_error tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable); +tdm_error tdm_layer_set_video_pos(tdm_layer *layer, int zpos); tdm_capture *tdm_layer_create_capture(tdm_layer *layer, tdm_error *error); diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 81eb89c..c649d73 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -149,6 +149,7 @@ typedef struct _tdm_func_display tdm_error (*layer_get_info)(tdm_layer *layer, tdm_info_layer *info); tdm_error (*layer_set_buffer)(tdm_layer *layer, tdm_buffer *buffer); tdm_error (*layer_unset_buffer)(tdm_layer *layer); + tdm_error (*layer_set_video_pos)(tdm_layer *layer, int zpos); tdm_capture *(*layer_create_capture)(tdm_layer *layer, tdm_error *error); } tdm_func_display; diff --git a/src/tdm_display.c b/src/tdm_display.c index 0ae9bb5..109c808 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -1104,6 +1104,35 @@ tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable) return ret; } +EXTERN tdm_error +tdm_layer_set_video_pos(tdm_layer *layer, int zpos) +{ + tdm_func_display *func_display; + LAYER_FUNC_ENTRY(); + + pthread_mutex_lock(&private_display->lock); + + func_display = &private_display->func_display; + + if (!(private_layer->caps.capabilities & TDM_LAYER_CAPABILITY_VIDEO)) + { + TDM_ERR("layer is not video layer"); + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_INVALID_PARAMETER; + } + + if (!func_display->layer_set_video_pos) + { + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + ret = func_display->layer_set_video_pos(private_layer->layer_backend, zpos); + + pthread_mutex_unlock(&private_display->lock); + + return ret; +} EXTERN tdm_capture* tdm_layer_create_capture(tdm_layer *layer, tdm_error *error) -- 2.7.4