X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftdm_display.c;h=d28cf944c203256b6ab6f64978004ce2cc5b74fd;hb=41905377b07f3240402818a489d6b36956ba4e2a;hp=e4f88837dce4cd22471d39d9033575b288c5a444;hpb=a3f04f163b1c7802fbd80c2edfa4909ec7058d5e;p=platform%2Fcore%2Fuifw%2Flibtdm.git diff --git a/src/tdm_display.c b/src/tdm_display.c index e4f8883..d28cf94 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -91,6 +91,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. private_output = private_layer->private_output; \ private_display = private_output->private_display +#define LAYER_FUNC_ENTRY_VOID_RETURN() \ + tdm_private_display *private_display; \ + tdm_private_output *private_output; \ + tdm_private_layer *private_layer; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_IF_FAIL(layer != NULL); \ + private_layer = (tdm_private_layer*)layer; \ + private_output = private_layer->private_output; \ + private_display = private_output->private_display + EXTERN tdm_error tdm_display_get_capabilities(tdm_display *dpy, tdm_display_capability *capabilities) { @@ -116,6 +126,13 @@ tdm_display_get_pp_capabilities(tdm_display *dpy, tdm_pp_capability *capabilitie pthread_mutex_lock(&private_display->lock); + if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) + { + TDM_ERR("no pp capability"); + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NO_CAPABILITY; + } + *capabilities = private_display->caps_pp.capabilities; pthread_mutex_unlock(&private_display->lock); @@ -133,6 +150,13 @@ tdm_display_get_pp_available_formats(tdm_display *dpy, const tbm_format **format pthread_mutex_lock(&private_display->lock); + if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) + { + TDM_ERR("no pp capability"); + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NO_CAPABILITY; + } + *formats = (const tbm_format*)private_display->caps_pp.formats; *count = private_display->caps_pp.format_count; @@ -149,6 +173,13 @@ tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, pthread_mutex_lock(&private_display->lock); + if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_PP)) + { + TDM_ERR("no pp capability"); + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NO_CAPABILITY; + } + if (min_w) *min_w = private_display->caps_pp.min_w; if (min_h) @@ -174,6 +205,13 @@ tdm_display_get_capture_capabilities(tdm_display *dpy, tdm_capture_capability *c pthread_mutex_lock(&private_display->lock); + if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) + { + TDM_ERR("no capture capability"); + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NO_CAPABILITY; + } + *capabilities = private_display->caps_capture.capabilities; pthread_mutex_unlock(&private_display->lock); @@ -191,6 +229,13 @@ tdm_display_get_catpure_available_formats(tdm_display *dpy, const tbm_format **f pthread_mutex_lock(&private_display->lock); + if (!(private_display->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) + { + TDM_ERR("no capture capability"); + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NO_CAPABILITY; + } + *formats = (const tbm_format*)private_display->caps_capture.formats; *count = private_display->caps_capture.format_count; @@ -226,7 +271,7 @@ tdm_display_get_output_count(tdm_display *dpy, int *count) } -EXTERN const tdm_output* +EXTERN tdm_output* tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error) { tdm_private_output *private_output = NULL; @@ -245,7 +290,7 @@ tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error) if (i == index) { pthread_mutex_unlock(&private_display->lock); - return (const tdm_output*)private_output; + return private_output; } i++; } @@ -320,6 +365,25 @@ tdm_display_create_pp(tdm_display *dpy, tdm_error *error) } EXTERN tdm_error +tdm_output_get_model_info(tdm_output *output, const char **maker, const char **model, const char **name) +{ + OUTPUT_FUNC_ENTRY(); + + pthread_mutex_lock(&private_display->lock); + + if (maker) + *maker = private_output->caps.maker; + if (model) + *model = private_output->caps.model; + if (name) + *name = private_output->caps.name; + + pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status) { OUTPUT_FUNC_ENTRY(); @@ -377,7 +441,7 @@ tdm_output_get_layer_count(tdm_output *output, int *count) } -EXTERN const tdm_layer* +EXTERN tdm_layer* tdm_output_get_layer(tdm_output *output, int index, tdm_error *error) { tdm_private_layer *private_layer = NULL; @@ -516,20 +580,20 @@ tdm_output_get_pipe(tdm_output *output, unsigned int *pipe) EXTERN tdm_error tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) { - tdm_func_display *func_display; + tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_output = &private_display->func_output; - if (!func_display->output_set_property) + if (!func_output->output_set_property) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->output_set_property(private_output->output_backend, id, value); + ret = func_output->output_set_property(private_output->output_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -539,22 +603,22 @@ tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value) EXTERN tdm_error tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) { - tdm_func_display *func_display; + tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_output = &private_display->func_output; - if (!func_display->output_get_property) + if (!func_output->output_get_property) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->output_get_property(private_output->output_backend, id, value); + ret = func_output->output_get_property(private_output->output_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -572,13 +636,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 +654,45 @@ _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 = NULL; TDM_RETURN_IF_FAIL(commit_handler); - private_display = commit_handler->private_output->private_display; + private_output = commit_handler->private_output; + private_display = private_output->private_display; - pthread_mutex_unlock(&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); + + if (private_layer->buffer_queue) + { + pthread_mutex_unlock(&private_display->lock); + tbm_surface_queue_release(private_layer->buffer_queue, + private_layer->showing_buffer); + pthread_mutex_lock(&private_display->lock); + } + } + + private_layer->showing_buffer = private_layer->waiting_buffer; + private_layer->waiting_buffer = NULL; + } 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_DEL(&commit_handler->link); free(commit_handler); @@ -611,15 +702,15 @@ EXTERN tdm_error 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_func_output *func_output; tdm_private_vblank_handler *vblank_handler; OUTPUT_FUNC_ENTRY(); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_output = &private_display->func_output; - if (!func_display->output_wait_vblank) + if (!func_output->output_wait_vblank) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; @@ -638,7 +729,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, vblank_handler->func = func; vblank_handler->user_data = user_data; - ret = func_display->output_wait_vblank(private_output->output_backend, interval, + ret = func_output->output_wait_vblank(private_output->output_backend, interval, sync, vblank_handler); if (ret != TDM_ERROR_NONE) { @@ -649,7 +740,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, if (!private_output->regist_vblank_cb) { private_output->regist_vblank_cb = 1; - ret = func_display->output_set_vblank_handler(private_output->output_backend, + ret = func_output->output_set_vblank_handler(private_output->output_backend, _tdm_output_cb_vblank); } @@ -658,20 +749,17 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, return ret; } -EXTERN tdm_error -tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data) +static tdm_error +_tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data) { - tdm_func_display *func_display; + tdm_func_output *func_output; tdm_private_commit_handler *commit_handler; OUTPUT_FUNC_ENTRY(); - pthread_mutex_lock(&private_display->lock); + func_output = &private_display->func_output; - func_display = &private_display->func_display; - - if (!func_display->output_commit) + if (!func_output->output_commit) { - pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } @@ -679,7 +767,6 @@ tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, if (!commit_handler) { TDM_ERR("failed: alloc memory"); - pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_OUT_OF_MEMORY; } @@ -688,44 +775,55 @@ 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_backend, sync, commit_handler); + ret = func_output->output_commit(private_output->output_backend, sync, commit_handler); if (ret != TDM_ERROR_NONE) { - pthread_mutex_unlock(&private_display->lock); return ret; } if (!private_output->regist_commit_cb) { private_output->regist_commit_cb = 1; - ret = func_display->output_set_commit_handler(private_output->output_backend, + ret = func_output->output_set_commit_handler(private_output->output_backend, _tdm_output_cb_commit); } + return ret; +} + +EXTERN tdm_error +tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data) +{ + OUTPUT_FUNC_ENTRY(); + + pthread_mutex_lock(&private_display->lock); + + ret = _tdm_output_commit(output, sync, func, user_data); + pthread_mutex_unlock(&private_display->lock); return ret; } EXTERN tdm_error -tdm_output_set_mode(tdm_output *output, tdm_output_mode *mode) +tdm_output_set_mode(tdm_output *output, const tdm_output_mode *mode) { - tdm_func_display *func_display; + tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_output = &private_display->func_output; - if (!func_display->output_set_mode) + if (!func_output->output_set_mode) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->output_set_mode(private_output->output_backend, mode); + ret = func_output->output_set_mode(private_output->output_backend, mode); pthread_mutex_unlock(&private_display->lock); @@ -735,22 +833,22 @@ tdm_output_set_mode(tdm_output *output, tdm_output_mode *mode) EXTERN tdm_error tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) { - tdm_func_display *func_display; + tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_output = &private_display->func_output; - if (!func_display->output_get_mode) + if (!func_output->output_get_mode) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->output_get_mode(private_output->output_backend, mode); + ret = func_output->output_get_mode(private_output->output_backend, mode); pthread_mutex_unlock(&private_display->lock); @@ -760,23 +858,25 @@ tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) EXTERN tdm_error tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) { - tdm_func_display *func_display; + tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); - TDM_RETURN_VAL_IF_FAIL(dpms_value >= TDM_OUTPUT_DPMS_ON, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(dpms_value < TDM_OUTPUT_DPMS_MAX, TDM_ERROR_INVALID_PARAMETER); + if (dpms_value < TDM_OUTPUT_DPMS_ON) + dpms_value = TDM_OUTPUT_DPMS_ON; + else if (dpms_value > TDM_OUTPUT_DPMS_OFF) + dpms_value = TDM_OUTPUT_DPMS_OFF; pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_output = &private_display->func_output; - if (!func_display->output_set_dpms) + if (!func_output->output_set_dpms) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->output_set_dpms(private_output->output_backend, dpms_value); + ret = func_output->output_set_dpms(private_output->output_backend, dpms_value); pthread_mutex_unlock(&private_display->lock); @@ -786,22 +886,22 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) EXTERN tdm_error tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) { - tdm_func_display *func_display; + tdm_func_output *func_output; OUTPUT_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_output = &private_display->func_output; - if (!func_display->output_get_dpms) + if (!func_output->output_get_dpms) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->output_get_dpms(private_output->output_backend, dpms_value); + ret = func_output->output_get_dpms(private_output->output_backend, dpms_value); pthread_mutex_unlock(&private_display->lock); @@ -895,20 +995,20 @@ tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos) EXTERN tdm_error tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) { - tdm_func_display *func_display; + tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_layer = &private_display->func_layer; - if (!func_display->layer_set_property) + if (!func_layer->layer_set_property) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->layer_set_property(private_layer->layer_backend, id, value); + ret = func_layer->layer_set_property(private_layer->layer_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -918,22 +1018,22 @@ tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value) EXTERN tdm_error tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) { - tdm_func_display *func_display; + tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_layer = &private_display->func_layer; - if (!func_display->layer_get_property) + if (!func_layer->layer_get_property) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->layer_get_property(private_layer->layer_backend, id, value); + ret = func_layer->layer_get_property(private_layer->layer_backend, id, value); pthread_mutex_unlock(&private_display->lock); @@ -943,24 +1043,24 @@ tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value) EXTERN tdm_error tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) { - tdm_func_display *func_display; + tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_layer = &private_display->func_layer; private_layer->usable = 0; - if (!func_display->layer_set_info) + if (!func_layer->layer_set_info) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->layer_set_info(private_layer->layer_backend, info); + ret = func_layer->layer_set_info(private_layer->layer_backend, info); pthread_mutex_unlock(&private_display->lock); @@ -970,22 +1070,22 @@ tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info) EXTERN tdm_error tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) { - tdm_func_display *func_display; + tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_layer = &private_display->func_layer; - if (!func_display->layer_get_info) + if (!func_layer->layer_get_info) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->layer_get_info(private_layer->layer_backend, info); + ret = func_layer->layer_get_info(private_layer->layer_backend, info); pthread_mutex_unlock(&private_display->lock); @@ -993,37 +1093,35 @@ tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info) } EXTERN tdm_error -tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer) +tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) { - tdm_func_display *func_display; + tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_layer = &private_display->func_layer; private_layer->usable = 0; - if (!func_display->layer_set_buffer) + if (!func_layer->layer_set_buffer) { pthread_mutex_unlock(&private_display->lock); 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)); + ret = func_layer->layer_set_buffer(private_layer->layer_backend, buffer); pthread_mutex_unlock(&private_display->lock); @@ -1033,29 +1131,199 @@ tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer) EXTERN tdm_error tdm_layer_unset_buffer(tdm_layer *layer) { - tdm_func_display *func_display; + tdm_func_layer *func_layer; LAYER_FUNC_ENTRY(); pthread_mutex_lock(&private_display->lock); - func_display = &private_display->func_display; + func_layer = &private_display->func_layer; - if (private_layer->current_buffer) + if (private_layer->waiting_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->waiting_buffer); + pthread_mutex_lock(&private_display->lock); + private_layer->waiting_buffer = NULL; + } + + 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 = NULL; } private_layer->usable = 1; - if (!func_display->layer_unset_buffer) + if (!func_layer->layer_unset_buffer) { pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; } - ret = func_display->layer_unset_buffer(private_layer->layer_backend); + ret = func_layer->layer_unset_buffer(private_layer->layer_backend); + + pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +static void +_tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data) +{ + TDM_RETURN_IF_FAIL(data != NULL); + tdm_layer *layer = data; + tdm_func_layer *func_layer; + tbm_surface_h surface = NULL; + LAYER_FUNC_ENTRY_VOID_RETURN(); + + pthread_mutex_lock(&private_display->lock); + + func_layer = &private_display->func_layer; + if (!func_layer->layer_set_buffer) + { + pthread_mutex_unlock(&private_display->lock); + return; + } + + if (TBM_SURFACE_QUEUE_ERROR_NONE != tbm_surface_queue_acquire(private_layer->buffer_queue, &surface) || + surface == NULL) + { + TDM_ERR("tbm_surface_queue_acquire() failed surface:%p", surface); + pthread_mutex_unlock(&private_display->lock); + return; + } + + if (private_layer->waiting_buffer) + { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + tbm_surface_queue_release(private_layer->buffer_queue, private_layer->waiting_buffer); + pthread_mutex_lock(&private_display->lock); + } + + private_layer->waiting_buffer = tdm_buffer_ref_backend(surface); + + func_layer->layer_set_buffer(private_layer->layer_backend, surface); + + ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL); + if (ret != TDM_ERROR_NONE) + TDM_ERR("_tdm_output_commit() is fail"); + + pthread_mutex_unlock(&private_display->lock); +} + +static void +_tbm_layer_queue_destroy_cb(tbm_surface_queue_h surface_queue, void *data) +{ + TDM_RETURN_IF_FAIL(data != NULL); + tdm_layer *layer = data; + LAYER_FUNC_ENTRY_VOID_RETURN(); + TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); + + pthread_mutex_lock(&private_display->lock); + + if (private_layer->waiting_buffer) + { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + tbm_surface_queue_release(private_layer->buffer_queue, private_layer->waiting_buffer); + pthread_mutex_lock(&private_display->lock); + } + + private_layer->buffer_queue = NULL; + + pthread_mutex_unlock(&private_display->lock); +} + +EXTERN tdm_error +tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) +{ + tdm_func_layer *func_layer; + LAYER_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(buffer_queue != NULL, TDM_ERROR_INVALID_PARAMETER); + + pthread_mutex_lock(&private_display->lock); + + func_layer = &private_display->func_layer; + + private_layer->usable = 0; + + if (!func_layer->layer_set_buffer) + { + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + if (buffer_queue == private_layer->buffer_queue) + { + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + if (private_layer->waiting_buffer) + { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + tbm_surface_queue_release(private_layer->buffer_queue, private_layer->waiting_buffer); + private_layer->waiting_buffer = NULL; + pthread_mutex_lock(&private_display->lock); + } + + private_layer->buffer_queue = buffer_queue; + tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, + _tbm_layer_queue_acquirable_cb, + layer); + tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue, + _tbm_layer_queue_destroy_cb, + layer); + pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_layer_unset_buffer_queue(tdm_layer *layer) +{ + tdm_func_layer *func_layer; + LAYER_FUNC_ENTRY(); + + pthread_mutex_lock(&private_display->lock); + + func_layer = &private_display->func_layer; + + if (private_layer->waiting_buffer) + { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->waiting_buffer); + tbm_surface_queue_release(private_layer->buffer_queue, private_layer->waiting_buffer); + private_layer->waiting_buffer = NULL; + pthread_mutex_lock(&private_display->lock); + } + + if (private_layer->showing_buffer) + { + pthread_mutex_unlock(&private_display->lock); + tdm_buffer_unref_backend(private_layer->showing_buffer); + tbm_surface_queue_release(private_layer->buffer_queue, private_layer->showing_buffer); + pthread_mutex_lock(&private_display->lock); + private_layer->showing_buffer = NULL; + } + + tbm_surface_queue_set_acquirable_cb(private_layer->buffer_queue, NULL, NULL); + tbm_surface_queue_set_destroy_cb(private_layer->buffer_queue, NULL, NULL); + private_layer->buffer_queue = NULL; + private_layer->usable = 1; + + if (!func_layer->layer_unset_buffer) + { + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + ret = func_layer->layer_unset_buffer(private_layer->layer_backend); pthread_mutex_unlock(&private_display->lock); @@ -1078,6 +1346,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_layer *func_layer; + LAYER_FUNC_ENTRY(); + + pthread_mutex_lock(&private_display->lock); + + func_layer = &private_display->func_layer; + + 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_layer->layer_set_video_pos) + { + pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + ret = func_layer->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)