Re: [PATCH] xf86SetDesiredModes enhancements

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Monday, March 17, 2008 1:15 pm Keith Packard wrote:
> On Mon, 2008-03-17 at 12:36 -0700, Jesse Barnes wrote:
> > Something like the attached patch?
>
> Yeah, that looks good.
>
> I'd add calls to DPMSOff outputs and crtcs which are currently unused as
> well; it's possible that they'll be left semi-running and set us up for
> failure if they are.

Ok, hopefully this one is complete enough to push.  I added some logic for the 
unused outputs & crtcs stuff like you said and also a check for the 
new ->get_crtc callback.  If it's not there, we fall back to the old "just 
disable it" behavior.

Jesse
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 6b845b7..536b530 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2034,6 +2034,72 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
 }
 
 /*
+ * Check the CRTC we're going to map each output to vs. it's current
+ * CRTC.  If they don't match, we have to disable the output and the CRTC
+ * since the driver will have to re-route things.
+ */
+static void
+xf86PrepareOutputs (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o;
+
+    for (o = 0; o < config->num_output; o++) {
+	xf86OutputPtr output = config->output[o];
+#if RANDR_GET_CRTC_INTERFACE
+	/* If we can't get the current CRTC, play it safe */
+	if (!output->funcs->get_crtc) {
+	    (*output->funcs->dpms)(output, DPMSModeOff);
+	    continue;
+	}
+	/* Disable outputs that are unused or will be re-routed */
+	if (output->crtc != (*output->funcs->get_crtc)(output) ||
+	    output->crtc == NULL)
+#endif
+	    (*output->funcs->dpms)(output, DPMSModeOff);
+    }
+}
+
+static void
+xf86PrepareCrtcs (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    for (c = 0; c < config->num_crtc; c++) {
+#if RANDR_GET_CRTC_INTERFACE
+	xf86CrtcPtr	crtc = config->crtc[c];
+	xf86OutputPtr	output = NULL;
+	uint32_t	desired_outputs = 0, current_outputs = 0;
+	int		o;
+
+	for (o = 0; o < config->num_output; o++) {
+	    output = config->output[o];
+	    if (output->crtc == crtc)
+		desired_outputs |= (1<<o);
+	    /* If we can't tell where it's mapped, force it off */
+	    if (!output->funcs->get_crtc) {
+		desired_outputs = 0;
+		break;
+	    }
+	    if ((*output->funcs->get_crtc)(output) == crtc)
+		current_outputs |= (1<<o);
+	}
+
+	/*
+	 * If mappings are different or the CRTC is unused,
+	 * we need to disable it
+	 */
+	if (desired_outputs != current_outputs ||
+	    !desired_outputs)
+	    (*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#else
+	(*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#endif
+    }
+}
+
+/*
  * Using the desired mode information in each crtc, set
  * modes (used in EnterVT functions, or at server startup)
  */
@@ -2042,26 +2108,11 @@ _X_EXPORT Bool
 xf86SetDesiredModes (ScrnInfoPtr scrn)
 {
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			c, o;
-
-    /*
-     * Turn off everything so mode setting is done
-     * with hardware in a consistent state
-     */
-    for (o = 0; o < config->num_output; o++) 
-    {
-	xf86OutputPtr  output = config->output[o];
-	(*output->funcs->dpms)(output, DPMSModeOff);
-    }
+    int			c;
 
-    for (c = 0; c < config->num_crtc; c++) 
-    {
-	xf86CrtcPtr crtc = config->crtc[c];
+    xf86PrepareOutputs(scrn);
+    xf86PrepareCrtcs(scrn);
 
-	crtc->funcs->dpms(crtc, DPMSModeOff);
-	memset(&crtc->mode, 0, sizeof(crtc->mode));
-    }
-    
     for (c = 0; c < config->num_crtc; c++)
     {
 	xf86CrtcPtr	crtc = config->crtc[c];
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index a542e7f..2d723a5 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -425,6 +425,13 @@ typedef struct _xf86OutputFuncs {
     (*get_property)(xf86OutputPtr output,
 		    Atom property);
 #endif
+#ifdef RANDR_GET_CRTC_INTERFACE
+    /**
+     * Callback to get current CRTC for a given output
+     */
+    xf86CrtcPtr
+    (*get_crtc)(xf86OutputPtr output);
+#endif
     /**
      * Clean up driver-specific bits of the output
      */
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 4d7c9cc..62d4bbf 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -55,6 +55,7 @@
 #define RANDR_10_INTERFACE 1
 #define RANDR_12_INTERFACE 1
 #define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
+#define RANDR_GET_CRTC_INTERFACE 1
 
 #define RANDR_INTERFACE_VERSION 0x0103
 
_______________________________________________
xorg mailing list
xorg@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/xorg

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [X Forum]     [Intel Graphics]     [AMD Graphics]     [Nouveau Driver]     [XFree86]     [XFree86 Newbie]     [IETF Annouce]     [Security]     [Fontconfig]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Video for Linux]     [Linux RAID]

  Powered by Linux