Skip to content

Commit

Permalink
Add workaround to use just 1 thread on Apple M1
Browse files Browse the repository at this point in the history
Downsize is resize is not as smooth, but upside does not crash.

Fixes fyne-io#2188
  • Loading branch information
andydotxyz committed Nov 22, 2021
1 parent a2ee1f3 commit da0f834
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 17 deletions.
2 changes: 2 additions & 0 deletions internal/driver/glfw/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ type gLDriver struct {
drawDone chan interface{}

animation *animation.Runner

drawOnMainThread bool // A workaround on Apple M1, just use 1 thread until fixed upstream
}

func (d *gLDriver) RenderedTextSize(text string, textSize float32, style fyne.TextStyle) (size fyne.Size, baseline float32) {
Expand Down
51 changes: 34 additions & 17 deletions internal/driver/glfw/loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,31 @@ func runOnDraw(w *window, f func()) {
<-done
}

func (d *gLDriver) drawSingleFrame() {
refreshingCanvases := make([]fyne.Canvas, 0)
for _, win := range d.windowList() {
w := win.(*window)
w.viewLock.RLock()
canvas := w.canvas
closing := w.closing
visible := w.visible
w.viewLock.RUnlock()

if closing || !canvas.IsDirty() || !visible {
continue
}
d.repaintWindow(w)
refreshingCanvases = append(refreshingCanvases, canvas)
}
cache.CleanCanvases(refreshingCanvases)
}

func (d *gLDriver) initGLFW() {
initOnce.Do(func() {
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
d.drawOnMainThread = true
}

err := glfw.Init()
if err != nil {
fyne.LogError("failed to initialise GLFW", err)
Expand Down Expand Up @@ -146,6 +169,10 @@ func (d *gLDriver) runGL() {
}

newWindows = append(newWindows, win)

if d.drawOnMainThread {
d.drawSingleFrame()
}
}
if reassign {
d.windowLock.Lock()
Expand Down Expand Up @@ -187,7 +214,12 @@ func (d *gLDriver) repaintWindow(w *window) {
func (d *gLDriver) startDrawThread() {
settingsChange := make(chan fyne.Settings)
fyne.CurrentApp().Settings().AddChangeListener(settingsChange)
draw := time.NewTicker(time.Second / 60)
var draw *time.Ticker
if d.drawOnMainThread {
draw = time.NewTicker(time.Hour * 24 * 365 * 100) // don't tick when on M1
} else {
draw = time.NewTicker(time.Second / 60)
}

go func() {
runtime.LockOSThread()
Expand All @@ -213,22 +245,7 @@ func (d *gLDriver) startDrawThread() {
go c.reloadScale()
})
case <-draw.C:
refreshingCanvases := make([]fyne.Canvas, 0)
for _, win := range d.windowList() {
w := win.(*window)
w.viewLock.RLock()
canvas := w.canvas
closing := w.closing
visible := w.visible
w.viewLock.RUnlock()

if closing || !canvas.IsDirty() || !visible {
continue
}
d.repaintWindow(w)
refreshingCanvases = append(refreshingCanvases, canvas)
}
cache.CleanCanvases(refreshingCanvases)
d.drawSingleFrame()
}
}
}()
Expand Down

0 comments on commit da0f834

Please sign in to comment.