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

Chris Wilson ickle at kemper.freedesktop.org
Sat Feb 21 08:59:33 PST 2015


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

New commits:
commit b6d4f49176c6177561b760b116ae3e5f0a39aa95
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Feb 21 16:50:50 2015 +0000

    sna: Cache the output status and modes for 15s
    
    As the output configuration rarely changes, and is normally accompanied
    by a hotplug event, we can cache the last probe for a small number of
    seconds. If a hotplug event does fire, in the worst case by the 30s
    output polling thread, then we reset the cache and force the probe. This
    should improve application (and desktop) startup times as they often
    seem to do many full xrandr probes (rather than query current status).
    
    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 63ce7c5..657e998 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -88,6 +88,8 @@ union compat_mode_get_connector{
 #define DEFAULT_DPI 96
 #endif
 
+#define OUTPUT_STATUS_CACHE_MS 15000
+
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 
 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
@@ -187,6 +189,9 @@ struct sna_output {
 	struct backlight backlight;
 	int backlight_active_level;
 
+	uint32_t last_detect;
+	uint32_t status;
+
 	int num_modes;
 	struct drm_mode_modeinfo *modes;
 
@@ -2898,6 +2903,7 @@ sna_output_detect(xf86OutputPtr output)
 	struct sna *sna = to_sna(output->scrn);
 	struct sna_output *sna_output = output->driver_private;
 	union compat_mode_get_connector compat_conn;
+	uint32_t now;
 
 	DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
 
@@ -2906,6 +2912,16 @@ sna_output_detect(xf86OutputPtr output)
 		return XF86OutputStatusDisconnected;
 	}
 
+	/* Cache detections for 15s or hotplug event  */
+	now = GetTimeInMillis();
+	if (sna_output->last_detect != 0 &&
+	    (int32_t)(now - sna_output->last_detect) <= OUTPUT_STATUS_CACHE_MS) {
+		DBG(("%s(%s) reporting cached status (since %dms): %d\n",
+		     __FUNCTION__, output->name, now - sna_output->last_detect,
+		     sna_output->status));
+		return sna_output->status;
+	}
+
 	VG_CLEAR(compat_conn);
 	compat_conn.conn.connector_id = sna_output->id;
 	sna_output->num_modes = compat_conn.conn.count_modes = 0; /* reprobe */
@@ -2948,15 +2964,17 @@ sna_output_detect(xf86OutputPtr output)
 	DBG(("%s(%s): found %d modes, connection status=%d\n",
 	     __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection));
 
+	sna_output->last_detect = now;
 	switch (compat_conn.conn.connection) {
 	case DRM_MODE_CONNECTED:
-		return XF86OutputStatusConnected;
+		sna_output->status = XF86OutputStatusConnected;
 	case DRM_MODE_DISCONNECTED:
-		return XF86OutputStatusDisconnected;
+		sna_output->status = XF86OutputStatusDisconnected;
 	default:
 	case DRM_MODE_UNKNOWNCONNECTION:
-		return XF86OutputStatusUnknown;
+		sna_output->status = XF86OutputStatusUnknown;
 	}
+	return sna_output->status;
 }
 
 static Bool
@@ -4259,16 +4277,18 @@ void sna_mode_discover(struct sna *sna)
 
 	for (i = 0; i < sna->mode.num_real_output; i++) {
 		xf86OutputPtr output = config->output[i];
+		struct sna_output *sna_output = to_sna_output(output);
 
-		if (to_sna_output(output)->id == 0)
+		if (sna_output->id == 0)
 			continue;
 
-		if (to_sna_output(output)->serial == serial)
+		sna_output->last_detect = 0;
+		if (sna_output->serial == serial)
 			continue;
 
 		DBG(("%s: removing output %s (id=%d), serial=%u [now %u]\n",
-		     __FUNCTION__, output->name, to_sna_output(output)->id,
-		    to_sna_output(output)->serial, serial));
+		     __FUNCTION__, output->name, sna_output->id,
+		    sna_output->serial, serial));
 
 		xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
 			   "%s output %s\n",
@@ -4278,7 +4298,7 @@ void sna_mode_discover(struct sna *sna)
 			sna_output_del(output);
 			i--;
 		} else {
-			to_sna_output(output)->id = 0;
+			sna_output->id = 0;
 			output->crtc = NULL;
 		}
 		changed |= 2;


More information about the xorg-commit mailing list