Skip to content

Commit 0695771

Browse files
pelwellpopcornmix
authored andcommitted
drm/vc4: Add async update support for cursor planes
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]>
1 parent 2a22e35 commit 0695771

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

drivers/gpu/drm/vc4/vc4_firmware_kms.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,50 @@ static int vc4_plane_atomic_check(struct drm_plane *plane,
675675
return vc4_plane_to_mb(plane, &vc4_plane->mb, new_plane_state);
676676
}
677677

678+
static void vc4_plane_atomic_async_update(struct drm_plane *plane,
679+
struct drm_atomic_state *state)
680+
{
681+
struct drm_plane_state *new_plane_state =
682+
drm_atomic_get_new_plane_state(state, plane);
683+
684+
swap(plane->state->fb, new_plane_state->fb);
685+
plane->state->crtc_x = new_plane_state->crtc_x;
686+
plane->state->crtc_y = new_plane_state->crtc_y;
687+
plane->state->crtc_w = new_plane_state->crtc_w;
688+
plane->state->crtc_h = new_plane_state->crtc_h;
689+
plane->state->src_x = new_plane_state->src_x;
690+
plane->state->src_y = new_plane_state->src_y;
691+
plane->state->src_w = new_plane_state->src_w;
692+
plane->state->src_h = new_plane_state->src_h;
693+
plane->state->alpha = new_plane_state->alpha;
694+
plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode;
695+
plane->state->rotation = new_plane_state->rotation;
696+
plane->state->zpos = new_plane_state->zpos;
697+
plane->state->normalized_zpos = new_plane_state->normalized_zpos;
698+
plane->state->color_encoding = new_plane_state->color_encoding;
699+
plane->state->color_range = new_plane_state->color_range;
700+
plane->state->src = new_plane_state->src;
701+
plane->state->dst = new_plane_state->dst;
702+
plane->state->visible = new_plane_state->visible;
703+
704+
vc4_plane_set_blank(plane, false);
705+
}
706+
707+
static int vc4_plane_atomic_async_check(struct drm_plane *plane,
708+
struct drm_atomic_state *state)
709+
{
710+
struct drm_plane_state *new_plane_state =
711+
drm_atomic_get_new_plane_state(state, plane);
712+
int ret = -EINVAL;
713+
714+
if (plane->type == 2 &&
715+
plane->state->fb &&
716+
new_plane_state->crtc->state->active)
717+
ret = 0;
718+
719+
return ret;
720+
}
721+
678722
/* Called during init to allocate the plane's atomic state. */
679723
static void vc4_plane_reset(struct drm_plane *plane)
680724
{
@@ -769,6 +813,8 @@ static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
769813
.atomic_check = vc4_plane_atomic_check,
770814
.atomic_update = vc4_plane_atomic_update,
771815
.atomic_disable = vc4_plane_atomic_disable,
816+
.atomic_async_check = vc4_plane_atomic_async_check,
817+
.atomic_async_update = vc4_plane_atomic_async_update,
772818
};
773819

774820
static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,

0 commit comments

Comments
 (0)