diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c index 02642801735d..48b1cf0f4ec8 100644 --- a/drivers/gpu/drm/vkms/vkms_composer.c +++ b/drivers/gpu/drm/vkms/vkms_composer.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -64,7 +65,17 @@ static u8 blend_channel(u8 src, u8 dst, u8 alpha) return new_color; } -static void alpha_blending(const u8 *argb_src, u8 *argb_dst) +/** + * alpha_blend - alpha blending equation + * @argb_src: src pixel on premultiplied alpha mode + * @argb_dst: dst pixel completely opaque + * + * blend pixels using premultiplied blend formula. The current DRM assumption + * is that pixel color values have been already pre-multiplied with the alpha + * channel values. See more drm_plane_create_blend_mode_property(). Also, this + * formula assumes a completely opaque background. + */ +static void alpha_blend(const u8 *argb_src, u8 *argb_dst) { u8 alpha; @@ -72,8 +83,16 @@ static void alpha_blending(const u8 *argb_src, u8 *argb_dst) argb_dst[0] = blend_channel(argb_src[0], argb_dst[0], alpha); argb_dst[1] = blend_channel(argb_src[1], argb_dst[1], alpha); argb_dst[2] = blend_channel(argb_src[2], argb_dst[2], alpha); - /* Opaque primary */ - argb_dst[3] = 0xFF; +} + +/** + * x_blend - blending equation that ignores the pixel alpha + * + * overwrites RGB color value from src pixel to dst pixel. + */ +static void x_blend(const u8 *xrgb_src, u8 *xrgb_dst) +{ + memcpy(xrgb_dst, xrgb_src, sizeof(u8) * 3); } /** @@ -82,16 +101,20 @@ static void alpha_blending(const u8 *argb_src, u8 *argb_dst) * @vaddr_src: source address * @dst_composer: destination framebuffer's metadata * @src_composer: source framebuffer's metadata + * @pixel_blend: blending equation based on plane format * - * Blend the vaddr_src value with the vaddr_dst value using the pre-multiplied - * alpha blending equation, since DRM currently assumes that the pixel color - * values have already been pre-multiplied with the alpha channel values. See - * more drm_plane_create_blend_mode_property(). This function uses buffer's - * metadata to locate the new composite values at vaddr_dst. + * Blend the vaddr_src value with the vaddr_dst value using a pixel blend + * equation according to the supported plane formats DRM_FORMAT_(A/XRGB8888) + * and clearing alpha channel to an completely opaque background. This function + * uses buffer's metadata to locate the new composite values at vaddr_dst. + * + * TODO: completely clear the primary plane (a = 0xff) before starting to blend + * pixel color values */ static void blend(void *vaddr_dst, void *vaddr_src, struct vkms_composer *dst_composer, - struct vkms_composer *src_composer) + struct vkms_composer *src_composer, + void (*pixel_blend)(const u8 *, u8 *)) { int i, j, j_dst, i_dst; int offset_src, offset_dst; @@ -119,7 +142,9 @@ static void blend(void *vaddr_dst, void *vaddr_src, pixel_src = (u8 *)(vaddr_src + offset_src); pixel_dst = (u8 *)(vaddr_dst + offset_dst); - alpha_blending(pixel_src, pixel_dst); + pixel_blend(pixel_src, pixel_dst); + /* clearing alpha channel (0xff)*/ + pixel_dst[3] = 0xff; } i_dst++; } @@ -131,6 +156,8 @@ static void compose_plane(struct vkms_composer *primary_composer, { struct drm_gem_object *plane_obj; struct drm_gem_shmem_object *plane_shmem_obj; + struct drm_framebuffer *fb = &plane_composer->fb; + void (*pixel_blend)(const u8 *p_src, u8 *p_dst); plane_obj = drm_gem_fb_get_obj(&plane_composer->fb, 0); plane_shmem_obj = to_drm_gem_shmem_obj(plane_obj); @@ -138,8 +165,13 @@ static void compose_plane(struct vkms_composer *primary_composer, if (WARN_ON(!plane_shmem_obj->vaddr)) return; - blend(vaddr_out, plane_shmem_obj->vaddr, - primary_composer, plane_composer); + if (fb->format->format == DRM_FORMAT_ARGB8888) + pixel_blend = &alpha_blend; + else + pixel_blend = &x_blend; + + blend(vaddr_out, plane_shmem_obj->vaddr, primary_composer, + plane_composer, pixel_blend); } static int compose_active_planes(void **vaddr_out, diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 135140f8e87a..da4251aff67f 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -16,8 +16,9 @@ static const u32 vkms_formats[] = { DRM_FORMAT_XRGB8888, }; -static const u32 vkms_cursor_formats[] = { +static const u32 vkms_plane_formats[] = { DRM_FORMAT_ARGB8888, + DRM_FORMAT_XRGB8888 }; static struct drm_plane_state * @@ -200,8 +201,8 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev, int nformats; if (type == DRM_PLANE_TYPE_CURSOR) { - formats = vkms_cursor_formats; - nformats = ARRAY_SIZE(vkms_cursor_formats); + formats = vkms_plane_formats; + nformats = ARRAY_SIZE(vkms_plane_formats); funcs = &vkms_primary_helper_funcs; } else { formats = vkms_formats;