TDM_RETURN_IF_FAIL(private_output != NULL); \
private_display = private_output->private_display
+static int hwc_use_vblank;
+static unsigned int hwc_vblank_fps;
static tdm_private_hwc_window *
_tdm_hwc_find_private_hwc_window(tdm_private_hwc *private_hwc, tdm_hwc_window *hwc_window_backend)
return NULL;
}
+static tdm_error
+_tdm_hwc_check_hwc_commit_handler_validation(tdm_private_hwc *private_hwc, tdm_private_hwc_commit_handler *hwc_commit_handler)
+{
+ tdm_private_hwc_commit_handler *commit_handler = NULL;
+
+ if (LIST_IS_EMPTY(&private_hwc->hwc_commit_handler_list))
+ return TDM_ERROR_INVALID_PARAMETER;
+
+ LIST_FOR_EACH_ENTRY(commit_handler, &private_hwc->hwc_commit_handler_list, link) {
+ if (commit_handler == hwc_commit_handler)
+ return TDM_ERROR_NONE;
+ }
+
+ return TDM_ERROR_INVALID_PARAMETER;
+}
+
static void
_tdm_hwc_thread_cb_commit(tdm_private_display *private_display, void *object,
tdm_thread_cb_base *cb_base, void *user_data)
tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler,
_tdm_hwc_thread_cb_commit, NULL);
+ TDM_RETURN_IF_FAIL(_tdm_hwc_check_hwc_commit_handler_validation(private_hwc, hwc_commit_handler) == TDM_ERROR_NONE)
+
LIST_DEL(&hwc_commit_handler->link);
if (tdm_debug_module & TDM_DEBUG_COMMIT) {
TDM_INFO("handler(%p)", hwc_commit_handler);
}
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_ASYNC_END((intptr_t)hwc_commit_handler, "[HWC_COMMIT~HANDLER] %d",
+ private_hwc->private_output->pipe);
+
+ /* LCOV_EXCL_START */
+ if (private_display->print_fps) {
+ double curr = tdm_helper_get_time();
+ if (private_hwc->fps_stamp == 0) {
+ private_hwc->fps_stamp = curr;
+ } else if ((curr - private_hwc->fps_stamp) > 1.0) {
+ TDM_INFO("hwc(%p,%d) fps: %d",
+ private_hwc, private_hwc->index, private_hwc->fps_count);
+ private_hwc->fps_count = 0;
+ private_hwc->fps_stamp = curr;
+ } else
+ private_hwc->fps_count++;
+ } else if (private_hwc->fps_stamp != 0) {
+ private_hwc->fps_stamp = 0;
+ private_hwc->fps_count = 0;
+ }
+ /* LCOV_EXCL_STOP */
+
if (hwc_commit_handler->func) {
_pthread_mutex_unlock(&private_display->lock);
hwc_commit_handler->func(private_hwc,
TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
}
+static void
+_tdm_hwc_cb_commit_hal_tdm(hal_tdm_hwc *hwc_backend, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ tdm_private_hwc_commit_handler *hwc_commit_handler = user_data;
+ tdm_private_hwc *private_hwc;
+ tdm_thread_cb_hwc_commit hwc_commit;
+ tdm_error ret;
+
+ if (hwc_commit_handler)
+ private_hwc = hwc_commit_handler->private_hwc;
+ else
+ private_hwc = tdm_display_find_private_hwc(tdm_display_get(), (tdm_hwc *)hwc_backend);
+
+ memset(&hwc_commit, 0, sizeof hwc_commit);
+ hwc_commit.base.type = TDM_THREAD_CB_HWC_COMMIT;
+ hwc_commit.base.length = sizeof hwc_commit;
+ hwc_commit.base.object_stamp = private_hwc->stamp;
+ hwc_commit.base.data = hwc_commit_handler;
+ hwc_commit.base.sync = 0;
+ hwc_commit.sequence = sequence;
+ hwc_commit.tv_sec = tv_sec;
+ hwc_commit.tv_usec = tv_usec;
+
+ ret = tdm_thread_cb_call(private_hwc, &hwc_commit.base, 1);
+ TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
+}
+
+/* LCOV_EXCL_START */
+static void
+_tdm_hwc_got_wait_vblank(unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ tdm_private_hwc_commit_handler *hwc_commit_handler = user_data;
+ tdm_private_hwc *private_hwc;
+ tdm_thread_cb_hwc_commit hwc_commit;
+
+ private_hwc = hwc_commit_handler->private_hwc;
+ private_hwc->private_output->layer_waiting_vblank = 0;
+
+ memset(&hwc_commit, 0, sizeof hwc_commit);
+ hwc_commit.base.type = TDM_THREAD_CB_HWC_COMMIT;
+ hwc_commit.base.length = sizeof hwc_commit;
+ hwc_commit.base.object_stamp = private_hwc->stamp;
+ hwc_commit.base.data = hwc_commit_handler;
+ hwc_commit.base.sync = 0;
+ hwc_commit.sequence = sequence;
+ hwc_commit.tv_sec = tv_sec;
+ hwc_commit.tv_usec = tv_usec;
+
+ _tdm_hwc_thread_cb_commit(private_hwc->private_output->private_display, private_hwc, &hwc_commit.base, user_data);
+}
+
+static void
+_tdm_hwc_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_hwc_commit_handler *hwc_commit_handler = user_data;
+ tdm_private_output *private_output = NULL;
+ tdm_private_display *private_display;
+
+ if (!hwc_commit_handler->use_vblank)
+ return;
+
+ TDM_RETURN_IF_FAIL(hwc_commit_handler != NULL);
+ TDM_RETURN_IF_FAIL(hwc_commit_handler->private_hwc != NULL);
+
+ private_output = hwc_commit_handler->private_hwc->private_output;
+ TDM_RETURN_IF_FAIL(private_output != NULL);
+
+ private_display = private_output->private_display;
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ _tdm_hwc_got_wait_vblank(sequence, tv_sec, tv_usec, user_data);
+
+ _pthread_mutex_unlock(&private_display->lock);
+}
+
+static tdm_error
+_tdm_hwc_vblank(tdm_private_hwc *private_hwc, tdm_private_hwc_commit_handler *hwc_commit_handler)
+{
+ tdm_private_display *private_display;
+ tdm_private_output *private_output;
+ tdm_error ret = TDM_ERROR_NONE;
+
+ private_output = private_hwc->private_output;
+ TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ private_display = private_output->private_display;
+
+ 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_RETURN_VAL_IF_FAIL(private_output->vblank != NULL, TDM_ERROR_OPERATION_FAILED);
+ }
+
+ if (!private_output->layer_waiting_vblank) {
+ ret = tdm_vblank_set_fps(private_output->vblank, hwc_vblank_fps);
+ if (ret != TDM_ERROR_NONE)
+ goto done;
+
+ private_output->layer_waiting_vblank = 1;
+
+ /* 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_hwc_cb_wait_vblank, hwc_commit_handler);
+ _pthread_mutex_lock(&private_display->lock);
+ if (ret != TDM_ERROR_NONE) {
+ if (!TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) {
+ private_output->layer_waiting_vblank = 0;
+ }
+ }
+ }
+
+done:
+ return ret;
+}
+/* LCOV_EXCL_STOP */
+
INTERN tdm_error
tdm_hwc_init(tdm_private_display *private_display)
{
return TDM_ERROR_NONE;
}
+INTERN void
+tdm_hwc_set_vblank(unsigned int fps)
+{
+ hwc_use_vblank = 1;
+ hwc_vblank_fps = fps;
+}
+
+INTERN void
+tdm_hwc_unset_vblank(void)
+{
+ hwc_use_vblank = 0;
+ hwc_vblank_fps = 0;
+}
+
EXTERN tdm_hwc_window *
tdm_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
{
private_module = private_output->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_get_video_supported_formats) {
- /* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return TDM_ERROR_NOT_IMPLEMENTED;
- /* LCOV_EXCL_STOP */
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_video_supported_formats((hal_tdm_hwc *)private_hwc->hwc_backend, formats, count);
+ } else {
+ if (!func_hwc->hwc_get_video_supported_formats) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_get_video_supported_formats(private_hwc->hwc_backend, formats, count);
}
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+EXTERN tdm_error
+tdm_hwc_get_video_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+
+ HWC_FUNC_ENTRY();
- ret = func_hwc->hwc_get_video_supported_formats(private_hwc->hwc_backend, formats, count);
+ 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);
+
+ private_module = private_output->private_module;
+ func_hwc = &private_module->func_hwc;
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_video_available_properties((hal_tdm_hwc *)private_hwc->hwc_backend,
+ (const hal_tdm_prop **)props, count);
+ } else {
+ if (!func_hwc->hwc_get_video_available_properties) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_get_video_available_properties(private_hwc->hwc_backend, props, count);
+ }
_pthread_mutex_unlock(&private_display->lock);
return ret;
}
EXTERN tdm_error
-tdm_hwc_get_video_capability(tdm_hwc *hwc,
- tdm_hwc_video_capability *video_capability)
+tdm_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
{
tdm_private_module *private_module;
tdm_func_hwc *func_hwc;
private_module = private_output->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_get_video_capability) {
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return TDM_ERROR_NOT_IMPLEMENTED;
- }
-
- ret = func_hwc->hwc_get_video_capability(private_hwc->hwc_backend,
- video_capability);
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_capabilities((hal_tdm_hwc *)private_hwc->hwc_backend, (hal_tdm_hwc_capability *)capabilities);
+ } else {
+ if (!func_hwc->hwc_get_capabilities) {
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ }
+ ret = func_hwc->hwc_get_capabilities(private_hwc->hwc_backend, capabilities);
+ }
_pthread_mutex_unlock(&private_display->lock);
return ret;
private_module = private_output->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_get_available_properties) {
- /* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return TDM_ERROR_NOT_IMPLEMENTED;
- /* LCOV_EXCL_STOP */
- }
-
- ret = func_hwc->hwc_get_available_properties(private_hwc->hwc_backend, props, count);
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_available_properties((hal_tdm_hwc *)private_hwc->hwc_backend, (const hal_tdm_prop **)props, count);
+ } else {
+ if (!func_hwc->hwc_get_available_properties) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ /* LCOV_EXCL_STOP */
+ }
+ ret = func_hwc->hwc_get_available_properties(private_hwc->hwc_backend, props, count);
+ }
_pthread_mutex_unlock(&private_display->lock);
return ret;
private_module = private_hwc->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_get_client_target_buffer_queue) {
- /* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return NULL;
- /* LCOV_EXCL_STOP */
+ if (private_module->use_hal_tdm) {
+ queue = hal_tdm_hwc_get_client_target_buffer_queue((hal_tdm_hwc *)private_hwc->hwc_backend, (hal_tdm_error *)error);
+ } else {
+ if (!func_hwc->hwc_get_client_target_buffer_queue) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return NULL;
+ /* LCOV_EXCL_STOP */
+ }
+
+ queue = func_hwc->hwc_get_client_target_buffer_queue(private_hwc->hwc_backend, error);
}
+ _pthread_mutex_unlock(&private_display->lock);
- queue = func_hwc->hwc_get_client_target_buffer_queue(private_hwc->hwc_backend, error);
+ return queue;
+}
+
+EXTERN tdm_error
+tdm_hwc_set_client_target_buffer_info(tdm_hwc *hwc, tdm_hwc_window_info *info)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+
+ HWC_FUNC_ENTRY();
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ private_module = private_hwc->private_module;
+ func_hwc = &private_module->func_hwc;
+
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_set_client_target_buffer_info((hal_tdm_hwc *)private_hwc->hwc_backend, (hal_tdm_hwc_window_info *)info);
+ } else {
+ if (!func_hwc->hwc_set_client_target_buffer_info) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_set_client_target_buffer_info(private_hwc->hwc_backend, info);
+ }
_pthread_mutex_unlock(&private_display->lock);
- return queue;
+ return ret;
}
EXTERN tdm_error
_pthread_mutex_lock(&private_display->lock);
+ if (tdm_ttrace_module & TDM_TTRACE_HWC) {
+ if (target_buffer) {
+ tbm_bo bo = tbm_surface_internal_get_bo(target_buffer, 0);
+ TDM_TRACE_BEGIN("tdm_hwc_set_client_target_buffer %d", tbm_bo_export(bo));
+ } else {
+ TDM_TRACE_BEGIN("tdm_hwc_set_client_target_buffer NULL");
+ }
+ }
+
if (tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) {
/* LCOV_EXCL_START */
char str[TDM_PATH_LEN];
private_module = private_hwc->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_set_client_target_buffer) {
- /* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return TDM_ERROR_NOT_IMPLEMENTED;
- /* LCOV_EXCL_STOP */
+ if (private_module->use_hal_tdm) {
+ hal_tdm_region hdamage;
+ memcpy(&hdamage, &damage, sizeof(hal_tdm_region));
+ ret = (tdm_error)hal_tdm_hwc_set_client_target_buffer((hal_tdm_hwc *)private_hwc->hwc_backend, target_buffer, hdamage);
+ } else {
+ if (!func_hwc->hwc_set_client_target_buffer) {
+ /* LCOV_EXCL_START */
+ TDM_WRN("not implemented!!");
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_set_client_target_buffer(private_hwc->hwc_backend, target_buffer, damage);
+ }
+ if (private_hwc->display_target_buffer) {
+ if (private_hwc->display_target_buffer != target_buffer) {
+ tbm_surface_internal_unref(private_hwc->display_target_buffer);
+ private_hwc->display_target_buffer = target_buffer;
+ if (target_buffer)
+ tbm_surface_internal_ref(private_hwc->display_target_buffer);
+ }
+ } else {
+ if (target_buffer) {
+ private_hwc->display_target_buffer = target_buffer;
+ tbm_surface_internal_ref(private_hwc->display_target_buffer);
+ }
}
- ret = func_hwc->hwc_set_client_target_buffer(private_hwc->hwc_backend, target_buffer, damage);
+done:
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
_pthread_mutex_unlock(&private_display->lock);
return ret;
}
+EXTERN tdm_error
+tdm_hwc_set_client_target_acquire_fence(tdm_hwc *hwc, int acquire_fence)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+
+ HWC_FUNC_ENTRY();
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ private_module = private_hwc->private_module;
+ func_hwc = &private_module->func_hwc;
+
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_set_client_target_acquire_fence((hal_tdm_hwc *)private_hwc->hwc_backend, acquire_fence);
+ } else {
+ if (!func_hwc->hwc_set_client_target_acquire_fence) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_set_client_target_acquire_fence(private_hwc->hwc_backend, acquire_fence);
+ }
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
EXTERN tdm_error
tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
_pthread_mutex_lock(&private_display->lock);
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_BEGIN(__FUNCTION__);
+
private_module = private_hwc->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_validate) {
- /* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return TDM_ERROR_NOT_IMPLEMENTED;
- /* LCOV_EXCL_STOP */
- }
-
- if (num_wnds == 0) {
- ret = func_hwc->hwc_validate(private_hwc->hwc_backend, NULL, 0, num_types);
+ if (private_module->use_hal_tdm) {
+ if (num_wnds == 0) {
+ ret = (tdm_error)hal_tdm_hwc_validate((hal_tdm_hwc *)private_hwc->hwc_backend, NULL, 0, num_types);
+ goto done;
+ }
+ } else {
+ if (!func_hwc->hwc_validate) {
+ /* LCOV_EXCL_START */
+ TDM_WRN("not implemented!!");
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
- _pthread_mutex_unlock(&private_display->lock);
- return ret;
+ if (num_wnds == 0) {
+ ret = func_hwc->hwc_validate(private_hwc->hwc_backend, NULL, 0, num_types);
+ goto done;
+ }
}
-
composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *));
if (!composited_wnds_backend) {
/* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- return TDM_ERROR_OUT_OF_MEMORY;
+ ret = TDM_ERROR_OUT_OF_MEMORY;
+ goto done;
/* LCOV_EXCL_STOP */
}
for (i = 0; i < num_wnds; i++)
composited_wnds_backend[i] = composited_wnds_frontend[i]->hwc_window_backend;
- ret = func_hwc->hwc_validate(private_hwc->hwc_backend, composited_wnds_backend,
- num_wnds, num_types);
+ if (private_module->use_hal_tdm)
+ ret = (tdm_error)hal_tdm_hwc_validate((hal_tdm_hwc *)private_hwc->hwc_backend, (hal_tdm_hwc_window **)composited_wnds_backend,
+ num_wnds, num_types);
+ else
+ ret = func_hwc->hwc_validate(private_hwc->hwc_backend, composited_wnds_backend,
+ num_wnds, num_types);
free(composited_wnds_backend);
+done:
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
+
_pthread_mutex_unlock(&private_display->lock);
return ret;
_pthread_mutex_lock(&private_display->lock);
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_BEGIN(__FUNCTION__);
+
private_module = private_hwc->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_get_changed_composition_types) {
- /* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return TDM_ERROR_NOT_IMPLEMENTED;
- /* LCOV_EXCL_STOP */
- }
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_changed_composition_types((hal_tdm_hwc *)private_hwc->hwc_backend, num_elements,
+ (hal_tdm_hwc_window **)hwc_window,
+ (hal_tdm_hwc_window_composition *)composition_types);
+ } else {
+ if (!func_hwc->hwc_get_changed_composition_types) {
+ /* LCOV_EXCL_START */
+ TDM_WRN("not implemented!!");
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
- ret = func_hwc->hwc_get_changed_composition_types(private_hwc->hwc_backend,
- num_elements, hwc_window, composition_types);
+ ret = func_hwc->hwc_get_changed_composition_types(private_hwc->hwc_backend,
+ num_elements, hwc_window, composition_types);
+ }
if (ret != TDM_ERROR_NONE) {
/* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- return ret;
+ goto done;
/* LCOV_EXCL_STOP */
}
if (hwc_window == NULL || composition_types == NULL) {
- _pthread_mutex_unlock(&private_display->lock);
- return TDM_ERROR_NONE;
+ goto done;
}
for (i = 0; i < *num_elements; i++) {
TDM_ERR("failed! This should never happen!");
tdm_hwc_window_destroy_internal(private_hwc_window);
*num_elements = 0;
- _pthread_mutex_unlock(&private_display->lock);
- return TDM_ERROR_OPERATION_FAILED;
+ ret = TDM_ERROR_OPERATION_FAILED;
+ goto done;
/* LCOV_EXCL_STOP */
}
hwc_window[i] = (tdm_hwc_window*)private_hwc_window;
}
+done:
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
+
_pthread_mutex_unlock(&private_display->lock);
return ret;
_pthread_mutex_lock(&private_display->lock);
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_BEGIN(__FUNCTION__);
+
private_module = private_hwc->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_validate) {
- /* LCOV_EXCL_START */
- _pthread_mutex_unlock(&private_display->lock);
- TDM_WRN("not implemented!!");
- return TDM_ERROR_NOT_IMPLEMENTED;
- /* LCOV_EXCL_STOP */
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_accept_validation((hal_tdm_hwc *)private_hwc->hwc_backend);
+ } else {
+ if (!func_hwc->hwc_validate) {
+ /* LCOV_EXCL_START */
+ TDM_WRN("not implemented!!");
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_accept_validation(private_hwc->hwc_backend);
}
- ret = func_hwc->hwc_accept_validation(private_hwc->hwc_backend);
+done:
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
_pthread_mutex_unlock(&private_display->lock);
return ret;
}
-/* temporary prototype to avoid build break */
-tdm_error
-tdm_hwc_accept_changes(tdm_hwc *hwc)
-{
- return tdm_hwc_accept_validation(hwc);
-}
-
EXTERN tdm_error
tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_data)
{
tdm_private_module *private_module;
tdm_func_hwc *func_hwc = NULL;
tdm_private_hwc_commit_handler *hwc_commit_handler = NULL;
+ tdm_private_voutput *private_voutput = NULL;
+ tdm_private_voutput_commit_handler *voutput_commit_handler = NULL;
HWC_FUNC_ENTRY();
_pthread_mutex_lock(&private_display->lock);
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_BEGIN(__FUNCTION__);
+
private_module = private_hwc->private_module;
func_hwc = &private_module->func_hwc;
- if (!func_hwc->hwc_commit) {
- /* LCOV_EXCL_START */
- TDM_WRN("not implemented!!");
- _pthread_mutex_unlock(&private_display->lock);
- return TDM_ERROR_NOT_IMPLEMENTED;
- /* LCOV_EXCL_STOP */
+ if (!private_module->use_hal_tdm) {
+ if (!func_hwc->hwc_commit) {
+ /* LCOV_EXCL_START */
+ TDM_WRN("not implemented!!");
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
}
//TODO: I am not sure yet whether we have to check the dpms at hwc_commit.
if (tdm_debug_module & TDM_DEBUG_COMMIT)
TDM_INFO("hwc(%d) commit", private_hwc->index);
+ if (private_module == private_display->virtual_module) {
+ if (!private_output->private_voutput) {
+ TDM_ERR("virtual module but don't have voutput");
+ ret = TDM_ERROR_BAD_MODULE;
+ goto done;
+ }
+ }
+
if (!private_hwc->regist_commit_cb) {
private_hwc->regist_commit_cb = 1;
- ret = func_hwc->hwc_set_commit_handler(private_hwc->hwc_backend, _tdm_hwc_cb_commit);
+ if (private_module->use_hal_tdm)
+ ret = (tdm_error)hal_tdm_hwc_set_commit_handler((hal_tdm_hwc *)private_hwc->hwc_backend, _tdm_hwc_cb_commit_hal_tdm);
+ else
+ ret = func_hwc->hwc_set_commit_handler(private_hwc->hwc_backend, _tdm_hwc_cb_commit);
/* LCOV_EXCL_START */
if (ret != TDM_ERROR_NONE) {
private_hwc->regist_commit_cb = 0;
TDM_ERR("hwc(%d) fail to set hwc_set_commit_handler", private_hwc->index);
- _pthread_mutex_unlock(&private_display->lock);
- return ret;
+ goto done;
/* LCOV_EXCL_STOP */
}
}
if (!hwc_commit_handler) {
/* LCOV_EXCL_START */
TDM_ERR("failed: alloc memory");
- _pthread_mutex_unlock(&private_display->lock);
- return TDM_ERROR_OUT_OF_MEMORY;
+ ret = TDM_ERROR_OUT_OF_MEMORY;
+ goto done;
/* LCOV_EXCL_STOP */
}
if (ret != TDM_ERROR_NONE) {
TDM_ERR("tdm_thread_cb_add failed");
free(hwc_commit_handler);
- _pthread_mutex_unlock(&private_display->lock);
- return ret;
+ goto done;
}
LIST_ADDTAIL(&hwc_commit_handler->link, &private_hwc->hwc_commit_handler_list);
hwc_commit_handler->user_data = user_data;
hwc_commit_handler->owner_tid = syscall(SYS_gettid);
- ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler);
- TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+ if (private_module == private_display->virtual_module) {
+ private_voutput = private_output->private_voutput;
- if (tdm_debug_module & TDM_DEBUG_COMMIT)
- TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)",
- private_hwc->index, hwc_commit_handler, func, user_data);
+ 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_hwc->display_target_buffer;
+ }
+ }
+
+ if (hwc_use_vblank) {
+ /* LCOV_EXCL_START */
+ hwc_commit_handler->use_vblank = 1;
+
+ if (private_module->use_hal_tdm)
+ ret = (tdm_error)hal_tdm_hwc_commit((hal_tdm_hwc *)private_hwc->hwc_backend, sync, NULL);
+ else
+ ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, NULL);
+ TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+
+ ret = _tdm_hwc_vblank(private_hwc, hwc_commit_handler);
+ if (ret == TDM_ERROR_NONE) {
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("hwc(%d) backend commit: wait vblank handle(%p) func(%p) user_data(%p)",
+ private_hwc->index, hwc_commit_handler, func, user_data);
+ } else
+ goto commit_failed;
+ /* LCOV_EXCL_STOP */
+ } else {
+ if (private_module->use_hal_tdm)
+ ret = (tdm_error)hal_tdm_hwc_commit((hal_tdm_hwc *)private_hwc->hwc_backend, sync, hwc_commit_handler);
+ else
+ ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler);
+ TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+
+ if (tdm_debug_module & TDM_DEBUG_COMMIT)
+ TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)",
+ private_hwc->index, hwc_commit_handler, func, user_data);
+ }
+
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_ASYNC_BEGIN((intptr_t)hwc_commit_handler, "[HWC_COMMIT~HANDLER] %d",
+ private_hwc->private_output->pipe);
+
+done:
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
_pthread_mutex_unlock(&private_display->lock);
commit_failed:
/* LCOV_EXCL_START */
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
+
if (hwc_commit_handler) {
tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler,
_tdm_hwc_thread_cb_commit, NULL);
return ret;
/* LCOV_EXCL_STOP */
-}
\ No newline at end of file
+}
+
+EXTERN tdm_error
+tdm_hwc_get_commit_fence(tdm_hwc *hwc, int *commit_fence)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+
+ HWC_FUNC_ENTRY();
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_BEGIN(__FUNCTION__);
+
+ private_module = private_hwc->private_module;
+ func_hwc = &private_module->func_hwc;
+
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_commit_fence((hal_tdm_hwc *)private_hwc->hwc_backend, commit_fence);
+ } else {
+ if (!func_hwc->hwc_get_commit_fence) {
+ /* LCOV_EXCL_START */
+ TDM_WRN("not implemented!!");
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_get_commit_fence(private_hwc->hwc_backend, commit_fence);
+ }
+
+done:
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+EXTERN tdm_error
+tdm_hwc_get_release_fences(tdm_hwc *hwc, uint32_t *num_elements,
+ tdm_hwc_window **hwc_windows, int *fences)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+ tdm_private_hwc_window *private_hwc_window = NULL;
+ int i;
+
+ HWC_FUNC_ENTRY();
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_BEGIN(__FUNCTION__);
+
+ private_module = private_hwc->private_module;
+ func_hwc = &private_module->func_hwc;
+
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_release_fences((hal_tdm_hwc *)private_hwc->hwc_backend, num_elements,
+ (hal_tdm_hwc_window **)hwc_windows, fences);
+ } else {
+ if (!func_hwc->hwc_get_release_fences) {
+ /* LCOV_EXCL_START */
+ TDM_WRN("not implemented!!");
+ ret = TDM_ERROR_NOT_IMPLEMENTED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_get_release_fences(private_hwc->hwc_backend, num_elements,
+ hwc_windows, fences);
+ }
+ if (hwc_windows == NULL || fences == NULL)
+ goto done;
+
+ for (i = 0; i < *num_elements; i++) {
+ private_hwc_window = _tdm_hwc_find_private_hwc_window(private_hwc, hwc_windows[i]);
+ if (private_hwc_window == NULL) {
+ /* LCOV_EXCL_START */
+ TDM_ERR("failed! This should never happen!");
+ tdm_hwc_window_destroy_internal(private_hwc_window);
+ *num_elements = 0;
+ ret = TDM_ERROR_OPERATION_FAILED;
+ goto done;
+ /* LCOV_EXCL_STOP */
+ }
+
+ hwc_windows[i] = (tdm_hwc_window*)private_hwc_window;
+ }
+
+done:
+ if (tdm_ttrace_module & TDM_TTRACE_HWC)
+ TDM_TRACE_END();
+
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+tdm_error
+tdm_hwc_set_property(tdm_hwc *hwc, uint32_t id, tdm_value value)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+
+ HWC_FUNC_ENTRY();
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ private_module = private_hwc->private_module;
+ func_hwc = &private_module->func_hwc;
+
+ if (private_module->use_hal_tdm) {
+ hal_tdm_value hvalue;
+ memcpy(&hvalue.ptr, &value.ptr, sizeof(hal_tdm_value));
+ ret = (tdm_error)hal_tdm_hwc_set_property((hal_tdm_hwc *)private_hwc->hwc_backend, id, hvalue);
+ } else {
+ if (!func_hwc->hwc_set_property) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_set_property(private_hwc->hwc_backend, id, value);
+ }
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+tdm_error
+tdm_hwc_get_property(tdm_hwc *hwc, uint32_t id, tdm_value *value)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+
+ HWC_FUNC_ENTRY();
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ private_module = private_hwc->private_module;
+ func_hwc = &private_module->func_hwc;
+
+ if (private_module->use_hal_tdm) {
+ hal_tdm_value hvalue;
+ ret = (tdm_error)hal_tdm_hwc_get_property((hal_tdm_hwc *)private_hwc->hwc_backend, id, &hvalue);
+ if (ret == TDM_ERROR_NONE)
+ memcpy(&value->ptr, &hvalue.ptr, sizeof(tdm_value));
+ } else {
+ if (!func_hwc->hwc_get_property) {
+ /* LCOV_EXCL_START */
+ _pthread_mutex_unlock(&private_display->lock);
+ TDM_WRN("not implemented!!");
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ /* LCOV_EXCL_STOP */
+ }
+
+ ret = func_hwc->hwc_get_property(private_hwc->hwc_backend, id, value);
+ }
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}
+
+tdm_error
+tdm_hwc_get_commit_interval(tdm_hwc *hwc, tdm_hwc_commit_interval *refresh)
+{
+ tdm_private_module *private_module;
+ tdm_func_hwc *func_hwc = NULL;
+
+ HWC_FUNC_ENTRY();
+
+ _pthread_mutex_lock(&private_display->lock);
+
+ private_module = private_hwc->private_module;
+ func_hwc = &private_module->func_hwc;
+
+ if (private_module->use_hal_tdm) {
+ ret = (tdm_error)hal_tdm_hwc_get_commit_interval((hal_tdm_hwc *)private_hwc->hwc_backend, (hal_tdm_hwc_commit_interval *)refresh);
+ } else {
+ /* LCOV_EXCL_START */
+ if (!func_hwc->hwc_get_commit_interval) {
+ _pthread_mutex_unlock(&private_display->lock);
+ return TDM_ERROR_NOT_IMPLEMENTED;
+ }
+
+ ret = func_hwc->hwc_get_commit_interval(private_hwc->hwc_backend, refresh);
+ /* LCOV_EXCL_STOP */
+ }
+ _pthread_mutex_unlock(&private_display->lock);
+
+ return ret;
+}