hwc: modify the functions with the new hwc api 40/175840/1
authorSooChan Lim <sc1.lim@samsung.com>
Mon, 9 Apr 2018 12:14:35 +0000 (21:14 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Fri, 13 Apr 2018 01:28:18 +0000 (10:28 +0900)
Change-Id: I610bdf1374b22d504146520aca29ce850043b694

src/tdm_sprd.c
src/tdm_sprd.h
src/tdm_sprd_display.c

index 8a9f752..878fda8 100644 (file)
@@ -116,6 +116,7 @@ tdm_sprd_init(tdm_display *dpy, tdm_error *error)
        tdm_func_display sprd_func_display;
        tdm_func_output sprd_func_output;
        tdm_func_layer sprd_func_layer;
+       tdm_func_hwc sprd_func_hwc;
        tdm_func_hwc_window sprd_func_hwc_window;
        tdm_func_pp sprd_func_pp;
        tdm_func_capture sprd_func_capture;
@@ -175,27 +176,30 @@ tdm_sprd_init(tdm_display *dpy, tdm_error *error)
        sprd_func_output.output_get_mode = sprd_output_get_mode;
        sprd_func_output.output_create_capture = sprd_capture_create;
        if (sprd_data->hwc_mode) {
-               sprd_func_output.output_hwc_create_window = sprd_output_hwc_window_create;
-               sprd_func_output.output_hwc_destroy_window = sprd_output_hwc_window_destroy;
-               sprd_func_output.output_hwc_validate = sprd_output_hwc_validate;
-               sprd_func_output.output_hwc_get_changed_composition_types = sprd_output_hwc_get_changed_composition_types;
-               sprd_func_output.output_hwc_accept_changes = sprd_output_hwc_accept_changes;
-               sprd_func_output.output_hwc_get_target_buffer_queue = sprd_output_hwc_get_target_buffer_queue;
-               sprd_func_output.output_hwc_set_client_target_buffer = sprd_output_hwc_set_client_target_buffer;
-               sprd_func_output.output_hwc_get_video_supported_formats = sprd_output_hwc_get_video_supported_formats;
-               sprd_func_output.output_hwc_create_video_window = sprd_output_hwc_create_video_window;
-       }
+               sprd_func_output.output_get_hwc = sprd_output_get_hwc;
+
+               memset(&sprd_func_hwc, 0, sizeof(sprd_func_hwc));
+               sprd_func_hwc.hwc_create_window = sprd_hwc_create_window;
+               sprd_func_hwc.hwc_get_supported_formats = sprd_hwc_get_supported_formats;
+               sprd_func_hwc.hwc_get_available_properties = sprd_hwc_get_available_properties;
+               sprd_func_hwc.hwc_get_client_target_buffer_queue = sprd_hwc_get_client_target_buffer_queue;
+               sprd_func_hwc.hwc_set_client_target_buffer = sprd_hwc_set_client_target_buffer;
+               sprd_func_hwc.hwc_validate = sprd_hwc_validate;
+               sprd_func_hwc.hwc_get_changed_composition_types = sprd_hwc_get_changed_composition_types;
+               sprd_func_hwc.hwc_accept_changes = sprd_hwc_accept_changes;
+               sprd_func_hwc.hwc_commit = sprd_hwc_commit;
+               sprd_func_hwc.hwc_set_commit_handler = sprd_hwc_set_commit_handler;
 
-       if (sprd_data->hwc_mode) {
                memset(&sprd_func_hwc_window, 0, sizeof(sprd_func_hwc_window));
-               sprd_func_hwc_window.hwc_window_get_tbm_buffer_queue = sprd_hwc_window_get_tbm_buffer_queue;
-               sprd_func_hwc_window.hwc_window_set_buffer = sprd_hwc_window_set_buffer;
+               sprd_func_hwc_window.hwc_window_destroy = sprd_hwc_window_destroy;
+               sprd_func_hwc_window.hwc_window_get_buffer_queue = NULL;
                sprd_func_hwc_window.hwc_window_set_composition_type = sprd_hwc_window_set_composition_type;
-               sprd_func_hwc_window.hwc_window_set_info = sprd_hwc_window_set_info;
                sprd_func_hwc_window.hwc_window_set_buffer_damage = sprd_hwc_window_set_buffer_damage;
-               sprd_func_hwc_window.hwc_window_set_flags = sprd_hwc_window_set_flags;
-               sprd_func_hwc_window.hwc_window_unset_flags = sprd_hwc_window_unset_flags;
-               sprd_func_hwc_window.hwc_window_video_get_capability = sprd_hwc_window_video_get_capability;
+               sprd_func_hwc_window.hwc_window_set_info = sprd_hwc_window_set_info;
+               sprd_func_hwc_window.hwc_window_get_info = sprd_hwc_window_get_info;
+               sprd_func_hwc_window.hwc_window_set_buffer = sprd_hwc_window_set_buffer;
+               sprd_func_hwc_window.hwc_window_set_property = sprd_hwc_window_set_property;
+               sprd_func_hwc_window.hwc_window_get_property = sprd_hwc_window_get_property;
        }
 
        memset(&sprd_func_layer, 0, sizeof(sprd_func_layer));
index 7bd3b53..539131a 100644 (file)
@@ -40,19 +40,7 @@ tdm_error    sprd_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value
 tdm_error    sprd_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value);
 tdm_error    sprd_output_set_mode(tdm_output *output, const tdm_output_mode *mode);
 tdm_error    sprd_output_get_mode(tdm_output *output, const tdm_output_mode **mode);
-tdm_hwc_window * sprd_output_hwc_window_create(tdm_output *output, tdm_error *error);
-tdm_error    sprd_output_hwc_window_destroy(tdm_output *output, tdm_hwc_window *hwc_window);
-tdm_error    sprd_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
-                                                                       uint32_t num_wnds, uint32_t *num_types);
-tdm_error    sprd_output_hwc_get_changed_composition_types(tdm_output *output, uint32_t *num_elements,
-                                                                                tdm_hwc_window **hwc_window,
-                                                                                tdm_hwc_window_composition *composition_types);
-tdm_error    sprd_output_hwc_accept_changes(tdm_output *output);
-tbm_surface_queue_h sprd_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error);
-tdm_error    sprd_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h buffer, tdm_hwc_region damage);
-tdm_error    sprd_output_hwc_get_video_supported_formats(tdm_output *output,
-                                                                       const tbm_format **formats, int *count);
-tdm_hwc_window *sprd_output_hwc_create_video_window(tdm_output *output, tdm_error *error);
+tdm_hwc *    sprd_output_get_hwc(tdm_output *output, tdm_error *error);
 
 tdm_error    sprd_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps);
 tdm_error    sprd_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value);
@@ -62,16 +50,26 @@ tdm_error    sprd_layer_get_info(tdm_layer *layer, tdm_info_layer *info);
 tdm_error    sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer);
 tdm_error    sprd_layer_unset_buffer(tdm_layer *layer);
 tdm_error    sprd_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags);
-tdm_error    sprd_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
-                                                                                                 tdm_hwc_window_video_capability *video_capability);
-tbm_surface_queue_h sprd_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error);
-tdm_error    sprd_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
-                                                                                               tdm_hwc_window_composition composition_type);
-tdm_error    sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage);
+
+tdm_hwc_window     *sprd_hwc_create_window(tdm_hwc *hwc, tdm_error *error);
+tdm_error           sprd_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count);
+tdm_error           sprd_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count);
+tbm_surface_queue_h sprd_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error);
+tdm_error           sprd_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage);
+tdm_error           sprd_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types);
+tdm_error           sprd_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_window, tdm_hwc_window_composition *composition_types);
+tdm_error           sprd_hwc_accept_changes(tdm_hwc *hwc);
+tdm_error           sprd_hwc_commit(tdm_hwc *hwc, int sync, void *user_data);
+tdm_error           sprd_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func);
+
+void         sprd_hwc_window_destroy(tdm_hwc_window *hwc_window);
+tdm_error    sprd_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type);
+tdm_error    sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage);
 tdm_error    sprd_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info);
+tdm_error    sprd_hwc_window_get_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info);
 tdm_error    sprd_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface);
-tdm_error    sprd_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags);
-tdm_error    sprd_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags);
+tdm_error    sprd_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value);
+tdm_error    sprd_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value);
 
 void         sprd_pp_destroy(tdm_pp *pp);
 tdm_error    sprd_pp_set_info(tdm_pp *pp, tdm_info_pp *info);
@@ -92,6 +90,7 @@ tdm_error    sprd_output_attach_capture(tdm_output *output, tdm_capture *capture
 void         sprd_output_dettach_capture(tdm_output *output, tdm_capture *capture);
 
 
+
 tdm_backend_data* sprd_output_get_sprd_data(tdm_output *output);
 
 /* sprd module internal macros, structures, functions */
@@ -158,4 +157,6 @@ tdm_error    tdm_sprd_display_init_event_handling(tdm_sprd_data *sprd_data);
 void         tdm_sprd_display_deinit_event_handling(tdm_sprd_data *sprd_data);
 tdm_error    sprd_layer_get_buffer(tdm_layer *layer, tbm_surface_h *surface);
 tdm_error    sprd_layer_get_zpos(tdm_layer *layer, int *zpos);
+
+tdm_error    sprd_hwc_initailize_target_window(tdm_hwc *hwc_data, int width, int height);
 #endif /* _TDM_SPRD_H_ */
index 71c1f6e..31b74ba 100644 (file)
@@ -29,6 +29,7 @@ typedef struct drm_event hw_event_t;
 
 typedef struct _tdm_sprd_output_data tdm_sprd_output_data;
 typedef struct _tdm_sprd_layer_data tdm_sprd_layer_data;
+typedef struct _tdm_sprd_hwc_data tdm_sprd_hwc_data;
 typedef struct _tdm_sprd_hwc_window_data tdm_sprd_hwc_window_data;
 typedef struct _tdm_sprd_vblank_data_s tdm_sprd_vblank_data;
 
@@ -92,14 +93,10 @@ struct _tdm_sprd_output_data {
 
        tdm_output_dpms dpms_value;
 
-       tdm_sprd_hwc_window_data *target_hwc_window;
-       tdm_sprd_hwc_window_data *video_hwc_window;
-
-       int need_validate;
-       int need_target_buffer;
-
        struct list_head capture_list;
-       struct list_head hwc_window_list;
+
+       /* hwc data */
+       tdm_sprd_hwc_data *hwc_data;
 };
 
 struct _tdm_sprd_layer_data {
@@ -128,12 +125,26 @@ struct _tdm_sprd_layer_data {
        int need_unset;
 };
 
+struct _tdm_sprd_hwc_data {
+       tdm_sprd_hwc_window_data *target_hwc_window;
+
+       int need_validate;
+       int need_target_window;
+       int need_set_crtc;
+
+       int target_window_zpos;
+
+       tdm_sprd_output_data *output_data;
+       struct list_head hwc_window_list;
+
+       tdm_hwc_commit_handler commit_func;
+};
+
 struct _tdm_sprd_hwc_window_data {
        struct list_head link;
 
        /* data which are fixed at initializing */
-       tdm_sprd_data *sprd_data;
-       tdm_sprd_output_data *output_data;
+       tdm_sprd_hwc_data *hwc_data;
 
        /* not fixed data below */
        tdm_hwc_window_info info;
@@ -177,8 +188,49 @@ tbm_format hwc_window_video_formats[] = {
        TBM_FORMAT_YUV420
 };
 
-tdm_hwc_window * _sprd_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info, tdm_error *error);
+static const char *
+_comp_to_str(tdm_hwc_window_composition composition_type)
+{
+       if (composition_type == TDM_COMPOSITION_CLIENT)
+               return "CLIENT";
+       else if (composition_type == TDM_COMPOSITION_DEVICE_CANDIDATE)
+               return "DEVICE_CANDIDATE";
+       else if (composition_type == TDM_COMPOSITION_DEVICE)
+               return "DEVICE";
+       else if (composition_type == TDM_COMPOSITION_CURSOR)
+               return "CURSOR";
+       else if (composition_type == TDM_COMPOSITION_NONE)
+               return "NONE";
+
+       return "unknown";
+}
+
+static tbm_surface_queue_h
+_sprd_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+{
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+       tbm_surface_queue_h tqueue = NULL;
+
+       if (error)
+               *error = TDM_ERROR_INVALID_PARAMETER;
+
+       RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
+       hwc_window_data = hwc_window;
+
+       int wight = hwc_window_data->info.src_config.size.h;
+       int hight = hwc_window_data->info.src_config.size.v;
+       tbm_format format = hwc_window_data->info.src_config.format;
 
+       tqueue = tbm_surface_queue_create(3, wight, hight, format, TBM_BO_SCANOUT);
+       if (error)
+               *error = TDM_ERROR_OPERATION_FAILED;
+       RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return tqueue;
+}
 
 #if 0
 static tdm_error
@@ -480,26 +532,6 @@ _tdm_sprd_tbmformat_to_sprdformat(int tbm_format, overlay_info *ovi)
 }
 
 static tdm_error
-_sprd_layer_attach_window(tdm_sprd_layer_data *layer_data, tdm_sprd_hwc_window_data *hwc_window_data)
-{
-       tdm_error ret = TDM_ERROR_NONE;
-
-       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED);
-
-       if (hwc_window_data == NULL || hwc_window_data->display_buffer == NULL) {
-               ret = sprd_layer_unset_buffer(layer_data);
-               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
-       } else {
-               ret = sprd_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info));
-               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
-               RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
-               ret = sprd_layer_set_buffer(layer_data, hwc_window_data->display_buffer->buffer);
-               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
-       }
-       return ret;
-}
-
-static tdm_error
 _tdm_sprd_display_do_commit(tdm_sprd_output_data *output_data)
 {
        tdm_error res = TDM_ERROR_NONE;
@@ -607,6 +639,7 @@ _tdm_sprd_display_cb_pp(int fd, unsigned int prop_id, unsigned int *buf_idx,
        tdm_sprd_pp_handler(prop_id, buf_idx, tv_sec, tv_usec, user_data);
 }
 #endif
+
 #if 0
 static int
 _tdm_sprd_display_events_handle(int fd, Drm_Event_Context *evctx)
@@ -866,145 +899,429 @@ _tdm_sprd_display_create_output_LCD(tdm_sprd_data *sprd_data)
                free(output_data);
                return NULL;
        }
+
        LIST_INITHEAD(&output_data->capture_list);
-       if (sprd_data->hwc_mode)
-               LIST_INITHEAD(&output_data->hwc_window_list);
+
        return output_data;
 }
 
-void
-tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data)
+tdm_sprd_layer_data *
+_sprd_output_get_layer(tdm_sprd_output_data *output_data, int index)
 {
-       tdm_sprd_output_data *o = NULL, *oo = NULL;
-
-       if (LIST_IS_EMPTY(&sprd_data->output_list))
-               return;
+       RETURN_VAL_IF_FAIL(output_data, NULL);
 
-       LIST_FOR_EACH_ENTRY_SAFE(o, oo, &sprd_data->output_list, link) {
-               LIST_DEL(&o->link);
-               if (o->fb_fd > 0)
-                       close(o->fb_fd);
-               if (!LIST_IS_EMPTY(&o->capture_list)) {
-                       tdm_sprd_output_capture_data *l = NULL, *ll = NULL;
-                       LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->capture_list, link) {
-                               sprd_capture_destroy(l->tdm_capture_p);
-                       }
-               }
-               if (!LIST_IS_EMPTY(&o->layer_list)) {
-                       tdm_sprd_layer_data *l = NULL, *ll = NULL;
-                       LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
-                               LIST_DEL(&l->link);
-                               free(l);
-                       }
-               }
-               free(o->output_modes);
-               free(o);
-       }
+       tdm_sprd_layer_data *l = NULL;
+       LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
+               if (l->zpos == index)
+                       return l;
+       return NULL;
 }
 
-tdm_error
-tdm_sprd_display_create_output_list(tdm_sprd_data *sprd_data)
+#if 0
+static tdm_error
+_sprd_layer_attach_window(tdm_sprd_layer_data *layer_data, tdm_sprd_hwc_window_data *hwc_window_data)
 {
-       tdm_sprd_output_data *output_data = NULL;
-
-       RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&sprd_data->output_list), TDM_ERROR_OPERATION_FAILED);
-
-       //have only LCD output
-       output_data = _tdm_sprd_display_create_output_LCD(sprd_data);
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_OPERATION_FAILED);
-       LIST_ADDTAIL(&output_data->link, &sprd_data->output_list);
-       sprd_data->output_count = 1;
+       tdm_error ret = TDM_ERROR_NONE;
 
-       TDM_DBG("output count: %d", sprd_data->output_count);
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_OPERATION_FAILED);
 
-       return TDM_ERROR_NONE;
+       if (hwc_window_data == NULL || hwc_window_data->display_buffer == NULL) {
+               ret = sprd_layer_unset_buffer(layer_data);
+               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+       } else {
+               ret = sprd_layer_set_info((tdm_layer *)layer_data, (tdm_info_layer *)&(hwc_window_data->info));
+               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+               RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
+               ret = sprd_layer_set_buffer(layer_data, hwc_window_data->display_buffer->buffer);
+               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+       }
+       return ret;
 }
 
-void
-tdm_sprd_display_destroy_buffer_list(tdm_sprd_data *sprd_data)
+static int
+_get_number_of_visible_windows(tdm_sprd_output_data *output_data)
 {
-       tdm_sprd_display_buffer *b = NULL, *bb = NULL;
+       int number = 0;
+       tdm_sprd_hwc_window_data *window = NULL;
 
-       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &sprd_data->buffer_list, link) {
-               tdm_buffer_remove_destroy_handler(b->buffer, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
-               _tdm_sprd_display_cb_destroy_buffer(b->buffer, sprd_data);
-       }
-}
+       RETURN_VAL_IF_FAIL(output_data, 0);
 
-tdm_error
-sprd_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
-{
-       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+       LIST_FOR_EACH_ENTRY(window, &output_data->hwc_window_list, link) {
+               if (window->client_type == TDM_COMPOSITION_NONE)
+                       continue;
 
-       caps->max_layer_count = -1; /* not defined */
+               number++;
+       }
 
-       return TDM_ERROR_NONE;
+       return number;
 }
 
-tdm_error
-sprd_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps)
-{
-       return tdm_sprd_pp_get_capability(bdata, caps);
-}
+static tdm_error
+_tdm_sprd_display_prepare_commit(tdm_sprd_output_data *output_data) {
 
-tdm_output **
-sprd_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error)
-{
-       tdm_sprd_data *sprd_data = bdata;
-       tdm_sprd_output_data *output_data = NULL;
-       tdm_output **outputs;
-       tdm_error ret;
-       int i;
+       tdm_sprd_layer_data * layer = NULL;
+       int i = HW_LAYER_NUM-1;
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
 
-       RETURN_VAL_IF_FAIL(sprd_data, NULL);
-       RETURN_VAL_IF_FAIL(count, NULL);
+       RETURN_VAL_IF_FAIL(output_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
 
-       *count = 0;
-       LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
-               (*count)++;
+       if (!_get_number_of_visible_windows(output_data))
+               output_data->need_target_buffer = 1;
 
-       if (*count == 0) {
-               ret = TDM_ERROR_NONE;
-               goto failed_get;
+       /* set target hwc window */
+       if (output_data->need_target_buffer) {
+               layer = _sprd_output_get_layer(output_data, i--);
+               _sprd_layer_attach_window(layer, output_data->target_hwc_window);
        }
 
-       /* will be freed in frontend */
-       outputs = calloc(*count, sizeof(tdm_sprd_output_data *));
-       if (!outputs) {
-               TDM_ERR("failed: alloc memory");
-               *count = 0;
-               ret = TDM_ERROR_OUT_OF_MEMORY;
-               goto failed_get;
+       /* set hwc windows */
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+                       continue;
+               if (hwc_window_data->client_type != TDM_COMPOSITION_DEVICE)
+                       continue;
+               if (i < 0)
+                       return TDM_ERROR_OPERATION_FAILED;
+               layer = _sprd_output_get_layer(output_data, i--);
+               _sprd_layer_attach_window(layer, hwc_window_data);
        }
 
-       i = 0;
-       LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
-               outputs[i++] = output_data;
-
-       if (error)
-               *error = TDM_ERROR_NONE;
+       /* disable unused layer */
+       while (i >= 0) {
+               layer = _sprd_output_get_layer(output_data, i--);
+               _sprd_layer_attach_window(layer, NULL);
+       }
 
-       return outputs;
-failed_get:
-       if (error)
-               *error = ret;
-       return NULL;
+       return TDM_ERROR_NONE;
 }
+#endif
 
-tdm_error
-sprd_display_get_fd(tdm_backend_data *bdata, int *fd)
+tdm_sprd_display_buffer *
+_tdm_sprd_display_creat_buffer(tdm_sprd_data *sprd_data, tbm_surface_h surface, tdm_error * err)
 {
-       tdm_sprd_data *sprd_data = bdata;
-
-       RETURN_VAL_IF_FAIL(sprd_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
-
-       *fd = sprd_data->drm_fd;
+       int i, count;
+       int bw, bh;
+       tdm_sprd_display_buffer * display_buffer = NULL;
+       tdm_error res = TDM_ERROR_NONE;
 
-       return TDM_ERROR_NONE;
-}
+       RETURN_VAL_IF_FAIL(sprd_data, NULL);
+       RETURN_VAL_IF_FAIL(surface, NULL);
 
-tdm_error
+       display_buffer = calloc(1, sizeof(tdm_sprd_display_buffer));
+       if (!display_buffer) {
+               if (err)
+                       *err = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       display_buffer->buffer = surface;
+
+       res = tdm_buffer_add_destroy_handler(surface, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
+       if (res != TDM_ERROR_NONE) {
+               if (err)
+                       *err = res;
+               TDM_ERR("add destroy handler fail");
+               free(display_buffer);
+               return NULL;
+       }
+
+       tdm_helper_get_buffer_full_size(surface, &bw, &bh);
+
+       display_buffer->width = bw;
+       display_buffer->height = bh;
+       display_buffer->format = tbm_surface_get_format(surface);
+       display_buffer->count = tbm_surface_internal_get_num_bos(surface);
+       count = tbm_surface_internal_get_num_planes(display_buffer->format);
+       TDM_DBG("create buffer: %dx%d %c%c%c%c bo_num:%d plane_num:%d",
+                       display_buffer->width, display_buffer->height, FOURCC_STR(display_buffer->format),
+                       display_buffer->count, count);
+
+       for (i = 0; i < display_buffer->count; i++) {
+               tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
+               display_buffer->handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
+               display_buffer->name[i] = tbm_bo_export(bo);
+               TDM_DBG("    create buffer: bo%d(name:%d handle:%d)", i, display_buffer->name[i],
+                               display_buffer->handles[i]);
+       }
+       for (i = 0; i < count; i++) {
+               tbm_surface_internal_get_plane_data(surface, i, &display_buffer->size, &display_buffer->offsets[i],
+                                                                                               &display_buffer->pitches[i]);
+               TDM_DBG("    create buffer: plane%d(size:%d offset:%d pitch:%d)", i, display_buffer->size,
+                               display_buffer->offsets[i], display_buffer->pitches[i]);
+       }
+
+       if (IS_RGB(display_buffer->format))
+               display_buffer->width = display_buffer->pitches[0] >> 2;
+       else
+               display_buffer->width = display_buffer->pitches[0];
+
+       if (err)
+               *err = TDM_ERROR_NONE;
+
+       return display_buffer;
+}
+
+static int
+_sprd_drm_user_handler(struct drm_event *event)
+{
+       RETURN_VAL_IF_FAIL(event, -1);
+
+       TDM_DBG("got event %d\n", event->type);
+
+       if (event->type != DRM_SPRD_IPP_EVENT)
+               return -1;
+       tdm_sprd_pp_handler((struct drm_sprd_ipp_event *) event);
+
+       return 0;
+}
+
+static void
+_sprd_drm_vblank_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+       tdm_sprd_vblank_data *vblank_data = (tdm_sprd_vblank_data *) user_data;
+       tdm_sprd_output_data *output_data;
+       tdm_sprd_layer_data *layer_data = NULL;
+
+       if (!vblank_data) {
+               TDM_ERR("no vblank data");
+               return;
+       }
+
+       output_data = vblank_data->output_data;
+       if (!output_data) {
+               TDM_ERR("no output data");
+               return;
+       }
+       switch (vblank_data->type) {
+       case VBLANK_TYPE_WAIT:
+               if (output_data->vblank_func)
+                       output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
+               break;
+       case VBLANK_TYPE_COMMIT:
+               LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
+                       if (layer_data->need_unset) {
+                               _tdm_sprd_display_layer_disable(layer_data);
+                               layer_data->need_unset = 0;
+                       }
+               }
+
+               if (output_data->commit_func)
+                       output_data->commit_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
+
+               break;
+       default:
+               break;
+       }
+       free(vblank_data);
+}
+
+static void
+_sprd_drm_flip_complete_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+       TDM_DBG("FLIP EVENT");
+}
+
+#if 0
+static int
+_sprd_layer_is_supported_format(tdm_sprd_layer_data *layer_data, tbm_format format)
+{
+       RETURN_VAL_IF_FAIL(layer_data, 0);
+       return IS_RGB(format);
+}
+
+static int
+_sprd_hwc_window_is_reserved_buffer(tdm_sprd_hwc_window_data *hwc_window_data) {
+       tbm_bo bo = NULL;
+       int falgs = 0;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, 0);
+       RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, 0);
+
+       bo = tbm_surface_internal_get_bo(hwc_window_data->display_buffer->buffer, 0);
+       RETURN_VAL_IF_FAIL(bo != NULL, 0);
+
+       falgs = tbm_bo_get_flags(bo);
+
+       return falgs & TBM_BO_SCANOUT;
+}
+#endif
+
+int
+_sprd_output_get_changed_number(tdm_sprd_hwc_data *hwc_data)
+{
+       int num = 0;
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+                       continue;
+
+               if (hwc_window_data->client_type != hwc_window_data->validated_type)
+                       num++;
+       }
+
+       return num;
+}
+
+static tdm_hwc_window *
+_sprd_hwc_create_window(tdm_sprd_hwc_data *hwc_data, tdm_hwc_window_info *info, tdm_error *error)
+{
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       hwc_window_data = calloc(1, sizeof(tdm_sprd_hwc_window_data));
+       if (!hwc_window_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+
+       hwc_window_data->hwc_data = hwc_data;
+
+       if (info)
+               memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
+
+       LIST_INITHEAD(&hwc_window_data->link);
+
+       return hwc_window_data;
+}
+
+void
+tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data)
+{
+       tdm_sprd_output_data *o = NULL, *oo = NULL;
+
+       if (LIST_IS_EMPTY(&sprd_data->output_list))
+               return;
+
+       LIST_FOR_EACH_ENTRY_SAFE(o, oo, &sprd_data->output_list, link) {
+               LIST_DEL(&o->link);
+               if (o->fb_fd > 0)
+                       close(o->fb_fd);
+               if (!LIST_IS_EMPTY(&o->capture_list)) {
+                       tdm_sprd_output_capture_data *l = NULL, *ll = NULL;
+                       LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->capture_list, link) {
+                               sprd_capture_destroy(l->tdm_capture_p);
+                       }
+               }
+               if (!LIST_IS_EMPTY(&o->layer_list)) {
+                       tdm_sprd_layer_data *l = NULL, *ll = NULL;
+                       LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
+                               LIST_DEL(&l->link);
+                               free(l);
+                       }
+               }
+               free(o->output_modes);
+               free(o);
+       }
+}
+
+tdm_error
+tdm_sprd_display_create_output_list(tdm_sprd_data *sprd_data)
+{
+       tdm_sprd_output_data *output_data = NULL;
+
+       RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&sprd_data->output_list), TDM_ERROR_OPERATION_FAILED);
+
+       //have only LCD output
+       output_data = _tdm_sprd_display_create_output_LCD(sprd_data);
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_OPERATION_FAILED);
+       LIST_ADDTAIL(&output_data->link, &sprd_data->output_list);
+       sprd_data->output_count = 1;
+
+       TDM_DBG("output count: %d", sprd_data->output_count);
+
+       return TDM_ERROR_NONE;
+}
+
+void
+tdm_sprd_display_destroy_buffer_list(tdm_sprd_data *sprd_data)
+{
+       tdm_sprd_display_buffer *b = NULL, *bb = NULL;
+
+       LIST_FOR_EACH_ENTRY_SAFE(b, bb, &sprd_data->buffer_list, link) {
+               tdm_buffer_remove_destroy_handler(b->buffer, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
+               _tdm_sprd_display_cb_destroy_buffer(b->buffer, sprd_data);
+       }
+}
+
+tdm_error
+sprd_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
+{
+       RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
+
+       caps->max_layer_count = -1; /* not defined */
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps)
+{
+       return tdm_sprd_pp_get_capability(bdata, caps);
+}
+
+tdm_output **
+sprd_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error)
+{
+       tdm_sprd_data *sprd_data = bdata;
+       tdm_sprd_output_data *output_data = NULL;
+       tdm_output **outputs;
+       tdm_error ret;
+       int i;
+
+       RETURN_VAL_IF_FAIL(sprd_data, NULL);
+       RETURN_VAL_IF_FAIL(count, NULL);
+
+       *count = 0;
+       LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
+               (*count)++;
+
+       if (*count == 0) {
+               ret = TDM_ERROR_NONE;
+               goto failed_get;
+       }
+
+       /* will be freed in frontend */
+       outputs = calloc(*count, sizeof(tdm_sprd_output_data *));
+       if (!outputs) {
+               TDM_ERR("failed: alloc memory");
+               *count = 0;
+               ret = TDM_ERROR_OUT_OF_MEMORY;
+               goto failed_get;
+       }
+
+       i = 0;
+       LIST_FOR_EACH_ENTRY(output_data, &sprd_data->output_list, link)
+               outputs[i++] = output_data;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return outputs;
+failed_get:
+       if (error)
+               *error = ret;
+       return NULL;
+}
+
+tdm_error
+sprd_display_get_fd(tdm_backend_data *bdata, int *fd)
+{
+       tdm_sprd_data *sprd_data = bdata;
+
+       RETURN_VAL_IF_FAIL(sprd_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
+
+       *fd = sprd_data->drm_fd;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
 sprd_display_handle_events(tdm_backend_data *bdata)
 {
        tdm_sprd_data *sprd_data = bdata;
@@ -1026,19 +1343,6 @@ sprd_display_create_pp(tdm_backend_data *bdata, tdm_error *error)
        return tdm_sprd_pp_create(sprd_data, error);
 }
 
-tdm_sprd_layer_data *
-_sprd_output_get_layer(tdm_sprd_output_data *output_data, int index)
-{
-       RETURN_VAL_IF_FAIL(output_data, NULL);
-
-       tdm_sprd_layer_data *l = NULL;
-       LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link)
-               if (l->zpos == index)
-                       return l;
-       return NULL;
-}
-
-
 tdm_error
 sprd_output_get_capability(tdm_output *output, tdm_caps_output *caps)
 {
@@ -1087,7 +1391,6 @@ sprd_output_get_capability(tdm_output *output, tdm_caps_output *caps)
        if (output_data->sprd_data->hwc_mode)
                caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC;
 
-
        return TDM_ERROR_NONE;
 }
 
@@ -1204,70 +1507,6 @@ sprd_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler fun
        return TDM_ERROR_NONE;
 }
 
-static int
-_get_number_of_visible_windows(tdm_sprd_output_data *output_data)
-{
-       int number = 0;
-       tdm_sprd_hwc_window_data *window = NULL;
-
-       RETURN_VAL_IF_FAIL(output_data, 0);
-
-       LIST_FOR_EACH_ENTRY(window, &output_data->hwc_window_list, link) {
-               if (window->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-
-               number++;
-       }
-
-       return number;
-}
-
-static tdm_error
-_tdm_sprd_display_prepare_commit(tdm_sprd_output_data *output_data) {
-
-       tdm_sprd_layer_data * layer = NULL;
-       int i = HW_LAYER_NUM-1;
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-
-       RETURN_VAL_IF_FAIL(output_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
-
-       if (!_get_number_of_visible_windows(output_data))
-               output_data->need_target_buffer = 1;
-
-       /* set target hwc window */
-       if (output_data->need_target_buffer) {
-               layer = _sprd_output_get_layer(output_data, i--);
-               _sprd_layer_attach_window(layer, output_data->target_hwc_window);
-       }
-
-       if (output_data->video_hwc_window) {
-               layer = _sprd_output_get_layer(output_data, 0);
-               _sprd_layer_attach_window(layer, output_data->video_hwc_window);
-       }
-
-       /* set hwc windows */
-       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-               if (hwc_window_data->client_type != TDM_COMPOSITION_DEVICE)
-                       continue;
-               if (i < 0)
-                       return TDM_ERROR_OPERATION_FAILED;
-               layer = _sprd_output_get_layer(output_data, i--);
-               _sprd_layer_attach_window(layer, hwc_window_data);
-       }
-
-       /* disable unused layer */
-       while (i >= 0) {
-               if (i == 0 && output_data->video_hwc_window)
-                       break;
-               layer = _sprd_output_get_layer(output_data, i--);
-               _sprd_layer_attach_window(layer, NULL);
-       }
-
-       return TDM_ERROR_NONE;
-}
-
 tdm_error
 sprd_output_commit(tdm_output *output, int sync, void *user_data)
 {
@@ -1279,11 +1518,6 @@ sprd_output_commit(tdm_output *output, int sync, void *user_data)
 
        sprd_data = output_data->sprd_data;
 
-       if (sprd_data->hwc_mode) {
-               ret = _tdm_sprd_display_prepare_commit(output_data);
-               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
-       }
-
        _tdm_sprd_display_do_commit(output_data);
        RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
 
@@ -1367,33 +1601,19 @@ tdm_error
 sprd_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
 {
        tdm_sprd_output_data *output_data = output;
+       tdm_error ret = TDM_ERROR_NONE;
 
        RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(output_data->sprd_data, TDM_ERROR_INVALID_PARAMETER);
 
+       /* create or replace the target_window when the output mode is set */
        if (output_data->sprd_data->hwc_mode) {
-
-               tdm_hwc_window_info info = {0};
-               tdm_error ret = TDM_ERROR_NONE;
-               tdm_sprd_hwc_window_data * target_hwc_window;
-
-               info.src_config.pos.h = mode->vdisplay;
-               info.src_config.pos.w = mode->hdisplay;
-               info.src_config.size.h = mode->hdisplay;
-               info.src_config.size.v = mode->vdisplay;
-               info.src_config.format = TBM_FORMAT_ARGB8888;
-
-               target_hwc_window = _sprd_output_hwc_window_create(output_data, &info, &ret);
-               if (ret != TDM_ERROR_NONE)  {
+               ret = sprd_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->hdisplay);
+               if (ret != TDM_ERROR_NONE) {
                        TDM_ERR("create target hwc window failed (%d)", ret);
-                       return TDM_ERROR_OPERATION_FAILED;
+                       return ret;
                }
-
-               if (output_data->target_hwc_window)
-                       sprd_output_hwc_window_destroy(output, output_data->target_hwc_window);
-
-               output_data->target_hwc_window = target_hwc_window;
        }
 
        output_data->current_mode = mode;
@@ -1487,71 +1707,6 @@ sprd_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
        return TDM_ERROR_NONE;
 }
 
-tdm_sprd_display_buffer *
-_tdm_sprd_display_creat_buffer(tdm_sprd_data *sprd_data, tbm_surface_h surface, tdm_error * err)
-{
-       int i, count;
-       int bw, bh;
-       tdm_sprd_display_buffer * display_buffer = NULL;
-       tdm_error res = TDM_ERROR_NONE;
-
-       RETURN_VAL_IF_FAIL(sprd_data, NULL);
-       RETURN_VAL_IF_FAIL(surface, NULL);
-
-       display_buffer = calloc(1, sizeof(tdm_sprd_display_buffer));
-       if (!display_buffer) {
-               if (err)
-                       *err = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       display_buffer->buffer = surface;
-
-       res = tdm_buffer_add_destroy_handler(surface, _tdm_sprd_display_cb_destroy_buffer, sprd_data);
-       if (res != TDM_ERROR_NONE) {
-               if (err)
-                       *err = res;
-               TDM_ERR("add destroy handler fail");
-               free(display_buffer);
-               return NULL;
-       }
-
-       tdm_helper_get_buffer_full_size(surface, &bw, &bh);
-
-       display_buffer->width = bw;
-       display_buffer->height = bh;
-       display_buffer->format = tbm_surface_get_format(surface);
-       display_buffer->count = tbm_surface_internal_get_num_bos(surface);
-       count = tbm_surface_internal_get_num_planes(display_buffer->format);
-       TDM_DBG("create buffer: %dx%d %c%c%c%c bo_num:%d plane_num:%d",
-                       display_buffer->width, display_buffer->height, FOURCC_STR(display_buffer->format),
-                       display_buffer->count, count);
-
-       for (i = 0; i < display_buffer->count; i++) {
-               tbm_bo bo = tbm_surface_internal_get_bo(surface, i);
-               display_buffer->handles[i] = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT).u32;
-               display_buffer->name[i] = tbm_bo_export(bo);
-               TDM_DBG("    create buffer: bo%d(name:%d handle:%d)", i, display_buffer->name[i],
-                               display_buffer->handles[i]);
-       }
-       for (i = 0; i < count; i++) {
-               tbm_surface_internal_get_plane_data(surface, i, &display_buffer->size, &display_buffer->offsets[i],
-                                                                                               &display_buffer->pitches[i]);
-               TDM_DBG("    create buffer: plane%d(size:%d offset:%d pitch:%d)", i, display_buffer->size,
-                               display_buffer->offsets[i], display_buffer->pitches[i]);
-       }
-
-       if (IS_RGB(display_buffer->format))
-               display_buffer->width = display_buffer->pitches[0] >> 2;
-       else
-               display_buffer->width = display_buffer->pitches[0];
-
-       if (err)
-               *err = TDM_ERROR_NONE;
-
-       return display_buffer;
-}
-
 tdm_error
 sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h surface)
 {
@@ -1597,84 +1752,24 @@ sprd_layer_unset_buffer(tdm_layer *layer)
                _tdm_sprd_display_layer_disable(layer);
        layer_data->display_buffer = NULL;
 
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-sprd_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
-{
-       tdm_sprd_layer_data *layer_data = layer;
-
-       switch (layer_data->zpos) {
-       case 0:
-       case 1:
-               *flags = TBM_BO_SCANOUT;
-               break;
-       default:
-               return TDM_ERROR_INVALID_PARAMETER;
-       }
-
-       return TDM_ERROR_NONE;
-}
-
-static int
-_sprd_drm_user_handler(struct drm_event *event)
-{
-       RETURN_VAL_IF_FAIL(event, -1);
-
-       TDM_DBG("got event %d\n", event->type);
-
-       if (event->type != DRM_SPRD_IPP_EVENT)
-               return -1;
-       tdm_sprd_pp_handler((struct drm_sprd_ipp_event *) event);
-
-       return 0;
-}
-
-static void
-_sprd_drm_vblank_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
-       tdm_sprd_vblank_data *vblank_data = (tdm_sprd_vblank_data *) user_data;
-       tdm_sprd_output_data *output_data;
-       tdm_sprd_layer_data *layer_data = NULL;
-
-       if (!vblank_data) {
-               TDM_ERR("no vblank data");
-               return;
-       }
-
-       output_data = vblank_data->output_data;
-       if (!output_data) {
-               TDM_ERR("no output data");
-               return;
-       }
-       switch (vblank_data->type) {
-       case VBLANK_TYPE_WAIT:
-               if (output_data->vblank_func)
-                       output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
-               break;
-       case VBLANK_TYPE_COMMIT:
-               LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
-                       if (layer_data->need_unset) {
-                               _tdm_sprd_display_layer_disable(layer_data);
-                               layer_data->need_unset = 0;
-                       }
-               }
+       return TDM_ERROR_NONE;
+}
 
-               if (output_data->commit_func)
-                       output_data->commit_func(output_data, sequence, tv_sec, tv_usec, vblank_data->user_data);
+tdm_error
+sprd_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags)
+{
+       tdm_sprd_layer_data *layer_data = layer;
 
+       switch (layer_data->zpos) {
+       case 0:
+       case 1:
+               *flags = TBM_BO_SCANOUT;
                break;
        default:
-               break;
+               return TDM_ERROR_INVALID_PARAMETER;
        }
-       free(vblank_data);
-}
 
-static void
-_sprd_drm_flip_complete_event(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
-{
-       TDM_DBG("FLIP EVENT");
+       return TDM_ERROR_NONE;
 }
 
 tdm_error
@@ -1769,106 +1864,18 @@ sprd_layer_get_zpos(tdm_layer *layer, int *zpos)
        return TDM_ERROR_NONE;
 }
 
-#if 0
-static int
-_sprd_layer_is_supported_format(tdm_sprd_layer_data *layer_data, tbm_format format)
-{
-       RETURN_VAL_IF_FAIL(layer_data, 0);
-       return IS_RGB(format);
-}
-
-static int
-_sprd_hwc_window_is_reserved_buffer(tdm_sprd_hwc_window_data *hwc_window_data) {
-       tbm_bo bo = NULL;
-       int falgs = 0;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, 0);
-       RETURN_VAL_IF_FAIL(hwc_window_data->display_buffer != NULL, 0);
-
-       bo = tbm_surface_internal_get_bo(hwc_window_data->display_buffer->buffer, 0);
-       RETURN_VAL_IF_FAIL(bo != NULL, 0);
-
-       falgs = tbm_bo_get_flags(bo);
-
-       return falgs & TBM_BO_SCANOUT;
-}
-#endif
-
-int
-_sprd_output_get_changed_number(tdm_sprd_output_data *output_data)
-{
-       int num = 0;
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-
-               if (hwc_window_data->client_type != hwc_window_data->validated_type)
-                       num++;
-       }
-       return num;
-}
-
-tdm_hwc_window *
-_sprd_output_hwc_window_create(tdm_output *output, tdm_hwc_window_info *info, tdm_error *error)
-{
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       tdm_sprd_output_data *output_data = output;
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       if (!output_data) {
-               TDM_ERR("invalid params");
-               if (error)
-                       *error = TDM_ERROR_INVALID_PARAMETER;
-               return NULL;
-       }
-
-       hwc_window_data = calloc(1, sizeof(tdm_sprd_hwc_window_data));
-       if (!hwc_window_data) {
-               TDM_ERR("alloc failed");
-               if (error)
-                       *error = TDM_ERROR_OUT_OF_MEMORY;
-               return NULL;
-       }
-
-       if ((hwc_window_data->sprd_data = sprd_output_get_sprd_data(output)) == NULL) {
-               TDM_ERR("invalid params");
-               if (error)
-                       *error = TDM_ERROR_INVALID_PARAMETER;
-               goto fail;
-       }
-
-       hwc_window_data->output_data = output;
-
-       if (info)
-               memcpy(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info));
-
-       LIST_INITHEAD(&hwc_window_data->link);
-
-       return hwc_window_data;
-fail:
-       if (hwc_window_data)
-               free(hwc_window_data);
-       return NULL;
-}
-
 tdm_hwc_window *
-sprd_output_hwc_window_create(tdm_output *output, tdm_error *error)
+sprd_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
 {
        tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       tdm_sprd_output_data *output_data = output;
+       tdm_sprd_hwc_data *hwc_data = hwc;
 
-       RETURN_VAL_IF_FAIL(output_data, NULL);
+       RETURN_VAL_IF_FAIL(hwc_data, NULL);
 
-       hwc_window_data = _sprd_output_hwc_window_create(output_data, NULL, error);
+       hwc_window_data = _sprd_hwc_create_window(hwc_data, NULL, error);
        RETURN_VAL_IF_FAIL(hwc_window_data, NULL);
 
-       LIST_ADDTAIL(&hwc_window_data->link, &output_data->hwc_window_list);
+       LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
 
        TDM_DBG("hwc_window(%p) create", hwc_window_data);
        if (error)
@@ -1877,54 +1884,30 @@ sprd_output_hwc_window_create(tdm_output *output, tdm_error *error)
        return hwc_window_data;
 }
 
-tdm_error
-sprd_output_hwc_window_destroy(tdm_output *output, tdm_hwc_window *hwc_window)
+void
+sprd_hwc_window_destroy(tdm_hwc_window *hwc_window)
 {
-       RETURN_VAL_IF_FAIL(output, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(hwc_window, TDM_ERROR_INVALID_PARAMETER);
-
        tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
 
+       if (!hwc_window_data)
+               return;
+
        LIST_DEL(&hwc_window_data->link);
 
        free(hwc_window_data);
-
-       return TDM_ERROR_NONE;
-}
-
-static const char *
-_comp_to_str(tdm_hwc_window_composition composition_type)
-{
-       if (composition_type == TDM_COMPOSITION_CLIENT)
-               return "CLIENT";
-       else if (composition_type == TDM_COMPOSITION_DEVICE_CANDIDATE)
-               return "DEVICE_CANDIDATE";
-       else if (composition_type == TDM_COMPOSITION_DEVICE)
-               return "DEVICE";
-       else if (composition_type == TDM_COMPOSITION_CURSOR)
-               return "CURSOR";
-       else if (composition_type == TDM_COMPOSITION_NONE)
-               return "NONE";
-
-       return "unknown";
 }
 
 tdm_error
-sprd_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
-                                                                       uint32_t num_wnds, uint32_t *num_types)
+sprd_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
 {
-       tdm_sprd_output_data *output_data = output;
-       tdm_sprd_data *sprd_data = NULL;
+       tdm_sprd_hwc_data *hwc_data = hwc;
        tdm_sprd_hwc_window_data *hwc_window_data = NULL;
 
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       sprd_data = output_data->sprd_data;
-       RETURN_VAL_IF_FAIL(sprd_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
        /* decide the validated_types with client_types */
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
                /* set the none to validated_type */
                if (hwc_window_data->client_type == TDM_COMPOSITION_NONE &&
                        hwc_window_data->validated_type != TDM_COMPOSITION_NONE) {
@@ -1932,12 +1915,6 @@ sprd_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
                        continue;
                  }
 
-               /* set the TDM_COMPOSITION_VIDEO type */
-               if (hwc_window_data == output_data->video_hwc_window) {
-                       hwc_window_data->validated_type = TDM_COMPOSITION_DEVICE;
-                       continue;
-               }
-
                /* all hwc_windows make TDM_COMPOSITION_CLIENT */
                if (hwc_window_data->client_type != TDM_COMPOSITION_CLIENT) {
                        hwc_window_data->validated_type = TDM_COMPOSITION_CLIENT;
@@ -1945,7 +1922,7 @@ sprd_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
        }
 
     /* debugging log */
-       LIST_FOR_EACH_ENTRY(hwc_window_data, &output_data->hwc_window_list, link) {
+       LIST_FOR_EACH_ENTRY(hwc_window_data, &hwc_data->hwc_window_list, link) {
                if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
                        continue;
 
@@ -1955,34 +1932,32 @@ sprd_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds,
        }
 
     /* The driver always needs the target_buffer */
-       output_data->need_target_buffer = 1;
+       hwc_data->need_target_window = 1;
 
-       *num_types = _sprd_output_get_changed_number(output_data);
+       *num_types = _sprd_output_get_changed_number(hwc_data);
        if (*num_types == 0)
-               output_data->need_validate = 0;
+               hwc_data->need_validate = 0;
 
        return TDM_ERROR_NONE;
 }
 
 tdm_error
-sprd_output_hwc_get_changed_composition_types(tdm_output *output,
-                                                                                uint32_t *num_elements,
-                                                                                tdm_hwc_window **hwc_window,
-                                                                                tdm_hwc_window_composition *composition_types)
+sprd_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements,
+                               tdm_hwc_window **hwc_window, tdm_hwc_window_composition *composition_types)
 {
-       tdm_sprd_output_data *output_data = output;
+       tdm_sprd_hwc_data *hwc_data = hwc;
        int num = 0;
 
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        if ((hwc_window == NULL) || (composition_types == NULL)) {
-               *num_elements = _sprd_output_get_changed_number(output_data);
+               *num_elements = _sprd_output_get_changed_number(hwc_data);
                return TDM_ERROR_NONE;
        }
 
        tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
                if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
                        continue;
 
@@ -2003,43 +1978,43 @@ sprd_output_hwc_get_changed_composition_types(tdm_output *output,
 }
 
 tdm_error
-sprd_output_hwc_accept_changes(tdm_output *output)
+sprd_hwc_accept_changes(tdm_hwc *hwc)
 {
-       tdm_sprd_output_data *output_data = output;
+       tdm_sprd_hwc_data *hwc_data = hwc;
 
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &output_data->hwc_window_list, link) {
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
                if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
                        continue;
 
                hwc_window_data->client_type = hwc_window_data->validated_type;
        }
 
-       output_data->need_validate = 0;
+       hwc_data->need_validate = 0;
 
        return TDM_ERROR_NONE;
 }
 
 tbm_surface_queue_h
-sprd_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error)
+sprd_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
 {
-       tdm_sprd_output_data *output_data = output;
+       tdm_sprd_hwc_data *hwc_data = hwc;
        tbm_surface_queue_h tqueue = NULL;
 
        if (error)
                *error = TDM_ERROR_INVALID_PARAMETER;
 
-       RETURN_VAL_IF_FAIL(output_data != NULL, NULL);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
 
-       if (output_data->target_hwc_window == NULL) {
+       if (hwc_data->target_hwc_window == NULL) {
                if (error)
                        *error = TDM_ERROR_OPERATION_FAILED;
                return NULL;
        }
 
-       tqueue = sprd_hwc_window_get_tbm_buffer_queue(output_data->target_hwc_window, error);
+       tqueue = _sprd_hwc_window_get_tbm_buffer_queue(hwc_data->target_hwc_window, error);
        RETURN_VAL_IF_FAIL(tqueue, NULL);
 
        if (error)
@@ -2048,100 +2023,50 @@ sprd_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error)
 }
 
 tdm_error
-sprd_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h buffer, tdm_hwc_region damage)
+sprd_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage)
 {
-       tdm_sprd_output_data *output_data = output;
+       tdm_sprd_hwc_data *hwc_data = hwc;
        tdm_error err;
 
        /* TODO: as the sprd-driver currently doesn't support DEVICE to CLIENT transition.
         * we silence skip 'composited_wnds' */
 
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data->target_hwc_window  != NULL, TDM_ERROR_OPERATION_FAILED);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data->target_hwc_window  != NULL, TDM_ERROR_OPERATION_FAILED);
 
-       err = sprd_hwc_window_set_buffer(output_data->target_hwc_window, buffer);
+       err = sprd_hwc_window_set_buffer(hwc_data->target_hwc_window, buffer);
        RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
 
-       err = sprd_hwc_window_set_buffer_damage(output_data->target_hwc_window, damage);
+       err = sprd_hwc_window_set_buffer_damage(hwc_data->target_hwc_window, damage);
        RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
 
        return TDM_ERROR_NONE;
 }
 
 tdm_error
-sprd_output_hwc_get_video_supported_formats(tdm_output *output,
-                                                                                       const tbm_format **formats,
-                                                                                       int *count)
+sprd_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
 {
-       RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
 
+       // TODO: fix these formats.
        *formats = hwc_window_video_formats;
        *count = sizeof(hwc_window_video_formats) / sizeof(tbm_format);
 
        return TDM_ERROR_NONE;
 }
 
-tdm_hwc_window *
-sprd_output_hwc_create_video_window(tdm_output *output, tdm_error *error)
-{
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       tdm_sprd_output_data *output_data = output;
-
-       if (error)
-               *error = TDM_ERROR_INVALID_PARAMETER;
-
-       RETURN_VAL_IF_FAIL(output_data != NULL, NULL);
-
-       if (error)
-               *error = TDM_ERROR_OPERATION_FAILED;
-
-       if (output_data->video_hwc_window)
-               return NULL;
-
-       hwc_window_data = _sprd_output_hwc_window_create(output_data, NULL, error);
-       if (hwc_window_data == NULL)
-               return NULL;
-
-       output_data->video_hwc_window = hwc_window_data;
-
-       TDM_DBG("hwc_window(%p) video create", hwc_window_data);
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return hwc_window_data;
-}
-
-tbm_surface_queue_h
-sprd_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+tdm_error
+sprd_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
 {
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       tdm_sprd_output_data *output_data = NULL;
-       tbm_surface_queue_h tqueue = NULL;
-
-       if (error)
-               *error = TDM_ERROR_INVALID_PARAMETER;
-
-       RETURN_VAL_IF_FAIL(hwc_window != NULL, NULL);
-       hwc_window_data = hwc_window;
-       output_data = hwc_window_data->output_data;
-
-       RETURN_VAL_IF_FAIL(output_data != NULL, NULL);
-
-       int wight = hwc_window_data->info.src_config.size.h;
-       int hight = hwc_window_data->info.src_config.size.v;
-       tbm_format format = hwc_window_data->info.src_config.format;
+       tdm_sprd_hwc_data *hwc_data = hwc;
 
-       tqueue = tbm_surface_queue_create(3, wight, hight, format, TBM_BO_SCANOUT);
-       if (error)
-               *error = TDM_ERROR_OPERATION_FAILED;
-       RETURN_VAL_IF_FAIL(tqueue != NULL, NULL);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       if (error)
-               *error = TDM_ERROR_NONE;
-       return tqueue;
+       // TODO:
 
+       return TDM_ERROR_NONE;
 }
 
 tdm_error
@@ -2149,30 +2074,28 @@ sprd_hwc_window_set_composition_type(tdm_hwc_window *hwc_window,
                                                                        tdm_hwc_window_composition comp_type)
 {
        tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_sprd_output_data *output_data = hwc_window_data->output_data;
+       tdm_sprd_hwc_data *hwc_data = hwc_window_data->hwc_data;
 
        RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        if (hwc_window_data->client_type == comp_type)
                return TDM_ERROR_NONE;
 
        hwc_window_data->client_type = comp_type;
 
-       output_data->need_validate = 1;
+       hwc_data->need_validate = 1;
 
        return TDM_ERROR_NONE;
 
 }
 
 tdm_error
-sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage)
+sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
 {
        tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_sprd_output_data *output_data = hwc_window_data->output_data;
 
        RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        //TODO::
 
@@ -2183,17 +2106,30 @@ tdm_error
 sprd_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
 {
        tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_sprd_output_data *output_data = hwc_window_data->output_data;
+       tdm_sprd_hwc_data *hwc_data = hwc_window_data->hwc_data;
 
        RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
        RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
 
        if (memcmp(&hwc_window_data->info, info, sizeof(tdm_hwc_window_info)) == 0)
                return TDM_ERROR_NONE;
 
        hwc_window_data->info = *info;
-       output_data->need_validate = 1;
+       hwc_data->need_validate = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_window_get_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info)
+{
+       tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
+
+       *info = hwc_window_data->info;
 
        return TDM_ERROR_NONE;
 }
@@ -2202,6 +2138,7 @@ tdm_error
 sprd_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
 {
        tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+       tdm_sprd_hwc_data *hwc_data;
        tdm_sprd_output_data *output_data;
        tdm_sprd_data *sprd_data;
        tdm_error err = TDM_ERROR_OPERATION_FAILED;
@@ -2209,11 +2146,11 @@ sprd_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
        tdm_sprd_display_buffer *display_buffer = NULL;
 
        RETURN_VAL_IF_FAIL(hwc_window_data != NULL, err);
-
-       output_data = hwc_window_data->output_data;
-       sprd_data = hwc_window_data->sprd_data;
-
-       RETURN_VAL_IF_FAIL(output_data != NULL, err);
+       hwc_data = hwc_window_data->hwc_data;
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, err);
+       output_data = hwc_data->output_data;
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, err);
+       sprd_data = output_data->sprd_data;
        RETURN_VAL_IF_FAIL(sprd_data != NULL, err);
 
        if (!surface) {
@@ -2237,43 +2174,124 @@ sprd_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h surface)
 }
 
 tdm_error
-sprd_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
+sprd_hwc_initailize_target_window(tdm_hwc *hwc, int width, int height)
 {
-       tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+       tdm_hwc_window_info info = {0};
+       tdm_error ret = TDM_ERROR_NONE;
+       tdm_sprd_hwc_window_data *target_hwc_window;
+       tdm_sprd_hwc_data *hwc_data = hwc;
 
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+
+       info.dst_pos.x = 0;
+       info.dst_pos.y = 0;
+       info.dst_pos.h = height;
+       info.dst_pos.w = width;
+
+       info.src_config.pos.x = 0;
+       info.src_config.pos.y = 0;
+       info.src_config.pos.h = height;
+       info.src_config.pos.w = width;
+
+       info.src_config.size.h = width;
+       info.src_config.size.v = height;
+       info.src_config.format = TBM_FORMAT_ARGB8888;
+
+       target_hwc_window = _sprd_hwc_create_window(hwc_data, &info, &ret);
+       if (ret != TDM_ERROR_NONE) {
+               TDM_ERR("create target hwc window failed (%d)", ret);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       if (hwc_data->target_hwc_window)
+               sprd_hwc_window_destroy(hwc_data->target_hwc_window);
+
+       hwc_data->target_hwc_window = target_hwc_window;
+       hwc_data->need_set_crtc = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_hwc *
+sprd_output_get_hwc(tdm_output *output, tdm_error *error)
+{
+       tdm_sprd_hwc_data *hwc_data = NULL;
+       tdm_sprd_output_data *output_data = output;
+
+       if (!output_data) {
+               TDM_ERR("invalid params");
+               if (error)
+                       *error = TDM_ERROR_INVALID_PARAMETER;
+               return NULL;
+       }
+
+       if (output_data->hwc_data) {
+               TDM_INFO("hwc_data already exists");
+               if (error)
+                       *error = TDM_ERROR_NONE;
+               return output_data->hwc_data;
+       }
+
+       hwc_data = calloc(1, sizeof(tdm_sprd_hwc_data));
+       if (!hwc_data) {
+               TDM_ERR("alloc failed");
+               if (error)
+                       *error = TDM_ERROR_OUT_OF_MEMORY;
+               return NULL;
+       }
+       hwc_data->output_data = output_data;
+
+       LIST_INITHEAD(&hwc_data->hwc_window_list);
+
+       output_data->hwc_data = hwc_data;
+
+       if (error)
+               *error = TDM_ERROR_NONE;
 
-       hwc_window_data->flags |= flags;
+       return hwc_data;
+}
+
+tdm_error
+sprd_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
+{
+// TODO:
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
+{
+       tdm_sprd_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
+
+       hwc_data->commit_func = func;
 
        return TDM_ERROR_NONE;
 }
 
 tdm_error
-sprd_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags)
+sprd_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value)
 {
        tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
 
        RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       hwc_window_data->flags &= ~flags;
+       //TODO:
 
        return TDM_ERROR_NONE;
 }
 
 tdm_error
-sprd_hwc_window_video_get_capability(tdm_hwc_window *hwc_window,
-                                                                        tdm_hwc_window_video_capability *video_capability)
+sprd_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value)
 {
        tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
-       tdm_sprd_output_data *output_data;
 
-       RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER);
-       output_data = hwc_window_data->output_data;
-       RETURN_VAL_IF_FAIL(output_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(output_data->video_hwc_window == hwc_window_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
 
-       *video_capability = TDM_HWC_WINDOW_VIDEO_CAPABILITY_SCANOUT;
+       //TODO:
 
        return TDM_ERROR_NONE;
-}
+}
\ No newline at end of file