}
static void
+_tdm_layer_cb_output_commit(tdm_output *output, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ tdm_private_layer_commit_handler *layer_commit_handler = user_data;
+ tdm_private_layer_commit_handler *lm = NULL;
+ tdm_private_display *private_display;
+ tdm_private_output *private_output = output;
+ tdm_private_layer *private_layer;
+ int found = 0;
+
+ TDM_RETURN_IF_FAIL(layer_commit_handler != NULL);
+
+ private_display = private_output->private_display;
+
+ LIST_FOR_EACH_ENTRY(lm, &private_output->layer_commit_handler_list, link) {
+ if (layer_commit_handler == lm) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ return;
+
+ private_layer = layer_commit_handler->private_layer;
+
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("layer(%p) commit: output(%d) committed", private_layer, private_output->pipe);
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ _tdm_layer_committed(private_layer);
+
+ if (layer_commit_handler->func) {
+ _pthread_mutex_unlock(&private_display->lock);
+ layer_commit_handler->func(private_output, sequence,
+ tv_sec, tv_usec, layer_commit_handler->user_data);
+ _pthread_mutex_lock(&private_display->lock);
+ }
+
+ LIST_DEL(&layer_commit_handler->link);
+ free(layer_commit_handler);
+
+ _pthread_mutex_unlock(&private_display->lock);
+}
+
+static void
_tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence,
unsigned int tv_sec, unsigned int tv_usec, void *user_data)
{
tdm_private_output *private_output = private_layer->private_output;
tdm_private_display *private_display = private_output->private_display;
- if (!private_display->commit_per_vblank) {
- if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("layer(%p) commit: commit_per_vblank false", private_layer);
- return 1;
- }
-
if (private_display->commit_per_vblank == 1 && _tdm_output_used_layer_count(private_output) == 1) {
if (tdm_debug_module & TDM_DEBUG_COMMIT)
TDM_INFO("layer(%p) commit: 1 layer", private_layer);
static tdm_error
_tdm_layer_commit(tdm_layer *layer, tdm_layer_commit_handler func, void *user_data)
{
- tdm_private_layer_commit_handler *layer_commit_handler = NULL;
+ tdm_private_layer_commit_handler *layer_commit_handler;
LAYER_FUNC_ENTRY();
if (private_layer->committing)
layer_commit_handler->func = func;
layer_commit_handler->user_data = user_data;
- if (_tdm_layer_commit_possible(private_layer)) {
- /* add to layer_commit_handler_list */
- LIST_ADD(&layer_commit_handler->link, &private_output->layer_commit_handler_list);
+ if (!private_display->commit_per_vblank) {
+ TDM_GOTO_IF_FAIL(private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT, commit_failed);
- ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
+ LIST_ADD(&layer_commit_handler->link, &private_output->layer_commit_handler_list);
+ ret = _tdm_output_commit(private_layer->private_output, 0, _tdm_layer_cb_output_commit, layer_commit_handler);
TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("layer(%p) commit: output", private_layer);
+ TDM_INFO("layer(%p) commit: no commit-per-vblank", private_layer);
} else {
- /* add to pending_commit_handler_list. It will be commited when a vblank occurs */
- LIST_ADD(&layer_commit_handler->link, &private_output->pending_commit_handler_list);
+ TDM_GOTO_IF_FAIL(private_display->commit_type == TDM_COMMIT_TYPE_LAYER, commit_failed);
- if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("layer(%p) commit: pending", private_layer);
- }
+ if (_tdm_layer_commit_possible(private_layer)) {
+ /* add to layer_commit_handler_list */
+ LIST_ADD(&layer_commit_handler->link, &private_output->layer_commit_handler_list);
- if (!private_output->vblank) {
- /* tdm_vblank APIs is for server. it should be called in unlock status*/
- _pthread_mutex_unlock(&private_display->lock);
- private_output->vblank = tdm_vblank_create(private_display, private_output, NULL);
- _pthread_mutex_lock(&private_display->lock);
- TDM_GOTO_IF_FAIL(private_output->vblank != NULL, commit_failed);
+ ret = _tdm_output_commit(private_layer->private_output, 0, NULL, NULL);
+ TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
- tdm_vblank_set_add_front(private_output->vblank, 1);
- }
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("layer(%p) commit: output", private_layer);
+ } else {
+ /* add to pending_commit_handler_list. It will be commited when a vblank occurs */
+ LIST_ADD(&layer_commit_handler->link, &private_output->pending_commit_handler_list);
- if (!private_output->waiting_vblank) {
- /* tdm_vblank APIs is for server. it should be called in unlock status*/
- _pthread_mutex_unlock(&private_display->lock);
- ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output);
- _pthread_mutex_lock(&private_display->lock);
- TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
- private_output->waiting_vblank = 1;
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("layer(%p) commit: pending", private_layer);
+ }
- if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("layer(%p) commit: wait vblank", private_layer);
+ if (!private_output->vblank) {
+ /* tdm_vblank APIs is for server. it should be called in unlock status*/
+ _pthread_mutex_unlock(&private_display->lock);
+ private_output->vblank = tdm_vblank_create(private_display, private_output, NULL);
+ _pthread_mutex_lock(&private_display->lock);
+ TDM_GOTO_IF_FAIL(private_output->vblank != NULL, commit_failed);
+
+ /* to call the frontend's internal vblank handlers before the extern vblank handlers */
+ tdm_vblank_set_add_front(private_output->vblank, 1);
+ }
+
+ if (!private_output->waiting_vblank) {
+ /* tdm_vblank APIs is for server. it should be called in unlock status*/
+ _pthread_mutex_unlock(&private_display->lock);
+ ret = tdm_vblank_wait(private_output->vblank, 0, 0, 1, _tdm_layer_cb_wait_vblank, private_output);
+ _pthread_mutex_lock(&private_display->lock);
+ TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+ private_output->waiting_vblank = 1;
+
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("layer(%p) commit: wait vblank", private_layer);
+ }
}
return ret;
_pthread_mutex_lock(&private_display->lock);
- if (private_display->commit_type == TDM_COMMIT_TYPE_NONE)
- private_display->commit_type = TDM_COMMIT_TYPE_LAYER;
- else if (private_display->commit_type == TDM_COMMIT_TYPE_OUTPUT) {
- TDM_ERR("Can't supported. Use tdm_output_commit");
- _pthread_mutex_unlock(&private_display->lock);
- return TDM_ERROR_BAD_REQUEST;
+ if (private_display->commit_type == TDM_COMMIT_TYPE_NONE) {
+ if (!private_display->commit_per_vblank)
+ private_display->commit_type = TDM_COMMIT_TYPE_OUTPUT;
+ else
+ private_display->commit_type = TDM_COMMIT_TYPE_LAYER;
}
if (private_output->current_dpms_value > TDM_OUTPUT_DPMS_ON) {