Skip to content

Commit

Permalink
drm/vc4: Add async update support for cursor planes
Browse files Browse the repository at this point in the history
Now that cursors are implemented as regular planes, all cursor
movements result in atomic updates. As the firmware-kms driver
doesn't support asynchronous updates, these are synchronous, which
limits the update rate to the screen refresh rate. Xorg seems unaware
of this (or at least of the effect of this), because if the mouse is
configured with a higher update rate than the screen then continuous
mouse movement results in an increasing backlog of mouse events -
cue extreme lag.

Add minimal support for asynchronous updates - limited to cursor
planes - to eliminate the lag.

See: #4971
     #4988

Signed-off-by: Phil Elwell <[email protected]>
  • Loading branch information
pelwell authored and popcornmix committed Aug 31, 2022
1 parent b5741e9 commit 37e65d8
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions drivers/gpu/drm/vc4/vc4_firmware_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,50 @@ static int vc4_plane_atomic_check(struct drm_plane *plane,
return vc4_plane_to_mb(plane, &vc4_plane->mb, new_plane_state);
}

static void vc4_plane_atomic_async_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct drm_plane_state *new_plane_state =
drm_atomic_get_new_plane_state(state, plane);

swap(plane->state->fb, new_plane_state->fb);
plane->state->crtc_x = new_plane_state->crtc_x;
plane->state->crtc_y = new_plane_state->crtc_y;
plane->state->crtc_w = new_plane_state->crtc_w;
plane->state->crtc_h = new_plane_state->crtc_h;
plane->state->src_x = new_plane_state->src_x;
plane->state->src_y = new_plane_state->src_y;
plane->state->src_w = new_plane_state->src_w;
plane->state->src_h = new_plane_state->src_h;
plane->state->alpha = new_plane_state->alpha;
plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode;
plane->state->rotation = new_plane_state->rotation;
plane->state->zpos = new_plane_state->zpos;
plane->state->normalized_zpos = new_plane_state->normalized_zpos;
plane->state->color_encoding = new_plane_state->color_encoding;
plane->state->color_range = new_plane_state->color_range;
plane->state->src = new_plane_state->src;
plane->state->dst = new_plane_state->dst;
plane->state->visible = new_plane_state->visible;

vc4_plane_set_blank(plane, false);
}

static int vc4_plane_atomic_async_check(struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct drm_plane_state *new_plane_state =
drm_atomic_get_new_plane_state(state, plane);
int ret = -EINVAL;

if (plane->type == 2 &&
plane->state->fb &&
new_plane_state->crtc->state->active)
ret = 0;

return ret;
}

/* Called during init to allocate the plane's atomic state. */
static void vc4_plane_reset(struct drm_plane *plane)
{
Expand Down Expand Up @@ -766,6 +810,8 @@ static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
.atomic_check = vc4_plane_atomic_check,
.atomic_update = vc4_plane_atomic_update,
.atomic_disable = vc4_plane_atomic_disable,
.atomic_async_check = vc4_plane_atomic_async_check,
.atomic_async_update = vc4_plane_atomic_async_update,
};

static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
Expand Down

0 comments on commit 37e65d8

Please sign in to comment.