xrandr doesn't unclone CRTCs...

Matthias Hopf mhopf at suse.de
Thu Nov 8 03:28:22 PST 2007

While implementing RandR 1.2 support for the randeonhd driver I stumbled
upon the following:

Two monitors, one 1024x768 CRT on output A, one 1280x1024 LVDS on output B.
The driver allows any output/crtc combinations, and any clone
combinations. If I disallow clones, everything works fine.

Initial:        A: 1024x768 on CRTC 1   B: 1280x1024 on CRTC 0
Disabling A:    xrandr --output A --off
                A: off                  B: 1280x1024 on CRTC 0
Re-enabling A:  xrandr --output A --auto
                A: 1024x768 on CRTC 0   B: 1024x768 on CRTC 0  <- WTF?
Asking for available modes: xrandr
                A: up to 1024x768 (active)
		B: up to 1280x768 (1024x768 active)
Setting 1280:   xrandr --output B --mode 1280x1024
X Error of failed request:  BadMatch (invalid parameter attributes)

Ok, I debugged this a little further, and it turned out that the xrandr
application is the culprit.

When selecting a crtc for an output, it doesn't check for already
attached outputs in check_crtc_for_output(), and so may select an crtc
that is already in use.
In this case during Re-enabling A it selects the CRTC the LVDS display
is already using for the CRT. Thus the mode of the CRTC is set to
1024x768, with the side effect of switching the LVDS as well.

Also, when trying to set 1280x1024 on output B after a cloned setup has
been used, it would have to un-clone the CRTC, and set up a second CRTC
for the new mode that is different to output B.
So "xrandr --output B --crtc 1 --auto" actually worked.
This is due to pick_crtcs() not verifying already attached crtcs.

The attached patch fixes these problems for me, but xrandr turned out to
be pretty sophisticated, and as any change can have subtle side effects
I'd like to have this verified before I apply it.

One thing I found a bit awkward about the data structures in xrandr is
that crtc_info is mostly used for storing XRRCrtcInfo struct pointers
for the previous configuration - except for in output_t, where it is
used for storing a pointer to crtc_t...  Thus the pretty strange looking
'output->crtc_info->crtc_info->noutput' in pick_crtcs().

xrandr still doesn't prefer cloned modes (if crtc 1 is active for a
single screen, and a second screen with the same mode is to be used,
crtc 0 is activated as well instead of cloning crtc 1. However, this
does work if crtc 0 had been active in the first place), but otherwise
it seems to work well for me.


Matthias Hopf <mhopf at suse.de>      __        __   __
Maxfeldstr. 5 / 90409 Nuernberg   (_   | |  (_   |__          mat at mshopf.de
Phone +49-911-74053-715           __)  |_|  __)  |__  R & D   www.mshopf.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: xrandr_fix_crtc_switching.diff
Type: text/x-patch
Size: 1410 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg/attachments/20071108/4632d61c/attachment.bin>

More information about the xorg mailing list