tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_VBLANK, tdm_display_find_output_stamp);
tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_STATUS, tdm_display_find_output_stamp);
tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_DPMS, tdm_display_find_output_stamp);
+ tdm_thread_cb_set_find_func(TDM_THREAD_CB_VOUTPUT_COMMIT, tdm_display_find_private_voutput);
return TDM_ERROR_NONE;
}
TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
}
+static void
+_tdm_voutput_thread_cb_commit(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data)
+{
+ tdm_thread_cb_voutput_commit *voutput_commit = (tdm_thread_cb_voutput_commit *)cb_base;
+ tdm_private_voutput_commit_handler *voutput_commit_handler = voutput_commit->base.data;
+ tdm_private_voutput *private_voutput = object;
+ tdm_private_output *private_output = NULL;
+
+ TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
+
+ if (!voutput_commit_handler)
+ return;
+
+ assert(voutput_commit_handler->owner_tid == syscall(SYS_gettid));
+
+ tdm_thread_cb_remove(private_voutput, TDM_THREAD_CB_VOUTPUT_COMMIT, voutput_commit_handler, _tdm_voutput_thread_cb_commit, NULL);
+
+ LIST_DEL(&voutput_commit_handler->link);
+
+ private_output = private_voutput->private_output;
+ if (tdm_debug_module & TDM_DEBUG_COMMIT) {
+ TDM_INFO("----------------------------------------- voutput(%d) committed", private_output->pipe);
+ TDM_INFO("handler(%p)", voutput_commit_handler);
+ }
+
+ if (voutput_commit_handler->func && private_voutput->set_voutput_commit != 0) {
+ _pthread_mutex_unlock(&private_display->lock);
+ voutput_commit_handler->func(private_voutput, voutput_commit_handler->user_data);
+ _pthread_mutex_lock(&private_display->lock);
+ }
+
+ free(voutput_commit_handler);
+
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("-----------------------------------------...");
+}
+
+static void
+_tdm_voutput_cb_commit(tdm_voutput *voutput_backend, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
+ tdm_private_module *private_module;
+ tdm_private_voutput *private_voutput = NULL, *v = NULL;
+ tdm_private_output *private_output;
+ tdm_thread_cb_voutput_commit voutput_commit;
+ tdm_error ret;
+
+ private_module = tdm_display_get()->virtual_module;
+
+ LIST_FOR_EACH_ENTRY(v, &private_module->voutput_list, link) {
+ if (v->voutput_backend == voutput_backend) {
+ private_voutput = v;
+ break;
+ }
+ }
+ if (!private_voutput) {
+ TDM_ERR("cannot find voutput");
+ return;
+ }
+
+ if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) == 0) return;
+
+ voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link);
+
+ private_output = private_voutput->private_output;
+
+ memset(&voutput_commit, 0, sizeof voutput_commit);
+ voutput_commit.base.type = TDM_THREAD_CB_VOUTPUT_COMMIT;
+ voutput_commit.base.length = sizeof voutput_commit;
+ voutput_commit.base.object_stamp = private_output->stamp;
+ voutput_commit.base.data = voutput_commit_handler;
+ voutput_commit.base.sync = 0;
+ voutput_commit.sequence = sequence;
+ voutput_commit.tv_sec = tv_sec;
+ voutput_commit.tv_usec = tv_usec;
+
+ ret = tdm_thread_cb_call(private_voutput, &voutput_commit.base, 1);
+ TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
+}
+
/* add_front: To distinguish between the user vblank handlers and the layer
* commit vblank handlers. The layer commit handlers will be called
* before calling the user vblank handlers.
}
}
+static void
+_voutput_commit_func(tdm_voutput *voutput, tbm_surface_h buffer)
+{
+ tdm_private_voutput *private_voutput = (tdm_private_voutput *)voutput;
+ tdm_error ret;
+
+ TDM_RETURN_IF_FAIL(voutput != NULL);
+ TDM_RETURN_IF_FAIL(buffer != NULL);
+
+ ret = tdm_voutput_attach_buffer(private_voutput, buffer);
+ TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
+ ret = tdm_voutput_commit_buffer(private_voutput);
+ TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
+
+ return;
+}
+
+INTERN tdm_error
+tdm_output_set_voutput_commit(tdm_voutput *voutput)
+{
+ tdm_private_display *private_display;
+ tdm_private_output *private_output;
+ tdm_private_voutput *private_voutput;
+ tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput *)voutput;
+ private_display = private_voutput->private_display;
+ private_output = (tdm_private_output *)private_voutput->private_output;
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) {
+ _pthread_mutex_unlock(&private_display->lock);
+ return ret;
+ }
+
+ if (!private_voutput->regist_commit_cb) {
+ private_voutput->regist_commit_cb = 1;
+ ret = tdm_voutput_set_commit_func(private_voutput, _tdm_voutput_cb_commit);
+ if (ret != TDM_ERROR_NONE) {
+ TDM_ERR("failed: tdm_voutput_set_commit_func");
+ return ret;
+ }
+ }
+
+ voutput_commit_handler = calloc(1, sizeof(tdm_private_voutput_commit_handler));
+ if (!voutput_commit_handler) {
+ /* LCOV_EXCL_START */
+ TDM_ERR("failed: alloc memory");
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_OUT_OF_MEMORY;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = tdm_thread_cb_add(private_output->private_voutput, TDM_THREAD_CB_VOUTPUT_COMMIT, voutput_commit_handler, _tdm_voutput_thread_cb_commit, NULL);
+ if (ret != TDM_ERROR_NONE) {
+ TDM_ERR("tdm_thread_cb_add failed");
+ free(voutput_commit_handler);
+ _pthread_mutex_unlock(&private_display->lock);
+ return ret;
+ }
+
+ LIST_ADDTAIL(&voutput_commit_handler->link, &private_voutput->voutput_commit_handler_list);
+ voutput_commit_handler->private_voutput = private_voutput;
+ voutput_commit_handler->func = _voutput_commit_func;
+ voutput_commit_handler->owner_tid = syscall(SYS_gettid);
+
+ private_voutput->set_voutput_commit = 1;
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+INTERN tdm_error
+tdm_output_unset_voutput_commit(tdm_voutput *voutput)
+{
+ tdm_private_display *private_display;
+ tdm_private_output *private_output;
+ tdm_private_voutput *private_voutput;
+ tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput *)voutput;
+ private_display = private_voutput->private_display;
+ private_output = (tdm_private_output *)private_voutput->private_output;
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ private_voutput->set_voutput_commit = 0;
+
+ if (private_voutput->regist_commit_cb) {
+ private_voutput->regist_commit_cb = 0;
+ ret = tdm_voutput_set_commit_func(private_voutput, NULL);
+ if (ret != TDM_ERROR_NONE) {
+ TDM_ERR("failed: tdm_voutput_set_commit_func");
+ return ret;
+ }
+ }
+
+ if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) == 0) {
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_NONE;
+ }
+
+ if (LIST_LENGTH(&private_output->output_commit_handler_list) != 0) {
+ //commiting. don't remove voutput commit thread here
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_NONE;
+ }
+
+ if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) {
+ voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link);
+ } else {
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_NONE;
+ }
+
+ tdm_thread_cb_remove(private_output->private_voutput, TDM_THREAD_CB_VOUTPUT_COMMIT, voutput_commit_handler, _tdm_voutput_thread_cb_commit, NULL);
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return TDM_ERROR_NONE;
+}
+
INTERN tdm_error
tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data)
{
+ tdm_private_display *private_display;
tdm_private_output *private_output;
+ tdm_private_voutput *private_voutput;
tdm_private_module *private_module;
tdm_func_output *func_output;
tdm_private_output_commit_handler *output_commit_handler = NULL;
+ tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
tdm_private_layer *private_layer = NULL;
tdm_output_dpms dpms_value = TDM_OUTPUT_DPMS_ON;
tdm_error ret = TDM_ERROR_NONE;
private_output = (tdm_private_output*)output;
private_module = private_output->private_module;
+ private_display = private_module->private_display;
func_output = &private_module->func_output;
if (!func_output->output_commit) {
/* LCOV_EXCL_STOP */
}
+ if (private_module == private_display->virtual_module) {
+ if (!private_output->private_voutput) {
+ TDM_ERR("virtual module but don't have voutput");
+ free(output_commit_handler);
+ return TDM_ERROR_BAD_MODULE;
+ }
+ }
+
ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL);
if (ret != TDM_ERROR_NONE) {
TDM_ERR("tdm_thread_cb_add failed");
output_commit_handler->user_data = user_data;
output_commit_handler->owner_tid = syscall(SYS_gettid);
+ if (private_module == private_display->virtual_module) {
+ private_voutput = private_output->private_voutput;
+
+ /* voutput use only 1 layer */
+ private_layer = LIST_FIRST_ENTRY(&private_output->layer_list, tdm_private_layer, link);
+
+ if (LIST_LENGTH(&private_voutput->voutput_commit_handler_list) != 0) {
+ voutput_commit_handler = LIST_FIRST_ENTRY(&private_voutput->voutput_commit_handler_list, tdm_private_voutput_commit_handler, link);
+ voutput_commit_handler->user_data = private_layer->commiting_buffer;
+ }
+ }
+
ret = func_output->output_commit(private_output->output_backend, sync,
output_commit_handler);
TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
private_layer->committed_buffer = private_layer->waiting_buffer;
private_layer->waiting_buffer = NULL;
+ private_layer->commiting_buffer = NULL;
if (tdm_debug_module & TDM_DEBUG_BUFFER)
TDM_INFO("layer(%p) waiting_buffer(%p) committed_buffer(%p)",
private_layer, private_layer->waiting_buffer,
LIST_DEL(&output_commit_handler->link);
free(output_commit_handler);
}
+
return ret;
/* LCOV_EXCL_STOP */
}
_pthread_mutex_lock(&private_display->lock);
- if (error)
- *error = TDM_ERROR_NONE;
+ if (error) *error = TDM_ERROR_NONE;
private_voutput = calloc(1, sizeof(tdm_private_voutput));
if (!private_voutput) {
- *error = TDM_ERROR_OUT_OF_MEMORY;
+ if (error) *error = TDM_ERROR_OUT_OF_MEMORY;
_pthread_mutex_unlock(&private_display->lock);
return NULL;
}
if (voutput_backend == NULL || ret != TDM_ERROR_NONE) {
TDM_ERR("voutput_create fail");
free(private_voutput);
- *error = ret;
+ if (error) *error = ret;
private_display->current_module = current_module;
_pthread_mutex_unlock(&private_display->lock);
return NULL;
if (output_backend == NULL || ret != TDM_ERROR_NONE) {
TDM_ERR("voutput_get_output fail");
free(private_voutput);
- *error = ret;
+ if (error) *error = ret;
if (func_voutput->voutput_destroy)
func_voutput->voutput_destroy(voutput_backend);
else
func_voutput->voutput_destroy(voutput_backend);
else
TDM_ERR("no destroy function");
- *error = ret;
+ if (error) *error = ret;
private_display->current_module = current_module;
_pthread_mutex_unlock(&private_display->lock);
return NULL;
func_voutput->voutput_destroy(voutput_backend);
else
TDM_ERR("no destroy function");
+ private_voutput = NULL;
} else {
- strncpy(private_voutput->name, name, TDM_NAME_LEN);
- strncpy(private_output->name, name, TDM_NAME_LEN);
+ strncpy(private_voutput->name, name, TDM_NAME_LEN - 1);
+ private_voutput->name[TDM_NAME_LEN - 1] = '\0';
+ strncpy(private_output->name, name, TDM_NAME_LEN - 1);
+ private_output->name[TDM_NAME_LEN - 1] = '\0';
private_voutput->private_output = private_output;
private_output->private_voutput = private_voutput;
return ret;
}
+
+/* LCOV_EXCL_START */
+INTERN tdm_error
+tdm_voutput_set_commit_func(tdm_voutput *voutput, tdm_voutput_commit_handler func)
+{
+ tdm_private_display *private_display;
+ tdm_private_module *private_module = NULL;
+ tdm_private_voutput *private_voutput;
+ tdm_func_voutput *func_voutput = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput*)voutput;
+ private_display = private_voutput->private_display;
+ private_module = private_voutput->private_module;
+ TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE);
+
+ func_voutput = &private_module->func_voutput;
+ if (func_voutput->voutput_set_commit_func)
+ ret = func_voutput->voutput_set_commit_func(private_voutput->voutput_backend, func);
+ else
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+
+ return ret;
+}
+
+INTERN tdm_error
+tdm_voutput_commit_done(tdm_voutput *voutput)
+{
+ tdm_private_display *private_display;
+ tdm_private_module *private_module = NULL;
+ tdm_private_voutput *private_voutput;
+ tdm_func_voutput *func_voutput = NULL;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_voutput = (tdm_private_voutput*)voutput;
+ private_display = private_voutput->private_display;
+ private_module = private_voutput->private_module;
+ TDM_RETURN_VAL_IF_FAIL(private_module == private_display->virtual_module, TDM_ERROR_BAD_MODULE);
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ func_voutput = &private_module->func_voutput;
+ if (func_voutput->voutput_commit_done)
+ ret = func_voutput->voutput_commit_done(private_voutput->voutput_backend);
+ else
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+/* LCOV_EXCL_STOP */