From 45b398b4772a5bb77d9f6b3a67b8eecfc55b81c4 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 21 Feb 2019 14:57:48 -0500 Subject: [PATCH 1595/2940] drm/amd/display: Expose support for alpha blending on overlays [Why] The DRM overlay planes DM exposes support RGBA formats but are currently forced as fully opaque over whatever they overlay. [How] Expose DRM blending mode and alpha properties to userspace. The overlays exposed support per-pixel pre-multiplied alpha along with global plane opacity. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Harry Wentland Acked-by: Leo Li --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e0d0691711fa..fc04cbc719a5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2639,6 +2639,42 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, } +static void +fill_blending_from_plane_state(struct drm_plane_state *plane_state, + const struct dc_plane_state *dc_plane_state, + bool *per_pixel_alpha, bool *global_alpha, + int *global_alpha_value) +{ + *per_pixel_alpha = false; + *global_alpha = false; + *global_alpha_value = 0xff; + + if (plane_state->plane->type != DRM_PLANE_TYPE_OVERLAY) + return; + + if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) { + static const uint32_t alpha_formats[] = { + DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_ABGR8888, + }; + uint32_t format = plane_state->fb->format->format; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(alpha_formats); ++i) { + if (format == alpha_formats[i]) { + *per_pixel_alpha = true; + break; + } + } + } + + if (plane_state->alpha < 0xffff) { + *global_alpha = true; + *global_alpha_value = plane_state->alpha >> 8; + } +} + static int fill_plane_attributes(struct amdgpu_device *adev, struct dc_plane_state *dc_plane_state, struct drm_plane_state *plane_state, @@ -2672,6 +2708,11 @@ static int fill_plane_attributes(struct amdgpu_device *adev, dc_plane_state->in_transfer_func = NULL; } + fill_blending_from_plane_state(plane_state, dc_plane_state, + &dc_plane_state->per_pixel_alpha, + &dc_plane_state->global_alpha, + &dc_plane_state->global_alpha_value); + return ret; } @@ -4013,6 +4054,15 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, break; } + /* TODO: Check DC plane caps explicitly here for adding propertes */ + if (plane->type == DRM_PLANE_TYPE_OVERLAY) { + unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | + BIT(DRM_MODE_BLEND_PREMULTI); + + drm_plane_create_alpha_property(plane); + drm_plane_create_blend_mode_property(plane, blend_caps); + } + drm_plane_helper_add(plane, &dm_plane_helper_funcs); /* Create (reset) the plane state */ @@ -4876,6 +4926,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->plane_infos[planes_count].stereo_format = dc_plane->stereo_format; bundle->plane_infos[planes_count].tiling_info = dc_plane->tiling_info; bundle->plane_infos[planes_count].visible = dc_plane->visible; + bundle->plane_infos[planes_count].global_alpha = dc_plane->global_alpha; + bundle->plane_infos[planes_count].global_alpha_value = dc_plane->global_alpha_value; bundle->plane_infos[planes_count].per_pixel_alpha = dc_plane->per_pixel_alpha; bundle->plane_infos[planes_count].dcc = dc_plane->dcc; bundle->surface_updates[planes_count].plane_info = &bundle->plane_infos[planes_count]; -- 2.17.1