mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/ui: use a separate render thread for Nintendo Switch
Updates #2512
This commit is contained in:
parent
312dce950c
commit
0bdfeec610
2
doc.go
2
doc.go
@ -99,7 +99,7 @@
|
||||
// `ebitenginesinglethread` disables Ebitengine's thread safety to unlock maximum performance. If you use this you will have
|
||||
// to manage threads yourself. Functions like IsKeyPressed will no longer be concurrent-safe with this build tag.
|
||||
// They must be called from the main thread or the same goroutine as the given game's callback functions like Update
|
||||
// to RunGame.
|
||||
// to RunGame. `ebitenginesinglethread` works only with desktops.
|
||||
//
|
||||
// `microsoftgdk` is for Microsoft GDK (e.g. Xbox).
|
||||
//
|
||||
|
@ -81,10 +81,13 @@ func (e *egl) init(nativeWindowHandle C.NativeWindowType) error {
|
||||
return fmt.Errorf("ui: eglCreateContext failed: error: %d", C.eglGetError())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *egl) makeContextCurrent() error {
|
||||
if r := C.eglMakeCurrent(e.display, e.surface, e.surface, e.context); r == 0 {
|
||||
return fmt.Errorf("ui: eglMakeCurrent failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,16 @@ package ui
|
||||
import "C"
|
||||
|
||||
import (
|
||||
stdcontext "context"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/gamepad"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/thread"
|
||||
)
|
||||
|
||||
type graphicsDriverCreatorImpl struct{}
|
||||
@ -61,6 +66,9 @@ type userInterfaceImpl struct {
|
||||
nativeTouches []C.struct_Touch
|
||||
|
||||
egl egl
|
||||
|
||||
mainThread *thread.OSThread
|
||||
renderThread *thread.OSThread
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) Run(game Game, options *RunOptions) error {
|
||||
@ -78,19 +86,54 @@ func (u *userInterfaceImpl) Run(game Game, options *RunOptions) error {
|
||||
|
||||
initializeProfiler()
|
||||
|
||||
u.mainThread = thread.NewOSThread()
|
||||
u.renderThread = thread.NewOSThread()
|
||||
graphicscommand.SetRenderThread(u.renderThread)
|
||||
|
||||
ctx, cancel := stdcontext.WithCancel(stdcontext.Background())
|
||||
defer cancel()
|
||||
|
||||
var wg errgroup.Group
|
||||
|
||||
// Run the render thread.
|
||||
wg.Go(func() error {
|
||||
defer cancel()
|
||||
_ = u.renderThread.Loop(ctx)
|
||||
return nil
|
||||
})
|
||||
|
||||
// Run the game thread.
|
||||
wg.Go(func() error {
|
||||
defer cancel()
|
||||
|
||||
u.renderThread.Call(func() {
|
||||
u.egl.makeContextCurrent()
|
||||
})
|
||||
|
||||
for {
|
||||
recordProfilerHeartbeat()
|
||||
|
||||
// TODO: Make a separate thread for rendering (#2512).
|
||||
u.mainThread.Call(func() {
|
||||
gamepad.Update()
|
||||
u.updateInputState()
|
||||
})
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, float64(C.kScreenWidth), float64(C.kScreenHeight), deviceScaleFactor, u); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.renderThread.Call(func() {
|
||||
u.egl.swapBuffers()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Run the main thread.
|
||||
_ = u.mainThread.Loop(ctx)
|
||||
if err := wg.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*userInterfaceImpl) DeviceScaleFactor() float64 {
|
||||
|
Loading…
Reference in New Issue
Block a user