[PATCH v5 7/9] drm: vkms: Supports to the case where primary plane doesn't match the CRTC
Igor Torrente
igormtorrente at gmail.com
Mon Apr 4 20:45:13 UTC 2022
We will break the current assumption that the primary plane has the
same size and position as CRTC.
For that we will add CRTC dimension information to `vkms_crtc_state`
and add a opaque black backgound color.
Because now we need to fill the background, we had a loss in
performance with this change. Results running the IGT[1] test
`igt at kms_cursor_crc@pipe-a-cursor-512x512-onscreen` ten times:
| Frametime |
|:--------------------------------------------:|
| Implementation | Previous | This commit |
|:---------------:|:---------:|:--------------:|
| frametime range | 5~18 ms | 10~22 ms |
| Average | 8.47 ms | 12.32 ms |
[1] IGT commit id: bc3f6833a12221a46659535dac06ebb312490eb4
Signed-off-by: Igor Torrente <igormtorrente at gmail.com>
---
Documentation/gpu/vkms.rst | 3 +--
drivers/gpu/drm/vkms/vkms_composer.c | 32 +++++++++++++++++++---------
drivers/gpu/drm/vkms/vkms_crtc.c | 4 ++++
drivers/gpu/drm/vkms/vkms_drv.h | 2 ++
4 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/Documentation/gpu/vkms.rst b/Documentation/gpu/vkms.rst
index a49e4ae92653..49db221c0f52 100644
--- a/Documentation/gpu/vkms.rst
+++ b/Documentation/gpu/vkms.rst
@@ -121,8 +121,7 @@ There's lots of plane features we could add support for:
- ARGB format on primary plane: blend the primary plane into background with
translucent alpha.
-- Support when the primary plane isn't exactly matching the output size: blend
- the primary plane into the black background.
+- Add background color KMS property[Good to get started].
- Full alpha blending on all planes.
diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index cf24015bf90f..f80842227669 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -61,6 +61,15 @@ static bool check_y_limit(struct vkms_frame_info *frame_info, int y)
return false;
}
+static void fill_background(struct pixel_argb_u16 *backgroud_color,
+ struct line_buffer *output_buffer)
+{
+ int i;
+
+ for (i = 0; i < output_buffer->n_pixels; i++)
+ output_buffer->pixels[i] = *backgroud_color;
+}
+
/**
* @wb_frame_info: The writeback frame buffer metadata
* @crtc_state: The crtc state
@@ -78,22 +87,23 @@ static void blend(struct vkms_writeback_job *wb,
struct line_buffer *output_buffer, s64 row_size)
{
struct vkms_plane_state **plane = crtc_state->active_planes;
- struct vkms_frame_info *primary_plane_info = plane[0]->frame_info;
u32 n_active_planes = crtc_state->num_active_planes;
- int y_dst = primary_plane_info->dst.y1;
- int h_dst = drm_rect_height(&primary_plane_info->dst);
- int y_limit = y_dst + h_dst;
+ struct pixel_argb_u16 background_color = (struct pixel_argb_u16) {
+ .a = 0xffff
+ };
+
+ int crtc_y_limit = crtc_state->crtc_height;
int y, i;
- for (y = y_dst; y < y_limit; y++) {
- plane[0]->format_func(output_buffer, primary_plane_info, y);
+ for (y = 0; y < crtc_y_limit; y++) {
+ fill_background(&background_color, output_buffer);
/* If there are other planes besides primary, we consider the active
* planes should be in z-order and compose them associatively:
* ((primary <- overlay) <- cursor)
*/
- for (i = 1; i < n_active_planes; i++) {
+ for (i = 0; i < n_active_planes; i++) {
if (!check_y_limit(plane[i]->frame_info, y))
continue;
@@ -154,7 +164,7 @@ static int compose_active_planes(struct vkms_writeback_job *active_wb,
if (WARN_ON(check_format_funcs(crtc_state, active_wb)))
return -EINVAL;
- line_width = drm_rect_width(&primary_plane_info->dst);
+ line_width = crtc_state->crtc_width;
stage_buffer.n_pixels = line_width;
output_buffer.n_pixels = line_width;
@@ -175,8 +185,10 @@ static int compose_active_planes(struct vkms_writeback_job *active_wb,
struct vkms_frame_info *wb_frame_info = &active_wb->frame_info;
wb_format = wb_frame_info->fb->format->format;
- wb_frame_info->src = primary_plane_info->src;
- wb_frame_info->dst = primary_plane_info->dst;
+ drm_rect_init(&wb_frame_info->src, 0, 0, crtc_state->crtc_width,
+ crtc_state->crtc_height);
+ drm_rect_init(&wb_frame_info->dst, 0, 0, crtc_state->crtc_width,
+ crtc_state->crtc_height);
}
blend(active_wb, crtc_state, crc32, &stage_buffer,
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 57bbd32e9beb..4a37e243c2d7 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -248,7 +248,9 @@ static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
static void vkms_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
struct vkms_output *vkms_output = drm_crtc_to_vkms_output(crtc);
+ struct drm_display_mode *mode = &crtc_state->mode;
if (crtc->state->event) {
spin_lock(&crtc->dev->event_lock);
@@ -264,6 +266,8 @@ static void vkms_crtc_atomic_flush(struct drm_crtc *crtc,
}
vkms_output->composer_state = to_vkms_crtc_state(crtc->state);
+ vkms_output->composer_state->crtc_width = mode->hdisplay;
+ vkms_output->composer_state->crtc_height = mode->vdisplay;
spin_unlock_irq(&vkms_output->lock);
}
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 2704cfb6904b..ab92d9f7b701 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -90,6 +90,8 @@ struct vkms_crtc_state {
bool wb_pending;
u64 frame_start;
u64 frame_end;
+ u16 crtc_width;
+ u16 crtc_height;
};
struct vkms_output {
--
2.30.2
More information about the dri-devel
mailing list