mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 03:38:55 +01:00
internal/uidriver/glfw: Bug fix: Wait for FramebufferSize callback after a window creation
Closes #1847
This commit is contained in:
parent
1dc637a66d
commit
2f2ccbbe55
@ -727,9 +727,12 @@ func (u *UserInterface) createWindow() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
initializeWindowAfterCreation(window)
|
initializeWindowAfterCreation(window)
|
||||||
|
|
||||||
u.window = window
|
u.window = window
|
||||||
|
|
||||||
|
// Even just after a window creation, FramebufferSize callback might be invoked (#1847).
|
||||||
|
// Ensure to consume this callback.
|
||||||
|
u.waitForFramebufferSizeCallback(nil)
|
||||||
|
|
||||||
if u.Graphics().IsGL() {
|
if u.Graphics().IsGL() {
|
||||||
u.window.MakeContextCurrent()
|
u.window.MakeContextCurrent()
|
||||||
}
|
}
|
||||||
@ -817,6 +820,51 @@ func (u *UserInterface) registerWindowCloseCallback() {
|
|||||||
u.window.SetCloseCallback(u.closeCallback)
|
u.window.SetCloseCallback(u.closeCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// waitForFramebufferSizeCallback waits for GLFW's FramebufferSize callback.
|
||||||
|
// f is a process executed after registering the callback.
|
||||||
|
// If the callback is not invoked for a while, waitForFramebufferSizeCallback times out and return.
|
||||||
|
//
|
||||||
|
// waitForFramebufferSizeCallback must be called from the main thread.
|
||||||
|
func (u *UserInterface) waitForFramebufferSizeCallback(f func()) {
|
||||||
|
u.framebufferSizeCallbackCh = make(chan struct{}, 1)
|
||||||
|
|
||||||
|
if u.framebufferSizeCallback == 0 {
|
||||||
|
u.framebufferSizeCallback = glfw.ToFramebufferSizeCallback(func(_ *glfw.Window, w, h int) {
|
||||||
|
// This callback can be invoked multiple times by one PollEvents in theory (#1618).
|
||||||
|
// Allow the case when the channel is full.
|
||||||
|
select {
|
||||||
|
case u.framebufferSizeCallbackCh <- struct{}{}:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
u.window.SetFramebufferSizeCallback(u.framebufferSizeCallback)
|
||||||
|
|
||||||
|
if f != nil {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the timeout as FramebufferSize event might not be fired (#1618).
|
||||||
|
t := time.NewTimer(time.Second)
|
||||||
|
defer t.Stop()
|
||||||
|
|
||||||
|
event:
|
||||||
|
for {
|
||||||
|
glfw.PollEvents()
|
||||||
|
select {
|
||||||
|
case <-u.framebufferSizeCallbackCh:
|
||||||
|
break event
|
||||||
|
case <-t.C:
|
||||||
|
break event
|
||||||
|
default:
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u.window.SetFramebufferSizeCallback(glfw.ToFramebufferSizeCallback(nil))
|
||||||
|
close(u.framebufferSizeCallbackCh)
|
||||||
|
u.framebufferSizeCallbackCh = nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UserInterface) init() error {
|
func (u *UserInterface) init() error {
|
||||||
if u.Graphics().IsGL() {
|
if u.Graphics().IsGL() {
|
||||||
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI)
|
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI)
|
||||||
@ -1293,41 +1341,11 @@ func (u *UserInterface) setWindowSizeInDIPImpl(width, height int, fullscreen boo
|
|||||||
newW := int(u.dipToGLFWPixel(float64(width), u.currentMonitor()))
|
newW := int(u.dipToGLFWPixel(float64(width), u.currentMonitor()))
|
||||||
newH := int(u.dipToGLFWPixel(float64(height), u.currentMonitor()))
|
newH := int(u.dipToGLFWPixel(float64(height), u.currentMonitor()))
|
||||||
if oldW != newW || oldH != newH {
|
if oldW != newW || oldH != newH {
|
||||||
u.framebufferSizeCallbackCh = make(chan struct{}, 1)
|
|
||||||
if u.framebufferSizeCallback == 0 {
|
|
||||||
u.framebufferSizeCallback = glfw.ToFramebufferSizeCallback(func(_ *glfw.Window, _, _ int) {
|
|
||||||
// This callback can be invoked multiple times by one PollEvents in theory (#1618).
|
|
||||||
// Allow the case when the channel is full.
|
|
||||||
select {
|
|
||||||
case u.framebufferSizeCallbackCh <- struct{}{}:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
u.window.SetFramebufferSizeCallback(u.framebufferSizeCallback)
|
|
||||||
u.window.SetSize(newW, newH)
|
|
||||||
// Just after SetSize, GetSize is not reliable especially on Linux/UNIX.
|
// Just after SetSize, GetSize is not reliable especially on Linux/UNIX.
|
||||||
// Let's wait for FramebufferSize callback in any cases.
|
// Let's wait for FramebufferSize callback in any cases.
|
||||||
|
u.waitForFramebufferSizeCallback(func() {
|
||||||
// Use the timeout as FramebufferSize event might not be fired (#1618).
|
u.window.SetSize(newW, newH)
|
||||||
t := time.NewTimer(time.Second)
|
})
|
||||||
defer t.Stop()
|
|
||||||
|
|
||||||
event:
|
|
||||||
for {
|
|
||||||
glfw.PollEvents()
|
|
||||||
select {
|
|
||||||
case <-u.framebufferSizeCallbackCh:
|
|
||||||
break event
|
|
||||||
case <-t.C:
|
|
||||||
break event
|
|
||||||
default:
|
|
||||||
time.Sleep(time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
u.window.SetFramebufferSizeCallback(glfw.ToFramebufferSizeCallback(nil))
|
|
||||||
close(u.framebufferSizeCallbackCh)
|
|
||||||
u.framebufferSizeCallbackCh = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window title might be lost on macOS after coming back from fullscreen.
|
// Window title might be lost on macOS after coming back from fullscreen.
|
||||||
|
Loading…
Reference in New Issue
Block a user