internal/graphicsdriver/directx: bug fix: ignore DXGI_STATUS_OCCLUDED

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
This commit is contained in:
Hajime Hoshi 2022-07-04 12:55:34 +09:00
parent fb23e4b578
commit 47c65a92ae
3 changed files with 13 additions and 1 deletions

View File

@ -6,6 +6,7 @@
package glfwwin
import (
"errors"
"fmt"
"math"
"reflect"
@ -307,6 +308,9 @@ func (w *Window) cursorInContentArea() (bool, error) {
pos, err := _GetCursorPos()
if err != nil {
if errors.Is(err, windows.ERROR_ACCESS_DENIED) {
return false, nil
}
return false, err
}
if _WindowFromPoint(pos) != w.win32.handle {
@ -2108,6 +2112,9 @@ func platformPostEmptyEvent() error {
func (w *Window) platformGetCursorPos() (xpos, ypos float64, err error) {
pos, err := _GetCursorPos()
if err != nil {
if errors.Is(err, windows.ERROR_ACCESS_DENIED) {
return 0, 0, nil
}
return 0, 0, err
}
if !microsoftgdk.IsXbox() {

View File

@ -2594,6 +2594,10 @@ func (i *_IDXGISwapChain4) GetCurrentBackBufferIndex() uint32 {
func (i *_IDXGISwapChain4) Present(syncInterval uint32, flags uint32) error {
r, _, _ := syscall.Syscall(i.vtbl.Present, 3, uintptr(unsafe.Pointer(i)), uintptr(syncInterval), uintptr(flags))
if uint32(r) != uint32(windows.S_OK) {
// During a screen lock, Present fails (#2179).
if uint32(r) == uint32(windows.DXGI_STATUS_OCCLUDED) {
return nil
}
return fmt.Errorf("directx: IDXGISwapChain4::Present failed: HRESULT(%d)", uint32(r))
}
return nil

View File

@ -18,6 +18,7 @@
package ui
import (
"errors"
"fmt"
"runtime"
"unsafe"
@ -181,7 +182,7 @@ func initialMonitorByOS() (*glfw.Monitor, error) {
}
px, py, err := _GetCursorPos()
if err != nil {
if err != nil && !errors.Is(err, windows.ERROR_ACCESS_DENIED) {
return nil, err
}
x, y := int(px), int(py)