|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
From 0fbd4d113e0d2123e896e8005d1b7fe407c28c05 Mon Sep 17 00:00:00 2001
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
From: David Herrmann <dh.herrmann@gmail.com>
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
Date: Sat, 20 Sep 2014 11:43:32 +0200
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
Subject: [PATCH] terminal: fix mode sync for connectors
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
The GETXY ioctls of DRM are usually called twice by libdrm: Once to
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
retrieve the number of objects, a second time with suitably sized buffers
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
to actually retrieve all objects. In grdrm, we avoid these excessive calls
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
and instead just call ioctls with cached buffers and resize them if they
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
were too small.
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
However, connectors need to read the mode list via EDID, which is horribly
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
slow. As the kernel still cannot do that asynchronously (seriously, we
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
need to fix this!), it has a hack to only do it if count_modes==0. This is
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
fine with libdrm, as it calls every ioctl twice, anyway. However, we fail
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
horribly with this as we usually never pass 0.
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
Fix this by calling into GETCONNECTOR ioctls twice in case we received an
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
hotplug event. Only in those cases, we need to re-read modes, so this
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
should be totally fine.
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
---
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
src/libsystemd-terminal/grdev-drm.c | 33 ++++++++++++++++++++++++---------
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
1 file changed, 24 insertions(+), 9 deletions(-)
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
diff --git a/src/libsystemd-terminal/grdev-drm.c b/src/libsystemd-terminal/grdev-drm.c
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
index 5cebb0609e..2e55ad326b 100644
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
--- a/src/libsystemd-terminal/grdev-drm.c
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+++ b/src/libsystemd-terminal/grdev-drm.c
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
@@ -264,6 +264,7 @@ struct grdrm_card {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
Hashmap *object_map;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
bool async_hotplug : 1;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ bool hotplug : 1;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
bool running : 1;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
bool ready : 1;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
bool cap_dumb : 1;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
@@ -603,12 +604,19 @@ static int grdrm_connector_resync(grdrm_connector *connector) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
res.count_encoders = connector->kern.max_encoders;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
res.count_props = connector->kern.max_props;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- /* Retrieve modes only if we have none. This avoids expensive
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- * EDID reads in the kernel, that can slow down resyncs
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- * considerably! */
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- if (connector->kern.n_modes == 0) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- res.count_modes = connector->kern.max_modes;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ /* The kernel reads modes from the EDID information only if we
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ * pass count_modes==0. This is a legacy hack for libdrm (which
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ * called every ioctl twice). Now we have to adopt.. *sigh*.
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ * If we never received an hotplug event, there's no reason to
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ * sync modes. EDID reads are heavy, so skip that if not
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ * required. */
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ if (card->hotplug) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ if (tries > 0) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ res.count_modes = connector->kern.max_modes;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ } else {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ resized = true;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ }
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
r = ioctl(card->fd, DRM_IOCTL_MODE_GETCONNECTOR, &res;;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
@@ -689,7 +697,6 @@ static int grdrm_connector_resync(grdrm_connector *connector) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
continue;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
connector->kern.n_encoders = res.count_encoders;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- connector->kern.n_modes = res.count_modes;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
connector->kern.n_props = res.count_props;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
connector->kern.type = res.connector_type;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
connector->kern.type_id = res.connector_type_id;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
@@ -698,6 +705,8 @@ static int grdrm_connector_resync(grdrm_connector *connector) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
connector->kern.mm_width = res.mm_width;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
connector->kern.mm_height = res.mm_height;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
connector->kern.subpixel = res.subpixel;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ if (res.modes_ptr == PTR_TO_UINT64(connector->kern.modes))
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ connector->kern.n_modes = res.count_modes;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
break;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
@@ -2167,6 +2176,7 @@ static void grdrm_card_hotplug(grdrm_card *card) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
grdrm_card_configure(card);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
card->ready = true;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ card->hotplug = false;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
grdev_session_unpin(card->base.session);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
@@ -2374,6 +2384,7 @@ static int grdrm_card_open(grdrm_card *card, int dev_fd) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ card->hotplug = true;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
card->fd = fd;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
fd = -1;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
@@ -3029,13 +3040,17 @@ void grdev_drm_card_hotplug(grdev_card *basecard, struct udev_device *ud) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
/* If we get add/remove events on DRM nodes without devnum, we
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
* got hotplugged DRM objects so refresh the device. */
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
devnum = udev_device_get_devnum(ud);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- if (devnum == 0)
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ if (devnum == 0) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ card->hotplug = true;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
grdrm_card_hotplug(card);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ }
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
} else if (streq_ptr(action, "change")) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
/* A change event with HOTPLUG=1 is sent whenever a connector
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
* changed state. Refresh the device to update our state. */
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
p = udev_device_get_property_value(ud, "HOTPLUG");
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
- if (streq_ptr(p, "1"))
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ if (streq_ptr(p, "1")) {
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ card->hotplug = true;
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
grdrm_card_hotplug(card);
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
+ }
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
}
|
|
Zbigniew Jędrzejewski-Szmek |
62fe94 |
}
|