We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1611

Summary: Refresh rate not restored properly when going out of fullscreen
Product: SDL Reporter: Sik <sik.the.hedgehog>
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED ABANDONED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: gabomdq
Version: HG 2.0   
Hardware: x86_64   
OS: Linux   

Description Sik 2012-09-28 02:53:52 UTC
When bug #1571 was fixed a new bug was introduced: when the resolution is restored when going out of fullscreen, the refresh rate is not restored properly. In my case, the desktop video mode is 1024×768 at 85Hz before going into fullscreen (set with "auto" in the nvidia preferences dialog), but when going out of fullscreen with SDL I end up with 1024×768 at 60Hz instead.

SDL 2.0.0-6488
Ubuntu 11.04 x86-64
Proprietary nvidia drivers (270.41.06)
GeForce 7300 GS

The program in question jumps into 640×480 when going fullscreen, if this matters. Refresh rate is not set explicitly.
Comment 1 Sam Lantinga 2012-09-29 00:43:05 UTC
Is the resolution switching being done by XRandR or XVidMode?  You can turn on debug output by uncommenting the following line in SDL_x11modes.c:
/*#define X11MODES_DEBUG*/

There are environment variables to control which is being used, if you need them for testing.
Comment 2 Sik 2012-09-29 01:46:59 UTC
Oh wow, this is more broken than I thought.

OK, did that. Xinerama and Xrandr are in use, and Xrandr is telling SDL that my current refresh rate is 50Hz, which not only is wrong, that refresh rate isn't even allowed by the driver (!!). So apparently it's the buggy Xrandr support. My video hardware is too old to use newer drivers it seems (GeForce 7300 GS) so I'm stuck with the buggy Xrandr. Tough luck.

I tried disabling Xrandr through the environment variable, and for some reason SDL kept ignoring me. I assumed I was doing something wrong (first time I mess with environment variables for a single program) so I proceeded to do it right from inside the program itself (with SDL_SetHintWithPriority), and... well, the system froze with a black screen. Not even Alt+SysRq+B was working, to give you an idea of how badly it froze. Looks like disabling Xrandr is a bad idea after all!

I suppose there isn't much else to do other than detect the buggy Xrandr and avoid changing the refresh rate automatically if this is the case (the user explicitly setting the refresh rate should still be safe, I think). Luckily it's easy to detect, because the refresh rates it returns for every resolution simply don't make sense at all (see below to get an idea of the pattern).

Running the program with X11MODES_DEBUG uncommented makes SDL output this:

Xinerama available!
XRandR available!
XRANDR: XRRQueryVersion: V1.3
XRANDR: mode =    0[0], w = 1024, h =  768, rate =   50
XRANDR: mode =    0[1], w = 1024, h =  768, rate =   51
XRANDR: mode =    0[2], w = 1024, h =  768, rate =   52
XRANDR: mode =    0[3], w = 1024, h =  768, rate =   53
XRANDR: mode =    0[4], w = 1024, h =  768, rate =   54
XRANDR: mode =    1[0], w =  960, h =  540, rate =   55
XRANDR: mode =    2[0], w =  960, h =  529, rate =   56
XRANDR: mode =    3[0], w =  840, h =  525, rate =   57
XRANDR: mode =    3[1], w =  840, h =  525, rate =   58
XRANDR: mode =    4[0], w =  832, h =  624, rate =   59
XRANDR: mode =    5[0], w =  800, h =  600, rate =   60
XRANDR: mode =    5[1], w =  800, h =  600, rate =   61
XRANDR: mode =    5[2], w =  800, h =  600, rate =   62
XRANDR: mode =    5[3], w =  800, h =  600, rate =   63
XRANDR: mode =    5[4], w =  800, h =  600, rate =   64
XRANDR: mode =    5[5], w =  800, h =  600, rate =   65
XRANDR: mode =    6[0], w =  800, h =  512, rate =   66
XRANDR: mode =    7[0], w =  720, h =  450, rate =   67
XRANDR: mode =    8[0], w =  720, h =  405, rate =   68
XRANDR: mode =    9[0], w =  720, h =  400, rate =   69
XRANDR: mode =   10[0], w =  680, h =  384, rate =   70
XRANDR: mode =   10[1], w =  680, h =  384, rate =   71
XRANDR: mode =   11[0], w =  640, h =  512, rate =   72
XRANDR: mode =   12[0], w =  640, h =  480, rate =   73
XRANDR: mode =   12[1], w =  640, h =  480, rate =   74
XRANDR: mode =   12[2], w =  640, h =  480, rate =   75
XRANDR: mode =   12[3], w =  640, h =  480, rate =   76
XRANDR: mode =   12[4], w =  640, h =  480, rate =   77
XRANDR: mode =   12[5], w =  640, h =  480, rate =   78
XRANDR: mode =   12[6], w =  640, h =  480, rate =   79
XRANDR: mode =   13[0], w =  640, h =  400, rate =   80
XRANDR: mode =   14[0], w =  640, h =  350, rate =   81
XRANDR: mode =   15[0], w =  576, h =  432, rate =   82
XRANDR: mode =   15[1], w =  576, h =  432, rate =   83
XRANDR: mode =   15[2], w =  576, h =  432, rate =   84
XRANDR: mode =   15[3], w =  576, h =  432, rate =   85
XRANDR: mode =   16[0], w =  512, h =  384, rate =   86
XRANDR: mode =   16[1], w =  512, h =  384, rate =   87
XRANDR: mode =   16[2], w =  512, h =  384, rate =   88
XRANDR: mode =   16[3], w =  512, h =  384, rate =   89
XRANDR: mode =   16[4], w =  512, h =  384, rate =   90
XRANDR: mode =   17[0], w =  416, h =  312, rate =   91
XRANDR: mode =   18[0], w =  400, h =  300, rate =   92
XRANDR: mode =   18[1], w =  400, h =  300, rate =   93
XRANDR: mode =   18[2], w =  400, h =  300, rate =   94
XRANDR: mode =   18[3], w =  400, h =  300, rate =   95
XRANDR: mode =   18[4], w =  400, h =  300, rate =   96
XRANDR: mode =   19[0], w =  360, h =  200, rate =   97
XRANDR: mode =   20[0], w =  320, h =  240, rate =   98
XRANDR: mode =   20[1], w =  320, h =  240, rate =   99
XRANDR: mode =   20[2], w =  320, h =  240, rate =  100
XRANDR: mode =   20[3], w =  320, h =  240, rate =  101
XRANDR: mode =   21[0], w =  320, h =  200, rate =  102
XRANDR: mode =   22[0], w =  320, h =  175, rate =  103
Xinerama is enabled
XRandR is enabled
XRANDR: get_real_resolution: w = 1024, h = 768, rate = 50
XRANDR: set_best_resolution(): w = 640, h = 480
XRANDR: get_real_resolution: w = 640, h = 480, rate = 50
XRANDR: set_best_resolution(): w = 1024, h = 768
XRANDR: get_real_resolution: w = 1024, h = 768, rate = 50
XRANDR: set_best_resolution(): w = 640, h = 480
XRANDR: get_real_resolution: w = 640, h = 480, rate = 50
XRANDR: set_best_resolution(): w = 1024, h = 768

Obviously I can't put here what's output with Xrandr disabled since the system outright crashes and requires me to reset it.
Comment 3 Sik 2012-09-30 20:24:05 UTC
Quick comment, about what I said before:
"the user explicitly setting the refresh rate should still be safe, I think"

Actually, if the user could set the refresh rate it would be impossible to return to the old one, so it's probably not a good idea to allow it. That is, unless it's possible to retrieve the current refresh rate using something other than Xrandr.

PS: I should set the status as "responded"? (forgot to do it last time) Sorry, I'm relatively new to bug reporting systems ^_^;
Comment 4 Sam Lantinga 2012-10-01 01:17:11 UTC
When XRandR is disabled, is it using XVidTune?  That's the only thing that I can think of that would hard-lock your screen.

Try disabling all of these, and then try enabling each one to see what happens:
export SDL_VIDEO_X11_XINERAMA=0
export SDL_VIDEO_X11_XVIDMODE=0
export SDL_VIDEO_X11_XRANDR=0
export SDL_VIDEO_X11_LEGACY_FULLSCREEN=0

Also make sure you're running from the latest snapshot, since there have been some fixes to this code in the last few days.

Thanks!
Comment 5 Sik 2012-10-01 02:24:35 UTC
Yeah, I had just built the latest snapshot in fact :P Checking now. In each of the following cases only one variable was set to 1 and the rest were set to 0.

---

All variables set to 0:

Works. Video mode is not changed, so it's actually running at 1024×768, not the requested video mode. Personally I'd prefer SDL to fail to create the window if it can't meet the requested requirements, but that's a separate issue.

---

SDL_VIDEO_X11_XINERAMA=1:

Same as above. Seems like Xinerama has no effect on this. This is a single monitor setup anyway, so maybe it isn't even getting in the way.

---

SDL_VIDEO_X11_XVIDMODE=1:

Huh... I've heard about overscan, but this is just plain ridiculous. Just... look at the pic linked below and you'll understand o_O;

http://sik.mdscene.net/.junk/P011012_05.jpg

The resolutions reported are the same as for Xrandr, but with the proper refresh rate values (mostly...), so I suppose this can be used to make up for the Xrandr bug. For some reason 640×480 reports 59Hz instead of 60Hz, I assume the massive overscan is related to that...

The terminal outputs this:

Xinerama disabled due to hint
XRandR disabled due to hint
XVidMode available!
VidMode modes: (unsorted)
Mode 0: 1024 x 768 @ 84
Mode 1: 1024 x 768 @ 43
Mode 2: 1024 x 768 @ 75
Mode 3: 1024 x 768 @ 70
Mode 4: 1024 x 768 @ 60
Mode 5: 960 x 540 @ 119
Mode 6: 960 x 529 @ 75
Mode 7: 840 x 525 @ 120
Mode 8: 840 x 525 @ 119
Mode 9: 832 x 624 @ 74
Mode 10: 800 x 600 @ 85
Mode 11: 800 x 600 @ 85
Mode 12: 800 x 600 @ 75
Mode 13: 800 x 600 @ 72
Mode 14: 800 x 600 @ 60
Mode 15: 800 x 600 @ 56
Mode 16: 800 x 512 @ 120
Mode 17: 720 x 450 @ 119
Mode 18: 720 x 405 @ 84
Mode 19: 720 x 400 @ 85
Mode 20: 680 x 384 @ 119
Mode 21: 680 x 384 @ 119
Mode 22: 640 x 512 @ 120
Mode 23: 640 x 480 @ 120
Mode 24: 640 x 480 @ 85
Mode 25: 640 x 480 @ 75
Mode 26: 640 x 480 @ 72
Mode 27: 640 x 480 @ 72
Mode 28: 640 x 480 @ 59
Mode 29: 640 x 480 @ 59
Mode 30: 640 x 400 @ 85
Mode 31: 640 x 350 @ 85
Mode 32: 576 x 432 @ 150
Mode 33: 576 x 432 @ 149
Mode 34: 576 x 432 @ 140
Mode 35: 576 x 432 @ 120
Mode 36: 512 x 384 @ 169
Mode 37: 512 x 384 @ 87
Mode 38: 512 x 384 @ 150
Mode 39: 512 x 384 @ 140
Mode 40: 512 x 384 @ 120
Mode 41: 416 x 312 @ 149
Mode 42: 400 x 300 @ 170
Mode 43: 400 x 300 @ 150
Mode 44: 400 x 300 @ 144
Mode 45: 400 x 300 @ 120
Mode 46: 400 x 300 @ 112
Mode 47: 360 x 200 @ 170
Mode 48: 320 x 240 @ 170
Mode 49: 320 x 240 @ 150
Mode 50: 320 x 240 @ 145
Mode 51: 320 x 240 @ 120
Mode 52: 320 x 200 @ 170
Mode 53: 320 x 175 @ 170
VidMode is enabled
Best Mode 28: 640 x 480 @ 59
Best Mode 0: 1024 x 768 @ 84
Best Mode 28: 640 x 480 @ 59
Best Mode 0: 1024 x 768 @ 84

---

SDL_VIDEO_X11_XRANDR=1:

This is exactly the same result I had reported before, so I won't bother explaining this again. It's comment #2 in this bug.

---

SDL_VIDEO_X11_LEGACY_FULLSCREEN=1:

Hey, guess which one hangs my system :P

In the first attempt I had tried this first before anything else, assuming it'd be the safest... I was wrong. The screen went completely black and the system hung up, just as had happened before. Had to reset the system.

In the second attempt I had tried all the other stuff before, then this. The game booted, and it seemed like it'd work as when everything was disabled. Then when the game quit it was stuck at a black screen. Alt+tabbing first switched to one program, but the GUI shell was dead. Alt+tabbing back to the game and then trying to alt+tab again would result in the screen getting stuck in black again, cursor aside. Was forced to reset again.

It seems like the massively broken one is this mode.

---

This is the full list of *real* resolutions (yes, I have some weird resolutions here):

1600×1200 60Hz
1440×900 60Hz
1360×768 60Hz
1280×1024 60Hz
1280×960 60Hz
1152×864 75Hz
1152×864 70Hz
1152×864 60Hz
1024×768 87Hz (interlace)
1024×768 85Hz
1024×768 75Hz
1024×768 70Hz
1024×768 60Hz
960×540 60Hz (double scan)
960×529 75Hz
840×525 60Hz (double scan)
832×624 75Hz
800×600 85Hz
800×600 75Hz
800×600 72Hz
800×600 60Hz
800×600 56Hz
800×512 60Hz (double scan)
720×450 60Hz (double scan)
720×405 85Hz
720×400 85Hz
680×384 60Hz (double scan)
640×512 60Hz (double scan)
640×480 60Hz (double scan)
640×480 80Hz
640×480 75Hz
640×480 73Hz
640×400 85Hz
640×350 85Hz
576×432 75Hz (double scan)
576×432 70Hz (double scan)
576×432 60Hz (double scan)
512×384 87Hz (double scan, interlace)
512×384 85Hz (double scan)
512×384 75Hz (double scan)
512×384 70Hz (double scan)
512×384 60Hz (double scan)
416×312 75Hz (double scan)
400×300 85Hz (double scan)
400×300 75Hz (double scan)
400×300 72Hz (double scan)
400×300 60Hz (double scan)
400×300 56Hz (double scan)
360×200 85Hz (double scan)
320×240 85Hz (double scan)
320×240 75Hz (double scan)
320×240 73Hz (double scan)
320×240 60Hz (double scan)
320×200 85Hz (double scan)
320×175 85Hz (double scan)

---

Sorry for the huge report but I think I better provide as much information as possible early on ^_^'
Comment 6 Sik 2012-10-01 02:53:23 UTC
Addenum: looking carefully at that image again, it seems like the pixels are not even-sized... which most likely means it isn't being rendered like it's 640×480. Maybe the video mode is OK, but SDL still treats it like it's 1024×768? Because that's exactly the kind of deformation I get in the cases when the game is forced to run in 1024×768.
Comment 7 Gabriel Jacobo 2012-10-04 07:51:04 UTC
A sidenote, from personal experience, the Xrandr support on nVidia binary blobs before the 302.xx versions is quite bad, there may be something related to the fact that you are using the 270.xx version.
Comment 8 Sik 2012-10-04 09:50:11 UTC
(In reply to comment #7)
> A sidenote, from personal experience, the Xrandr support on nVidia binary blobs
> before the 302.xx versions is quite bad, there may be something related to the
> fact that you are using the 270.xx version.

I'm 100% sure it's the broken Xrandr (see comment #2). This is one of those things where we should say "upgrade the drivers", but the problem is that only new cards support drivers that have the bug fixed, so this would be more along the lines of "buy new hardware" (which is not always an option). So maybe SDL should include a workaround for this.

One thing I noticed: I have installed DOSBox 0.84 from the Ubuntu repositories. DOSBox uses SDL 1.2 if I recall correctly. It can switch video modes just fine, including restoring the proper refresh rate. Does anybody know what changed since 1.2 that could have broken this?
Comment 9 Sam Lantinga 2012-10-04 20:49:46 UTC
Okay, I think I fixed this in the latest snapshot:
http://www.libsdl.org/tmp/SDL-2.0.zip

Please let me know how it looks! :)
Comment 10 Sik 2012-10-05 01:39:47 UTC
OK, tried it. The upside is that the video mode is restored properly now, refresh rate included :P There are two problems though.

The first problem is that the bottom of the screen is chopped off when going fullscreen. I moved the scan area and I can confirm it's indeed chopped instead of being the CRT limit. In fact, the cursor can cover all the visible area, but can't go off-screen, implying it's indeed using that chopped resolution. I have X11MODES_DEBUG enabled but it doesn't tell me to what resolution it switched :( Going to take a wild guess and say it's probably 640×400 (as opposed to 640×480), judging by how much got trimmed.

The second problem is when I quit the program. For some reason the window stays in place as a black rectangle and the program hangs. The only way to get out of that is to use 'xkill -frame' on it (at least I don't have to reboot, so I can check the terminal output).

I noticed XRandR is disabled and it's using XVidMode. That's the one that gave me the oversized image in the previous attempt, so I guess it's an improvement in that sense (though still broken). The black window leftover bug is new though.

Also just saw the XRandR comment after X11MODES_DEBUG. LOL
Comment 11 Ryan C. Gordon 2018-08-06 21:20:20 UTC
Hello, and sorry if you're getting dozens of copies of this message by email.

We are closing out bugs that appear to be abandoned in some form. This can happen for lots of reasons: we couldn't reproduce it, conversation faded out, the bug was noted as fixed in a comment but we forgot to mark it resolved, the report is good but the fix is impractical, we fixed it a long time ago without realizing there was an associated report, etc.

Individually, any of these bugs might have a better resolution (such as WONTFIX or WORKSFORME or INVALID) but we've added a new resolution of ABANDONED to make this easily searchable and make it clear that it's not necessarily unreasonable to revive a given bug report.

So if this bug is still a going concern and you feel it should still be open: please feel free to reopen it! But unless you respond, we'd like to consider these bugs closed, as many of them are several years old and overwhelming our ability to prioritize recent issues.

(please note that hundred of bug reports were sorted through here, so we apologize for any human error. Just reopen the bug in that case!)

Thanks,
--ryan.