over 5 years ago - [DE]Glen - Direct link

Update 25 included a number of invisible fixes and changes for how we handle fullscreen. In fact much of that work had nothing to do with fullscreen at all and was for something far more difficult, something that we weren’t ready to release, and something that has caused players problems for quite a while. We like to say “no good deed goes unpunished” to refer to problems uncovered while fixing or improving a feature of the game and this is a story of one such deed.

To understand this mess you need to have some background. In recent years computer displays have been getting better in a lot of ways: better color accuracy, faster response times, and most importantly: more pixels. There seems to have been some sort of arms race in laptop manufacturers in recent years where we’d see higher and higher resolution on tiny display panels -- it’s not unusual to see a 4K display on a 15-inch laptop with only an entry level mobile graphics chip to support it.

The first problem with high-resolution displays (also known as high-DPI) is that text can be too small to read at their native resolution. The solution for many years has been simple: you can tell Windows to scale apps up. Some apps are built with awareness of this scaling and instead of a simple “stretch” of the pixels they draw their text at your native resolution with a larger font; when apps do this it looks gorgeous -- I find reading on a 4K display much easier on my eyes.

The second problem with high-resolution displays is obviously games and here is where our story gets tricky. It turns out that Windows handles games in a very complicated way that tries very hard to do what’s best but ends up stuck between a rock and a hard-place. Let me first tell you about the rock. 

What’s the difference between 1080p (1920x1080 pixels) and 4K (3840x2160 pixels)? Apart from the fact that they changed from naming the mode after the screen height to width you can see here that they basically just doubled the resolution. So if you change your Desktop from 1080p to 4K and you want your apps to be the same size on your screen you just set your app scaling to 200% and everything looks great.

The problem is games need a lot of power from your graphics card: for many things you pay “by the pixel” -- more pixels take more time -- and if you double your resolution you actually quadruple the number of pixels you need to fill! Instead of 2 million pixels at 1080p you have over 8 million pixels to fill at 4K! You need a powerful graphics card to run at 4K resolution and this is why you probably don’t want to run Warframe on your 4K business laptop at native resolution!

Remember how I said that Windows will scale up your apps for you? It turns out that for games, this isn’t always true. Get ready: this is going to blow your mind!

If you only ever run a DPI-agnostic game in a Windowed or Borderless Fullscreen modes Windows will automatically scale it up. Your 720p game will be 1440p on your desktop and Windows will even do a nice sharpening filter on the up-scale so it looks nicer. This is the default and it’s making the best of a bad situation: it looks great, it doesn’t have to render 4 times the pixels, and it’s the ideal mode for a 4K laptop without a discrete graphics card.

Once you toggle to native fullscreen once -- just once -- everything changes. To go native fullscreen, Windows has to make the game aware of the true resolution of the monitor; if all you ever play is fullscreen this is fine -- you’ll never even notice -- but if you go back to Windowed you’re in trouble because now you’re playing at native resolution: your window will be much smaller than when you started. 

It turns out that once Windows notices that you went fullscreen once it remembers. It marks a flag in your registry to say “this app might go fullscreen so you’d better treat it as high-DPI aware from the start next time.” No more automatic scaling, no more nice sharpening filter, just a teeny-tiny window. Relaunching won’t fix it. Restarting Windows won’t fix it. Reinstalling Warframe won’t fix it. You’re stuck.

So what did players do? They just made their window bigger: two times bigger, four times the pixels, and then couldn’t understand why Warframe suddenly ran much slower. That’s what started this whole journey: players with 4K displays wondering why their game went from 60 FPS to 15. Since this was an increasingly frequent problem we had to do something, and remember: no good deed goes unpunished.

As we started to investigate what would be required to improve our handling of high-DPI the first thing we noticed was that the fullscreen handling code was full of violent abuse of the graphics driver. Since our handling of windowed and fullscreen resolutions involves a lot of the same code we decided to do some housekeeping first.

Before I tell you more let me pause for a moment to tell you how difficult it is to debug fullscreen games. Everyone hates it because you can’t just run the game in your debugger like you normally would because the display is fullscreen and locks you out of your debugger windows! You can’t look at variables, you can’t step into code, and it’s very frustrating. Once we had fullscreen code working years ago we left it alone: nobody wanted to touch it because if you had to fix it you were in for a world of hurt.

I spent a week with a wimpy 4K laptop tethered to my workstation for remote debugging so I could iron out the kinks in our fullscreen support and implement high-DPI features. Because it had to load all the data over the network it took about 5 minutes to run each test. It was a game of inches -- fixing one bug exposed another bug under it -- and at the end there was still optimization to be done (we made toggling fullscreen faster but with a bit more work it could be twice as fast as it currently is!).

As Update 25 loomed we had high-DPI support working but there hadn’t been enough testing so at the last minute it was shelved until after mainline dust had settled; we shipped all the polish but none of the high-DPI support. To help players stuck in native resolution we added a workaround in the launcher to make Windows forget that you had ever gone fullscreen. Everything should have run just like when you started Warframe using the nice Windows sharpening upscale filter -- fast and smooth -- but remember no good deed goes unpunished. 

We talked about the rock; now let me tell you about the hard place.

One critical mistake was that we assumed that when DirectX went fullscreen and forced the game to become DPI-aware that it would do be able to do this seamlessly. Remember that we wanted to be DPI-agnostic by default so that Windows would do the nice sharpening upscale filter. We only have a few 4K machines to test on and while this appeared to work for us it turns out that for many people this caused all kinds of problems.
 
If you look through the MSDN documentation for high-DPI support you’ll find time and again it advised against what we were doing: it said that becoming DPI-aware at runtime can lead to unexpected application behavior. We hoped that we could get away with it and have it run fast and look good in all cases but this didn’t go as planned: we started getting reports of the mouse being trapped in the upper left quadrant of the window, windows being scaled off the edge of the screen, and other strange issues.

The other problem is that some players weren’t aware of this scaling and had probably gone to native fullscreen once at some point in the past which had made Windows disable it. They had adjusted their settings for their native resolution and when we restored the default scaling their windows became bigger. Savvy players would ask why their borderless fullscreen wasn’t running at their native panel resolution (not noticing that their frame-rate had improved!)

Another problem we found was that if the game pretended to be unaware of DPI mode it might let you make scaled windows that wouldn’t fit on your desktop: again in some tests this was fine but we heard problems where players had entered their panel’s native resolution as a windowed mode not knowing that Windows was going to scale that up by 200% and they ended up with a window so big that it didn’t fit on their screen and they couldn’t see the UI to undo their change.

We worked late into the night after we deployed Update 25 trying to find a compromise. We experimented with high-DPI support we had worked on earlier to see if we could support both modes. Eventually we abandoned all hope of using the native Windows scaling -- you can’t “play dumb” if you ever need to change your mind later -- this seems to explain why Windows insists on marking your game as high-DPI aware forever if you ever go fullscreen. 

So there’s our rock and a hard-place: some people want high-DPI scaling because they have a fantastic monitor but a weak discrete or even integrated graphics processor, some people want native resolution because they have a graphics card that can handle it. Some people (like me) want the native OS scaling because it’s sharper but we can’t safely switch it off on the fly without inviting “unexpected application behavior.” 

Coming soon in hotfix 25.0.2 is the high-DPI support we had worked on before the update. We had hoped to integrate it with some other things (UI or HUD scaling etc) and possibly experiment with using our internal mixed-resolution rendering so that your UI would be crisp but the game would still run fast but there isn’t time -- we need to fix this ASAP.

In your Display Settings there is a new “Window Scaling Mode” option; if you have Windows App Scaling at 100% it won’t make any difference but if you have a high-DPI scale set you can choose between having it scale up the window (speed!) or render at native resolution (quality!). If you were running at 4K before and are confused by everything getting big just set it to Native and hopefully it’ll be just like it was before.

The display settings screen could be better -- it’s a bit confusing when you’ve enable scaled mode because it shows you the resolution before scaling not after (it’s been this way for so long that changing this now would likely cause an equal amount of confusion).

Other known-issues that we weren’t able to solve before shipping: 

  • If you change your Windows App Scale on the fly the game does not respond well to this (especially if you were fullscreen)
  • If you drag Warframe from to a monitor with a different DPI scale the game will not update the window size (I’m not sure if we need to fix this?)
  • In scaled mode you can make comically giant windows if you have multiple monitors

If there are other issues after hotfix 25.0.2 please let us know in the comments below -- we’re not done working on this and there are sure to be other fun idiosyncrasies to figure out. No good deed goes unpunished. 

Edited by [DE]Glen