re-arrange the files and the functions. 19/191819/1
authorSooChan Lim <sc1.lim@samsung.com>
Mon, 22 Oct 2018 05:31:08 +0000 (14:31 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 22 Oct 2018 07:16:41 +0000 (16:16 +0900)
add tdm_sprd_hwc.c tdm_sprd_hwc_window.c and
arrange the code.

Change-Id: I55eddca0775058c2d4404dc40d412d9910d6d74f

src/Makefile.am
src/tdm_sprd.h
src/tdm_sprd_display.c
src/tdm_sprd_hwc.c [new file with mode: 0644]
src/tdm_sprd_hwc_window.c [new file with mode: 0644]

index 9d6d6cd..c39df00 100644 (file)
@@ -10,6 +10,8 @@ libtdm_sprd_la_LIBADD = $(TDM_SPRD_LIBS) -ldl -ldrm
 libtdm_sprd_la_SOURCES = \
        tdm_sprd_format.c \
        tdm_sprd_display.c \
+       tdm_sprd_hwc.c \
+       tdm_sprd_hwc_window.c \
        tdm_sprd_pp.c \
        tdm_sprd_capture.c \
        tdm_sprd.c
index fb9766b..f30c429 100644 (file)
 #include <tdm_log.h>
 #include <tdm_list.h>
 #include "sprd_pp_7727.h"
+#include <tdm_helper.h>
+#include <linux/fb.h>
+#include <drm.h>
+#include <video/sprdfb.h>
+
 /* sprd backend functions (display) */
 tdm_error    sprd_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps);
 tdm_error    sprd_display_get_pp_capability(tdm_backend_data *bdata, tdm_caps_pp *caps);
@@ -131,7 +136,14 @@ tdm_backend_data* sprd_output_get_sprd_data(tdm_output *output);
 
 #define RETURN_VOID_IF_FAIL(cond) RETURN_VAL_IF_FAIL(cond, NOP)
 
-typedef struct _tdm_sprd_data {
+typedef struct _tdm_sprd_data tdm_sprd_data;
+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;
+
+struct _tdm_sprd_data {
        drmEventContext evctx;
 
        tdm_display *dpy;
@@ -143,7 +155,139 @@ typedef struct _tdm_sprd_data {
        struct list_head output_list;
        struct list_head buffer_list;
 
-} tdm_sprd_data;
+};
+
+typedef enum {
+       VBLANK_TYPE_WAIT,
+       VBLANK_TYPE_COMMIT,
+} vblank_type_t;
+
+struct _tdm_sprd_vblank_data_s {
+       vblank_type_t type;
+       tdm_sprd_output_data *output_data;
+       int hwc_mode;
+       void *user_data;
+};
+
+typedef struct _tdm_sprd_display_buffer {
+       struct list_head link;
+
+       unsigned int fb_id;
+       tbm_surface_h buffer;
+       int width;
+       unsigned int height;
+       unsigned int format;
+       unsigned int handles[4];
+       unsigned int name[4];
+       unsigned int pitches[4];
+       unsigned int offsets[4];
+       unsigned int size;
+       unsigned int count;
+} tdm_sprd_display_buffer;
+
+typedef struct _tdm_sprd_output_capture_data {
+       tdm_capture * tdm_capture_p;
+       struct list_head link;
+} tdm_sprd_output_capture_data;
+
+struct _tdm_sprd_output_data {
+       struct list_head link;
+
+       /* data which are fixed at initializing */
+       tdm_sprd_data *sprd_data;
+       uint32_t pipe;
+       int count_modes;
+       tdm_output_mode *output_modes;
+       tdm_output_type connector_type;
+       unsigned int connector_type_id;
+       struct list_head layer_list;
+
+       tdm_output_vblank_handler vblank_func;
+       tdm_output_commit_handler commit_func;
+       tdm_output_conn_status status;
+
+       int mode_changed;
+       const tdm_output_mode *current_mode;
+
+       int waiting_vblank_event;
+
+       char *fb_fd_name;
+       int fb_fd;
+
+       struct fb_var_screeninfo mi;
+
+       tdm_output_dpms dpms_value;
+
+       struct list_head capture_list;
+
+       /* hwc data */
+       tdm_sprd_hwc_data *hwc_data;
+};
+
+struct _tdm_sprd_layer_data {
+       struct list_head link;
+
+       /* data which are fixed at initializing */
+       tdm_sprd_data *sprd_data;
+       tdm_sprd_output_data *output_data;
+       tdm_layer_capability capabilities;
+       int zpos;
+
+       //list of sprd formats
+       int format_count;
+       tbm_format *formats;
+
+       /* not fixed data below */
+       tdm_info_layer info;
+       int info_changed;
+
+       tdm_sprd_display_buffer *display_buffer;
+       int display_buffer_changed;
+       /* current hw overlay setting */
+       overlay_info ovi;
+       int enabled_flag;
+
+       int need_unset;
+};
+
+struct _tdm_sprd_hwc_data {
+       tdm_sprd_hwc_window_data *target_hwc_window;
+
+       int need_validate;
+       int need_target_window;
+
+       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_hwc_data *hwc_data;
+
+       /* not fixed data below */
+       tdm_hwc_window_info info;
+       int info_changed;
+
+       tdm_sprd_display_buffer *display_buffer;
+       int display_buffer_changed;
+       int enabled_flag;
+
+       /* client_type stores the initial type given to us by client(compositor) */
+       tdm_hwc_window_composition client_type;
+       /* validated_type stores the type after running Validate */
+       tdm_hwc_window_composition validated_type;
+
+       int constraints;
+       tbm_surface_queue_h tqueue;
+
+       int zpos;
+};
 
 uint32_t     tdm_sprd_format_to_drm_format(tbm_format format);
 tbm_format   tdm_sprd_format_to_tbm_format(uint32_t format);
@@ -152,14 +296,21 @@ tdm_error    tdm_sprd_display_create_output_list(tdm_sprd_data *sprd_data);
 void         tdm_sprd_display_destroy_output_list(tdm_sprd_data *sprd_data);
 void         tdm_sprd_display_destroy_buffer_list(tdm_sprd_data *sprd_data);
 tdm_error    tdm_sprd_display_create_layer_list(tdm_sprd_data *sprd_data);
-
-tdm_error    tdm_sprd_pp_get_capability(tdm_sprd_data *sprd_data, tdm_caps_pp *caps);
-tdm_pp*      tdm_sprd_pp_create(tdm_sprd_data *sprd_data, tdm_error *error);
-void         tdm_sprd_pp_handler(struct drm_sprd_ipp_event *hw_ipp_p);
 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_sprd_display_buffer *tdm_sprd_display_creat_buffer(tdm_sprd_data *sprd_data, tbm_surface_h surface, tdm_error *err);
+tdm_sprd_display_buffer *tdm_sprd_display_find_buffer(tdm_sprd_data *sprd_data, tbm_surface_h buffer);
+
+tdm_error    tdm_sprd_output_do_commit(tdm_sprd_output_data *output_data);
+tdm_error    tdm_sprd_output_get_cur_msc(int fd, int pipe, uint *msc);
+tdm_error    tdm_sprd_output_wait_vblank(int fd, int pipe, uint *target_msc, void *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);
+tdm_error    tdm_sprd_pp_get_capability(tdm_sprd_data *sprd_data, tdm_caps_pp *caps);
+tdm_pp*      tdm_sprd_pp_create(tdm_sprd_data *sprd_data, tdm_error *error);
+void         tdm_sprd_pp_handler(struct drm_sprd_ipp_event *hw_ipp_p);
+
+tdm_error    tdm_sprd_hwc_initailize_target_window(tdm_hwc *hwc_data, int width, int height);
 #endif /* _TDM_SPRD_H_ */
index 055e32e..9e612ec 100644 (file)
@@ -2,15 +2,8 @@
 #include "config.h"
 #endif
 
-#include <tdm_helper.h>
-#include <linux/fb.h>
-#include <drm.h>
-#include <video/sprdfb.h>
-#include <tbm_surface.h>
-#include <tbm_surface_queue.h>
 #include "tdm_sprd.h"
 
-#define MIN_WIDTH   32
 #ifdef HAVE_FB_VBLANK
 /** @TODO fb event struct */
 #else
@@ -27,144 +20,6 @@ typedef struct drm_event hw_event_t;
                (__after)->next->prev = (__item); \
                (__after)->next = (__item);
 
-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;
-
-typedef enum {
-       VBLANK_TYPE_WAIT,
-       VBLANK_TYPE_COMMIT,
-} vblank_type_t;
-
-struct _tdm_sprd_vblank_data_s {
-       vblank_type_t type;
-       tdm_sprd_output_data *output_data;
-       int hwc_mode;
-       void *user_data;
-};
-
-typedef struct _tdm_sprd_display_buffer {
-       struct list_head link;
-
-       unsigned int fb_id;
-       tbm_surface_h buffer;
-       int width;
-       unsigned int height;
-       unsigned int format;
-       unsigned int handles[4];
-       unsigned int name[4];
-       unsigned int pitches[4];
-       unsigned int offsets[4];
-       unsigned int size;
-       unsigned int count;
-} tdm_sprd_display_buffer;
-
-typedef struct _tdm_sprd_output_capture_data {
-       tdm_capture * tdm_capture_p;
-       struct list_head link;
-} tdm_sprd_output_capture_data;
-
-struct _tdm_sprd_output_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_sprd_data *sprd_data;
-       uint32_t pipe;
-       int count_modes;
-       tdm_output_mode *output_modes;
-       tdm_output_type connector_type;
-       unsigned int connector_type_id;
-       struct list_head layer_list;
-
-       tdm_output_vblank_handler vblank_func;
-       tdm_output_commit_handler commit_func;
-       tdm_output_conn_status status;
-
-       int mode_changed;
-       const tdm_output_mode *current_mode;
-
-       int waiting_vblank_event;
-
-       char *fb_fd_name;
-       int fb_fd;
-
-       struct fb_var_screeninfo mi;
-
-       tdm_output_dpms dpms_value;
-
-       struct list_head capture_list;
-
-       /* hwc data */
-       tdm_sprd_hwc_data *hwc_data;
-};
-
-struct _tdm_sprd_layer_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_sprd_data *sprd_data;
-       tdm_sprd_output_data *output_data;
-       tdm_layer_capability capabilities;
-       int zpos;
-
-       //list of sprd formats
-       int format_count;
-       tbm_format *formats;
-
-       /* not fixed data below */
-       tdm_info_layer info;
-       int info_changed;
-
-       tdm_sprd_display_buffer *display_buffer;
-       int display_buffer_changed;
-       /* current hw overlay setting */
-       overlay_info ovi;
-       int enabled_flag;
-
-       int need_unset;
-};
-
-struct _tdm_sprd_hwc_data {
-       tdm_sprd_hwc_window_data *target_hwc_window;
-
-       int need_validate;
-       int need_target_window;
-
-       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_hwc_data *hwc_data;
-
-       /* not fixed data below */
-       tdm_hwc_window_info info;
-       int info_changed;
-
-       tdm_sprd_display_buffer *display_buffer;
-       int display_buffer_changed;
-       int enabled_flag;
-
-       /* client_type stores the initial type given to us by client(compositor) */
-       tdm_hwc_window_composition client_type;
-       /* validated_type stores the type after running Validate */
-       tdm_hwc_window_composition validated_type;
-
-       int constraints;
-       tbm_surface_queue_h tqueue;
-
-       int zpos;
-};
-
 typedef struct _Drm_Event_Context {
        void (*vblank_handler)(int fd, unsigned int sequence, unsigned int tv_sec,
                                                        unsigned int tv_usec, void *user_data);
@@ -183,122 +38,8 @@ tbm_format osd_layer_formats[] = {
        TBM_FORMAT_ARGB8888
 };
 
-tbm_format hwc_window_video_formats[] = {
-       TBM_FORMAT_NV12,
-       TBM_FORMAT_YUV420
-};
-#if 0
-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)
-               return "DEVICE";
-       else if (composition_type == TDM_COMPOSITION_CURSOR)
-               return "CURSOR";
-       else if (composition_type == TDM_COMPOSITION_NONE)
-               return "NONE";
-
-       return "unknown";
-}
-#endif
-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;
-
-       if (!hwc_window_data->tqueue) {
-               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);
-
-               hwc_window_data->tqueue = tqueue;
-       }
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return tqueue;
-}
-
-#if 0
-static tdm_error
-check_hw_restriction(unsigned int output_w, unsigned int buf_w,
-               unsigned int src_x, unsigned int src_w, unsigned int dst_x, unsigned int dst_w,
-               unsigned int *new_src_x, unsigned int *new_src_w,
-               unsigned int *new_dst_x, unsigned int *new_dst_w)
-{
-       int start, end, diff;
-       int virtual_screen;
-
-       *new_src_x = src_x;
-       *new_src_w = src_w;
-       *new_dst_x = dst_x;
-       *new_dst_w = dst_w;
-
-       if (buf_w < MIN_WIDTH || buf_w % 2) {
-               TDM_ERR("buf_w(%d) not 2's multiple or less than %d", buf_w, MIN_WIDTH);
-               return TDM_ERROR_BAD_REQUEST;
-       }
-
-       if (src_x > dst_x || ((dst_x - src_x) + buf_w) > output_w)
-               virtual_screen = 1;
-       else
-               virtual_screen = 0;
-
-       start = (dst_x < 0) ? 0 : dst_x;
-       end = ((dst_x + dst_w) > output_w) ? output_w : (dst_x + dst_w);
-
-       /* check window minimun width */
-       if ((end - start) < MIN_WIDTH) {
-               TDM_ERR("visible_w(%d) less than %d", end - start, MIN_WIDTH);
-               return TDM_ERROR_BAD_REQUEST;
-       }
-
-       if (!virtual_screen) {
-               /* Pagewidth of window (= 8 byte align / bytes-per-pixel ) */
-               if ((end - start) % 2)
-                       end--;
-       } else {
-               /* You should align the sum of PAGEWIDTH_F and OFFSIZE_F double-word (8 byte) boundary. */
-               if (end % 2)
-                       end--;
-       }
-
-       *new_dst_x = start;
-       *new_dst_w = end - start;
-       *new_src_w = *new_dst_w;
-       diff = start - dst_x;
-       *new_src_x += diff;
-
-       RETURN_VAL_IF_FAIL(*new_src_w > 0, TDM_ERROR_BAD_REQUEST);
-       RETURN_VAL_IF_FAIL(*new_dst_w > 0, TDM_ERROR_BAD_REQUEST);
-
-       if (src_x != *new_src_x || src_w != *new_src_w || dst_x != *new_dst_x ||
-                       dst_w != *new_dst_w)
-       TDM_DBG("=> buf_w(%d) src(%d,%d) dst(%d,%d), virt(%d) start(%d) end(%d)",
-                       buf_w, *new_src_x, *new_src_w, *new_dst_x, *new_dst_w, virtual_screen, start,
-                       end);
-
-       return TDM_ERROR_NONE;
-}
-#endif
-
-static tdm_sprd_display_buffer *
-_tdm_sprd_display_find_buffer(tdm_sprd_data *sprd_data, tbm_surface_h buffer)
+tdm_sprd_display_buffer *
+tdm_sprd_display_find_buffer(tdm_sprd_data *sprd_data, tbm_surface_h buffer)
 {
        tdm_sprd_display_buffer *display_buffer = NULL;
 
@@ -395,8 +136,8 @@ out:
        return ret;
 }
 
-static tdm_error
-_tdm_sprd_display_get_cur_msc(int fd, int pipe, uint *msc)
+tdm_error
+tdm_sprd_output_get_cur_msc(int fd, int pipe, uint *msc)
 {
        drmVBlank vbl;
 
@@ -416,8 +157,8 @@ _tdm_sprd_display_get_cur_msc(int fd, int pipe, uint *msc)
        return TDM_ERROR_NONE;
 }
 
-static tdm_error
-_tdm_sprd_display_wait_vblank(int fd, int pipe, uint *target_msc, void *data)
+tdm_error
+tdm_sprd_output_wait_vblank(int fd, int pipe, uint *target_msc, void *data)
 {
        drmVBlank vbl;
 
@@ -532,8 +273,8 @@ _tdm_sprd_tbmformat_to_sprdformat(int tbm_format, overlay_info *ovi)
        return TDM_ERROR_NONE;
 }
 
-static tdm_error
-_tdm_sprd_display_do_commit(tdm_sprd_output_data *output_data)
+tdm_error
+tdm_sprd_output_do_commit(tdm_sprd_output_data *output_data)
 {
        tdm_error res = TDM_ERROR_NONE;
        tdm_sprd_layer_data *layer_data = NULL;
@@ -826,7 +567,7 @@ _tdm_sprd_display_cb_destroy_buffer(tbm_surface_h buffer, void *user_data)
 
        sprd_data = (tdm_sprd_data *) user_data;
 
-       display_buffer = _tdm_sprd_display_find_buffer(sprd_data, buffer);
+       display_buffer = tdm_sprd_display_find_buffer(sprd_data, buffer);
        if (!display_buffer) {
                TDM_ERR("no display_buffer");
                return;
@@ -906,110 +647,8 @@ _tdm_sprd_display_create_output_LCD(tdm_sprd_data *sprd_data)
        return output_data;
 }
 
-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;
-}
-
-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) {
-               if (layer_data->display_buffer)
-                       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 int
-_get_number_of_visible_windows(tdm_sprd_hwc_data *hwc_data)
-{
-       int number = 0;
-       tdm_sprd_hwc_window_data *window = NULL;
-
-       RETURN_VAL_IF_FAIL(hwc_data, 0);
-
-       LIST_FOR_EACH_ENTRY(window, &hwc_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;
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       tdm_sprd_hwc_data *hwc_data = NULL;
-       int osd_use = 0, img_use = 0;
-
-       hwc_data = output_data->hwc_data;
-       RETURN_VAL_IF_FAIL(hwc_data, 0);
-       RETURN_VAL_IF_FAIL(hwc_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
-
-       if (!_get_number_of_visible_windows(hwc_data))
-               hwc_data->need_target_window = 1;
-
-       /* set target hwc window */
-       if (hwc_data->need_target_window) {
-               layer = _sprd_output_get_layer(output_data, 1);
-               _sprd_layer_attach_window(layer, hwc_data->target_hwc_window);
-               osd_use = 1;
-       }
-
-       /* set hwc windows */
-       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_DEVICE) {
-                       layer = _sprd_output_get_layer(output_data, 1);
-                       osd_use = 1;
-               } else if (hwc_window_data->client_type == TDM_COMPOSITION_VIDEO) {
-                       layer = _sprd_output_get_layer(output_data, 0);
-                       img_use = 1;
-               } else {
-                       continue;
-               }
-
-               _sprd_layer_attach_window(layer, hwc_window_data);
-       }
-
-       /* disable unused layer */
-       if (!osd_use) {
-               layer = _sprd_output_get_layer(output_data, 1);
-               _sprd_layer_attach_window(layer, NULL);
-       }
-
-       if (!img_use) {
-               layer = _sprd_output_get_layer(output_data, 0);
-               _sprd_layer_attach_window(layer, NULL);
-       }
-
-       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)
+tdm_sprd_display_creat_buffer(tdm_sprd_data *sprd_data, tbm_surface_h surface, tdm_error *err)
 {
        int i, count;
        int bw, bh;
@@ -1142,74 +781,6 @@ _sprd_drm_flip_complete_event(int fd, unsigned int sequence, unsigned int tv_sec
        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);
-}
-#endif
-
-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;
-}
-
-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)
 {
@@ -1497,7 +1068,7 @@ sprd_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_d
 
        sprd_data = output_data->sprd_data;
 
-       ret = _tdm_sprd_display_get_cur_msc(sprd_data->drm_fd, output_data->pipe, &target_msc);
+       ret = tdm_sprd_output_get_cur_msc(sprd_data->drm_fd, output_data->pipe, &target_msc);
        if (ret != TDM_ERROR_NONE)
                goto failed_vblank;
 
@@ -1507,7 +1078,7 @@ sprd_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_d
        vblank_data->output_data = output_data;
        vblank_data->user_data = user_data;
 
-       ret = _tdm_sprd_display_wait_vblank(sprd_data->drm_fd, output_data->pipe, &target_msc, vblank_data);
+       ret = tdm_sprd_output_wait_vblank(sprd_data->drm_fd, output_data->pipe, &target_msc, vblank_data);
        if (ret != TDM_ERROR_NONE)
                goto failed_vblank;
 
@@ -1539,7 +1110,7 @@ sprd_output_commit(tdm_output *output, int sync, void *user_data)
 
        sprd_data = output_data->sprd_data;
 
-       _tdm_sprd_display_do_commit(output_data);
+       tdm_sprd_output_do_commit(output_data);
        RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
 
        tdm_sprd_vblank_data *vblank_data = calloc(1, sizeof(tdm_sprd_vblank_data));
@@ -1550,7 +1121,7 @@ sprd_output_commit(tdm_output *output, int sync, void *user_data)
                return TDM_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = _tdm_sprd_display_get_cur_msc(sprd_data->drm_fd, output_data->pipe, &target_msc);
+       ret = tdm_sprd_output_get_cur_msc(sprd_data->drm_fd, output_data->pipe, &target_msc);
        if (ret != TDM_ERROR_NONE) {
                free(vblank_data);
                return ret;
@@ -1562,7 +1133,7 @@ sprd_output_commit(tdm_output *output, int sync, void *user_data)
        vblank_data->output_data = output_data;
        vblank_data->user_data = user_data;
 
-       ret = _tdm_sprd_display_wait_vblank(sprd_data->drm_fd, output_data->pipe, &target_msc, vblank_data);
+       ret = tdm_sprd_output_wait_vblank(sprd_data->drm_fd, output_data->pipe, &target_msc, vblank_data);
        if (ret != TDM_ERROR_NONE) {
                free(vblank_data);
                return ret;
@@ -1630,7 +1201,7 @@ sprd_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
 
        /* create or replace the target_window when the output mode is set */
        if (output_data->sprd_data->hwc_mode) {
-               ret = sprd_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay);
+               ret = tdm_sprd_hwc_initailize_target_window(output_data->hwc_data, mode->hdisplay, mode->vdisplay);
                if (ret != TDM_ERROR_NONE) {
                        TDM_ERR("create target hwc window failed (%d)", ret);
                        return ret;
@@ -1740,9 +1311,9 @@ sprd_layer_set_buffer(tdm_layer *layer, tbm_surface_h surface)
        RETURN_VAL_IF_FAIL(surface, TDM_ERROR_INVALID_PARAMETER);
 
        sprd_data = layer_data->sprd_data;
-       display_buffer = _tdm_sprd_display_find_buffer(sprd_data, surface);
+       display_buffer = tdm_sprd_display_find_buffer(sprd_data, surface);
        if (!display_buffer) {
-               display_buffer = _tdm_sprd_display_creat_buffer(sprd_data, surface, &err);
+               display_buffer = tdm_sprd_display_creat_buffer(sprd_data, surface, &err);
                RETURN_VAL_IF_FAIL(display_buffer != NULL, err);
                LIST_ADDTAIL(&display_buffer->link, &sprd_data->buffer_list);
        }
@@ -1885,429 +1456,6 @@ sprd_layer_get_zpos(tdm_layer *layer, int *zpos)
        return TDM_ERROR_NONE;
 }
 
-tdm_hwc_window *
-sprd_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
-{
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       tdm_sprd_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data, NULL);
-
-       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, &hwc_data->hwc_window_list);
-
-       TDM_DBG("hwc_window(%p) create", hwc_window_data);
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return hwc_window_data;
-}
-
-void
-sprd_hwc_window_destroy(tdm_hwc_window *hwc_window)
-{
-       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);
-}
-
-static int
-_can_set_hwc_window_on_hw_layer(tdm_sprd_hwc_window_data *hwc_window_data)
-{
-       if (!hwc_window_data->display_buffer)
-               return 0;
-
-       if (!_sprd_hwc_window_is_reserved_buffer(hwc_window_data))
-               return 0;
-
-       if (hwc_window_data->info.transform != TDM_TRANSFORM_NORMAL)
-               return 0;
-
-       if (hwc_window_data->info.src_config.pos.w != hwc_window_data->info.dst_pos.w)
-               return 0;
-
-       if (hwc_window_data->info.src_config.pos.h != hwc_window_data->info.dst_pos.h)
-               return 0;
-
-       if (!IS_RGB(hwc_window_data->info.src_config.format))
-               return 0;
-
-       if (hwc_window_data->info.dst_pos.x > hwc_window_data->hwc_data->output_data->current_mode->hdisplay ||
-               hwc_window_data->info.dst_pos.y > hwc_window_data->hwc_data->output_data->current_mode->vdisplay)
-               return 0;
-
-       if (hwc_window_data->info.src_config.pos.w < MIN_WIDTH || hwc_window_data->info.src_config.pos.w % 2)
-               return 0;
-
-       return 1;
-}
-
-tdm_error
-sprd_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
-{
-       tdm_sprd_hwc_data *hwc_data = hwc;
-       tdm_sprd_hwc_window_data **composited_list = NULL;
-       int i = 0, zpos = 0;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       composited_list = (tdm_sprd_hwc_window_data **)composited_wnds;
-
-       hwc_data->need_target_window = 1;
-
-       if (num_wnds == 0) {
-               hwc_data->need_target_window = 1;
-       } else if (num_wnds == 1) {
-               if (composited_list[0]->client_type == TDM_COMPOSITION_DEVICE) {
-                       if (_can_set_hwc_window_on_hw_layer(composited_list[0])) {
-                               hwc_data->need_target_window = 0;
-                               composited_list[0]->validated_type = TDM_COMPOSITION_DEVICE;
-                               composited_list[0]->zpos = zpos;
-                               zpos++;
-                       } else {
-                               composited_list[0]->validated_type = TDM_COMPOSITION_CLIENT;
-                               composited_list[0]->zpos = -1;
-                       }
-                       composited_list[0]->constraints = TDM_CONSTRAINT_BUFFER_QUEUE;
-               } else if (composited_list[0]->client_type == TDM_COMPOSITION_CLIENT) {
-                       composited_list[0]->validated_type = TDM_COMPOSITION_CLIENT;
-                       composited_list[0]->zpos = -1;
-               } else if (composited_list[0]->client_type == TDM_COMPOSITION_VIDEO) {
-                       composited_list[0]->validated_type = TDM_COMPOSITION_VIDEO;
-                       composited_list[0]->zpos = zpos;
-                       zpos++;
-               } else {
-                       composited_list[0]->validated_type = TDM_COMPOSITION_NONE;
-                       composited_list[0]->zpos = -1;
-               }
-       } else {
-               int has_video = 0;
-
-               for (i = 0; i < num_wnds; i++) {
-                       if (composited_list[i]->client_type == TDM_COMPOSITION_VIDEO)
-                               has_video++;
-               }
-
-               for (i = 0 ; i < num_wnds; i++) {
-                   if (num_wnds == 2 && has_video == 1) {
-                               if (composited_list[i]->client_type == TDM_COMPOSITION_DEVICE) {
-                                       if (_can_set_hwc_window_on_hw_layer(composited_list[i])) {
-                                               hwc_data->need_target_window = 0;
-                                               composited_list[i]->validated_type = TDM_COMPOSITION_DEVICE;
-                                               composited_list[i]->zpos = zpos;
-                                               zpos++;
-                                       } else {
-                                               composited_list[0]->validated_type = TDM_COMPOSITION_CLIENT;
-                                               composited_list[0]->zpos = -1;
-                                       }
-                               } else if (composited_list[i]->client_type == TDM_COMPOSITION_CLIENT) {
-                                       composited_list[i]->validated_type = TDM_COMPOSITION_CLIENT;
-                                       composited_list[i]->zpos = -1;
-                               } else if (composited_list[i]->client_type == TDM_COMPOSITION_VIDEO) {
-                                       composited_list[i]->validated_type = TDM_COMPOSITION_VIDEO;
-                                       composited_list[i]->zpos = zpos;
-                                       zpos++;
-                               } else {
-                                       composited_list[i]->validated_type = TDM_COMPOSITION_NONE;
-                                       composited_list[i]->zpos = -1;
-                               }
-                       } else {
-                               if (composited_list[i]->client_type == TDM_COMPOSITION_DEVICE ||
-                                       composited_list[i]->client_type == TDM_COMPOSITION_CLIENT) {
-                                       composited_list[i]->validated_type = TDM_COMPOSITION_CLIENT;
-                                       composited_list[i]->zpos = -1;
-                               } else if (composited_list[i]->client_type == TDM_COMPOSITION_NONE) {
-                                       composited_list[i]->validated_type = TDM_COMPOSITION_NONE;
-                                       composited_list[i]->zpos = -1;
-                               }
-                       }
-               }
-       }
-
-       *num_types = _sprd_output_get_changed_number(hwc_data);
-       if (*num_types == 0)
-               hwc_data->need_validate = 0;
-
-       return TDM_ERROR_NONE;
-}
-
-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_sprd_hwc_data *hwc_data = hwc;
-       int num = 0;
-
-       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(hwc_data);
-               return TDM_ERROR_NONE;
-       }
-
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
-               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
-                       continue;
-
-               if (num >= *num_elements)
-                       break;
-
-               if (hwc_window_data->client_type != hwc_window_data->validated_type) {
-                       composition_types[num] = hwc_window_data->validated_type;
-                       hwc_window[num] = hwc_window_data;
-                       num++;
-               }
-       }
-
-       /* set real num of changed composition types */
-       *num_elements = num;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-sprd_hwc_accept_changes(tdm_hwc *hwc)
-{
-       tdm_sprd_hwc_data *hwc_data = hwc;
-
-       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, &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;
-       }
-
-       hwc_data->need_validate = 0;
-
-       return TDM_ERROR_NONE;
-}
-
-tbm_surface_queue_h
-sprd_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
-{
-       tdm_sprd_hwc_data *hwc_data = hwc;
-       tbm_surface_queue_h tqueue = NULL;
-
-       if (error)
-               *error = TDM_ERROR_INVALID_PARAMETER;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, 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(hwc_data->target_hwc_window, error);
-       RETURN_VAL_IF_FAIL(tqueue, NULL);
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-       return tqueue;
-}
-
-tdm_error
-sprd_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage)
-{
-       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(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(hwc_data->target_hwc_window, buffer);
-       RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
-
-       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_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
-{
-       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_error
-sprd_hwc_get_video_capability(tdm_hwc *hwc, tdm_hwc_video_capability *video_capability)
-{
-       RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       *video_capability = TDM_HWC_VIDEO_CAPABILITY_SCANOUT;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-sprd_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
-{
-       tdm_sprd_hwc_data *hwc_data = hwc;
-
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       // TODO:
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-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_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(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       hwc_window_data->constraints = TDM_CONSTRAINT_NONE;
-
-       if (hwc_window_data->client_type == comp_type)
-               return TDM_ERROR_NONE;
-
-       hwc_window_data->client_type = comp_type;
-
-       hwc_data->need_validate = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
-{
-       tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       //TODO::
-
-       return TDM_ERROR_NONE;
-}
-
-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_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(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;
-       hwc_data->need_validate = 1;
-
-       return TDM_ERROR_NONE;
-}
-
-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;
-
-       tdm_sprd_display_buffer *display_buffer = NULL;
-
-       RETURN_VAL_IF_FAIL(hwc_window_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) {
-               hwc_window_data->display_buffer = NULL;
-               return TDM_ERROR_NONE;
-       }
-
-       display_buffer = _tdm_sprd_display_find_buffer(sprd_data, surface);
-       if (!display_buffer) {
-               display_buffer = _tdm_sprd_display_creat_buffer(sprd_data, surface, &err);
-               RETURN_VAL_IF_FAIL(display_buffer != NULL, err);
-               LIST_ADDTAIL(&display_buffer->link, &sprd_data->buffer_list);
-       }
-
-       if (hwc_window_data->display_buffer == display_buffer)
-               return TDM_ERROR_NONE;
-
-       hwc_window_data->display_buffer = display_buffer;
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-sprd_hwc_initailize_target_window(tdm_hwc *hwc, int width, int height)
-{
-       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_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;
-
-       return TDM_ERROR_NONE;
-}
-
 tdm_hwc *
 sprd_output_get_hwc(tdm_output *output, tdm_error *error)
 {
@@ -2347,140 +1495,3 @@ sprd_output_get_hwc(tdm_output *output, tdm_error *error)
        return hwc_data;
 }
 
-tdm_error
-sprd_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
-{
-       tdm_sprd_output_data *output_data = NULL;
-       tdm_sprd_hwc_data *hwc_data = NULL;
-       tdm_sprd_data *sprd_data = NULL;
-       tdm_error ret = TDM_ERROR_NONE;
-
-       RETURN_VAL_IF_FAIL(hwc, TDM_ERROR_INVALID_PARAMETER);
-
-       hwc_data = (tdm_sprd_hwc_data *)hwc;
-
-       output_data = hwc_data->output_data;
-       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
-
-       sprd_data = output_data->sprd_data;
-
-       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);
-
-       tdm_sprd_vblank_data *vblank_data = calloc(1, sizeof(tdm_sprd_vblank_data));
-       uint target_msc;
-
-       if (!vblank_data) {
-               TDM_ERR("alloc failed");
-               return TDM_ERROR_OUT_OF_MEMORY;
-       }
-
-       ret = _tdm_sprd_display_get_cur_msc(sprd_data->drm_fd, output_data->pipe, &target_msc);
-       if (ret != TDM_ERROR_NONE) {
-               free(vblank_data);
-               return ret;
-       }
-
-       target_msc++;
-
-       vblank_data->type = VBLANK_TYPE_COMMIT;
-       vblank_data->hwc_mode = 1;
-       vblank_data->output_data = output_data;
-       vblank_data->user_data = user_data;
-
-       ret = _tdm_sprd_display_wait_vblank(sprd_data->drm_fd, output_data->pipe, &target_msc, vblank_data);
-       if (ret != TDM_ERROR_NONE) {
-               free(vblank_data);
-               return ret;
-       }
-
-       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_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);
-
-       //TODO:
-
-       return TDM_ERROR_NONE;
-}
-
-tdm_error
-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;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       //TODO:
-
-       return TDM_ERROR_NONE;
-}
-
-tbm_surface_queue_h
-sprd_hwc_window_acquire_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
-{
-       tdm_sprd_hwc_data *hwc_data = NULL;
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-       tdm_sprd_hwc_window_data *target_hwc_window_data = NULL;
-
-       if (error)
-               *error = TDM_ERROR_INVALID_PARAMETER;
-
-       hwc_window_data = (tdm_sprd_hwc_window_data *)hwc_window;
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, NULL);
-
-       hwc_data = hwc_window_data->hwc_data;
-       RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
-
-       target_hwc_window_data = hwc_data->target_hwc_window;
-       RETURN_VAL_IF_FAIL(target_hwc_window_data != NULL, NULL);
-
-       RETURN_VAL_IF_FAIL(target_hwc_window_data->tqueue != NULL, NULL);
-
-       if (error)
-               *error = TDM_ERROR_NONE;
-
-       return target_hwc_window_data->tqueue;
-}
-
-void
-sprd_hwc_window_release_buffer_queue(tdm_hwc_window *hwc_window, tbm_surface_queue_h queue)
-{
-       return;
-}
-
-tdm_error
-sprd_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints)
-{
-       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
-
-       hwc_window_data = (tdm_sprd_hwc_window_data *)hwc_window;
-
-       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(constraints != NULL, TDM_ERROR_INVALID_PARAMETER);
-
-       *constraints = hwc_window_data->constraints;
-
-       return TDM_ERROR_NONE;
-}
diff --git a/src/tdm_sprd_hwc.c b/src/tdm_sprd_hwc.c
new file mode 100644 (file)
index 0000000..b6d2aab
--- /dev/null
@@ -0,0 +1,589 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_sprd.h"
+
+#define MIN_WIDTH   32
+
+tbm_format hwc_window_video_formats[] = {
+       TBM_FORMAT_NV12,
+       TBM_FORMAT_YUV420
+};
+
+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;
+}
+
+static int
+_sprd_can_set_hwc_window_on_hw_layer(tdm_sprd_hwc_window_data *hwc_window_data)
+{
+       if (!hwc_window_data->display_buffer)
+               return 0;
+
+       if (!_sprd_hwc_window_is_reserved_buffer(hwc_window_data))
+               return 0;
+
+       if (hwc_window_data->info.transform != TDM_TRANSFORM_NORMAL)
+               return 0;
+
+       if (hwc_window_data->info.src_config.pos.w != hwc_window_data->info.dst_pos.w)
+               return 0;
+
+       if (hwc_window_data->info.src_config.pos.h != hwc_window_data->info.dst_pos.h)
+               return 0;
+
+       if (!IS_RGB(hwc_window_data->info.src_config.format))
+               return 0;
+
+       if (hwc_window_data->info.dst_pos.x > hwc_window_data->hwc_data->output_data->current_mode->hdisplay ||
+               hwc_window_data->info.dst_pos.y > hwc_window_data->hwc_data->output_data->current_mode->vdisplay)
+               return 0;
+
+       if (hwc_window_data->info.src_config.pos.w < MIN_WIDTH || hwc_window_data->info.src_config.pos.w % 2)
+               return 0;
+
+       return 1;
+}
+
+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;
+
+       if (!hwc_window_data->tqueue) {
+               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);
+
+               hwc_window_data->tqueue = tqueue;
+       }
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return tqueue;
+}
+
+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) {
+               if (layer_data->display_buffer)
+                       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;
+}
+
+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;
+}
+
+static int
+_sprd_get_number_of_visible_windows(tdm_sprd_hwc_data *hwc_data)
+{
+       int number = 0;
+       tdm_sprd_hwc_window_data *window = NULL;
+
+       RETURN_VAL_IF_FAIL(hwc_data, 0);
+
+       LIST_FOR_EACH_ENTRY(window, &hwc_data->hwc_window_list, link) {
+               if (window->client_type == TDM_COMPOSITION_NONE)
+                       continue;
+
+               number++;
+       }
+
+       return number;
+}
+
+static tdm_error
+_sprd_display_prepare_commit(tdm_sprd_output_data *output_data) {
+
+       tdm_sprd_layer_data * layer = NULL;
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+       tdm_sprd_hwc_data *hwc_data = NULL;
+       int osd_use = 0, img_use = 0;
+
+       hwc_data = output_data->hwc_data;
+       RETURN_VAL_IF_FAIL(hwc_data, 0);
+       RETURN_VAL_IF_FAIL(hwc_data->need_validate == 0, TDM_ERROR_OPERATION_FAILED);
+
+       if (!_sprd_get_number_of_visible_windows(hwc_data))
+               hwc_data->need_target_window = 1;
+
+       /* set target hwc window */
+       if (hwc_data->need_target_window) {
+               layer = _sprd_output_get_layer(output_data, 1);
+               _sprd_layer_attach_window(layer, hwc_data->target_hwc_window);
+               osd_use = 1;
+       }
+
+       /* set hwc windows */
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_COMPOSITION_DEVICE) {
+                       layer = _sprd_output_get_layer(output_data, 1);
+                       osd_use = 1;
+               } else if (hwc_window_data->client_type == TDM_COMPOSITION_VIDEO) {
+                       layer = _sprd_output_get_layer(output_data, 0);
+                       img_use = 1;
+               } else {
+                       continue;
+               }
+
+               _sprd_layer_attach_window(layer, hwc_window_data);
+       }
+
+       /* disable unused layer */
+       if (!osd_use) {
+               layer = _sprd_output_get_layer(output_data, 1);
+               _sprd_layer_attach_window(layer, NULL);
+       }
+
+       if (!img_use) {
+               layer = _sprd_output_get_layer(output_data, 0);
+               _sprd_layer_attach_window(layer, NULL);
+       }
+
+       return TDM_ERROR_NONE;
+}
+
+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;
+}
+
+
+tdm_hwc_window *
+sprd_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
+{
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+       tdm_sprd_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data, NULL);
+
+       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, &hwc_data->hwc_window_list);
+
+       TDM_DBG("hwc_window(%p) create", hwc_window_data);
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return hwc_window_data;
+}
+
+tdm_error
+sprd_hwc_get_video_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count)
+{
+       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_error
+sprd_hwc_get_video_capability(tdm_hwc *hwc, tdm_hwc_video_capability *video_capability)
+{
+       RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       *video_capability = TDM_HWC_VIDEO_CAPABILITY_SCANOUT;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count)
+{
+       tdm_sprd_hwc_data *hwc_data = hwc;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       // TODO:
+
+       return TDM_ERROR_NONE;
+}
+
+tbm_surface_queue_h
+sprd_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error)
+{
+       tdm_sprd_hwc_data *hwc_data = hwc;
+       tbm_surface_queue_h tqueue = NULL;
+
+       if (error)
+               *error = TDM_ERROR_INVALID_PARAMETER;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, 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(hwc_data->target_hwc_window, error);
+       RETURN_VAL_IF_FAIL(tqueue, NULL);
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+       return tqueue;
+}
+
+tdm_error
+sprd_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage)
+{
+       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(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(hwc_data->target_hwc_window, buffer);
+       RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
+
+       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_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
+{
+       tdm_sprd_hwc_data *hwc_data = hwc;
+       tdm_sprd_hwc_window_data **composited_list = NULL;
+       int i = 0, zpos = 0;
+
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       composited_list = (tdm_sprd_hwc_window_data **)composited_wnds;
+
+       hwc_data->need_target_window = 1;
+
+       if (num_wnds == 0) {
+               hwc_data->need_target_window = 1;
+       } else if (num_wnds == 1) {
+               if (composited_list[0]->client_type == TDM_COMPOSITION_DEVICE) {
+                       if (_sprd_can_set_hwc_window_on_hw_layer(composited_list[0])) {
+                               hwc_data->need_target_window = 0;
+                               composited_list[0]->validated_type = TDM_COMPOSITION_DEVICE;
+                               composited_list[0]->zpos = zpos;
+                               zpos++;
+                       } else {
+                               composited_list[0]->validated_type = TDM_COMPOSITION_CLIENT;
+                               composited_list[0]->zpos = -1;
+                       }
+                       composited_list[0]->constraints = TDM_CONSTRAINT_BUFFER_QUEUE;
+               } else if (composited_list[0]->client_type == TDM_COMPOSITION_CLIENT) {
+                       composited_list[0]->validated_type = TDM_COMPOSITION_CLIENT;
+                       composited_list[0]->zpos = -1;
+               } else if (composited_list[0]->client_type == TDM_COMPOSITION_VIDEO) {
+                       composited_list[0]->validated_type = TDM_COMPOSITION_VIDEO;
+                       composited_list[0]->zpos = zpos;
+                       zpos++;
+               } else {
+                       composited_list[0]->validated_type = TDM_COMPOSITION_NONE;
+                       composited_list[0]->zpos = -1;
+               }
+       } else {
+               int has_video = 0;
+
+               for (i = 0; i < num_wnds; i++) {
+                       if (composited_list[i]->client_type == TDM_COMPOSITION_VIDEO)
+                               has_video++;
+               }
+
+               for (i = 0 ; i < num_wnds; i++) {
+                   if (num_wnds == 2 && has_video == 1) {
+                               if (composited_list[i]->client_type == TDM_COMPOSITION_DEVICE) {
+                                       if (_sprd_can_set_hwc_window_on_hw_layer(composited_list[i])) {
+                                               hwc_data->need_target_window = 0;
+                                               composited_list[i]->validated_type = TDM_COMPOSITION_DEVICE;
+                                               composited_list[i]->zpos = zpos;
+                                               zpos++;
+                                       } else {
+                                               composited_list[0]->validated_type = TDM_COMPOSITION_CLIENT;
+                                               composited_list[0]->zpos = -1;
+                                       }
+                               } else if (composited_list[i]->client_type == TDM_COMPOSITION_CLIENT) {
+                                       composited_list[i]->validated_type = TDM_COMPOSITION_CLIENT;
+                                       composited_list[i]->zpos = -1;
+                               } else if (composited_list[i]->client_type == TDM_COMPOSITION_VIDEO) {
+                                       composited_list[i]->validated_type = TDM_COMPOSITION_VIDEO;
+                                       composited_list[i]->zpos = zpos;
+                                       zpos++;
+                               } else {
+                                       composited_list[i]->validated_type = TDM_COMPOSITION_NONE;
+                                       composited_list[i]->zpos = -1;
+                               }
+                       } else {
+                               if (composited_list[i]->client_type == TDM_COMPOSITION_DEVICE ||
+                                       composited_list[i]->client_type == TDM_COMPOSITION_CLIENT) {
+                                       composited_list[i]->validated_type = TDM_COMPOSITION_CLIENT;
+                                       composited_list[i]->zpos = -1;
+                               } else if (composited_list[i]->client_type == TDM_COMPOSITION_NONE) {
+                                       composited_list[i]->validated_type = TDM_COMPOSITION_NONE;
+                                       composited_list[i]->zpos = -1;
+                               }
+                       }
+               }
+       }
+
+       *num_types = _sprd_output_get_changed_number(hwc_data);
+       if (*num_types == 0)
+               hwc_data->need_validate = 0;
+
+       return TDM_ERROR_NONE;
+}
+
+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_sprd_hwc_data *hwc_data = hwc;
+       int num = 0;
+
+       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(hwc_data);
+               return TDM_ERROR_NONE;
+       }
+
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if (hwc_window_data->client_type == TDM_COMPOSITION_NONE)
+                       continue;
+
+               if (num >= *num_elements)
+                       break;
+
+               if (hwc_window_data->client_type != hwc_window_data->validated_type) {
+                       composition_types[num] = hwc_window_data->validated_type;
+                       hwc_window[num] = hwc_window_data;
+                       num++;
+               }
+       }
+
+       /* set real num of changed composition types */
+       *num_elements = num;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_accept_changes(tdm_hwc *hwc)
+{
+       tdm_sprd_hwc_data *hwc_data = hwc;
+
+       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, &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;
+       }
+
+       hwc_data->need_validate = 0;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_commit(tdm_hwc *hwc, int sync, void *user_data)
+{
+       tdm_sprd_output_data *output_data = NULL;
+       tdm_sprd_hwc_data *hwc_data = NULL;
+       tdm_sprd_data *sprd_data = NULL;
+       tdm_error ret = TDM_ERROR_NONE;
+
+       RETURN_VAL_IF_FAIL(hwc, TDM_ERROR_INVALID_PARAMETER);
+
+       hwc_data = (tdm_sprd_hwc_data *)hwc;
+
+       output_data = hwc_data->output_data;
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+       sprd_data = output_data->sprd_data;
+
+       ret = _sprd_display_prepare_commit(output_data);
+       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+       tdm_sprd_output_do_commit(output_data);
+       RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+       tdm_sprd_vblank_data *vblank_data = calloc(1, sizeof(tdm_sprd_vblank_data));
+       uint target_msc;
+
+       if (!vblank_data) {
+               TDM_ERR("alloc failed");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = tdm_sprd_output_get_cur_msc(sprd_data->drm_fd, output_data->pipe, &target_msc);
+       if (ret != TDM_ERROR_NONE) {
+               free(vblank_data);
+               return ret;
+       }
+
+       target_msc++;
+
+       vblank_data->type = VBLANK_TYPE_COMMIT;
+       vblank_data->hwc_mode = 1;
+       vblank_data->output_data = output_data;
+       vblank_data->user_data = user_data;
+
+       ret = tdm_sprd_output_wait_vblank(sprd_data->drm_fd, output_data->pipe, &target_msc, vblank_data);
+       if (ret != TDM_ERROR_NONE) {
+               free(vblank_data);
+               return ret;
+       }
+
+       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
+tdm_sprd_hwc_initailize_target_window(tdm_hwc *hwc, int width, int height)
+{
+       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_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;
+
+       return TDM_ERROR_NONE;
+}
diff --git a/src/tdm_sprd_hwc_window.c b/src/tdm_sprd_hwc_window.c
new file mode 100644 (file)
index 0000000..e21384e
--- /dev/null
@@ -0,0 +1,199 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tdm_sprd.h"
+
+#if 0
+static const char *
+_sprd_comp_to_str(tdm_hwc_window_composition composition_type)
+{
+       if (composition_type == TDM_COMPOSITION_CLIENT)
+               return "CLIENT";
+       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";
+}
+#endif
+
+void
+sprd_hwc_window_destroy(tdm_hwc_window *hwc_window)
+{
+       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);
+}
+
+tbm_surface_queue_h
+sprd_hwc_window_acquire_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error)
+{
+       tdm_sprd_hwc_data *hwc_data = NULL;
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+       tdm_sprd_hwc_window_data *target_hwc_window_data = NULL;
+
+       if (error)
+               *error = TDM_ERROR_INVALID_PARAMETER;
+
+       hwc_window_data = (tdm_sprd_hwc_window_data *)hwc_window;
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, NULL);
+
+       hwc_data = hwc_window_data->hwc_data;
+       RETURN_VAL_IF_FAIL(hwc_data != NULL, NULL);
+
+       target_hwc_window_data = hwc_data->target_hwc_window;
+       RETURN_VAL_IF_FAIL(target_hwc_window_data != NULL, NULL);
+
+       RETURN_VAL_IF_FAIL(target_hwc_window_data->tqueue != NULL, NULL);
+
+       if (error)
+               *error = TDM_ERROR_NONE;
+
+       return target_hwc_window_data->tqueue;
+}
+
+void
+sprd_hwc_window_release_buffer_queue(tdm_hwc_window *hwc_window, tbm_surface_queue_h queue)
+{
+       return;
+}
+
+tdm_error
+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_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(hwc_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       hwc_window_data->constraints = TDM_CONSTRAINT_NONE;
+
+       if (hwc_window_data->client_type == comp_type)
+               return TDM_ERROR_NONE;
+
+       hwc_window_data->client_type = comp_type;
+
+       hwc_data->need_validate = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage)
+{
+       tdm_sprd_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       //TODO::
+
+       return TDM_ERROR_NONE;
+}
+
+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_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(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;
+       hwc_data->need_validate = 1;
+
+       return TDM_ERROR_NONE;
+}
+
+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;
+
+       tdm_sprd_display_buffer *display_buffer = NULL;
+
+       RETURN_VAL_IF_FAIL(hwc_window_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) {
+               hwc_window_data->display_buffer = NULL;
+               return TDM_ERROR_NONE;
+       }
+
+       display_buffer = tdm_sprd_display_find_buffer(sprd_data, surface);
+       if (!display_buffer) {
+               display_buffer = tdm_sprd_display_creat_buffer(sprd_data, surface, &err);
+               RETURN_VAL_IF_FAIL(display_buffer != NULL, err);
+               LIST_ADDTAIL(&display_buffer->link, &sprd_data->buffer_list);
+       }
+
+       if (hwc_window_data->display_buffer == display_buffer)
+               return TDM_ERROR_NONE;
+
+       hwc_window_data->display_buffer = display_buffer;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+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);
+
+       //TODO:
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+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;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       //TODO:
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+sprd_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints)
+{
+       tdm_sprd_hwc_window_data *hwc_window_data = NULL;
+
+       hwc_window_data = (tdm_sprd_hwc_window_data *)hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(constraints != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       *constraints = hwc_window_data->constraints;
+
+       return TDM_ERROR_NONE;
+}