Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alt+Tab on FullScreen Direct3D game hangs on 3.6.0.X #1287

Closed
ericoporto opened this issue May 22, 2021 · 54 comments
Closed

Alt+Tab on FullScreen Direct3D game hangs on 3.6.0.X #1287

ericoporto opened this issue May 22, 2021 · 54 comments
Assignees
Labels
context: graphics mode res: needs testing issue needs (re)testing to update its status type: bug unexpected/erroneous behavior in the existing functionality

Comments

@ericoporto
Copy link
Member

Describe the bug
This bug has been reported on the forums as crashing here: https://www.adventuregamestudio.co.uk/forums/index.php?topic=58976.msg636635407#msg636635407

I actually don't have a crash on my Windows 10 PC, instead when I alt+tab a fullscreen Direct3D game, it just hangs with the window staying in the background, but I can't alt+tab back to it and the only way to close it is by killing using the task manager

AGS Version
Built directly from the master branch https://github.com/adventuregamestudio/ags/tree/3d0353e36ef55b14fffe3f7515d74adf095415a1

Game
Here's an example game, but it happens with any on this engine build (3.6.0.4 release happens too) game.zip

To Reproduce

  • Make sure the Direct3D is in use (check with Ctrl+V). If not, set using winsetup.
  • make sure the game is fullscreen (Alt+Enter if needed)
  • then, alt+tab
  • the game will hang in the background, you can't alt+tab back to it's window

Expected behavior
It's expected to alt+tab to any other window on the desktop and alt+tab back

Desktop:

  • OS: Windows
  • Version 10
@ivan-mogilko ivan-mogilko added this to the 3.6.0 (SDL2 Port) milestone May 22, 2021
@ivan-mogilko ivan-mogilko added context: graphics mode type: bug unexpected/erroneous behavior in the existing functionality labels May 22, 2021
@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 22, 2021

I get a different error when running on Windows 7:

Error: Unable to lock texture

This is where it comes from (unfortunately it does not print error code there):
https://github.com/adventuregamestudio/ags/blob/master/Engine/platform/windows/gfx/ali3dd3d.cpp#L1505

Good thing that the problem is reproducible in some way.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 22, 2021

Ah. AGS does not stop running the game and keep redrawing even when window has no focus. Looks like suspending the alt+tabbed game is not working in SDL version yet (I could forget about this).

Maybe Direct3D does not like that in fullscreen mode. But I don't remember how it worked in previous versions when Multitasking mode was on. Might be worth comparing, maybe there was some condition that prevented renderer from working that is now not active.

UPDATE: interesting, testing 3.5.1 it seems that when the game is in multitasking mode Direct3D frozes up when alt+tabbing.

@ericoporto
Copy link
Member Author

AGS does not stop running the game and keep redrawing even when window has no focus

Uhm. AGS has System.HasInputFocus in the script API to be able to detect if the game is focused or not, does this means it should keep running just not drawing?

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 22, 2021

AGS has two modes: multitasking and non-multitasking, they are controlled by SetMultitaskingMode. In multitasking mode engine supposed to run game loops when alt+tabbed, otherwise it should suspend game execution.
(Default is non-multitasking)

I keep forgetting details about allegro version, allegro probably had this as a library feature which AGS relied upon. This is no longer working in SDL version.

Yes, System.HasInputFocus returns current state (switched out / switched in).

As for drawing, I think that this may be dependent on a gfx mode and maybe on renderer too. For example game may loose focus but still be on screen in windowed mode. Or loose focus but be fullscreen on another display (don't remember if it works like that, but probably does?). So this is a complex condition.
In case of Direct3D - it seems it does not like when it is in exclusive (fullscreen) mode, minimized (after alt-tabbing) and getting certain calls.

@ericoporto
Copy link
Member Author

ericoporto commented May 22, 2021

Erh, in the manual page you linked there's the following comment:

Note that mode 1 does not work with some graphics cards in full-screen mode, so you should only rely on it working when your game is run in windowed mode.

This kinda sounds familiar. Maybe the different behavior is due to my graphics card?

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 23, 2021

So, more bad news, apparently the engine no longer suspends upon loosing focus since AGS 3.5.1. It works in 3.5.0.
This is easy to test: make a game from default template, tell character to walk to another side of the screen and alt+tab. Wait 10 seconds and switch back. Normally character should continue from where you switched out.

I believe this broke after the update mechanic was changed from using allegro's timer to the time period calculation + sleep in the engine itself. If my understanding is correct, allegro pauses its timers when told to suspend, but the new mechanic does not handle this at all.

So now this has to be fixed starting from 3.5.1.

But I guess this is a separate issue and task on its own. This ticket refers strictly to Direct3D problem, so should stay dedicated to it. The broken game pause is only a reason why this problem became easier to notice.

@ericoporto
Copy link
Member Author

ericoporto commented May 23, 2021

SDL has a timer of it's own, does using it helps in any way? If it's the thread sleep in Engine/ac/timer.cpp, it would be something like:

SDL_Delay(std::chrono::duration_cast<std::chrono::milliseconds>(frame_time_remaining).count())

Edit: Maybe it's worth opening a new issue for this specific?

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 23, 2021

It's not about having a timer, it's about being able to suspend it anytime. Or, alternatively, keep running in a loop until certain flag is set/removed. SDL is only useful here if it provides utilities, but 3.5.1 does not have SDL anyway. But modern C++ itself probably has everything necessary for this.

Yes of course, this should be a separate issue.

@ivan-mogilko
Copy link
Contributor

I made a pr for the suspension issue (#1292), but unfortunately that won't be enough to fix Direct3D problem in SDL2 version because there's more in it; tried to explain in a comment.

@ericoporto
Copy link
Member Author

ericoporto commented May 23, 2021

The change in #1288 will prevent the crash on Directx, and it's a single line change, maybe consider it until the "real" Fullscreen is supported with it? I understand with both PRs both it will stop crashing and have the multitasking back. Then later the refactor for the extra SDL thread can be done when the full-screen selection type is available.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 23, 2021

Alright. Proper fixing everything will take a while anyway.

In regards to multitask fix, previously I said it wrong, it is not simply "not enough", it actually cannot be applied to sdl2 version at all as it is, because it will halt the update thread endlessly. The events have to be made processed separately from the game update first. So there seem to still be a number of serious issues in this version, and I better get to work on them asap.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented May 24, 2021

I actually managed to adjust a fix for 3.6.0 with a minimal addition (81aa550), for some reason this idea did not come to me yesterday.

That takes care of suspending game updates while there's no input focus, but I suspect that may be not enough for Direct3D fullscreen situation. BTW, allegro engine version had a mysterious "Delay(1000)" when handling this event, now i think that maybe this was made to make sure that game update is halted before hiding the window... just a guess.
If Direct3D still crashes/hangs there has to be an additional rendering prevention if engine detects that window gets minimized. Or something like that.

@ericoporto
Copy link
Member Author

ericoporto commented May 26, 2021

just for a note, with the temporary fix (#1288) now merged I don't have this problem anymore in Win10.

@PaddyMac
Copy link

I am not entirely sure if this is the same issue I have been experiencing, but it certainly sounds the same. using 3.5.1.12 on Linux and using OpenGL, I also experience hanging of AGS when Alt+Tabing away from the game in fullscreen mode. It seems to be fine in windowed mode. Just Alt+Tabing away doesn't always immediately hang AGS, but if I try to start recording the AGS game with OBS, then it definitely hangs. The hard drive light on my PC also turns on and stays on until I force close AGS.

@ericoporto
Copy link
Member Author

@PaddyMac you get this in any game or just a particular one?

@PaddyMac
Copy link

So far, the only game I've tried is The Cat Lady (GoG release). I only know of one other game in my library that I know uses AGS, so I'll give that one a try when I have the opportunity.

@ivan-mogilko ivan-mogilko self-assigned this Jan 13, 2022
@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Jan 13, 2022

I'm back to this problem, but would need to recall the details. IIRC since the multitasking mode has been fixed; and also meanwhile a proper switch was introduced between "real" and "desktop" fullscreen mode (#1428). Need to double check that "real" fullscreen works correctly on Windows now, and then see what can be done to close this bug report.

@PaddyMac

I am not entirely sure if this is the same issue I have been experiencing, but it certainly sounds the same. using 3.5.1.12 on Linux and using OpenGL

The issue reported was experienced with Direct3D exclusive fullscreen mode, for specific reasons. I don't remember anyone mentioning game hanging when using OpenGL before.
Unlike D3D, OpenGL is running always in windowed mode, its "fullscreen" is actually a fake (borderless window covering whole screen). It may or may not have similar problem when the window is switched off and minimized, but I would rather investigate it as a separate problem. Another detail to check is whether the game is scripted to run or pause when switched out (this is called "multitasking mode" in ags).

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Apr 3, 2022

In regards to "multitasking" mode, don't know how i missed this earlier, but i just realized that originally AGS prevented multitasking mode from working in fullscreen at all. This is both mentioned in documentation:

Note that mode 1 does not work with some graphics cards in full-screen mode, so you should only rely on it working when your game is run in windowed mode.

and may be noticed in the code:
https://github.com/adventuregamestudio/ags/blob/release-3.5.1/Engine/ac/global_game.cpp#L807-L809

The silly problem is that this was before engine supported switching between modes at runtime. When introducing the mode switch, i missed this miltitasking restriction, so now it's probably possible to start in windowed mode with multitasking mode on, and then switch to fullscreen, and this mode will be kept.

Tbh I suppose that it may be allowed in fullscreen so long as we may prevent renderer from unnecessary render / failing / hanging the program while switched out, but it definitely should be brought to consistent behavior (either allowed in fs or not).

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Apr 3, 2022

In regards to hanging, another ridiculous thing which i somehow missed is, our engine code potentially puts the render function in an infinite loop here: https://github.com/adventuregamestudio/ags/blob/release-3.5.1/Engine/ac/draw.cpp#L783
(linking to 3.5.1 branch, but i think 3.6.0 has similar code)

It runs Present attempts indefnitely, hoping that it will eventually succeed. While doing so it will probably not poll system events, etc, so hypothetically may lock the rest of the program. This has to be fixed.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Jun 20, 2022

I think the multitasking setting is now corrected, and should not be applied when not supported: 9f09192

Multitasking is not supposed to work in exclusive fullscreen mode, at all, so that question is closed.

However, there's still a problem, that I'm currently looking at: apparently, while switching out from fullscreen, the code execution may get into the endless "try render and present" loop, as there's no condition set when it should not go there or should get out if the game was switched out. As no event polling is done at the same time, the game cannot be restored (as stated in the ticket). So this is a general program logic issue, and has to be fixed.
On another hand, the Direct3D renderer has to be properly reset/restored too upon switching in, because if we just break the "try render" loop, engine will fail at the very next render with "Unable to lock texture" (or similar).
EDIT: in fact it's just failing to reset device all the time, it seems; something wrong is going on there.

@ericoporto
Copy link
Member Author

ericoporto commented Jun 20, 2022

@ivan-mogilko after 9f09192 now the engine hangs for me when alt+tab a fullscreen game when using Direct3D renderer on Windows.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Jun 21, 2022

@ivan-mogilko after 9f09192 now the engine hangs for me when alt+tab a fullscreen game when using Direct3D renderer on Windows.

Did not it hang for you before that? This is what the ticket was about.
Do you test with exclusive fullscreen or borderless window fullscreen?
How does it work if you build an earlier commit?

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Jun 21, 2022

Ah! Eureka, I found why it's not resetting in fullscreen. The call to IDirect3DDevice9::Reset was failing with D3DERR_INVALIDCALL after switching back, and it took me a while of debugging to realize why.

Apparently, when the program is switched out, it's window is reduced a little bit. This makes the engine to receive SDL_WINDOWEVENT_SIZE_CHANGED, and when it does it goes here:

ags/Engine/main/engine.cpp

Lines 1389 to 1394 in e8a1af3

void engine_on_window_changed(const Size &sz)
{
graphics_mode_on_window_changed(sz);
on_coordinates_scaling_changed();
invalidate_screen();
}

and then eventually here:

void D3DGraphicsDriver::UpdateDeviceScreen(const Size &screen_sz)
{
_mode.Width = screen_sz.Width;
_mode.Height = screen_sz.Height;
// TODO: following resets D3D9 device, which may be sub-optimal;
// there seem to be an option to not do this if new window size is smaller
// and SWAPEFFECT_COPY flag is set, in which case (supposedly) we could
// draw using same device parameters, but adjusting viewport accordingly.
d3dpp.BackBufferWidth = _mode.Width;
d3dpp.BackBufferHeight = _mode.Height;
HRESULT hr = ResetD3DDevice();

This was meant to update renderer mode when the window is resized by the user. But in this case it effectively corrupts the fullscreen mode width & height parameters. Because when it tries to Reset device back, the mode is already different, and it simply cannot init the exclusive fullscreen with these.

So, the cause is clear now, and making a quick hackish workaround proved that restoring true parameters make it work. So the remaining issue is to code a clean solution for this.

@ericoporto
Copy link
Member Author

ericoporto commented Jun 21, 2022

Nice catch! Is the event
SDL_WINDOWEVENT_SIZE_CHANGED produced in both changes for you or only in some? When I played around SDL2 for other thing I found that this event wasn't always called when switching windowed/fs or even rotation (I was playing with Android at the time).

Do you test with exclusive fullscreen or borderless window fullscreen?

Exclusive fullscreen. I absolutely believe that the default Fullscreen should be bordless windows, and need the specialized option be set for exclusive fullscreen, since that one seems to make everything go haywire...

@ericoporto
Copy link
Member Author

I used the AGS build from here, ran Quest For Glory 2, and the log quickly gets MBs of Renderer exception: Direct3D device is lost. I cut those lines at the end.

here's a log where I managed to hang in the very few alt+tab Adventure Game Studio v3.6 Interpreter Copyright (c) 1999-2011 Chris Jones and 2011-2022 others ACI version 3.6.0.36

Installing exception handler
Initializing backend libs
SDL Version: 2.24.1
Initializing game data
Looking for the game data.
Cwd: C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Path arg:
Searching in (cwd): C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Found game config: C:/Users/erico/Documents/AGSProjects/Quest for Glory II/acsetup.cfg
Cfg: data file:
Searching for game data in: C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Found game data pak: C:/Users/erico/Documents/AGSProjects/Quest for Glory II/Qfg2vga.exe
Located game data pak: c:/Users/erico/Documents/AGSProjects/Quest for Glory II/Qfg2vga.exe
Opened game data file: game28.dta
Game data version: 42
Compiled with: 3.2.0
Startup directory: C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Data directory: c:/Users/erico/Documents/AGSProjects/Quest for Glory II/
Setting up game configuration
Unable to init voice pack 'speech.vox', file not found or of unknown format.
audio.vox found and initialized.
Initializing TTF renderer
Initializing mouse: number of buttons reported is 3
Install timer
Initializing audio
Requested audio driver: default
Audio driver: wasapi
AudioCore: opened device "Default OpenAL playback device"
Supported sound decoders:

  • MIDI decoder, using a subset of TiMidity : MIDI,MID,
  • Play modules through ModPlug : 669,AMF,AMS,DBM,DMF,DSM,FAR,GDM,IT,MDL,MED,MOD,MT2,MTM,OKT,PTM,PSM,S3M,STM,ULT,UMX,XM,
  • MPEG-1 Audio Layer I-III : MP3,MP2,MP1,
  • Microsoft WAVE audio format : WAV,
  • Audio Interchange File Format : AIFF,AIF,
  • Sun/NeXT audio file format : AU,
  • Ogg Vorbis audio : OGG,
  • Creative Labs Voice format : VOC,
  • Raw audio : RAW,
  • Shorten-compressed audio data : SHN,
  • Free Lossless Audio Codec : FLAC,FLA,
    Install exit handler
    Initialize legacy path finder library
    Load game data
    Game title: 'Quest for Glory II'
    Game uid (old format): 1027255500
    Game guid: '{a46a9171-f6f9-456c-9b2b-a509b560ddc0}'
    Game GUI version: 115
    Checking for disk space
    Initializing resolution settings
    Game native resolution: 320 x 200 (32 bit)
    Mouse cursor graphic area: (0,0)-(319,199) (320x200)
    Device display resolution: 2560 x 1440
    Graphic settings: driver: D3D9, windowed: no, screen size: 2560 x 1440, game scale: proportional
    Built library path: d3d9.dll
    Using graphics factory: D3D9
    Created graphics driver: Direct3D 9
    Supported gfx modes (32-bit):
    640x480;640x480;640x480;720x480;720x480;720x576;800x600;800x600;
    1024x768;1024x768;1152x864;1176x664;1176x664;1176x664;1280x720;1280x720;
    1280x720;1280x768;1280x800;1280x960;1280x960;1280x1024;1280x1024;1360x768;
    1360x768;1366x768;1366x768;1600x900;1600x900;1600x1024;1600x1024;1600x1200;
    1680x1050;1680x1050;1920x1080;1920x1080;1920x1080;1920x1080;1920x1080;1920x1200;
    1920x1440;1920x1440;2560x1440;2560x1440;2048x1080;2048x1080;
    Attempting to find nearest supported resolution for screen size 2560 x 1440 (32-bit) fullscreen
    Attempt to switch gfx mode to 2560 x 1440 (32-bit) fullscreen
    Graphics mode set: 2560 x 1440 (32-bit) fullscreen
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Requested gfx filter: StdScale
    Graphics filter set: 'StdScale', filter dest (128, 0, 2431, 1439 : 2304 x 1440)
    Using gfx filter: StdScale
    Mouse speed control: disabled, unit: 1.000000, user value: 1.000000
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Multitasking mode set: 0
    Setting up window
    Multitasking mode set: 0
    Displaying preload image
    Initialize sprites
    Initialize game settings
    Prepare to start game
    Engine initialization complete
    Starting game
    SetMultitasking: overridden by fullscreen: 1 -> 0
    Multitasking mode set: 0
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: focus lost
    Suspending the game on switch out
    Switching out from the game
    Renderer exception: Direct3D device is lost
    Window event: focus gained
    Resuming the game on switch in
    Switching back into the game
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost
    Renderer exception: Direct3D device is lost

Here's a different log where it took me a little more time qfg2vga_alt_tab_bug_log.zip

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 25, 2022

Hm, would it work if you try 3.5.1 on same system?

@ericoporto
Copy link
Member Author

ericoporto commented Oct 25, 2022

Erh, apparently no, it hangs in a different way that it captures my mouse forever and I can't kill AGS and need to restart my machine. Used the latest release of AGS 3.5.1, 3.5.1.22.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 25, 2022

For the reference this is how it's handled in SDL2:
https://github.com/libsdl-org/SDL/blob/053b5f85f164dd2f730a6500096a666001dc9d5b/src/render/direct3d/SDL_render_d3d.c#L1391

Does the 3.6.0 sdl2's software renderer work if it's forced to be direct3d in config?

[graphics]
software_driver = direct3d

@ericoporto
Copy link
Member Author

ericoporto commented Oct 25, 2022

The 3.6.0 sdl2's software renderer with direct3d never hangs! So, Yes!

Here's the log for this $ ./ags_real.exe --console-attach --log-stdout=main:all

Adventure Game Studio v3.6 Interpreter
Copyright (c) 1999-2011 Chris Jones and 2011-2022 others
ACI version 3.6.0.36

Installing exception handler
Initializing backend libs
SDL Version: 2.24.1
Initializing game data
Looking for the game data.
Cwd: C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Path arg:
Searching in (cwd): C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Found game config: C:/Users/erico/Documents/AGSProjects/Quest for Glory II/acsetup.cfg
Cfg: data file:
Searching for game data in: C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Found game data pak: C:/Users/erico/Documents/AGSProjects/Quest for Glory II/Qfg2vga.exe
Located game data pak: c:/Users/erico/Documents/AGSProjects/Quest for Glory II/Qfg2vga.exe
Opened game data file: game28.dta
Game data version: 42
Compiled with: 3.2.0
Startup directory: C:/Users/erico/Documents/AGSProjects/Quest for Glory II
Data directory: c:/Users/erico/Documents/AGSProjects/Quest for Glory II/
Setting up game configuration
Unable to init voice pack 'speech.vox', file not found or of unknown format.
audio.vox found and initialized.
Initializing TTF renderer
Initializing mouse: number of buttons reported is 3
Install timer
Initializing audio
Requested audio driver: default
Audio driver: wasapi
AudioCore: opened device "Default OpenAL playback device"
Supported sound decoders:

  • MIDI decoder, using a subset of TiMidity : MIDI,MID,

  • Play modules through ModPlug : 669,AMF,AMS,DBM,DMF,DSM,FAR,GDM,IT,MDL,MED,MOD,MT2,MTM,OKT,PTM,PSM,S3M,STM,ULT,UMX,XM,

  • MPEG-1 Audio Layer I-III : MP3,MP2,MP1,

  • Microsoft WAVE audio format : WAV,

  • Audio Interchange File Format : AIFF,AIF,

  • Sun/NeXT audio file format : AU,

  • Ogg Vorbis audio : OGG,

  • Creative Labs Voice format : VOC,

  • Raw audio : RAW,

  • Shorten-compressed audio data : SHN,

  • Free Lossless Audio Codec : FLAC,FLA,
    Install exit handler
    Initialize legacy path finder library
    Load game data
    Game title: 'Quest for Glory II'
    Game uid (old format): 1027255500
    Game guid: '{a46a9171-f6f9-456c-9b2b-a509b560ddc0}'
    Game GUI version: 115
    Checking for disk space
    Initializing resolution settings
    Game native resolution: 320 x 200 (32 bit)
    Mouse cursor graphic area: (0,0)-(319,199) (320x200)
    Device display resolution: 2560 x 1440
    Graphic settings: driver: Software, windowed: no, screen size: 2560 x 1440, game scale: proportional
    Using graphics factory: Software
    Created graphics driver: SDL 2D Software renderer
    Supported gfx modes (32-bit):
    2560x1440;2560x1440;2048x1080;2048x1080;1920x1440;1920x1440;1920x1200;1920x1080;
    1920x1080;1920x1080;1920x1080;1920x1080;1680x1050;1680x1050;1600x1200;1600x1024;
    1600x1024;1600x900;1600x900;1366x768;1366x768;1360x768;1360x768;1280x1024;
    1280x1024;1280x960;1280x960;1280x800;1280x768;1280x720;1280x720;1280x720;
    1176x664;1176x664;1176x664;1152x864;1024x768;1024x768;800x600;800x600;
    720x576;720x480;720x480;640x480;640x480;640x480;
    Attempting to find nearest supported resolution for screen size 2560 x 1440 (32-bit) fullscreen
    Attempt to switch gfx mode to 2560 x 1440 (32-bit) fullscreen
    Created SDL Renderer: direct3d
    Available texture formats:
    - SDL_PIXELFORMAT_ARGB8888
    - SDL_PIXELFORMAT_YV12
    - SDL_PIXELFORMAT_IYUV
    Graphics mode set: 2560 x 1440 (32-bit) fullscreen
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Requested gfx filter: StdScale
    Graphics filter set: 'StdScale', filter dest (128, 0, 2431, 1439 : 2304 x 1440)
    Using gfx filter: StdScale
    Mouse speed control: disabled, unit: 1.000000, user value: 1.000000
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Multitasking mode set: 0
    Setting up window
    Multitasking mode set: 0
    Displaying preload image
    Initialize sprites
    Initialize game settings
    Prepare to start game
    Engine initialization complete
    Starting game
    SetMultitasking: overridden by fullscreen: 1 -> 0
    Multitasking mode set: 0
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: focus lost
    Suspending the game on switch out
    Switching out from the game
    Window event: focus gained
    Resuming the game on switch in
    Switching back into the game
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: focus lost
    Suspending the game on switch out
    Switching out from the game
    Window event: focus gained
    Resuming the game on switch in
    Switching back into the game
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: focus lost
    Suspending the game on switch out
    Switching out from the game
    Window event: focus gained
    Resuming the game on switch in
    Switching back into the game
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: focus lost
    Suspending the game on switch out
    Switching out from the game
    Window event: focus gained
    Resuming the game on switch in
    Switching back into the game
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: size changed (2560, 1440)
    Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
    Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
    Window event: focus lost
    Suspending the game on switch out
    Switching out from the game

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 25, 2022

Well, these logs don't show much tbh, except it's clear that our renderer gets stuck in D3DERR_DEVICELOST for some obscure reason. I hope to find time and compare with SDL2 more closely tomorrow, but a simple hypothesis is that either we do something that we should not, or not do something that is necessary after this is detected.

For slightly "better" logs it may be useful to (temporarily) add more debug messages inside all of these loops, and in ResetDeviceIfNecessary to see clearly how does the execution go in the code.

@ericoporto
Copy link
Member Author

ericoporto commented Oct 25, 2022

Gave it a shot at adding more log. As I mentioned previously, with d3d not all alt+tabs are hanging, it usually takes some tries to cause a hanging. In the log, the alt+tabs that doesn't hang have a Window event: size changed (2560, 1440) happening, and once it hangs, this event doesn't happen. This occurs right after display_switch_in_resume: game_update_suspend = false.

I hope to find time and compare with SDL2 more closely tomorrow

Take your time, I am only answering quickly because it's the few times I happen to be home lately.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 31, 2022

@ericoporto my tests may be not accurate, or this depends on some factors, but the change I mentioned earlier actually fixes the problem for me on win7. I pushed it as 27306da. I've been running same game using 2 builds with and without this commit, and this actually makes a difference on my machine.

Previously you mentioned that it does not fix the problem for you though, but could you test just in case?

@ericoporto
Copy link
Member Author

@ivan-mogilko , this change does make it harder for me hit the bug, but I can still cause the situation to happen through alt+tabbing a bit quicker

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 31, 2022

Hm, I cannot reproduce this no matter how much I try.

Maybe it depends on delay value? In the previous version the delay was 500 ms.

EDIT: does this happen in any game, or in particular game / during particular scene?

@ericoporto
Copy link
Member Author

Maybe it depends on delay value?

Tried 100ms and 1000ms, doesn't change much regards to hanging, but the smaller value reduced the blinking when alt+tab back in - when it works and doesn't hang.

does this happen in any game, or in particular game / during particular scene?

Any game. I can reproduce it even by just loading an empty sierra template game or the one made for the GUI issue.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Oct 31, 2022

So, something I noticed reading your log from above: this is how the switching into the game normally looks like:

Window event: focus gained
Resuming the game on switch in
Switching back into the game
display_switch_in_resume: video_resume()
display_switch_in_resume: game_update_suspend = false
Window event: size changed (2560, 1440)
Render frame set, render dest (128, 0, 2431, 1439 : 2304 x 1440)
Mouse cursor graphic area: (128,0)-(2431,1439) (2304x1440)
render_to_screen: gfxDriver->Render()
ResetDeviceIfNecessary: -2005530519 = direct3ddevice->TestCooperativeLevel()
ResetDeviceIfNecessary: after 0 = ResetD3DDevice()

This repeats 4 times, but the 5th last time looks like this:

Window event: focus gained
Resuming the game on switch in
Switching back into the game
display_switch_in_resume: video_resume()
display_switch_in_resume: game_update_suspend = false
render_to_screen: gfxDriver->Render()
ResetDeviceIfNecessary: -2005530520 = direct3ddevice->TestCooperativeLevel()
ResetDeviceIfNecessary: throw Ali3DFullscreenLostException()

To be precise, following part is missing in the case which leads to the hanging:

Window event: size changed (2560, 1440)

It seems like either the program not getting an event from SDL, or the window is not resized back successfully.

@ericoporto
Copy link
Member Author

ericoporto commented Oct 31, 2022

that debug log is from here:

Debug::Printf("Window event: size changed (%d, %d)", event.window.data1, event.window.data2);

alt_tab_hang.mp4

So just to illustrate how the hanging manifests here, made a video, once the hang happens, the mouse cursor disappears - not sure if the mouse cursor disappearing here is relevant. I need to use Windows Key+Tab to move AGS to a new workspace before I can go back to the previous workspace and use the task manager to kill AGS.

Screen recording misses some frames, when alt+tab happens, so I had to film the screen.

@ericoporto
Copy link
Member Author

ericoporto commented Jan 28, 2023

Recently Manu in the forums reported a similar problem, but it requires a GUI to reproduce.

https://www.adventuregamestudio.co.uk/forums/ags-engine-editor-releases/ags-3-6-0-release-candidate-rc1/msg636652983/#msg636652983

CrashInfo.3.6.0.41.zip

Edit: after investigating, the render targets are only recreated at this line

gui_render_tex[index] = recycle_render_target(gui_render_tex[index],

But once the Device is lost once in alt+tabbing, the render targets are deleted in release_drawobj_rendertargets, but we will be locked in a while loop so we never get to update the rendersurface in the batches because we don't reach the render target recycling again.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Jan 29, 2023

That recent crash should be fixed by 278ba3b.

But there's still problem that IDirect3DDevice9::Reset fails with code 0x8876086C sometimes (like each second time).

EDIT: it seems like this is caused by release_drawobj_rendertargets not being called, somehow, before the D3D9 resets the device...

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Jan 29, 2023

So, apparently, engine also has to react to "switch in" event and release render targets in case we're in real fullscreen mode.
Pushed 1c337a3 (also see comments to commit).

After these two commits Direct3D is working again, at least on my system (don't know if anything changed for users who reported original problem in this ticket).

@ericoporto
Copy link
Member Author

ericoporto commented Feb 4, 2023

Here's a log of a hang: log_hang.txt.zip
I added extra log messages as here: ericoporto@b11d6ac

And here is the same hang, but using the AGS 3.6.0.42 release, without the additional debug messages: log_hang2.txt.zip

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Feb 4, 2023

Here's a log of a hang: log_hang.txt.zip I added extra log messages as here: ericoporto@b11d6ac

And here is the same hang, but using the AGS 3.6.0.42 release, without the additional debug messages: log_hang2.txt.zip

I have one small request, could you please print HRESULT as hex %x, that makes it easier to lookup the error codes.

[DELETED] incorrect comment.

@ericoporto
Copy link
Member Author

ericoporto commented Feb 4, 2023

Here's the log using %x: log.txt.zip
And the change that added the log messages: ericoporto@1aaeef9

After extra logs: log_v2_ResetD3DDevice.txt.zip
Here ericoporto@313bc3b

From reading online (but not the docs), my guess for the hang would be either, a problem in my computer (drivers?), or some D3D object that is not invalidated/deleted before the device being reset.

Maybe I need to add a log when textures and the render surface textures are cleared.


log_extra_log_messages.txt.zip
Added extra logs on current master ericoporto@03d5a2a

@ericoporto
Copy link
Member Author

ericoporto commented Jan 17, 2024

I was thinking about this, would it make sense to add an [disabled] entry for fullscreen so one can lock it to full_window, essentially making borderless window the only way to run in fullscreen? I think in SDL3 there isn't the exclusive fullscreen mode anymore, so this problem will eventually take care of itself in the future.

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Mar 24, 2024

I don't know if it matters for this issue, but just now I found that potentially there could be render surface pointers not restored after device reset. I only noticed this problem in the current master branch, after PR #2353, where I replaced raw surface pointers with smart ptrs. Since this seem like a legit mistake, I backported the fix to release-3.6.0, e.g. see a4fb5e3
but it's not clear under which conditions that could actually cause problems.

@ivan-mogilko ivan-mogilko added the res: needs testing issue needs (re)testing to update its status label Mar 30, 2024
@ericoporto
Copy link
Member Author

I don't have the issue anymore but I also have recently upgraded my Nvidia Drivers that I had not upgraded in two years... I remember before upgrading that I didn't had the issue anymore in 3.6.1 but had in 3.6.0 at the time. I tried previous versions of 3.6.0 and can't reproduce anymore.... So whatever issue that had, it got fixed some time ago, but the one I still had was an issue on my particular computer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
context: graphics mode res: needs testing issue needs (re)testing to update its status type: bug unexpected/erroneous behavior in the existing functionality
Projects
None yet
Development

No branches or pull requests

3 participants