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

internal/graphicsdriver/directx: Directx driver causes go program exit when screen blanks or user locks #2179

Closed
steampoweredtaco opened this issue Jul 3, 2022 · 7 comments

Comments

@steampoweredtaco
Copy link

Hi! I'm using v2.3.5 (newest v2 release as of right now) on Windows 10 with the directx driver in use. If you are running an ebiten executable and lock the screen or the monitor suspends due to windows settings the program ebiten.RunGame returns with an error. You can see this behavior with the examples.

Here's the error:

$ go run hue.go 
2022/07/03 14:40:08 directx: IDXGISwapChain4::Present failed: The Present operation was invisible to the user.
exit status 1

It is really easy to reproduce, just run a program and hit the keys winkey-l (that's a L) to lock the screen. Unlock the screen and you'll see the error.

Is there a way to just re-invoke the Run call and it will leave off where it started as a workaround?

A naive expected behavior would be that ebiten wouldn't care about this error and continue with update calls and ignoring the presentation error, perhaps pause draw calls until the machine is back in a state where present wouldn't cause an error?

This is how most games on windows work, when my monitor suspends I usually can hear the sounds and the game events keep going in the background. Think idle games where this behavior is important. My current project is a long running simulation which is important to have this ability too.

Another option is a pause of the engine until directx will process the Present? However, if that is an option I'd like it a configurable behavior.

One way to tackle this (and maybe it does?) is to register a callback on these kinds of errors/events that cause them and the game logic can return in the callback if it should suspend processing or continue updates without display in the meantime? Maybe return timeout where the game engine will check again and call the callback again if it still can't Present?

@steampoweredtaco
Copy link
Author

Can confirm opengl works as my naive expectations, it just keeps working in the background.

Workaround for others that see this, place this before your main game loop:

os.Setenv("EBITEN_GRAPHICS_LIBRARY", "opengl")

@hajimehoshi hajimehoshi added this to the v2.3.6 milestone Jul 4, 2022
@hajimehoshi
Copy link
Owner

Thanks, I'll take a look!

@hajimehoshi
Copy link
Owner

Confirmed.

hajimehoshi added a commit that referenced this issue Jul 4, 2022
When a screen is locked, an Ebitengine application crashed as the
swap chain's Present returned DXGI_STATUS_OCCLUDED.

Let's ignore the error and continue to run the applications. In the
ideal world, an application should stop running during the screen lock,
so let's revisit this later.

This fix also fixes the issue that a Win32API GetCursorPos returned
an error ERROR_ACCESS_DENIED when the screen was locked.

Closes #2179
@hajimehoshi
Copy link
Owner

OK I've fixed the issue. Could you try 29b41fd07f24299866d951f6ad310433dd182407?

go get github.com/hajimehoshi/ebiten/v2@29b41fd07f24299866d951f6ad310433dd182407

Thanks!

@hajimehoshi
Copy link
Owner

hajimehoshi commented Jul 4, 2022

A naive expected behavior would be that ebiten wouldn't care about this error and continue with update calls and ignoring the presentation error, perhaps pause draw calls until the machine is back in a state where present wouldn't cause an error?

Ideally this seems the way to go. The current implementation is just to ignore the error. I'll consider a more sophisticated way at #2181.

This is how most games on windows work, when my monitor suspends I usually can hear the sounds and the game events keep going in the background. Think idle games where this behavior is important. My current project is a long running simulation which is important to have this ability too.

I see. I'll let applications work behind the lock screen. You can control the behavior when unfocused with SetRunnableOnUnfocused.

One way to tackle this (and maybe it does?) is to register a callback on these kinds of errors/events that cause them and the game logic can return in the callback if it should suspend processing or continue updates without display in the meantime? Maybe return timeout where the game engine will check again and call the callback again if it still can't Present?

IIUC testing presenting with DXGI_PRESENT_TEST seems the way to go.

hajimehoshi added a commit that referenced this issue Jul 4, 2022
hajimehoshi added a commit that referenced this issue Jul 4, 2022
@steampoweredtaco
Copy link
Author

go get github.com/hajimehoshi/ebiten/v2@29b41fd07f24299866d951f6ad310433dd182407

Confirmed that game doesn't error out when I lock the screen with directx and this change any longer, I'll resume using directx to help find any other issues with it as soon as it makes it to v2 officially.

@hajimehoshi
Copy link
Owner

Thank you very much!

@hajimehoshi hajimehoshi changed the title Directx driver causes go program exit when screen blanks or user locks internal/graphicsdriver/directx: Directx driver causes go program exit when screen blanks or user locks Jul 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants