mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/ui: bug fix: SetWindowIcon crashed in the single-thread mode
Updates #1468 Closes #2513
This commit is contained in:
parent
b597ed1e27
commit
7e7deeab22
@ -144,6 +144,10 @@ func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, update
|
||||
ui.resetForTick()
|
||||
}
|
||||
|
||||
// Update window icons during a frame, since an icon might be *ebiten.Image and
|
||||
// getting pixels from it needs to be in a frame (#1468).
|
||||
ui.updateIconIfNeeded()
|
||||
|
||||
// Draw the game.
|
||||
if err := c.drawGame(graphicsDriver, forceDraw); err != nil {
|
||||
return err
|
||||
|
@ -1046,41 +1046,6 @@ func (u *userInterfaceImpl) updateGame() error {
|
||||
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).
|
||||
@ -1105,6 +1070,40 @@ func (u *userInterfaceImpl) updateGame() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) updateIconIfNeeded() {
|
||||
// In the fullscreen mode, SetIcon fails (#1578).
|
||||
if u.isFullscreen() {
|
||||
return
|
||||
}
|
||||
|
||||
imgs := u.getIconImages()
|
||||
if len(imgs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
u.setIconImages(nil)
|
||||
|
||||
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() {
|
||||
u.window.SetIcon(newImgs)
|
||||
})
|
||||
}
|
||||
|
||||
// swapBuffers must be called from the main thread.
|
||||
func (u *userInterfaceImpl) swapBuffers() {
|
||||
if u.graphicsDriver.IsGL() {
|
||||
|
@ -694,6 +694,9 @@ func (u *userInterfaceImpl) beginFrame() {
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) updateIconIfNeeded() {
|
||||
}
|
||||
|
||||
func IsScreenTransparentAvailable() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -461,6 +461,9 @@ func (u *userInterfaceImpl) beginFrame() {
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) updateIconIfNeeded() {
|
||||
}
|
||||
|
||||
func IsScreenTransparentAvailable() bool {
|
||||
return false
|
||||
}
|
||||
|
@ -144,6 +144,9 @@ func (u *userInterfaceImpl) beginFrame() {
|
||||
func (u *userInterfaceImpl) endFrame() {
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) updateIconIfNeeded() {
|
||||
}
|
||||
|
||||
func IsScreenTransparentAvailable() bool {
|
||||
return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user