hwc: add the cursor implementation 86/201786/2
authorSooChan Lim <sc1.lim@samsung.com>
Tue, 19 Mar 2019 10:53:50 +0000 (19:53 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 20 Mar 2019 02:05:49 +0000 (02:05 +0000)
Change-Id: I0635b7a7c2b6a2a113a7f59b7e37f025c3316402

src/tdm_vc4.c
src/tdm_vc4.h
src/tdm_vc4_hwc.c
src/tdm_vc4_hwc_window.c
src/tdm_vc4_types.h

index bb89966..338a8fb 100644 (file)
@@ -320,7 +320,7 @@ tdm_vc4_init(tdm_display *dpy, tdm_error *error)
                vc4_func_hwc_window.hwc_window_get_property = vc4_hwc_window_get_property;
                vc4_func_hwc_window.hwc_window_get_constraints = vc4_hwc_window_get_constraints;
                vc4_func_hwc_window.hwc_window_set_name = vc4_hwc_window_set_name;
-               vc4_func_hwc_window.hwc_window_set_cursor_image = NULL; // no need
+               vc4_func_hwc_window.hwc_window_set_cursor_image = vc4_hwc_window_set_cursor_image;
        }
 
        memset(&vc4_func_layer, 0, sizeof(vc4_func_layer));
index 1898d54..0488d2a 100644 (file)
@@ -74,6 +74,7 @@ tdm_error      vc4_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned
 tdm_error      vc4_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value);
 tdm_error      vc4_hwc_window_get_constraints(tdm_hwc_window *hwc_window, int *constraints);
 tdm_error      vc4_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name);
+tdm_error      vc4_hwc_window_set_cursor_image(tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr);
 
 tdm_error      vc4_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps);
 tdm_error      vc4_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value);
index e3daa2f..d34e33d 100644 (file)
 #define NUM_LAYERS  3
 #define NUM_BUFFERS 3
 
-#define ZPOS_MAX  3
-#define ZPOS_2    2
-#define ZPOS_1    1
-#define ZPOS_0    0
+#define ZPOS_MAX     4
+#define ZPOS_CURSOR  3
+#define ZPOS_2       2
+#define ZPOS_1       1
+#define ZPOS_0       0
 #define ZPOS_VIDEO1  -1 //TODO:
 #define ZPOS_NONE    -999
 
@@ -39,6 +40,74 @@ _comp_to_str(tdm_hwc_window_composition composition_type)
        return "unknown";
 }
 
+static int
+_vc4_hwc_cursor_buffer_set(tdm_vc4_hwc_data *hwc_data, tdm_vc4_hwc_window_data *hwc_window_data)
+{
+       tbm_surface_h cursor_tsurface = NULL;
+       tbm_surface_info_s tsurface_info;
+       tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE;
+       int img_w, img_h, new_w, new_h;
+       tbm_format new_format;
+       unsigned int flags = TBM_BO_SCANOUT;
+       void *src_ptr = NULL, *dst_ptr = NULL;
+       int src_stride;
+       int i;
+
+       if (!hwc_window_data->cursor_img_refresh)
+               return 1;
+
+       img_w = hwc_window_data->cursor_img.width;
+       img_h = hwc_window_data->cursor_img.height;
+       new_format = hwc_window_data->info.src_config.format;
+
+       /* cursor restriction to set the cursor layer */
+       new_w = (CURSOR_MIN_W > img_w) ? CURSOR_MIN_W : img_w;
+       new_h = (CURSOR_MIN_H > img_h) ? CURSOR_MIN_H : img_h;
+
+       if (hwc_data->cursor_tsurface) {
+               tbm_surface_internal_unref(hwc_data->cursor_tsurface);
+               hwc_data->cursor_tsurface = NULL;
+       }
+
+       cursor_tsurface = tbm_surface_internal_create_with_flags(new_w, new_h, new_format, flags);
+       RETURN_VAL_IF_FAIL(cursor_tsurface, 0);
+
+       hwc_data->cursor_tsurface = cursor_tsurface;
+       ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info);
+       if (ret != TBM_SURFACE_ERROR_NONE) {
+               TDM_ERR("Failed to map tsurface\n");
+               tbm_surface_internal_unref(hwc_data->cursor_tsurface);
+               hwc_data->cursor_tsurface = NULL;
+               return 0;
+       }
+
+       src_ptr = hwc_window_data->cursor_img.ptr;
+       dst_ptr = tsurface_info.planes[0].ptr;
+       src_stride = hwc_window_data->cursor_img.stride;
+
+       memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height);
+
+       for (i = 0 ; i < img_h ; i++) {
+               memcpy(dst_ptr, src_ptr, src_stride);
+               dst_ptr += tsurface_info.planes[0].stride;
+               src_ptr += src_stride;
+       }
+
+       tbm_surface_unmap(hwc_data->cursor_tsurface);
+
+       hwc_window_data->surface = hwc_data->cursor_tsurface;
+
+       /* fix the dst_pos info of the cursor window */
+       hwc_window_data->info.src_config.pos.w = new_w;
+       hwc_window_data->info.src_config.pos.h = new_h;
+       hwc_window_data->info.dst_pos.w = new_w;
+       hwc_window_data->info.dst_pos.h = new_h;
+
+       hwc_window_data->cursor_img_refresh = 0;
+
+       return 1;
+}
+
 static void
 _print_validate_result(tdm_vc4_hwc_data *hwc_data, tdm_hwc_window **composited_wnds, uint32_t num_wnds)
 {
@@ -175,6 +244,10 @@ _vc4_hwc_prepare_commit(tdm_vc4_hwc_data *hwc_data)
                if (hwc_window_data == hwc_data->target_hwc_window)
                        continue;
 
+               /* set the cursor buffer HERE if it needs */
+               if (hwc_window_data->validated_type == TDM_HWC_WIN_COMPOSITION_CURSOR)
+                       _vc4_hwc_cursor_buffer_set(hwc_data, hwc_window_data);
+
                layer_data = vc4_output_data_get_layer_data(hwc_data->output_data, hwc_window_data->lzpos);
                _vc4_hwc_layer_attach_window(layer_data, hwc_window_data);
                use_layers_zpos[hwc_window_data->lzpos] = 1;
@@ -248,10 +321,17 @@ _vc4_hwc_apply_policy(tdm_vc4_hwc_data *hwc_data , tdm_hwc_window **composited_w
                        video_count++;
        }
 
-       /* TODO: not support the cursor layer yet */
-       if (cursor_count > 0)
+       /* apply the cursor layers */
+       if (cursor_count > 1)
                goto set_clients_below;
 
+       if (cursor_count == 1) {
+               /* set cursor composition and layer zpos */
+               composited_list[next_idx]->validated_type = TDM_HWC_WIN_COMPOSITION_CURSOR;
+               composited_list[next_idx]->lzpos = ZPOS_CURSOR;
+               next_idx++;
+       }
+
        /* reset the lzpos_bottom when it needs target_window */
        if ((client_count > 0) || (client_count + device_count > 2)) {
                hwc_data->need_target_window = 1;
index 1b8f6f9..38491ee 100644 (file)
@@ -134,3 +134,21 @@ vc4_hwc_window_set_name(tdm_hwc_window *hwc_window, const char *name)
 
        return TDM_ERROR_NONE;
 }
+
+tdm_error
+vc4_hwc_window_set_cursor_image(tdm_hwc_window *hwc_window, int width, int height, int stride, void *ptr)
+{
+       tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(hwc_window_data->client_type == TDM_HWC_WIN_COMPOSITION_CURSOR, TDM_ERROR_INVALID_PARAMETER);
+
+       hwc_window_data->cursor_img.width = width;
+       hwc_window_data->cursor_img.height = height;
+       hwc_window_data->cursor_img.stride = stride;
+       hwc_window_data->cursor_img.ptr = ptr;
+
+       hwc_window_data->cursor_img_refresh = 1;
+
+       return TDM_ERROR_NONE;
+}
index d3d71c2..bb06daf 100644 (file)
 
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
 
+#define CURSOR_MIN_W 192
+#define CURSOR_MIN_H 192
+#define CURSOR_MAX_W 192
+#define CURSOR_MAX_H 192
+
 #define RETURN_VAL_IF_FAIL(cond, val) {\
        if (!(cond)) {\
                TDM_ERR("'%s' failed", #cond);\
@@ -234,6 +239,8 @@ struct _tdm_vc4_hwc_data {
        tdm_vc4_output_data *output_data;
        struct list_head hwc_window_list;
 
+       tbm_surface_h cursor_tsurface;
+
        tdm_hwc_commit_handler commit_func;
 };
 struct _tdm_vc4_hwc_window_data {
@@ -248,6 +255,13 @@ struct _tdm_vc4_hwc_window_data {
        int lzpos;
 
        char name[TDM_NAME_LEN];
+       struct {
+               int width;
+               int height;
+               int stride;
+               void *ptr;
+       } cursor_img;
+       int cursor_img_refresh;
 };
 
 #endif /* _TDM_VC4_TYPES_H_ */