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@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 <igormtorre...@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

Reply via email to