aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vkms/vkms_composer.c
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2020-09-09 12:27:12 +1000
committerDave Airlie <[email protected]>2020-09-09 12:27:13 +1000
commit877d8c074302c20ac0759d1a4f689c14aada420d (patch)
treec4ac9ed42b665fc88dcc73c957cab62496037ac8 /drivers/gpu/drm/vkms/vkms_composer.c
parent1f4b2aca794f7aeb918ed5f0d7221d68a81d6b43 (diff)
parent79416e97dda0118b137302575a70a14259a27d7d (diff)
Merge tag 'topic/nouveau-i915-dp-helpers-and-cleanup-2020-08-31-1' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
UAPI Changes: None Cross-subsystem Changes: * Moves a bunch of miscellaneous DP code from the i915 driver into a set of shared DRM DP helpers Core Changes: * New DRM DP helpers (see above) Driver Changes: * Implements usage of the aforementioned DP helpers in the nouveau driver, along with some other various HPD related cleanup for nouveau Signed-off-by: Dave Airlie <[email protected]> From: Lyude Paul <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Diffstat (limited to 'drivers/gpu/drm/vkms/vkms_composer.c')
-rw-r--r--drivers/gpu/drm/vkms/vkms_composer.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index 4f3b07a32b60..eaecc5a6c5db 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -32,8 +32,6 @@ static uint32_t compute_crc(void *vaddr_out, struct vkms_composer *composer)
src_offset = composer->offset
+ (i * composer->pitch)
+ (j * composer->cpp);
- /* XRGB format ignores Alpha channel */
- bitmap_clear(vaddr_out + src_offset, 24, 8);
crc = crc32_le(crc, vaddr_out + src_offset,
sizeof(u32));
}
@@ -42,27 +40,51 @@ static uint32_t compute_crc(void *vaddr_out, struct vkms_composer *composer)
return crc;
}
+static u8 blend_channel(u8 src, u8 dst, u8 alpha)
+{
+ u32 pre_blend;
+ u8 new_color;
+
+ pre_blend = (src * 255 + dst * (255 - alpha));
+
+ /* Faster div by 255 */
+ new_color = ((pre_blend + ((pre_blend + 257) >> 8)) >> 8);
+
+ return new_color;
+}
+
+static void alpha_blending(const u8 *argb_src, u8 *argb_dst)
+{
+ u8 alpha;
+
+ alpha = argb_src[3];
+ 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;
+}
+
/**
* blend - blend value at vaddr_src with value at vaddr_dst
* @vaddr_dst: destination address
* @vaddr_src: source address
- * @dest_composer: destination framebuffer's metadata
+ * @dst_composer: destination framebuffer's metadata
* @src_composer: source framebuffer's metadata
*
- * Blend value at vaddr_src with value at vaddr_dst.
- * Currently, this function write value of vaddr_src on value
- * at vaddr_dst using buffer's metadata to locate the new values
- * from vaddr_src and their destination at vaddr_dst.
- *
- * TODO: Use the alpha value to blend vaddr_src with vaddr_dst
- * instead of overwriting it.
+ * 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.
*/
static void blend(void *vaddr_dst, void *vaddr_src,
- struct vkms_composer *dest_composer,
+ struct vkms_composer *dst_composer,
struct vkms_composer *src_composer)
{
int i, j, j_dst, i_dst;
int offset_src, offset_dst;
+ u8 *pixel_dst, *pixel_src;
int x_src = src_composer->src.x1 >> 16;
int y_src = src_composer->src.y1 >> 16;
@@ -77,15 +99,16 @@ static void blend(void *vaddr_dst, void *vaddr_src,
for (i = y_src, i_dst = y_dst; i < y_limit; ++i) {
for (j = x_src, j_dst = x_dst; j < x_limit; ++j) {
- offset_dst = dest_composer->offset
- + (i_dst * dest_composer->pitch)
- + (j_dst++ * dest_composer->cpp);
+ offset_dst = dst_composer->offset
+ + (i_dst * dst_composer->pitch)
+ + (j_dst++ * dst_composer->cpp);
offset_src = src_composer->offset
+ (i * src_composer->pitch)
+ (j * src_composer->cpp);
- memcpy(vaddr_dst + offset_dst,
- vaddr_src + offset_src, sizeof(u32));
+ pixel_src = (u8 *)(vaddr_src + offset_src);
+ pixel_dst = (u8 *)(vaddr_dst + offset_dst);
+ alpha_blending(pixel_src, pixel_dst);
}
i_dst++;
}