summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChangyeon Lee <cyeon.lee@samsung.com>2020-07-06 16:26:50 +0900
committerChangyeon Lee <cyeon.lee@samsung.com>2020-07-09 14:22:34 +0900
commit4c6192769a895d7d8e45730bbefc1879830a6e85 (patch)
treebad667e607ff9aedc720ce5e602aa94f2ed7a15a
parent76c1dedd2709d664480f3c95d98064e82b3792a2 (diff)
downloadlibtdm-vc4-4c6192769a895d7d8e45730bbefc1879830a6e85.tar.gz
libtdm-vc4-4c6192769a895d7d8e45730bbefc1879830a6e85.tar.bz2
libtdm-vc4-4c6192769a895d7d8e45730bbefc1879830a6e85.zip
add implement of hwc fence
default is diabled TDM_HWC_FENCE env can enable it Change-Id: Id56132918dcc7cced729418196f8a3a793ba6048
-rw-r--r--src/tdm_vc4.c4
-rw-r--r--src/tdm_vc4.h5
-rw-r--r--src/tdm_vc4_display.c54
-rw-r--r--src/tdm_vc4_hwc.c83
-rw-r--r--src/tdm_vc4_hwc_window.c18
-rw-r--r--src/tdm_vc4_types.h9
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;
}
@@ -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};
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_ */