From 4c6192769a895d7d8e45730bbefc1879830a6e85 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Mon, 6 Jul 2020 16:26:50 +0900 Subject: add implement of hwc fence default is diabled TDM_HWC_FENCE env can enable it Change-Id: Id56132918dcc7cced729418196f8a3a793ba6048 --- src/tdm_vc4.c | 4 +++ src/tdm_vc4.h | 5 +++ src/tdm_vc4_display.c | 54 +++++++++++++++++++++++++++++-- src/tdm_vc4_hwc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_vc4_hwc_window.c | 18 +++++++++++ src/tdm_vc4_types.h | 9 ++++++ 6 files changed, 170 insertions(+), 3 deletions(-) diff --git a/src/tdm_vc4.c b/src/tdm_vc4.c index 256f6ec..fa3db98 100644 --- a/src/tdm_vc4.c +++ b/src/tdm_vc4.c @@ -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)); diff --git a/src/tdm_vc4.h b/src/tdm_vc4.h index dffb04e..4f2748d 100644 --- a/src/tdm_vc4.h +++ b/src/tdm_vc4.h @@ -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); diff --git a/src/tdm_vc4_display.c b/src/tdm_vc4_display.c index 44b8f0d..7f48171 100644 --- a/src/tdm_vc4_display.c +++ b/src/tdm_vc4_display.c @@ -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; +} diff --git a/src/tdm_vc4_hwc.c b/src/tdm_vc4_hwc.c index 2d6a064..97c4280 100644 --- a/src/tdm_vc4_hwc.c +++ b/src/tdm_vc4_hwc.c @@ -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; } @@ -578,6 +596,21 @@ vc4_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h buffer, tdm_region return TDM_ERROR_NONE; } +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) { @@ -716,6 +749,56 @@ vc4_hwc_set_commit_handler(tdm_hwc *hwc, tdm_hwc_commit_handler func) return TDM_ERROR_NONE; } +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) { diff --git a/src/tdm_vc4_hwc_window.c b/src/tdm_vc4_hwc_window.c index 38491ee..1d8721c 100644 --- a/src/tdm_vc4_hwc_window.c +++ b/src/tdm_vc4_hwc_window.c @@ -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; +} diff --git a/src/tdm_vc4_types.h b/src/tdm_vc4_types.h index dc290be..7013bad 100644 --- a/src/tdm_vc4_types.h +++ b/src/tdm_vc4_types.h @@ -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_ */ -- cgit v1.2.3