internal/ui: add userInterfaceImpl.graphicsDriver

This commit is contained in:
Hajime Hoshi 2022-03-22 00:02:37 +09:00
parent be1836339b
commit 15548b4c74
6 changed files with 38 additions and 22 deletions

View File

@ -83,13 +83,13 @@ func Get() *UserInterface {
} }
func (u *UserInterface) imageAt(mipmap *mipmap.Mipmap, x, y int) (r, g, b, a byte, err error) { func (u *UserInterface) imageAt(mipmap *mipmap.Mipmap, x, y int) (r, g, b, a byte, err error) {
return mipmap.At(graphicsDriver(), x, y) return mipmap.At(u.graphicsDriver, x, y)
} }
func (u *UserInterface) dumpScreenshot(mipmap *mipmap.Mipmap, name string, blackbg bool) error { func (u *UserInterface) dumpScreenshot(mipmap *mipmap.Mipmap, name string, blackbg bool) error {
return mipmap.DumpScreenshot(graphicsDriver(), name, blackbg) return mipmap.DumpScreenshot(u.graphicsDriver, name, blackbg)
} }
func (u *UserInterface) dumpImages(dir string) error { func (u *UserInterface) dumpImages(dir string) error {
return atlas.DumpImages(graphicsDriver(), dir) return atlas.DumpImages(u.graphicsDriver, dir)
} }

View File

@ -21,6 +21,7 @@ import (
"runtime" "runtime"
"github.com/hajimehoshi/ebiten/v2/internal/cbackend" "github.com/hajimehoshi/ebiten/v2/internal/cbackend"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
) )
const deviceScaleFactor = 1 const deviceScaleFactor = 1
@ -30,19 +31,22 @@ func init() {
} }
type userInterfaceImpl struct { type userInterfaceImpl struct {
graphicsDriver graphicsdriver.Graphics
context *contextImpl context *contextImpl
input Input input Input
} }
func (u *userInterfaceImpl) Run(game Game) error { func (u *userInterfaceImpl) Run(game Game) error {
u.context = newContextImpl(game) u.context = newContextImpl(game)
u.graphicsDriver = graphicsDriver()
cbackend.InitializeGame() cbackend.InitializeGame()
for { for {
cbackend.BeginFrame() cbackend.BeginFrame()
u.input.update(u.context) u.input.update(u.context)
w, h := cbackend.ScreenSize() w, h := cbackend.ScreenSize()
if err := u.context.updateFrame(graphicsDriver(), float64(w), float64(h), deviceScaleFactor); err != nil { if err := u.context.updateFrame(u.graphicsDriver, float64(w), float64(h), deviceScaleFactor); err != nil {
return err return err
} }

View File

@ -28,6 +28,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/devicescale" "github.com/hajimehoshi/ebiten/v2/internal/devicescale"
"github.com/hajimehoshi/ebiten/v2/internal/glfw" "github.com/hajimehoshi/ebiten/v2/internal/glfw"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
"github.com/hajimehoshi/ebiten/v2/internal/hooks" "github.com/hajimehoshi/ebiten/v2/internal/hooks"
"github.com/hajimehoshi/ebiten/v2/internal/thread" "github.com/hajimehoshi/ebiten/v2/internal/thread"
) )
@ -46,6 +47,8 @@ func driverCursorModeToGLFWCursorMode(mode CursorMode) int {
} }
type userInterfaceImpl struct { type userInterfaceImpl struct {
graphicsDriver graphicsdriver.Graphics
context *contextImpl context *contextImpl
title string title string
window *glfw.Window window *glfw.Window
@ -660,7 +663,7 @@ func (u *userInterfaceImpl) createWindow(width, height int) error {
// Ensure to consume this callback. // Ensure to consume this callback.
u.waitForFramebufferSizeCallback(u.window, nil) u.waitForFramebufferSizeCallback(u.window, nil)
if graphicsDriver().IsGL() { if u.graphicsDriver.IsGL() {
u.window.MakeContextCurrent() u.window.MakeContextCurrent()
} }
@ -708,13 +711,13 @@ func (u *userInterfaceImpl) registerWindowSetSizeCallback() {
// In order to call it safely, use runOnAnotherThreadFromMainThread. // In order to call it safely, use runOnAnotherThreadFromMainThread.
var err error var err error
u.runOnAnotherThreadFromMainThread(func() { u.runOnAnotherThreadFromMainThread(func() {
err = u.context.forceUpdateFrame(graphicsDriver(), outsideWidth, outsideHeight, deviceScaleFactor) err = u.context.forceUpdateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor)
}) })
if err != nil { if err != nil {
u.err = err u.err = err
} }
if graphicsDriver().IsGL() { if u.graphicsDriver.IsGL() {
u.swapBuffers() u.swapBuffers()
} }
}) })
@ -808,7 +811,8 @@ event:
} }
func (u *userInterfaceImpl) init() error { func (u *userInterfaceImpl) init() error {
if graphicsDriver().IsGL() { u.graphicsDriver = graphicsDriver()
if u.graphicsDriver.IsGL() {
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI) glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI)
glfw.WindowHint(glfw.ContextVersionMajor, 2) glfw.WindowHint(glfw.ContextVersionMajor, 2)
glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.ContextVersionMinor, 1)
@ -829,7 +833,7 @@ func (u *userInterfaceImpl) init() error {
transparent = glfw.True transparent = glfw.True
} }
glfw.WindowHint(glfw.TransparentFramebuffer, transparent) glfw.WindowHint(glfw.TransparentFramebuffer, transparent)
graphicsDriver().SetTransparent(u.isInitScreenTransparent()) u.graphicsDriver.SetTransparent(u.isInitScreenTransparent())
// Before creating a window, set it unresizable no matter what u.isInitWindowResizable() is (#1987). // Before creating a window, set it unresizable no matter what u.isInitWindowResizable() is (#1987).
// Making the window resizable here doesn't work correctly when switching to enable resizing. // Making the window resizable here doesn't work correctly when switching to enable resizing.
@ -881,7 +885,7 @@ func (u *userInterfaceImpl) init() error {
u.window.Show() u.window.Show()
if g, ok := graphicsDriver().(interface{ SetWindow(uintptr) }); ok { if g, ok := u.graphicsDriver.(interface{ SetWindow(uintptr) }); ok {
g.SetWindow(u.nativeWindow()) g.SetWindow(u.nativeWindow())
} }
@ -1018,7 +1022,7 @@ func (u *userInterfaceImpl) loop() error {
return err return err
} }
if err := u.context.updateFrame(graphicsDriver(), outsideWidth, outsideHeight, deviceScaleFactor); err != nil { if err := u.context.updateFrame(u.graphicsDriver, outsideWidth, outsideHeight, deviceScaleFactor); err != nil {
return err return err
} }
@ -1060,7 +1064,7 @@ func (u *userInterfaceImpl) loop() error {
// swapBuffers also checks IsGL, so this condition is redundant. // swapBuffers also checks IsGL, so this condition is redundant.
// However, (*thread).Call is not good for performance due to channels. // However, (*thread).Call is not good for performance due to channels.
// Let's avoid this whenever possible (#1367). // Let's avoid this whenever possible (#1367).
if graphicsDriver().IsGL() { if u.graphicsDriver.IsGL() {
u.t.Call(u.swapBuffers) u.t.Call(u.swapBuffers)
} }
@ -1082,7 +1086,7 @@ func (u *userInterfaceImpl) loop() error {
// swapBuffers must be called from the main thread. // swapBuffers must be called from the main thread.
func (u *userInterfaceImpl) swapBuffers() { func (u *userInterfaceImpl) swapBuffers() {
if graphicsDriver().IsGL() { if u.graphicsDriver.IsGL() {
u.window.SwapBuffers() u.window.SwapBuffers()
} }
} }
@ -1139,7 +1143,7 @@ func (u *userInterfaceImpl) adjustWindowSizeBasedOnSizeLimitsInDIP(width, height
func (u *userInterfaceImpl) setWindowSizeInDIP(width, height int, fullscreen bool) { func (u *userInterfaceImpl) setWindowSizeInDIP(width, height int, fullscreen bool) {
width, height = u.adjustWindowSizeBasedOnSizeLimitsInDIP(width, height) width, height = u.adjustWindowSizeBasedOnSizeLimitsInDIP(width, height)
graphicsDriver().SetFullscreen(fullscreen) u.graphicsDriver.SetFullscreen(fullscreen)
scale := u.deviceScaleFactor(u.currentMonitor()) scale := u.deviceScaleFactor(u.currentMonitor())
if u.windowWidthInDIP == width && u.windowHeightInDIP == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == scale { if u.windowWidthInDIP == width && u.windowHeightInDIP == height && u.isFullscreen() == fullscreen && u.lastDeviceScaleFactor == scale {
@ -1213,7 +1217,7 @@ func (u *userInterfaceImpl) setWindowSizeInDIPImpl(width, height int, fullscreen
// Swapping buffer is necesary to prevent the image lag (#1004). // Swapping buffer is necesary to prevent the image lag (#1004).
// TODO: This might not work when vsync is disabled. // TODO: This might not work when vsync is disabled.
if graphicsDriver().IsGL() { if u.graphicsDriver.IsGL() {
glfw.PollEvents() glfw.PollEvents()
u.swapBuffers() u.swapBuffers()
} }
@ -1260,7 +1264,7 @@ func (u *userInterfaceImpl) setWindowSizeInDIPImpl(width, height int, fullscreen
// updateVsync must be called on the main thread. // updateVsync must be called on the main thread.
func (u *userInterfaceImpl) updateVsync() { func (u *userInterfaceImpl) updateVsync() {
if graphicsDriver().IsGL() { if u.graphicsDriver.IsGL() {
// SwapInterval is affected by the current monitor of the window. // SwapInterval is affected by the current monitor of the window.
// This needs to be called at least after SetMonitor. // This needs to be called at least after SetMonitor.
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375). // Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
@ -1274,7 +1278,7 @@ func (u *userInterfaceImpl) updateVsync() {
glfw.SwapInterval(0) glfw.SwapInterval(0)
} }
} }
graphicsDriver().SetVsyncEnabled(u.fpsMode == FPSModeVsyncOn) u.graphicsDriver.SetVsyncEnabled(u.fpsMode == FPSModeVsyncOn)
} }
// currentMonitor returns the current active monitor. // currentMonitor returns the current active monitor.

View File

@ -316,7 +316,7 @@ func (u *userInterfaceImpl) setNativeFullscreen(fullscreen bool) {
} }
func (u *userInterfaceImpl) adjustViewSize() { func (u *userInterfaceImpl) adjustViewSize() {
if graphicsDriver().IsGL() { if u.graphicsDriver.IsGL() {
return return
} }
C.adjustViewSize(C.uintptr_t(u.window.GetCocoaWindow())) C.adjustViewSize(C.uintptr_t(u.window.GetCocoaWindow()))

View File

@ -20,6 +20,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/devicescale" "github.com/hajimehoshi/ebiten/v2/internal/devicescale"
"github.com/hajimehoshi/ebiten/v2/internal/gamepad" "github.com/hajimehoshi/ebiten/v2/internal/gamepad"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
"github.com/hajimehoshi/ebiten/v2/internal/hooks" "github.com/hajimehoshi/ebiten/v2/internal/hooks"
) )
@ -47,6 +48,8 @@ func driverCursorShapeToCSSCursor(cursor CursorShape) string {
} }
type userInterfaceImpl struct { type userInterfaceImpl struct {
graphicsDriver graphicsdriver.Graphics
runnableOnUnfocused bool runnableOnUnfocused bool
fpsMode FPSModeType fpsMode FPSModeType
renderingScheduled bool renderingScheduled bool
@ -279,11 +282,11 @@ func (u *userInterfaceImpl) updateImpl(force bool) error {
w, h := u.outsideSize() w, h := u.outsideSize()
if force { if force {
if err := u.context.forceUpdateFrame(graphicsDriver(), w, h, u.DeviceScaleFactor()); err != nil { if err := u.context.forceUpdateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor()); err != nil {
return err return err
} }
} else { } else {
if err := u.context.updateFrame(graphicsDriver(), w, h, u.DeviceScaleFactor()); err != nil { if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor()); err != nil {
return err return err
} }
} }
@ -306,6 +309,7 @@ func (u *userInterfaceImpl) needsUpdate() bool {
func (u *userInterfaceImpl) loop(game Game) <-chan error { func (u *userInterfaceImpl) loop(game Game) <-chan error {
u.context = newContextImpl(game) u.context = newContextImpl(game)
u.graphicsDriver = graphicsDriver()
errCh := make(chan error, 1) errCh := make(chan error, 1)
reqStopAudioCh := make(chan struct{}) reqStopAudioCh := make(chan struct{})

View File

@ -36,6 +36,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/devicescale" "github.com/hajimehoshi/ebiten/v2/internal/devicescale"
"github.com/hajimehoshi/ebiten/v2/internal/gamepad" "github.com/hajimehoshi/ebiten/v2/internal/gamepad"
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand" "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/graphicsdriver/opengl"
"github.com/hajimehoshi/ebiten/v2/internal/hooks" "github.com/hajimehoshi/ebiten/v2/internal/hooks"
"github.com/hajimehoshi/ebiten/v2/internal/restorable" "github.com/hajimehoshi/ebiten/v2/internal/restorable"
@ -90,6 +91,8 @@ func (u *userInterfaceImpl) Update() error {
} }
type userInterfaceImpl struct { type userInterfaceImpl struct {
graphicsDriver graphicsdriver.Graphics
outsideWidth float64 outsideWidth float64
outsideHeight float64 outsideHeight float64
@ -267,12 +270,13 @@ func (u *userInterfaceImpl) run(game Game, mainloop bool) (err error) {
}() }()
u.context = newContextImpl(game) u.context = newContextImpl(game)
u.graphicsDriver = graphicsDriver()
if mainloop { if mainloop {
// When mainloop is true, gomobile-build is used. In this case, GL functions must be called via // When mainloop is true, gomobile-build is used. In this case, GL functions must be called via
// gl.Context so that they are called on the appropriate thread. // gl.Context so that they are called on the appropriate thread.
ctx := <-glContextCh ctx := <-glContextCh
graphicsDriver().(*opengl.Graphics).SetGomobileGLContext(ctx) u.graphicsDriver.(*opengl.Graphics).SetGomobileGLContext(ctx)
} else { } else {
u.t = thread.NewOSThread() u.t = thread.NewOSThread()
graphicscommand.SetRenderingThread(u.t) graphicscommand.SetRenderingThread(u.t)
@ -316,7 +320,7 @@ func (u *userInterfaceImpl) update() error {
}() }()
w, h := u.outsideSize() w, h := u.outsideSize()
if err := u.context.updateFrame(graphicsDriver(), w, h, deviceScale()); err != nil { if err := u.context.updateFrame(u.graphicsDriver, w, h, deviceScale()); err != nil {
return err return err
} }
return nil return nil