mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
driver: Let UI have Graphics
Now UIs own the implementation of Graphics. Updates #1026
This commit is contained in:
parent
e66f1fb71e
commit
982b7d6ddc
@ -31,8 +31,8 @@ type UIContext interface {
|
||||
var RegularTermination = errors.New("regular termination")
|
||||
|
||||
type UI interface {
|
||||
Run(context UIContext, graphics Graphics) error
|
||||
RunWithoutMainLoop(width, height int, scale float64, title string, context UIContext, graphics Graphics) <-chan error
|
||||
Run(context UIContext) error
|
||||
RunWithoutMainLoop(width, height int, scale float64, title string, context UIContext) <-chan error
|
||||
|
||||
DeviceScaleFactor() float64
|
||||
CursorMode() CursorMode
|
||||
@ -51,6 +51,7 @@ type UI interface {
|
||||
|
||||
Input() Input
|
||||
Window() Window
|
||||
Graphics() Graphics
|
||||
}
|
||||
|
||||
type Window interface {
|
||||
|
@ -12,11 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build darwin,!ios
|
||||
// +build darwin
|
||||
// +build !js
|
||||
// +build !ebitengl
|
||||
|
||||
package ebiten
|
||||
package glfw
|
||||
|
||||
// #cgo CFLAGS: -x objective-c
|
||||
// #cgo LDFLAGS: -framework Foundation
|
||||
@ -48,7 +48,7 @@ var (
|
||||
isMetalSupportedOnce sync.Once
|
||||
)
|
||||
|
||||
func graphicsDriver() driver.Graphics {
|
||||
func (*UserInterface) Graphics() driver.Graphics {
|
||||
isMetalSupportedOnce.Do(func() {
|
||||
// On old mac devices like iMac 2011, Metal is not supported (#779).
|
||||
if _, err := mtl.CreateSystemDefaultDevice(); err != nil {
|
@ -12,15 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build android darwin,ios,386 darwin,ios,amd64 freebsd js linux windows ebitengl
|
||||
// +build freebsd js linux windows ebitengl
|
||||
|
||||
package ebiten
|
||||
package glfw
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/internal/driver"
|
||||
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl"
|
||||
)
|
||||
|
||||
func graphicsDriver() driver.Graphics {
|
||||
func (*UserInterface) Graphics() driver.Graphics {
|
||||
return opengl.Get()
|
||||
}
|
@ -72,9 +72,8 @@ type UserInterface struct {
|
||||
reqWidth int
|
||||
reqHeight int
|
||||
|
||||
graphics driver.Graphics
|
||||
input Input
|
||||
iwindow window
|
||||
input Input
|
||||
iwindow window
|
||||
|
||||
t *thread.Thread
|
||||
m sync.RWMutex
|
||||
@ -509,11 +508,10 @@ func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
func (u *UserInterface) Run(uicontext driver.UIContext, graphics driver.Graphics) error {
|
||||
func (u *UserInterface) Run(uicontext driver.UIContext) error {
|
||||
// Initialize the main thread first so the thread is available at u.run (#809).
|
||||
u.t = thread.New()
|
||||
u.graphics = graphics
|
||||
u.graphics.SetThread(u.t)
|
||||
u.Graphics().SetThread(u.t)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
@ -532,7 +530,7 @@ func (u *UserInterface) Run(uicontext driver.UIContext, graphics driver.Graphics
|
||||
return <-ch
|
||||
}
|
||||
|
||||
func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, title string, context driver.UIContext, graphics driver.Graphics) <-chan error {
|
||||
func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, title string, context driver.UIContext) <-chan error {
|
||||
panic("glfw: RunWithoutMainLoop is not implemented")
|
||||
}
|
||||
|
||||
@ -553,7 +551,7 @@ func (u *UserInterface) createWindow() error {
|
||||
}
|
||||
u.window = window
|
||||
|
||||
if u.graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
u.window.MakeContextCurrent()
|
||||
}
|
||||
|
||||
@ -591,7 +589,7 @@ func (u *UserInterface) run(context driver.UIContext) error {
|
||||
u.window.Destroy()
|
||||
u.window = nil
|
||||
|
||||
if u.graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
glfw.WindowHint(glfw.ContextVersionMajor, 2)
|
||||
glfw.WindowHint(glfw.ContextVersionMinor, 1)
|
||||
} else {
|
||||
@ -609,7 +607,7 @@ func (u *UserInterface) run(context driver.UIContext) error {
|
||||
transparent = glfw.True
|
||||
}
|
||||
glfw.WindowHint(glfw.TransparentFramebuffer, transparent)
|
||||
u.graphics.SetTransparent(u.isInitScreenTransparent())
|
||||
u.Graphics().SetTransparent(u.isInitScreenTransparent())
|
||||
|
||||
resizable := glfw.False
|
||||
if u.isInitWindowResizable() {
|
||||
@ -652,7 +650,7 @@ func (u *UserInterface) run(context driver.UIContext) error {
|
||||
w = u.nativeWindow()
|
||||
return nil
|
||||
})
|
||||
u.graphics.SetWindow(w)
|
||||
u.Graphics().SetWindow(w)
|
||||
return u.loop(context)
|
||||
}
|
||||
|
||||
@ -807,7 +805,7 @@ func (u *UserInterface) loop(context driver.UIContext) error {
|
||||
|
||||
// swapBuffers must be called from the main thread.
|
||||
func (u *UserInterface) swapBuffers() {
|
||||
if u.graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
u.window.SwapBuffers()
|
||||
}
|
||||
}
|
||||
@ -844,13 +842,13 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool, vsync
|
||||
|
||||
// Swapping buffer is necesary to prevent the image lag (#1004).
|
||||
// TODO: This might not work when vsync is disabled.
|
||||
if u.graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
glfw.PollEvents()
|
||||
u.swapBuffers()
|
||||
}
|
||||
} else {
|
||||
if u.window.GetMonitor() != nil {
|
||||
if u.graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
// When OpenGL is used, swapping buffer is enough to solve the image-lag
|
||||
// issue (#1004). Rather, recreating window destroys GPU resources.
|
||||
// TODO: This might not work when vsync is disabled.
|
||||
@ -929,7 +927,7 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool, vsync
|
||||
u.windowWidth = width
|
||||
u.windowHeight = height
|
||||
|
||||
if u.graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
// SwapInterval is affected by the current monitor of the window.
|
||||
// This needs to be called at least after SetMonitor.
|
||||
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
|
||||
@ -943,14 +941,14 @@ func (u *UserInterface) setWindowSize(width, height int, fullscreen bool, vsync
|
||||
glfw.SwapInterval(0)
|
||||
}
|
||||
}
|
||||
u.graphics.SetVsyncEnabled(vsync)
|
||||
u.Graphics().SetVsyncEnabled(vsync)
|
||||
|
||||
u.toChangeSize = true
|
||||
return nil
|
||||
})
|
||||
|
||||
if windowRecreated {
|
||||
u.graphics.SetWindow(u.nativeWindow())
|
||||
u.Graphics().SetWindow(u.nativeWindow())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
||||
"github.com/hajimehoshi/ebiten/internal/driver"
|
||||
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl"
|
||||
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||
"github.com/hajimehoshi/ebiten/internal/jsutil"
|
||||
)
|
||||
@ -371,7 +372,7 @@ func init() {
|
||||
}))
|
||||
}
|
||||
|
||||
func (u *UserInterface) Run(context driver.UIContext, graphics driver.Graphics) error {
|
||||
func (u *UserInterface) Run(context driver.UIContext) error {
|
||||
canvas.Call("focus")
|
||||
u.running = true
|
||||
ch := u.loop(context)
|
||||
@ -392,7 +393,7 @@ func (u *UserInterface) Run(context driver.UIContext, graphics driver.Graphics)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, title string, context driver.UIContext, graphics driver.Graphics) <-chan error {
|
||||
func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, title string, context driver.UIContext) <-chan error {
|
||||
panic("js: RunWithoutMainLoop is not implemented")
|
||||
}
|
||||
|
||||
@ -434,3 +435,7 @@ func (u *UserInterface) Input() driver.Input {
|
||||
func (u *UserInterface) Window() driver.Window {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*UserInterface) Graphics() driver.Graphics {
|
||||
return opengl.Get()
|
||||
}
|
||||
|
@ -12,10 +12,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build darwin,ios,arm darwin,ios,arm64
|
||||
// +build ios,arm ios,arm64
|
||||
// +build !ebitengl
|
||||
|
||||
package ebiten
|
||||
package mobile
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -25,7 +25,7 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/metal/mtl"
|
||||
)
|
||||
|
||||
func graphicsDriver() driver.Graphics {
|
||||
func (*UserInterface) Graphics() driver.Graphics {
|
||||
if _, err := mtl.CreateSystemDefaultDevice(); err != nil {
|
||||
panic(fmt.Sprintf("ebiten: mtl.CreateSystemDefaultDevice failed on iOS: %v", err))
|
||||
}
|
26
internal/uidriver/mobile/graphics_opengl.go
Normal file
26
internal/uidriver/mobile/graphics_opengl.go
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2018 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build android ios,386 ios,amd64 ebitengl
|
||||
|
||||
package mobile
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/internal/driver"
|
||||
"github.com/hajimehoshi/ebiten/internal/graphicsdriver/opengl"
|
||||
)
|
||||
|
||||
func (*UserInterface) Graphics() driver.Graphics {
|
||||
return opengl.Get()
|
||||
}
|
@ -72,7 +72,7 @@ func (u *UserInterface) Update() {
|
||||
}
|
||||
}()
|
||||
|
||||
if u.graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
if u.glWorker == nil {
|
||||
panic("mobile: glWorker must be initialized but not")
|
||||
}
|
||||
@ -105,8 +105,7 @@ type UserInterface struct {
|
||||
gbuildHeightPx int
|
||||
setGBuildSizeCh chan struct{}
|
||||
|
||||
context driver.UIContext
|
||||
graphics driver.Graphics
|
||||
context driver.UIContext
|
||||
|
||||
input Input
|
||||
|
||||
@ -182,12 +181,12 @@ func (u *UserInterface) appMain(a app.App) {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserInterface) Run(context driver.UIContext, graphics driver.Graphics) error {
|
||||
func (u *UserInterface) Run(context driver.UIContext) error {
|
||||
// TODO: Remove width/height/scale arguments. They are not used from gomobile-build.
|
||||
|
||||
u.setGBuildSizeCh = make(chan struct{})
|
||||
go func() {
|
||||
if err := u.run(16, 16, 1, context, graphics, true); err != nil {
|
||||
if err := u.run(16, 16, 1, context, true); err != nil {
|
||||
// As mobile apps never ends, Loop can't return. Just panic here.
|
||||
panic(err)
|
||||
}
|
||||
@ -196,12 +195,12 @@ func (u *UserInterface) Run(context driver.UIContext, graphics driver.Graphics)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, title string, context driver.UIContext, graphics driver.Graphics) <-chan error {
|
||||
func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, title string, context driver.UIContext) <-chan error {
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
// title is ignored?
|
||||
if err := u.run(width, height, scale, context, graphics, false); err != nil {
|
||||
if err := u.run(width, height, scale, context, false); err != nil {
|
||||
ch <- err
|
||||
}
|
||||
}()
|
||||
@ -209,7 +208,7 @@ func (u *UserInterface) RunWithoutMainLoop(width, height int, scale float64, tit
|
||||
return ch
|
||||
}
|
||||
|
||||
func (u *UserInterface) run(width, height int, scale float64, context driver.UIContext, graphics driver.Graphics, mainloop bool) (err error) {
|
||||
func (u *UserInterface) run(width, height int, scale float64, context driver.UIContext, mainloop bool) (err error) {
|
||||
// Convert the panic to a regular error so that Java/Objective-C layer can treat this easily e.g., for
|
||||
// Crashlytics. A panic is treated as SIGABRT, and there is no way to handle this on Java/Objective-C layer
|
||||
// unfortunately.
|
||||
@ -226,20 +225,19 @@ func (u *UserInterface) run(width, height int, scale float64, context driver.UIC
|
||||
u.scale = scale
|
||||
u.sizeChanged = true
|
||||
u.context = context
|
||||
u.graphics = graphics
|
||||
u.m.Unlock()
|
||||
|
||||
if graphics.IsGL() {
|
||||
if u.Graphics().IsGL() {
|
||||
var ctx gl.Context
|
||||
if mainloop {
|
||||
ctx = <-glContextCh
|
||||
} else {
|
||||
ctx, u.glWorker = gl.NewContext()
|
||||
}
|
||||
graphics.(*opengl.Driver).SetMobileGLContext(ctx)
|
||||
u.Graphics().(*opengl.Driver).SetMobileGLContext(ctx)
|
||||
} else {
|
||||
u.t = thread.New()
|
||||
graphics.SetThread(u.t)
|
||||
u.Graphics().SetThread(u.t)
|
||||
}
|
||||
|
||||
// If gomobile-build is used, wait for the outside size fixed.
|
||||
|
4
run.go
4
run.go
@ -215,7 +215,7 @@ func RunGame(game Game) error {
|
||||
|
||||
func runGame(game Game, scale float64) error {
|
||||
theUIContext.set(game, scale)
|
||||
if err := uiDriver().Run(theUIContext, graphicsDriver()); err != nil {
|
||||
if err := uiDriver().Run(theUIContext); err != nil {
|
||||
if err == driver.RegularTermination {
|
||||
return nil
|
||||
}
|
||||
@ -236,7 +236,7 @@ func RunWithoutMainLoop(f func(*Image) error, width, height int, scale float64,
|
||||
height: height,
|
||||
}
|
||||
theUIContext.set(game, scale)
|
||||
return uiDriver().RunWithoutMainLoop(width, height, scale, title, theUIContext, graphicsDriver())
|
||||
return uiDriver().RunWithoutMainLoop(width, height, scale, title, theUIContext)
|
||||
}
|
||||
|
||||
// ScreenSizeInFullscreen is deprecated as of 1.11.0-alpha.
|
||||
|
@ -28,8 +28,8 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
shareable.SetGraphicsDriver(graphicsDriver())
|
||||
graphicscommand.SetGraphicsDriver(graphicsDriver())
|
||||
shareable.SetGraphicsDriver(uiDriver().Graphics())
|
||||
graphicscommand.SetGraphicsDriver(uiDriver().Graphics())
|
||||
}
|
||||
|
||||
type defaultGame struct {
|
||||
@ -275,7 +275,7 @@ func (c *uiContext) update(afterFrameUpdate func()) error {
|
||||
op := &DrawImageOptions{}
|
||||
|
||||
s := c.screenScale()
|
||||
switch vd := graphicsDriver().VDirection(); vd {
|
||||
switch vd := uiDriver().Graphics().VDirection(); vd {
|
||||
case driver.VDownward:
|
||||
// c.screen is special: its Y axis is down to up,
|
||||
// and the origin point is lower left.
|
||||
|
Loading…
Reference in New Issue
Block a user