add implement of hwc fence 70/238170/4
authorChangyeon Lee <cyeon.lee@samsung.com>
Mon, 6 Jul 2020 07:26:50 +0000 (16:26 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Thu, 9 Jul 2020 05:22:34 +0000 (14:22 +0900)
default is diabled
TDM_HWC_FENCE env can enable it

Change-Id: Id56132918dcc7cced729418196f8a3a793ba6048

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

index 256f6ec..fa3db98 100644 (file)
@@ -299,11 +299,14 @@ tdm_vc4_init(tdm_display *dpy, tdm_error *error)
                vc4_func_hwc.hwc_get_available_properties = vc4_hwc_get_available_properties;
                vc4_func_hwc.hwc_get_client_target_buffer_queue = vc4_hwc_get_client_target_buffer_queue;
                vc4_func_hwc.hwc_set_client_target_buffer = vc4_hwc_set_client_target_buffer;
+               vc4_func_hwc.hwc_set_client_target_acquire_fence = vc4_hwc_set_client_target_acquire_fence;
                vc4_func_hwc.hwc_validate = vc4_hwc_validate;
                vc4_func_hwc.hwc_get_changed_composition_types = vc4_hwc_get_changed_composition_types;
                vc4_func_hwc.hwc_accept_validation = vc4_hwc_accept_validation;
                vc4_func_hwc.hwc_commit = vc4_hwc_commit;
                vc4_func_hwc.hwc_set_commit_handler = vc4_hwc_set_commit_handler;
+               vc4_func_hwc.hwc_get_commit_fence = vc4_hwc_get_commit_fence;
+               vc4_func_hwc.hwc_get_release_fences = vc4_hwc_get_release_fences;
 
                memset(&vc4_func_hwc_window, 0, sizeof(vc4_func_hwc_window));
                vc4_func_hwc_window.hwc_window_destroy = vc4_hwc_window_destroy;
@@ -318,6 +321,7 @@ tdm_vc4_init(tdm_display *dpy, tdm_error *error)
                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 = vc4_hwc_window_set_cursor_image;
+               vc4_func_hwc_window.hwc_window_set_acquire_fence = vc4_hwc_window_set_acquire_fence;
        }
 
        memset(&vc4_func_layer, 0, sizeof(vc4_func_layer));
index dffb04e..4f2748d 100644 (file)
@@ -61,11 +61,14 @@ tdm_error            vc4_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *
 tdm_error            vc4_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count);
 tbm_surface_queue_h  vc4_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error);
 tdm_error            vc4_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region damage);
+tdm_error            vc4_hwc_set_client_target_acquire_fence(tdm_hwc *hwc, int acquire_fence);
 tdm_error            vc4_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types);
 tdm_error            vc4_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_wnds, tdm_hwc_window_composition *composition_types);
 tdm_error            vc4_hwc_accept_validation(tdm_hwc *hwc);
 tdm_error            vc4_hwc_commit(tdm_hwc *hwc, int sync, void *user_data);
 tdm_error            vc4_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func);
+tdm_error            vc4_hwc_get_commit_fence(tdm_hwc *hwc, int *fence);
+tdm_error            vc4_hwc_get_release_fences(tdm_hwc *hwc, uint32_t *num_elements, tdm_hwc_window **hwc_window, int *fences);
 
 void           vc4_hwc_window_destroy(tdm_hwc_window *hwc_window);
 tdm_error      vc4_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type);
@@ -77,6 +80,7 @@ tdm_error      vc4_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned
 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_hwc_window_set_acquire_fence(tdm_hwc_window *hwc_window, int acquire_fence);
 
 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);
@@ -86,6 +90,7 @@ tdm_error     vc4_layer_get_info(tdm_layer *layer, tdm_info_layer *info);
 tdm_error      vc4_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer);
 tdm_error      vc4_layer_unset_buffer(tdm_layer *layer);
 tdm_error      vc4_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags);
+tdm_error      vc4_layer_set_acquire_fence(tdm_layer *layer, int acquire_fence);
 
 uint32_t       tdm_vc4_format_to_drm_format(tbm_format format);
 tbm_format     tdm_vc4_format_to_tbm_format(uint32_t format);
index 44b8f0d..7f48171 100644 (file)
@@ -551,6 +551,7 @@ _tdm_vc4_display_create_layer_list(tdm_vc4_data *vc4_data)
                layer_data->vc4_data = vc4_data;
                layer_data->output_data = output_data;
                layer_data->plane_id = vc4_data->plane_res->planes[i];
+               layer_data->acquire_fence = -1;
 
                layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY |
                                                                   TDM_LAYER_CAPABILITY_GRAPHIC;
@@ -663,6 +664,7 @@ _tdm_vc4_display_create_layer_list_type(tdm_vc4_data *vc4_data)
                layer_data->vc4_data = vc4_data;
                layer_data->output_data = output_data;
                layer_data->plane_id = vc4_data->plane_res->planes[i];
+               layer_data->acquire_fence = -1;
 
                if (type == DRM_PLANE_TYPE_CURSOR) {
                        layer_data->capabilities = TDM_LAYER_CAPABILITY_CURSOR |
@@ -760,6 +762,13 @@ _tdm_vc4_display_create_layer_list_type(tdm_vc4_data *vc4_data)
                                free(layer_data);
                                goto failed_atomic_prop_id;
                        }
+
+                       ret = _vc4_output_get_atomic_prop_id(vc4_data->drm_fd, layer_data->plane_id,
+                                               DRM_MODE_OBJECT_PLANE, "IN_FENCE_FD", &layer_data->atomic_props_ids.in_fence_fd);
+                       if (ret != TDM_ERROR_NONE) {
+                               free(layer_data);
+                               goto failed_atomic_prop_id;
+                       }
                }
 
                drmModeFreePlane(plane);
@@ -957,6 +966,7 @@ tdm_vc4_display_create_output_list(tdm_vc4_data *vc4_data)
                output_data->pipe = c;
                output_data->connector_type = connector->connector_type;
                output_data->connector_type_id = connector->connector_type_id;
+               output_data->commit_fence = -1;
 
                if (connector->connection == DRM_MODE_CONNECTED)
                        output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
@@ -1041,6 +1051,11 @@ tdm_vc4_display_create_output_list(tdm_vc4_data *vc4_data)
                                        DRM_MODE_OBJECT_CRTC, "ACTIVE", &output_data->atomic_props_ids.crtc_active);
                        if (ret != TDM_ERROR_NONE)
                                goto failed_atomic_prop_id;
+
+                       ret = _vc4_output_get_atomic_prop_id(vc4_data->drm_fd, output_data->crtc_id,
+                                       DRM_MODE_OBJECT_CRTC, "OUT_FENCE_PTR", &output_data->atomic_props_ids.out_fence_ptr);
+                       if (ret != TDM_ERROR_NONE)
+                               goto failed_atomic_prop_id;
                }
        }
 
@@ -1456,7 +1471,7 @@ vc4_output_set_vblank_handler(tdm_output *output,
 static tdm_error
 _vc4_layer_add_atomic_properties(tdm_vc4_layer_data *layer_data, drmModeAtomicReqPtr request,
                        uint32_t fb_id, uint32_t crtc_id, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
-                       uint32_t crtc_x, uint32_t crtc_y, uint32_t crtc_w, uint32_t crtc_h)
+                       uint32_t crtc_x, uint32_t crtc_y, uint32_t crtc_w, uint32_t crtc_h, int acquire_fence)
 {
        tdm_error ret = TDM_ERROR_NONE;
 
@@ -1520,6 +1535,12 @@ _vc4_layer_add_atomic_properties(tdm_vc4_layer_data *layer_data, drmModeAtomicRe
                return TDM_ERROR_OPERATION_FAILED;
        }
 
+       ret = drmModeAtomicAddProperty(request, layer_data->plane_id, layer_data->atomic_props_ids.in_fence_fd, acquire_fence);
+       if (ret < 0) {
+               TDM_ERR("fail to add the atomic prop. acquire_fence(%d)", acquire_fence);
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
        return TDM_ERROR_NONE;
 }
 
@@ -1564,7 +1585,7 @@ _vc4_layer_make_atomic_request(tdm_vc4_layer_data *layer_data, drmModeAtomicReqP
                TDM_INFO("MakeAtomicRequest: drm_fd(%d) plane_id(%u) crtc_id(%u) off",
                                vc4_data->drm_fd, layer_data->plane_id, output_data->crtc_id);
 
-               ret = _vc4_layer_add_atomic_properties(layer_data, request, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+               ret = _vc4_layer_add_atomic_properties(layer_data, request, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1);
                if (ret != TDM_ERROR_NONE) {
                        TDM_ERR("_vc4_layer_add_atomic_properties failed.");
                        return ret;
@@ -1612,7 +1633,7 @@ _vc4_layer_make_atomic_request(tdm_vc4_layer_data *layer_data, drmModeAtomicReqP
                                                layer_data->display_buffer->fb_id, output_data->crtc_id,
                                                fx, fy, fw, fh,
                                                new_dst_x, layer_info.dst_pos.y,
-                                               new_dst_w, layer_info.dst_pos.h);
+                                               new_dst_w, layer_info.dst_pos.h, layer_data->acquire_fence);
        if (ret != TDM_ERROR_NONE) {
                TDM_ERR("MakeAtomicRequest failed");
                return ret;
@@ -1630,6 +1651,7 @@ _vc4_output_atomic_commit(tdm_output *output, int sync, void *user_data)
        drmModeAtomicReqPtr request;
        uint32_t flags =  0;
        tdm_error ret;
+       int out_fence_fd = -1;
 
        RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
 
@@ -1672,6 +1694,12 @@ _vc4_output_atomic_commit(tdm_output *output, int sync, void *user_data)
 
        flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;
 
+       ret = drmModeAtomicAddProperty(request, output_data->crtc_id, output_data->atomic_props_ids.out_fence_ptr, (uint32_t)&out_fence_fd);
+       if (ret < 0) {
+               TDM_ERR("fail to out fence ptr error:%d", errno);
+               return ret;
+       }
+
        LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link) {
                ret = _vc4_layer_make_atomic_request(layer_data, request);
                if (ret != TDM_ERROR_NONE) {
@@ -1701,6 +1729,11 @@ _vc4_output_atomic_commit(tdm_output *output, int sync, void *user_data)
                return TDM_ERROR_OPERATION_FAILED;
        }
 
+       if (output_data->commit_fence >= 0)
+               close(output_data->commit_fence);
+
+       output_data->commit_fence = out_fence_fd;
+
        drmModeAtomicFree(request);
 
        return TDM_ERROR_NONE;
@@ -2475,3 +2508,18 @@ vc4_output_data_prepare_mirror_commit(tdm_vc4_output_data *output_data, tbm_surf
 
        return TDM_ERROR_NONE;
 }
+
+tdm_error
+vc4_layer_set_acquire_fence(tdm_layer *layer, int acquire_fence)
+{
+       tdm_vc4_layer_data *layer_data = layer;
+
+       RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
+
+       TDM_DBG("layer[%p]zpos[%d] acquire_fence:%d", layer, layer_data->zpos, acquire_fence);
+
+       if (layer_data->acquire_fence != acquire_fence)
+               layer_data->acquire_fence = acquire_fence;
+
+       return TDM_ERROR_NONE;
+}
index 2d6a064..97c4280 100644 (file)
@@ -243,12 +243,18 @@ _vc4_hwc_layer_attach_window(tdm_vc4_layer_data *layer_data, tdm_vc4_hwc_window_
                if (layer_data->display_buffer)
                        ret = vc4_layer_unset_buffer(layer_data);
                RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+
+               if (layer_data->acquire_fence >= 0)
+                       ret = vc4_layer_set_acquire_fence(layer_data, -1);
+               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
        } else {
                ret = vc4_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->surface != NULL, TDM_ERROR_INVALID_PARAMETER);
                ret = vc4_layer_set_buffer(layer_data, hwc_window_data->surface);
                RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
+               ret = vc4_layer_set_acquire_fence(layer_data, hwc_window_data->acquire_fence);
+               RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret);
        }
 
        return ret;
@@ -485,6 +491,8 @@ vc4_hwc_create_window(tdm_hwc *hwc, tdm_error *error)
        hwc_window_data = _vc4_hwc_create_window(hwc_data, NULL, error);
        RETURN_VAL_IF_FAIL(hwc_window_data, NULL);
 
+       hwc_window_data->acquire_fence = -1;
+
        LIST_ADDTAIL(&hwc_window_data->link, &hwc_data->hwc_window_list);
 
        TDM_DBG("hwc_window(%p) create", hwc_window_data);
@@ -516,6 +524,16 @@ vc4_hwc_get_capabilities(tdm_hwc *hwc, tdm_hwc_capability *capabilities)
 
        *capabilities |= TDM_HWC_CAPABILITY_VIDEO_SCALE;
 
+       /* temporary enable/disable */
+       char *env;
+
+       env = getenv("TDM_HWC_FENCE");
+       if (env) {
+               if (atoi(env))
+                       *capabilities |= TDM_HWC_CAPABILITY_FENCE;
+       }
+       /* temporary enable/disable */
+
        return TDM_ERROR_NONE;
 }
 
@@ -579,6 +597,21 @@ vc4_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region
 }
 
 tdm_error
+vc4_hwc_set_client_target_acquire_fence(tdm_hwc *hwc, int acquire_fence)
+{
+       tdm_vc4_hwc_data *hwc_data = hwc;
+       tdm_error err;
+
+       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 = vc4_hwc_window_set_acquire_fence(hwc_data->target_hwc_window, acquire_fence);
+       RETURN_VAL_IF_FAIL(err == TDM_ERROR_NONE, err);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
 vc4_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types)
 {
        tdm_vc4_hwc_data *hwc_data = hwc;
@@ -717,6 +750,56 @@ vc4_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func)
 }
 
 tdm_error
+vc4_hwc_get_commit_fence(tdm_hwc *hwc, int *commit_fence)
+{
+       tdm_vc4_hwc_data *hwc_data = hwc;
+       tdm_vc4_output_data *output_data;
+
+       RETURN_VAL_IF_FAIL(hwc_data, TDM_ERROR_INVALID_PARAMETER);
+       RETURN_VAL_IF_FAIL(commit_fence, TDM_ERROR_INVALID_PARAMETER);
+
+       output_data = hwc_data->output_data;
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+       *commit_fence = dup(output_data->commit_fence);
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
+vc4_hwc_get_release_fences(tdm_hwc *hwc, uint32_t *num_elements,
+                                               tdm_hwc_window **hwc_wnds, int *fences)
+{
+       tdm_vc4_hwc_data *hwc_data = hwc;
+       tdm_vc4_output_data *output_data;
+       tdm_vc4_hwc_window_data *hwc_window_data = NULL;
+       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);
+
+       output_data = hwc_data->output_data;
+       RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
+
+       LIST_FOR_EACH_ENTRY_REV(hwc_window_data, &hwc_data->hwc_window_list, link) {
+               if ((hwc_window_data->validated_type != TDM_HWC_WIN_COMPOSITION_DEVICE) &&
+                       (hwc_window_data->validated_type != TDM_HWC_WIN_COMPOSITION_VIDEO))
+                       continue;
+
+               if (hwc_wnds && fences) {
+                       fences[num] = dup(output_data->commit_fence);
+                       hwc_wnds[num] = hwc_window_data;
+               }
+
+               num++;
+       }
+
+       *num_elements = num;
+
+       return TDM_ERROR_NONE;
+}
+
+tdm_error
 vc4_hwc_target_window_set_info(tdm_vc4_hwc_data *hwc_data, int width, int height)
 {
        tdm_hwc_window_info info = {0};
index 38491ee..1d8721c 100644 (file)
@@ -152,3 +152,21 @@ vc4_hwc_window_set_cursor_image(tdm_hwc_window *hwc_window, int width, int heigh
 
        return TDM_ERROR_NONE;
 }
+
+tdm_error
+vc4_hwc_window_set_acquire_fence(tdm_hwc_window *hwc_window, int acquire_fence)
+{
+       tdm_vc4_hwc_window_data *hwc_window_data = hwc_window;
+
+       RETURN_VAL_IF_FAIL(hwc_window_data != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       if (hwc_window_data->acquire_fence >= 0) {
+               close(hwc_window_data->acquire_fence);
+               hwc_window_data->acquire_fence = -1;
+       }
+
+       if (acquire_fence >= 0)
+               hwc_window_data->acquire_fence = dup(acquire_fence);
+
+       return TDM_ERROR_NONE;
+}
index dc290be..7013bad 100644 (file)
@@ -200,12 +200,15 @@ struct _tdm_vc4_output_data {
                uint32_t crtc_id;
                uint32_t crtc_mode_id;
                uint32_t crtc_active;
+               uint32_t out_fence_ptr;
        } atomic_props_ids;
 
        /* mirroring output_data, only one support */
        tdm_vc4_output_data *mirror_dst_output_data;
        tdm_transform        mirror_dst_transform;
        tdm_vc4_output_data *mirror_src_output_data;
+
+       int commit_fence;
 };
 
 struct _tdm_vc4_layer_data {
@@ -238,7 +241,10 @@ struct _tdm_vc4_layer_data {
                uint32_t crtc_w;
                uint32_t crtc_h;
                uint32_t zpos;
+               uint32_t in_fence_fd;
        } atomic_props_ids;
+
+       int acquire_fence;
 };
 
 struct _tdm_vc4_hwc_data {
@@ -257,6 +263,7 @@ struct _tdm_vc4_hwc_data {
 
        tdm_hwc_commit_handler commit_func;
 };
+
 struct _tdm_vc4_hwc_window_data {
        struct list_head link;
 
@@ -277,6 +284,8 @@ struct _tdm_vc4_hwc_window_data {
        } cursor_img;
        int cursor_img_surface;
        int cursor_img_refresh;
+
+       int acquire_fence;
 };
 
 #endif /* _TDM_VC4_TYPES_H_ */