Skip to content

Commit c81869e

Browse files
committed
always force zero rotation in KMS planes for consistency
primary planes are sometimes rotated when the framebuffer console is rotated. While it is potentially useful to respect that, and rotate the app accordingly, it won't rotate the input of the app nor the cursor plane. Just use zero rotation everywhere. Provide feedback if a cursor vs. overlay plane was allocated, if prefer_cursor was set. We can only use fast cursor updates if a cursor plane was allocated.
1 parent ce2d822 commit c81869e

File tree

6 files changed

+46
-11
lines changed

6 files changed

+46
-11
lines changed

src/dmabuf_surface.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ static int dmabuf_surface_present_kms(struct surface *_s, const struct fl_layer_
310310
},
311311
refcounted_dmabuf_unref_void,
312312
NULL,
313-
refcounted_dmabuf_ref(s->next_buf)
313+
refcounted_dmabuf_ref(s->next_buf),
314+
NULL
314315
);
315316
if (ok != 0) {
316317
LOG_ERROR("Couldn't push KMS fb layer. kms_req_builder_push_fb_layer: %s\n", strerror(ok));

src/egl_gbm_render_surface.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,15 +533,20 @@ static int egl_gbm_render_surface_present_kms(struct surface *s, const struct fl
533533
.src_w = DOUBLE_TO_FP1616_ROUNDED(egl_surface->render_surface.size.x),
534534
.src_h = DOUBLE_TO_FP1616_ROUNDED(egl_surface->render_surface.size.y),
535535

536-
.has_rotation = false,
536+
// If a rotated framebuffer console is shown, the rotation of the primary plane might be non-zero.
537+
//
538+
// Even though it'd be nice to keep using the already set rotation, other planes might not be rotated,
539+
// so just use zero rotation for all planes.
540+
.has_rotation = true,
537541
.rotation = PLANE_TRANSFORM_ROTATE_0,
538542

539543
.has_in_fence_fd = false,
540544
.in_fence_fd = 0,
541545
},
542546
on_release_layer,
543547
NULL,
544-
locked_fb_ref(egl_surface->locked_front_fb)
548+
locked_fb_ref(egl_surface->locked_front_fb),
549+
NULL
545550
);
546551
TRACER_END(egl_surface->surface.tracer, "kms_req_builder_push_fb_layer");
547552
if (ok != 0) {

src/modesetting.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <errno.h>
44
#include <inttypes.h>
5+
#include <stdatomic.h>
56
#include <stdint.h>
67
#include <stdio.h>
78
#include <stdlib.h>
@@ -2400,7 +2401,8 @@ int kms_req_builder_push_fb_layer(
24002401
const struct kms_fb_layer *layer,
24012402
kms_fb_release_cb_t release_callback,
24022403
kms_deferred_fb_release_cb_t deferred_release_callback,
2403-
void *userdata
2404+
void *userdata,
2405+
bool *allocated_cursor_plane
24042406
) {
24052407
struct drm_plane *plane;
24062408
int64_t zpos;
@@ -2449,7 +2451,10 @@ int kms_req_builder_push_fb_layer(
24492451
// clang-format on
24502452
);
24512453
if (plane == NULL) {
2454+
if (allocated_cursor_plane) *allocated_cursor_plane = false;
24522455
LOG_DEBUG("Couldn't find a fitting cursor plane.\n");
2456+
} else {
2457+
if (allocated_cursor_plane) *allocated_cursor_plane = true;
24532458
}
24542459
}
24552460

src/modesetting.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,10 @@ bool kms_req_builder_prefer_next_layer_opaque(struct kms_req_builder *builder);
861861
* instead.
862862
* @param userdata Userdata pointer that's passed to the release_callback or
863863
* deferred_release_callback as-is.
864+
* @param allocated_cursor_plane When layer->prefer_cursor is set, this will
865+
* be set to true if a cursor layer was
866+
* successfully allocated. Otherwise, it will
867+
* be set to false.
864868
* @returns Zero on success, otherwise:
865869
* - EINVAL: if attempting to push a second framebuffer layer, if
866870
* driver supports atomic modesetting but legacy modesetting is
@@ -877,7 +881,8 @@ int kms_req_builder_push_fb_layer(
877881
const struct kms_fb_layer *layer,
878882
kms_fb_release_cb_t release_callback,
879883
kms_deferred_fb_release_cb_t deferred_release_callback,
880-
void *userdata
884+
void *userdata,
885+
bool *allocated_cursor_plane
881886
);
882887

883888
/**

src/vk_gbm_render_surface.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,15 +687,17 @@ static int vk_gbm_render_surface_present_kms(struct surface *s, const struct fl_
687687
.src_w = DOUBLE_TO_FP1616_ROUNDED(vk_surface->render_surface.size.x),
688688
.src_h = DOUBLE_TO_FP1616_ROUNDED(vk_surface->render_surface.size.y),
689689

690-
.has_rotation = false,
690+
// see egl_gbm_render_surface_present_kms
691+
.has_rotation = true,
691692
.rotation = PLANE_TRANSFORM_ROTATE_0,
692693

693694
.has_in_fence_fd = false,
694695
.in_fence_fd = 0,
695696
},
696697
on_release_layer,
697698
NULL,
698-
locked_fb_ref(vk_surface->front_fb)
699+
locked_fb_ref(vk_surface->front_fb),
700+
NULL
699701
);
700702
TRACER_END(vk_surface->surface.tracer, "kms_req_builder_push_fb_layer");
701703
if (ok != 0) {

src/window.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ struct window {
173173
struct cursor_buffer *cursor;
174174

175175
bool logged_cursor_plane_allocation_failed;
176+
bool has_cursor_plane;
176177
} kms;
177178

178179
/**
@@ -1202,17 +1203,19 @@ static int kms_window_push_composition_locked(struct window *window, struct fl_l
12021203
.dst_y = window->cursor_pos.y - window->kms.cursor->hotspot.y,
12031204
.dst_w = window->kms.cursor->width,
12041205
.dst_h = window->kms.cursor->height,
1205-
.has_rotation = false,
1206-
.rotation = PLANE_TRANSFORM_NONE,
1206+
.has_rotation = true,
1207+
.rotation = PLANE_TRANSFORM_ROTATE_0,
12071208
.has_in_fence_fd = false,
12081209
.in_fence_fd = 0,
12091210
.prefer_cursor = true,
12101211
},
12111212
cursor_buffer_unref_with_locked_drmdev,
12121213
NULL,
1213-
window->kms.cursor
1214+
window->kms.cursor,
1215+
&window->kms.has_cursor_plane
12141216
);
12151217
if (ok != 0) {
1218+
window->kms.has_cursor_plane = false;
12161219
if (!window->kms.logged_cursor_plane_allocation_failed) {
12171220
window->kms.logged_cursor_plane_allocation_failed = true;
12181221
LOG_ERROR("Couldn't present cursor.\n");
@@ -1575,7 +1578,21 @@ static int kms_window_set_cursor_locked(
15751578
} else if (has_pos) {
15761579
// apply the new cursor position using drmModeMoveCursor
15771580
window->cursor_pos = pos;
1578-
drmdev_move_cursor(window->kms.drmdev, window->kms.crtc->id, vec2i_sub(pos, window->kms.cursor->hotspot));
1581+
1582+
// if we have a hardware cursor plane, just move the cursor.
1583+
// this is very fast and we can do that a lot of times per frame.
1584+
//
1585+
// if we don't have a hardware cursor plane, we need to do a full commit.
1586+
// However, we can only do one commit per vsync, so if flutter also later
1587+
// wants to present a frame, we wouldn't be able to present it. Even later
1588+
// cursor movements in the same vsync interval we couldn't show on screen anymore.
1589+
//
1590+
// Mutter (GNOME's compositor) has an extra KMS cursor thread with high priority for that purpose.
1591+
if (window->kms.has_cursor_plane) {
1592+
drmdev_move_cursor(window->kms.drmdev, window->kms.crtc->id, vec2i_sub(pos, window->kms.cursor->hotspot));
1593+
} else {
1594+
// for now just don't do anything.
1595+
}
15791596
}
15801597
} else {
15811598
if (window->kms.cursor != NULL) {

0 commit comments

Comments
 (0)