Package version up to 3.1.8
[platform/core/uifw/libtdm.git] / src / tdm_hwc.c
index 9238b29..81fb042 100644 (file)
@@ -129,6 +129,10 @@ _tdm_hwc_thread_cb_commit(tdm_private_display *private_display, void *object,
                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();
@@ -172,9 +176,6 @@ _tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence,
        tdm_thread_cb_hwc_commit hwc_commit;
        tdm_error ret;
 
-       if (hwc_commit_handler && hwc_commit_handler->use_vblank)
-               return;
-
        if (hwc_commit_handler)
                private_hwc = hwc_commit_handler->private_hwc;
        else
@@ -195,6 +196,35 @@ _tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence,
 }
 
 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)
 {
@@ -268,7 +298,6 @@ _tdm_hwc_vblank(tdm_private_hwc *private_hwc, tdm_private_hwc_commit_handler *hw
                if (ret != TDM_ERROR_NONE)
                        goto done;
 
-               hwc_commit_handler->use_vblank = 1;
                private_output->layer_waiting_vblank = 1;
 
                /* tdm_vblank APIs is for server. it should be called in unlock status*/
@@ -277,7 +306,6 @@ _tdm_hwc_vblank(tdm_private_hwc *private_hwc, tdm_private_hwc_commit_handler *hw
                _pthread_mutex_lock(&private_display->lock);
                if (ret != TDM_ERROR_NONE) {
                        if (!TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) {
-                               hwc_commit_handler->use_vblank = 0;
                                private_output->layer_waiting_vblank = 0;
                        }
                }
@@ -286,6 +314,7 @@ _tdm_hwc_vblank(tdm_private_hwc *private_hwc, tdm_private_hwc_commit_handler *hw
 done:
        return ret;
 }
+/* LCOV_EXCL_STOP */
 
 INTERN tdm_error
 tdm_hwc_init(tdm_private_display *private_display)
@@ -341,16 +370,19 @@ tdm_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, in
        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 */
-       }
-
-       ret = func_hwc->hwc_get_video_supported_formats(private_hwc->hwc_backend, formats, count);
+       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;
@@ -372,16 +404,20 @@ tdm_hwc_get_video_available_properties(tdm_hwc *hwc, const tdm_prop **props, int
        private_module = private_output->private_module;
        func_hwc = &private_module->func_hwc;
 
-       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);
+       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;
@@ -400,14 +436,17 @@ tdm_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
        private_module = private_output->private_module;
        func_hwc = &private_module->func_hwc;
 
-       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);
+       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;
@@ -429,16 +468,19 @@ tdm_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *coun
        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;
@@ -458,19 +500,53 @@ tdm_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
        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);
+
+       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 */
+               }
 
-       queue = func_hwc->hwc_get_client_target_buffer_queue(private_hwc->hwc_backend, error);
+               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
@@ -483,6 +559,15 @@ tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_
 
        _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];
@@ -495,16 +580,21 @@ tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_
        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 */
-       }
-
-       ret = func_hwc->hwc_set_client_target_buffer(private_hwc->hwc_backend, target_buffer, damage);
+       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);
@@ -519,6 +609,10 @@ tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_
                }
        }
 
+done:
+       if (tdm_ttrace_module & TDM_TTRACE_HWC)
+               TDM_TRACE_END();
+
        _pthread_mutex_unlock(&private_display->lock);
 
        return ret;
@@ -537,16 +631,19 @@ tdm_hwc_set_client_target_acquire_fence(tdm_hwc *hwc, int acquire_fence)
        private_module = private_hwc->private_module;
        func_hwc = &private_module->func_hwc;
 
-       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);
+       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;
@@ -567,29 +664,36 @@ tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wn
 
        _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 */
        }
 
@@ -598,11 +702,19 @@ tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wn
        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;
@@ -624,29 +736,36 @@ tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements,
 
        _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++) {
@@ -656,14 +775,18 @@ tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements,
                        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;
@@ -679,18 +802,29 @@ tdm_hwc_accept_validation(tdm_hwc *hwc)
 
        _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);
 
@@ -710,15 +844,20 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
 
        _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.
@@ -738,20 +877,22 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
        if (private_module == private_display->virtual_module) {
                if (!private_output->private_voutput) {
                        TDM_ERR("virtual module but don't have voutput");
-                       _pthread_mutex_unlock(&private_display->lock);
-                       return TDM_ERROR_BAD_MODULE;
+                       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 */
                }
        }
@@ -760,8 +901,8 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
        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 */
        }
 
@@ -770,8 +911,7 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
        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);
@@ -789,10 +929,16 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
                }
        }
 
-       ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler);
-       TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
-
        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)
@@ -800,18 +946,36 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
                                        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);
 
        return ret;
 
 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);
@@ -835,18 +999,90 @@ tdm_hwc_get_commit_fence(tdm_hwc *hwc, int *commit_fence)
 
        _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_commit_fence) {
-               /* 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_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);
        }
 
-       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);
 
@@ -866,23 +1102,62 @@ tdm_hwc_set_property(tdm_hwc *hwc, uint32_t id, tdm_value value)
        private_module = private_hwc->private_module;
        func_hwc = &private_module->func_hwc;
 
-       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 */
+       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;
+}
 
-       ret = func_hwc->hwc_set_property(private_hwc->hwc_backend, id, value);
+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_property(tdm_hwc *hwc, uint32_t id, tdm_value *value)
+tdm_hwc_get_commit_interval(tdm_hwc *hwc, tdm_hwc_commit_interval *refresh)
 {
        tdm_private_module *private_module;
        tdm_func_hwc *func_hwc = NULL;
@@ -894,16 +1169,18 @@ tdm_hwc_get_property(tdm_hwc *hwc, uint32_t id, tdm_value *value)
        private_module = private_hwc->private_module;
        func_hwc = &private_module->func_hwc;
 
-       if (!func_hwc->hwc_get_property) {
+       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 */
-               _pthread_mutex_unlock(&private_display->lock);
-               TDM_WRN("not implemented!!");
-               return TDM_ERROR_NOT_IMPLEMENTED;
+               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 */
        }
-
-       ret = func_hwc->hwc_get_property(private_hwc->hwc_backend, id, value);
-
        _pthread_mutex_unlock(&private_display->lock);
 
        return ret;