mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
internal/ui: refactoring
This commit is contained in:
parent
4d89b5de07
commit
dd853050e9
@ -1071,95 +1071,102 @@ func (u *userInterfaceImpl) loopGame() error {
|
||||
u.window.Destroy()
|
||||
glfw.Terminate()
|
||||
})
|
||||
|
||||
for {
|
||||
var unfocused bool
|
||||
|
||||
// On Windows, the focusing state might be always false (#987).
|
||||
// On Windows, even if a window is in another workspace, vsync seems to work.
|
||||
// Then let's assume the window is always 'focused' as a workaround.
|
||||
if runtime.GOOS != "windows" {
|
||||
unfocused = u.window.GetAttrib(glfw.Focused) == glfw.False
|
||||
}
|
||||
|
||||
var t1, t2 time.Time
|
||||
|
||||
if unfocused {
|
||||
t1 = time.Now()
|
||||
}
|
||||
|
||||
var outsideWidth, outsideHeight float64
|
||||
var deviceScaleFactor float64
|
||||
var err error
|
||||
if u.mainThread.Call(func() {
|
||||
outsideWidth, outsideHeight, err = u.update()
|
||||
deviceScaleFactor = u.deviceScaleFactor(u.currentMonitor())
|
||||
}); err != nil {
|
||||
if err := u.updateGame(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor, u); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create icon images in a different goroutine (#1478).
|
||||
// In the fullscreen mode, SetIcon fails (#1578).
|
||||
if imgs := u.getIconImages(); len(imgs) > 0 && !u.isFullscreen() {
|
||||
u.setIconImages(nil)
|
||||
|
||||
// Convert the icons in the different goroutine, as (*ebiten.Image).At cannot be invoked
|
||||
// from this goroutine. At works only in between BeginFrame and EndFrame.
|
||||
go func() {
|
||||
newImgs := make([]image.Image, len(imgs))
|
||||
for i, img := range imgs {
|
||||
// TODO: If img is not *ebiten.Image, this converting is not necessary.
|
||||
// However, this package cannot refer *ebiten.Image due to the package
|
||||
// dependencies.
|
||||
|
||||
b := img.Bounds()
|
||||
rgba := image.NewRGBA(b)
|
||||
for j := b.Min.Y; j < b.Max.Y; j++ {
|
||||
for i := b.Min.X; i < b.Max.X; i++ {
|
||||
rgba.Set(i, j, img.At(i, j))
|
||||
}
|
||||
}
|
||||
newImgs[i] = rgba
|
||||
}
|
||||
|
||||
u.mainThread.Call(func() {
|
||||
// In the fullscreen mode, reset the icon images and try again later.
|
||||
if u.isFullscreen() {
|
||||
u.setIconImages(imgs)
|
||||
return
|
||||
}
|
||||
u.window.SetIcon(newImgs)
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
// swapBuffers also checks IsGL, so this condition is redundant.
|
||||
// However, (*thread).Call is not good for performance due to channels.
|
||||
// Let's avoid this whenever possible (#1367).
|
||||
if u.graphicsDriver.IsGL() {
|
||||
u.mainThread.Call(u.swapBuffers)
|
||||
}
|
||||
|
||||
if unfocused {
|
||||
t2 = time.Now()
|
||||
}
|
||||
|
||||
// When a window is not focused, SwapBuffers might return immediately and CPU might be busy.
|
||||
// Mitigate this by sleeping (#982).
|
||||
if unfocused {
|
||||
d := t2.Sub(t1)
|
||||
const wait = time.Second / 60
|
||||
if d < wait {
|
||||
time.Sleep(wait - d)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) updateGame() error {
|
||||
var unfocused bool
|
||||
|
||||
// On Windows, the focusing state might be always false (#987).
|
||||
// On Windows, even if a window is in another workspace, vsync seems to work.
|
||||
// Then let's assume the window is always 'focused' as a workaround.
|
||||
if runtime.GOOS != "windows" {
|
||||
unfocused = u.window.GetAttrib(glfw.Focused) == glfw.False
|
||||
}
|
||||
|
||||
var t1, t2 time.Time
|
||||
|
||||
if unfocused {
|
||||
t1 = time.Now()
|
||||
}
|
||||
|
||||
var outsideWidth, outsideHeight float64
|
||||
var deviceScaleFactor float64
|
||||
var err error
|
||||
if u.mainThread.Call(func() {
|
||||
outsideWidth, outsideHeight, err = u.update()
|
||||
deviceScaleFactor = u.deviceScaleFactor(u.currentMonitor())
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor, u); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create icon images in a different goroutine (#1478).
|
||||
// In the fullscreen mode, SetIcon fails (#1578).
|
||||
if imgs := u.getIconImages(); len(imgs) > 0 && !u.isFullscreen() {
|
||||
u.setIconImages(nil)
|
||||
|
||||
// Convert the icons in the different goroutine, as (*ebiten.Image).At cannot be invoked
|
||||
// from this goroutine. At works only in between BeginFrame and EndFrame.
|
||||
go func() {
|
||||
newImgs := make([]image.Image, len(imgs))
|
||||
for i, img := range imgs {
|
||||
// TODO: If img is not *ebiten.Image, this converting is not necessary.
|
||||
// However, this package cannot refer *ebiten.Image due to the package
|
||||
// dependencies.
|
||||
|
||||
b := img.Bounds()
|
||||
rgba := image.NewRGBA(b)
|
||||
for j := b.Min.Y; j < b.Max.Y; j++ {
|
||||
for i := b.Min.X; i < b.Max.X; i++ {
|
||||
rgba.Set(i, j, img.At(i, j))
|
||||
}
|
||||
}
|
||||
newImgs[i] = rgba
|
||||
}
|
||||
|
||||
u.mainThread.Call(func() {
|
||||
// In the fullscreen mode, reset the icon images and try again later.
|
||||
if u.isFullscreen() {
|
||||
u.setIconImages(imgs)
|
||||
return
|
||||
}
|
||||
u.window.SetIcon(newImgs)
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
// swapBuffers also checks IsGL, so this condition is redundant.
|
||||
// However, (*thread).Call is not good for performance due to channels.
|
||||
// Let's avoid this whenever possible (#1367).
|
||||
if u.graphicsDriver.IsGL() {
|
||||
u.mainThread.Call(u.swapBuffers)
|
||||
}
|
||||
|
||||
if unfocused {
|
||||
t2 = time.Now()
|
||||
}
|
||||
|
||||
// When a window is not focused, SwapBuffers might return immediately and CPU might be busy.
|
||||
// Mitigate this by sleeping (#982).
|
||||
if unfocused {
|
||||
d := t2.Sub(t1)
|
||||
const wait = time.Second / 60
|
||||
if d < wait {
|
||||
time.Sleep(wait - d)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// swapBuffers must be called from the main thread.
|
||||
func (u *userInterfaceImpl) swapBuffers() {
|
||||
if u.graphicsDriver.IsGL() {
|
||||
|
Loading…
Reference in New Issue
Block a user