Re: [PATCH] xf86SetDesiredModes enhancements

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

 



On Monday, March 17, 2008 12:11 pm Keith Packard wrote:
> On Mon, 2008-03-17 at 11:17 -0700, Jesse Barnes wrote:
> > So the server part of this patchset adds a new callback, ->get_crtc, to
> > the xf86OutputFuncs structure.  The new xf86GetCurrentConfig routine uses
> > this callback to build an accurate picture of which CRTCs are mapped to
> > which outputs (or NULL if the output is currently disabled) and which
> > outputs are currently active.  The call to xf86GetCurrentConfig replaces
> > the output & CRTC DPMS off calls, which eliminates one set of flicker
> > from the startup & VT switch code paths.
>
> This won't work -- you're assuming that the crtcs that the desired
> initial configuration will match the crtc/output mapping present in the
> hardware before the X server starts.
>
> The underlying assumption that the driver makes is that all mode setting
> operations affect only the target crtc and outputs. However, if any of
> those outputs are currently being driven by another crtc, the output
> must be taken away from that crtc (and that other crtc turned off)
> before the output can be assigned to new crtc. If you fail to observe
> this protocol, you will lock up machines.

Yeah, I got mixed up between how output->crtc was used.  
xf86InitialConfiguration sets it to what the CRTC mapping *will* be, but 
other code made me think it was using it purely as a "current configuration" 
type variable.

> So, what you want to do in xf86SetDesiredModes is just turn off all
> outputs and crtcs which are not hooked up the way the server will set
> them up. For outputs, I think that's fairly straightforward; just
> DPMSModeOff whenever the output->crtc != output->funcs->get_crtc
> (output). For crtcs, you want to turn them off if no output is going to
> use them, or if the set of outputs using a crtc changes.

Something like the attached patch?

> The goal here should be to eliminate flashing when you're not switching
> the output/crtc configuration, and to make sure things work reliably
> when you are. We might be able to reduce flashing when you are switching
> configuration around, but that's not supposed to happen very often,
> especially once we have kernel mode setting that sets the desired mode
> when the system is booted.

Right, once this is working right I'll need to port it to the kernel along 
with some other flicker reduction stuff there.

Thanks,
Jesse
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 6b845b7..a4f9d18 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2034,6 +2034,56 @@ 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 (output->crtc != (*output->funcs->get_crtc)(output))
+#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 ((*output->funcs->get_crtc)(output) == crtc)
+		current_outputs |= (1<<o);
+	}
+
+	/* If mappings are different, we need to disable it */
+	if (desired_outputs != current_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 +2092,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