SDL: write access violation with OSD when updating screen
|Reported by:||criezy||Owned by:||bgK|
The issue was introduced with the recent changes related to OSD in SurfaceSdlGraphicsManager. Now when displaying OSD messages or icons dirty rects with coordinates in destination screen are created, but the issue is that dirty rects are assumed to be in source screen coordinates. So when using a 2X or 3X scaler we can get dirty rects that are outside of the screen. There is a sanity check on Y, but not on X, so in some cases we end up trying to write beyond the destination screen when applying the scaler.
Adding a sanity check on X would fix the crash, but this is not a proper fix and updates would be missing.
Here is the relevant part for the call stack of the crash:
0 Normal2x(unsigned char const*, unsigned int, unsigned char*, unsigned int, int, int) + 216 (scaler.cpp:218) 1 SurfaceSdlGraphicsManager::internUpdateScreen() + 1463 (surfacesdl-graphics.cpp:1130) 2 SurfaceSdlGraphicsManager::updateScreen() + 145 (surfacesdl-graphics.cpp:1006) 3 ModularBackend::updateScreen() + 50 (modular-backend.cpp:152)
I consider this a blocker because it for example causes a random crash when using a 2X or 3X scaler and switching between windowed and full screen mode as we get a OSD message and it triggers the bug.
With a 2X scaler when playing a 320x200 game, the OSD message when leaving full screen generates a dirty rect starting at 274x185 en ending at 366x214. The 214 gets clips to 200 because of the sanity check, but it still writes beyond the end of the screen surface because of the x=366 for the right border. The dirty rect should in this case have been 137x92->183x107.