Fix sign extension error
[platform/core/uifw/libtdm.git] / backends / virtual / tdm_virtual_display.c
index 1f1cc06..23d85aa 100644 (file)
@@ -4,98 +4,12 @@
 
 #include "tdm_virtual.h"
 
-typedef struct _tdm_virtual_output_data tdm_virtual_output_data;
-typedef struct _tdm_virtual_voutput_data tdm_virtual_voutput_data;
-typedef struct _tdm_virtual_layer_data tdm_virtual_layer_data;
-typedef struct _tdm_virtual_event_data tdm_virtual_event_data;
-
-typedef enum {
-       TDM_VIRTUAL_EVENT_TYPE_WAIT,
-       TDM_VIRTUAL_EVENT_TYPE_COMMIT,
-       TDM_VIRTUAL_EVENT_TYPE_VCOMMIT,
-} tdm_virtual_event_type;
-
-struct _tdm_virtual_event_data {
-       struct list_head link;
-
-       tdm_virtual_event_type type;
-       tdm_virtual_output_data *output_data;
-       void *user_data;
-};
-
-struct _tdm_virtual_output_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_virtual_data *virtual_data;
-       tdm_virtual_voutput_data *voutput_data;
-
-       char name[TDM_NAME_LEN]; /* output name */
-       uint32_t pipe;
-       tdm_output_type connector_type;
-       struct list_head layer_list;
-       tdm_virtual_layer_data *primary_layer;
-
-       tdm_output_dpms dpms;
-
-       /* not fixed data below */
-       tdm_output_vblank_handler vblank_func;
-       tdm_output_commit_handler commit_func;
-       void *commit_user_data;
-
-       tdm_output_conn_status status;
-       tdm_output_status_handler status_func;
-       void *status_user_data;
-
-       int mode_changed;
-       const tdm_output_mode *current_mode;
-
-       tdm_event_loop_source *timer;
-       unsigned int timer_waiting;
-       struct list_head timer_event_list;
-};
-
-struct _tdm_virtual_voutput_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_virtual_data *virtual_data;
-       tdm_virtual_output_data *output_data;
-
-       char name[TDM_NAME_LEN]; /* output name */
-
-       tdm_voutput_commit_handler vcommit_func;
-
-       tdm_output_mode *output_modes;
-       int mode_count;
-
-       unsigned int mmwidth;
-       unsigned int mmheight;
-};
-
-
-struct _tdm_virtual_layer_data {
-       struct list_head link;
-
-       /* data which are fixed at initializing */
-       tdm_virtual_data *virtual_data;
-       tdm_virtual_output_data *output_data;
-       tdm_layer_capability capabilities;
-       int zpos;
-
-       /* not fixed data below */
-       tdm_info_layer info;
-       int info_changed;
-
-       tbm_surface_h display_buffer;
-       int display_buffer_changed;
-};
-
 static void
 _tdm_virtual_display_cb_event(tdm_virtual_output_data *output_data, tdm_virtual_event_data *event_data,
                                                        unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec)
 {
        tdm_virtual_voutput_data *voutput_data = NULL;
+       tdm_virtual_hwc_data *hwc_data;
 
        switch (event_data->type) {
        case TDM_VIRTUAL_EVENT_TYPE_WAIT:
@@ -103,8 +17,20 @@ _tdm_virtual_display_cb_event(tdm_virtual_output_data *output_data, tdm_virtual_
                        output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data);
                break;
        case TDM_VIRTUAL_EVENT_TYPE_COMMIT:
-               if (output_data->commit_func)
-                       output_data->commit_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data);
+               if (output_data->hwc_enable) {
+                       hwc_data = output_data->hwc_data;
+                       if (!hwc_data) {
+                               TDM_ERR("no hwc_data");
+                               break;
+                       }
+
+                       if (hwc_data->commit_func)
+                               hwc_data->commit_func(hwc_data, sequence,
+                                                                                tv_sec, tv_usec,
+                                                                                event_data->user_data);
+               } else
+                       if (output_data->commit_func)
+                               output_data->commit_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data);
                break;
        case TDM_VIRTUAL_EVENT_TYPE_VCOMMIT:
                voutput_data = output_data->voutput_data;
@@ -114,12 +40,12 @@ _tdm_virtual_display_cb_event(tdm_virtual_output_data *output_data, tdm_virtual_
        }
 }
 
-static void _tdm_virtual_get_current_time(unsigned int *tv_sec, unsigned int *tv_usec)
+static void _tdm_virtual_get_current_time(long *tv_sec, long *tv_usec)
 {
        struct timespec tp;
 
        if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
-               *tv_sec = tp.tv_sec;
+               *tv_sec = (long)tp.tv_sec;
                *tv_usec = tp.tv_nsec / 1000;
        } else {
                *tv_sec = *tv_usec = 0;
@@ -131,7 +57,7 @@ _tdm_virtual_display_cb_timeout(void *user_data)
 {
        tdm_virtual_output_data *output_data = user_data;
        tdm_virtual_event_data *e = NULL, *ee = NULL;
-       unsigned int tv_sec, tv_usec;
+       long tv_sec, tv_usec;
        static unsigned int sequence = 0;
 
        sequence++;
@@ -140,7 +66,7 @@ _tdm_virtual_display_cb_timeout(void *user_data)
 
        LIST_FOR_EACH_ENTRY_SAFE(e, ee, &output_data->timer_event_list, link) {
                LIST_DEL(&e->link);
-               _tdm_virtual_display_cb_event(output_data, e, sequence, tv_sec, tv_usec);
+               _tdm_virtual_display_cb_event(output_data, e, sequence, (unsigned int)tv_sec, (unsigned int)tv_usec);
                free(e);
        }
 
@@ -343,6 +269,9 @@ virtual_output_get_capability(tdm_output *output, tdm_caps_output *caps)
 
        caps->prop_count = 0;
 
+       if (output_data->virtual_data->hwc_mode)
+               caps->capabilities |= TDM_OUTPUT_CAPABILITY_HWC;
+
        return TDM_ERROR_NONE;
 failed_get:
        memset(caps, 0, sizeof(tdm_caps_output));
@@ -361,6 +290,13 @@ virtual_output_get_layers(tdm_output *output,  int *count, tdm_error *error)
        RETURN_VAL_IF_FAIL(output_data, NULL);
        RETURN_VAL_IF_FAIL(count, NULL);
 
+       if (output_data->virtual_data->hwc_mode) {
+               TDM_INFO("layers aren't supported in HWC mode");
+               *count = 0;
+               ret = TDM_ERROR_NONE;
+               goto failed_get;
+       }
+
        *count = 0;
        LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
                (*count)++;
@@ -457,8 +393,28 @@ virtual_output_commit(tdm_output *output, int sync, void *user_data)
                                                                         output_data->status_user_data);
        }
 
+       layer_data = output_data->primary_layer;
+
+       if (layer_data->display_buffer == NULL && layer_data->display_buffer_changed == 1) {
+               event_data = calloc(1, sizeof(tdm_virtual_event_data));
+               if (!event_data) {
+                       TDM_ERR("alloc failed");
+                       return TDM_ERROR_OUT_OF_MEMORY;
+               }
+
+               event_data->type = TDM_VIRTUAL_EVENT_TYPE_COMMIT;
+               event_data->output_data = output_data;
+               event_data->user_data = user_data;
+
+               ret = _tdm_virtual_display_wait_vblank(output_data, 3, event_data);
+               if (ret != TDM_ERROR_NONE) {
+                       free(event_data);
+                       return ret;
+               }
+               goto done;
+       }
+
        if (voutput_data->vcommit_func) {
-               layer_data = output_data->primary_layer;
                if (layer_data->display_buffer_changed) {
                        output_data->commit_user_data = user_data;
                        event_data = calloc(1, sizeof(tdm_virtual_event_data));
@@ -495,6 +451,9 @@ virtual_output_commit(tdm_output *output, int sync, void *user_data)
                }
        }
 
+done:
+       layer_data->display_buffer_changed = 0;
+
        return TDM_ERROR_NONE;
 }
 
@@ -543,10 +502,20 @@ tdm_error
 virtual_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
 {
        tdm_virtual_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);
 
+       /* create or replace the target_window when the output mode is set */
+       if (output_data->virtual_data->hwc_mode) {
+               ret = virtual_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;
+               }
+       }
+
        output_data->current_mode = mode;
        output_data->mode_changed = 1;
 
@@ -581,8 +550,47 @@ virtual_output_set_status_handler(tdm_output *output,
        return TDM_ERROR_NONE;
 }
 
+tdm_hwc *
+virtual_output_get_hwc(tdm_output *output, tdm_error *error)
+{
+       tdm_virtual_hwc_data *hwc_data = NULL;
+       tdm_virtual_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_virtual_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;
+
+       return hwc_data;
+}
+
 tdm_error
-virtual_output_set_available_mode(tdm_voutput *voutput, const tdm_output_mode *modes, int count)
+virtual_voutput_set_available_mode(tdm_voutput *voutput, const tdm_output_mode *modes, int count)
 {
        tdm_virtual_voutput_data *voutput_data = voutput;
        tdm_virtual_output_data *output_data = NULL;
@@ -610,7 +618,7 @@ virtual_output_set_available_mode(tdm_voutput *voutput, const tdm_output_mode *m
 }
 
 tdm_error
-virtual_output_set_physical_size(tdm_voutput *voutput, unsigned int mmwidth, unsigned int mmheight)
+virtual_voutput_set_physical_size(tdm_voutput *voutput, unsigned int mmwidth, unsigned int mmheight)
 {
        tdm_virtual_voutput_data *voutput_data = voutput;
 
@@ -625,7 +633,7 @@ virtual_output_set_physical_size(tdm_voutput *voutput, unsigned int mmwidth, uns
 }
 
 tdm_error
-virtual_output_connect(tdm_voutput *voutput)
+virtual_voutput_connect(tdm_voutput *voutput)
 {
        tdm_virtual_voutput_data *voutput_data = voutput;
        tdm_virtual_output_data *output_data = NULL;
@@ -648,7 +656,7 @@ virtual_output_connect(tdm_voutput *voutput)
 }
 
 tdm_error
-virtual_output_disconnect(tdm_voutput *voutput)
+virtual_voutput_disconnect(tdm_voutput *voutput)
 {
 
        tdm_virtual_voutput_data *voutput_data = voutput;
@@ -755,7 +763,7 @@ virtual_layer_unset_buffer(tdm_layer *layer)
 }
 
 tdm_voutput *
-virtual_output_create(tdm_backend_data *bdata, const char *name, tdm_error *error)
+virtual_display_voutput_create(tdm_backend_data *bdata, const char *name, tdm_error *error)
 {
        tdm_virtual_data *virtual_data = bdata;
        tdm_virtual_voutput_data *voutput_data = NULL;
@@ -802,6 +810,8 @@ virtual_output_create(tdm_backend_data *bdata, const char *name, tdm_error *erro
        voutput_data->mmwidth = 10;
        voutput_data->mmheight = 10;
 
+       voutput_data->target_buffer_queue_flag = TBM_BO_SCANOUT;
+
        voutput_data->virtual_data = virtual_data;
 
        output_data = calloc(1, sizeof(tdm_virtual_output_data));
@@ -852,6 +862,9 @@ virtual_output_create(tdm_backend_data *bdata, const char *name, tdm_error *erro
 
        TDM_DBG("virtual output create(%s)(%p)(%p)", output_data->name, voutput_data, output_data);
 
+       if (output_data->virtual_data->hwc_mode)
+               output_data->hwc_enable = 1;
+
        return voutput_data;
 
 create_fail:
@@ -865,10 +878,10 @@ create_fail:
 }
 
 tdm_error
-virtual_output_destroy(tdm_voutput *voutput)
+virtual_voutput_destroy(tdm_voutput *voutput)
 {
        tdm_virtual_data *virtual_data = NULL;
-       tdm_virtual_voutput_data *vo, *voutput_data = voutput;
+       tdm_virtual_voutput_data *vo = NULL, *voutput_data = voutput;
        int find = 0;
 
        RETURN_VAL_IF_FAIL(voutput_data, TDM_ERROR_INVALID_PARAMETER);
@@ -920,7 +933,7 @@ virtual_output_destroy(tdm_voutput *voutput)
 }
 
 tdm_output *
-virtual_output_get_output(tdm_voutput *voutput, tdm_error *error)
+virtual_voutput_get_output(tdm_voutput *voutput, tdm_error *error)
 {
        tdm_virtual_voutput_data *voutput_data = voutput;
 
@@ -935,12 +948,11 @@ virtual_output_get_output(tdm_voutput *voutput, tdm_error *error)
 }
 
 tdm_error
-virtual_output_set_commit_func(tdm_voutput *voutput,  tdm_voutput_commit_handler commit_func)
+virtual_voutput_set_commit_func(tdm_voutput *voutput,  tdm_voutput_commit_handler commit_func)
 {
        tdm_virtual_voutput_data *voutput_data = voutput;
 
        RETURN_VAL_IF_FAIL(voutput_data, TDM_ERROR_INVALID_PARAMETER);
-       RETURN_VAL_IF_FAIL(commit_func, TDM_ERROR_INVALID_PARAMETER);
 
        voutput_data->vcommit_func = commit_func;
 
@@ -948,11 +960,11 @@ virtual_output_set_commit_func(tdm_voutput *voutput,  tdm_voutput_commit_handler
 }
 
 tdm_error
-virtual_output_commit_done(tdm_voutput *voutput)
+virtual_voutput_commit_done(tdm_voutput *voutput)
 {
        tdm_virtual_voutput_data *voutput_data = voutput;
        tdm_virtual_output_data *output_data = NULL;
-       unsigned int tv_sec, tv_usec;
+       long tv_sec, tv_usec;
        static unsigned int sequence = 0;
        tdm_virtual_event_data *event_data;
        tdm_error ret = TDM_ERROR_NONE;
@@ -983,3 +995,30 @@ virtual_output_commit_done(tdm_voutput *voutput)
        return TDM_ERROR_NONE;
 }
 
+tdm_error
+virtual_voutput_set_target_buffer_queue_flag(tdm_voutput *voutput, int flag)
+{
+       tdm_virtual_voutput_data *voutput_data = voutput;
+
+       RETURN_VAL_IF_FAIL(voutput_data, TDM_ERROR_INVALID_PARAMETER);
+
+       voutput_data->target_buffer_queue_flag = flag;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_virtual_layer_data *
+virtual_output_data_get_layer_data(tdm_virtual_output_data *output_data, int layer_zpos)
+{
+       tdm_virtual_layer_data *l = NULL;
+
+       RETURN_VAL_IF_FAIL(output_data, NULL);
+
+       LIST_FOR_EACH_ENTRY(l, &output_data->layer_list, link) {
+               if (l->zpos == layer_zpos)
+                       return l;
+       }
+
+       return NULL;
+}
+