xf86-video-intel: src/sna/sna_display.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Sep 10 02:24:23 PDT 2015


 src/sna/sna_display.c |  138 +++++++++++++-------------------------------------
 1 file changed, 36 insertions(+), 102 deletions(-)

New commits:
commit 2c08d72393e4c8ddf5926571b087459aaa225cb1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 10 10:21:00 2015 +0100

    sna: Use RRGetInfo() for setting hotplug/coldplug information
    
    Force the full reprobe, resetting all the output properties on all
    outputs if we detect a status change on hotplug. Rather than simply
    translate the kernel mode lists ourselves, use the common functions in
    case more settings change.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=91929
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index d75d282..0d7a2a1 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4789,108 +4789,35 @@ static bool disable_unused_crtc(struct sna *sna)
 	return update;
 }
 
-static int modecmp(DisplayModePtr a, DisplayModePtr b)
-{
-	int diff;
-
-	diff = (b->type & M_T_PREFERRED)- (a->type & M_T_PREFERRED);
-	if (diff)
-		return diff;
-
-	diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
-	if (diff)
-		return diff;
-
-	return b->Clock - a->Clock;
-}
-
-static DisplayModePtr sort_modes(DisplayModePtr in)
-{
-	DisplayModePtr out = NULL, i, o, *op, prev;
-
-	/* sort by preferred status and pixel area */
-	while (in) {
-		i = in;
-		in = in->next;
-		for (op = &out; (o = *op); op = &o->next) {
-			int ret = modecmp(o, i);
-			if (ret > 0)
-				break;
-			if (ret < 0)
-				continue;
-			if (!strcmp(o->name, i->name) && xf86ModesEqual(o, i)) {
-				free((void *)i->name);
-				free(i);
-				goto skip;
-			}
-		}
-		i->next = *op;
-		*op = i;
-skip: ;
-	}
-
-	/* hook up backward links */
-	prev = NULL;
-	for (o = out; o; o = o->next) {
-		o->prev = prev;
-		prev = o;
-	}
-	return out;
-}
-
-static void output_update_modes(xf86OutputPtr output)
+static bool
+output_check_status(struct sna *sna, struct sna_output *output)
 {
-	DBG(("%s: updating modes on output %s (id=%d): status=%d\n",
-	     __FUNCTION__, output->name, sna_output->id,
-	     sna_output->serial, serial, output->status));
-	RROutputChanged(output->randr_output, TRUE);
-
-	while (output->probed_modes)
-		xf86DeleteMode(&output->probed_modes, output->probed_modes);
-
-	if (output->status != XF86OutputStatusConnected)
-		return;
-
-	output->probed_modes = NULL;
-
-	if (output->conf_monitor)
-		output->probed_modes =
-			xf86ModesAdd(output->probed_modes,
-				     xf86GetMonitorModes(output->scrn,
-							 output->conf_monitor));
-
-	output->probed_modes =
-		xf86ModesAdd(output->probed_modes,
-			     output->funcs->get_modes(output));
-
-	output->probed_modes = sort_modes(output->probed_modes);
-}
+	union compat_mode_get_connector compat_conn;
+	struct drm_mode_modeinfo dummy;
+	xf86OutputStatus status;
 
-static bool output_set_status(xf86OutputPtr output, xf86OutputStatus status)
-{
-	unsigned value;
+	VG_CLEAR(compat_conn);
 
-	if (status == output->status)
-		return false;
+	compat_conn.conn.connector_id = output->id;
+	compat_conn.conn.count_modes = 1; /* skip detect */
+	compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
+	compat_conn.conn.count_encoders = 0;
+	compat_conn.conn.count_props = 0;
 
-	DBG(("%s: output %s (id=%d), changed status %d -> %d\n",
-	     __FUNCTION__, output->name, sna_output->id, output->status, status));
+	(void)drmIoctl(sna->kgem.fd,
+		       DRM_IOCTL_MODE_GETCONNECTOR,
+		       &compat_conn.conn);
 
-	output->status = status;
-	switch (status) {
-	case XF86OutputStatusConnected:
-		value = RR_Connected;
-		break;
-	case XF86OutputStatusDisconnected:
-		value = RR_Disconnected;
-		break;
+	switch (compat_conn.conn.connection) {
+	case DRM_MODE_CONNECTED:
+		status = XF86OutputStatusConnected;
+	case DRM_MODE_DISCONNECTED:
+		status = XF86OutputStatusDisconnected;
 	default:
-	case XF86OutputStatusUnknown:
-		value = RR_UnknownConnection;
-		break;
+	case DRM_MODE_UNKNOWNCONNECTION:
+		status = XF86OutputStatusUnknown;
 	}
-	RROutputSetConnection(output->randr_output, value);
-	return true;
+	return output->status == status;
 }
 
 void sna_mode_discover(struct sna *sna)
@@ -4952,11 +4879,13 @@ void sna_mode_discover(struct sna *sna)
 		if (sna_output->id == 0)
 			continue;
 
-		sna_output->last_detect = 0;
 		if (sna_output->serial == serial) {
-			if (output_set_status(output,
-					      sna_output_detect(output)))
-			    output_update_modes(output);
+			if (!output_check_status(sna, sna_output)) {
+				DBG(("%s: output %s (id=%d), changed state, reprobing]\n",
+				     __FUNCTION__, output->name, sna_output->id,
+				     sna_output->serial, serial));
+				sna_output->last_detect = 0;
+			}
 			continue;
 		}
 
@@ -4968,6 +4897,7 @@ void sna_mode_discover(struct sna *sna)
 			   "Disabled output %s\n",
 			   output->name);
 		sna_output->id = 0;
+		sna_output->last_detect = 0;
 		output->crtc = NULL;
 		RROutputChanged(output->randr_output, TRUE);
 		changed |= 2;
@@ -4988,6 +4918,7 @@ void sna_mode_discover(struct sna *sna)
 		xf86RandR12TellChanged(screen);
 	}
 
+	RRGetInfo(screen, TRUE);
 	RRTellChanged(screen);
 }
 
@@ -5000,6 +4931,7 @@ static CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data)
 	struct sna *sna = data;
 	ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	bool reprobe = false;
 	int i;
 
 	DBG(("%s()\n", __FUNCTION__));
@@ -5015,11 +4947,13 @@ static CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data)
 		if (output->status != XF86OutputStatusConnected)
 			continue;
 
-		output_set_status(output, sna_output_detect(output));
-		output_update_modes(output);
+		reprobe = true;
 	}
 
-	RRTellChanged(screen);
+	if (reprobe) {
+		RRGetInfo(screen, TRUE);
+		RRTellChanged(screen);
+	}
 	free(timer);
 	return 0;
 }


More information about the xorg-commit mailing list