mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
ebiten: add (*Monitor).DeviceScaleFactor()
This replaces ebiten.DeviceScaleFactor(). Updates #2795
This commit is contained in:
parent
67d947d37a
commit
6d898d752e
@ -72,7 +72,7 @@ func (g *Game) Update() error {
|
||||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
scale := ebiten.DeviceScaleFactor()
|
||||
scale := ebiten.Monitor().DeviceScaleFactor()
|
||||
|
||||
w, h := gophersImage.Bounds().Dx(), gophersImage.Bounds().Dy()
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
@ -99,15 +99,15 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
textOp := &text.DrawOptions{}
|
||||
textOp.GeoM.Translate(50*scale, 50*scale)
|
||||
textOp.ColorScale.ScaleWithColor(color.White)
|
||||
textOp.LineSpacing = 12 * ebiten.DeviceScaleFactor() * 1.5
|
||||
textOp.LineSpacing = 12 * ebiten.Monitor().DeviceScaleFactor() * 1.5
|
||||
text.Draw(screen, msg, &text.GoTextFace{
|
||||
Source: mplusFaceSource,
|
||||
Size: 12 * ebiten.DeviceScaleFactor(),
|
||||
Size: 12 * ebiten.Monitor().DeviceScaleFactor(),
|
||||
}, textOp)
|
||||
}
|
||||
|
||||
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||
s := ebiten.DeviceScaleFactor()
|
||||
s := ebiten.Monitor().DeviceScaleFactor()
|
||||
return int(float64(outsideWidth) * s), int(float64(outsideHeight) * s)
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
|
||||
// Scale the image by the device ratio so that the rendering result can be same
|
||||
// on various (different-DPI) environments.
|
||||
scale := ebiten.DeviceScaleFactor()
|
||||
scale := ebiten.Monitor().DeviceScaleFactor()
|
||||
op.GeoM.Scale(scale, scale)
|
||||
|
||||
// Move the image's center to the screen's center.
|
||||
@ -99,7 +99,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||
// The unit of outsideWidth/Height is device-independent pixels.
|
||||
// By multiplying them by the device scale factor, we can get a hi-DPI screen size.
|
||||
s := ebiten.DeviceScaleFactor()
|
||||
s := ebiten.Monitor().DeviceScaleFactor()
|
||||
return int(float64(outsideWidth) * s), int(float64(outsideHeight) * s)
|
||||
}
|
||||
|
||||
|
@ -376,7 +376,7 @@ Window size limitation: (%d, %d) - (%d, %d)
|
||||
Cursor: (%d, %d)
|
||||
TPS: Current: %0.2f / Max: %s
|
||||
FPS: %0.2f
|
||||
Device Scale Factor: %0.2f`, msgM, msgR, fg, wx, wy, ww, wh, minw, minh, maxw, maxh, cx, cy, ebiten.ActualTPS(), tpsStr, ebiten.ActualFPS(), ebiten.DeviceScaleFactor())
|
||||
Device Scale Factor: %0.2f`, msgM, msgR, fg, wx, wy, ww, wh, minw, minh, maxw, maxh, cx, cy, ebiten.ActualTPS(), tpsStr, ebiten.ActualFPS(), ebiten.Monitor().DeviceScaleFactor())
|
||||
ebitenutil.DebugPrint(screen, msg)
|
||||
}
|
||||
|
||||
@ -400,7 +400,7 @@ func parseWindowPosition() (int, int, bool) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Device scale factor: %0.2f\n", ebiten.DeviceScaleFactor())
|
||||
fmt.Printf("Device scale factor: %0.2f\n", ebiten.Monitor().DeviceScaleFactor())
|
||||
w, h := ebiten.ScreenSizeInFullscreen()
|
||||
fmt.Printf("Screen size in fullscreen: %d, %d\n", w, h)
|
||||
|
||||
|
@ -286,5 +286,5 @@ func (c *context) screenScaleAndOffsets() (scale, offsetX, offsetY float64) {
|
||||
}
|
||||
|
||||
func (u *UserInterface) LogicalPositionToClientPosition(x, y float64) (float64, float64) {
|
||||
return u.context.logicalPositionToClientPosition(x, y, u.DeviceScaleFactor())
|
||||
return u.context.logicalPositionToClientPosition(x, y, u.Monitor().DeviceScaleFactor())
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ func (u *UserInterface) updateInputStateImpl() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := m.deviceScaleFactor()
|
||||
s := m.DeviceScaleFactor()
|
||||
|
||||
cx, cy := u.savedCursorX, u.savedCursorY
|
||||
defer func() {
|
||||
|
@ -305,7 +305,7 @@ func (u *UserInterface) updateInputState() error {
|
||||
u.keyDurationsByKeyProperty[key]++
|
||||
}
|
||||
|
||||
s := u.DeviceScaleFactor()
|
||||
s := theMonitor.DeviceScaleFactor()
|
||||
|
||||
if !math.IsNaN(u.savedCursorX) && !math.IsNaN(u.savedCursorY) {
|
||||
// If savedCursorX and savedCursorY are valid values, the cursor is saved just before entering or exiting from fullscreen.
|
||||
|
@ -47,7 +47,7 @@ func (u *UserInterface) updateInputState() error {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
|
||||
s := u.DeviceScaleFactor()
|
||||
s := theMonitor.DeviceScaleFactor()
|
||||
|
||||
u.inputState.Touches = u.inputState.Touches[:0]
|
||||
for _, t := range u.touches {
|
||||
|
@ -60,7 +60,7 @@ func (u *UserInterface) updateInputStateImpl() error {
|
||||
|
||||
u.inputState.Touches = u.inputState.Touches[:0]
|
||||
for _, t := range u.nativeTouches {
|
||||
x, y := u.context.clientPositionToLogicalPosition(float64(t.x), float64(t.y), deviceScaleFactor)
|
||||
x, y := u.context.clientPositionToLogicalPosition(float64(t.x), float64(t.y), theMonitor.DeviceScaleFactor())
|
||||
u.inputState.Touches = append(u.inputState.Touches, Touch{
|
||||
ID: TouchID(t.id),
|
||||
X: int(x),
|
||||
|
@ -40,7 +40,8 @@ func (m *Monitor) Name() string {
|
||||
return m.name
|
||||
}
|
||||
|
||||
func (m *Monitor) deviceScaleFactor() float64 {
|
||||
// DeviceScaleFactor is concurrent-safe as contentScale is immutable.
|
||||
func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
// It is rare, but monitor can be nil when glfw.GetPrimaryMonitor returns nil.
|
||||
// In this case, return 1 as a tentative scale (#1878).
|
||||
if m == nil {
|
||||
|
@ -833,29 +833,6 @@ func (u *UserInterface) SetCursorShape(shape CursorShape) {
|
||||
})
|
||||
}
|
||||
|
||||
func (u *UserInterface) DeviceScaleFactor() float64 {
|
||||
if u.isTerminated() {
|
||||
return 0
|
||||
}
|
||||
if !u.isRunning() {
|
||||
return u.getInitMonitor().deviceScaleFactor()
|
||||
}
|
||||
|
||||
var f float64
|
||||
u.mainThread.Call(func() {
|
||||
if u.isTerminated() {
|
||||
return
|
||||
}
|
||||
m, err := u.currentMonitor()
|
||||
if err != nil {
|
||||
u.setError(err)
|
||||
return
|
||||
}
|
||||
f = m.deviceScaleFactor()
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
// createWindow creates a GLFW window.
|
||||
//
|
||||
// createWindow must be called from the main thread.
|
||||
@ -988,7 +965,7 @@ func (u *UserInterface) registerWindowFramebufferSizeCallback() error {
|
||||
u.setError(err)
|
||||
return
|
||||
}
|
||||
s := m.deviceScaleFactor()
|
||||
s := m.DeviceScaleFactor()
|
||||
ww := int(float64(w) / s)
|
||||
wh := int(float64(h) / s)
|
||||
if err := u.setWindowSizeInDIP(ww, wh, false); err != nil {
|
||||
@ -1460,7 +1437,7 @@ func (u *UserInterface) updateGame() error {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
deviceScaleFactor = m.deviceScaleFactor()
|
||||
deviceScaleFactor = m.DeviceScaleFactor()
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1639,7 +1616,7 @@ func (u *UserInterface) setWindowSizeInDIP(width, height int, callSetSize bool)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
scale := mon.deviceScaleFactor()
|
||||
scale := mon.DeviceScaleFactor()
|
||||
if u.origWindowWidthInDIP == width && u.origWindowHeightInDIP == height && u.lastDeviceScaleFactor == scale {
|
||||
return nil
|
||||
}
|
||||
|
@ -97,8 +97,6 @@ type userInterfaceImpl struct {
|
||||
onceUpdateCalled bool
|
||||
lastCaptureExitTime time.Time
|
||||
|
||||
deviceScaleFactor float64
|
||||
|
||||
context *context
|
||||
inputState InputState
|
||||
keyDurationsByKeyProperty map[Key]int
|
||||
@ -271,19 +269,6 @@ func (u *UserInterface) SetCursorShape(shape CursorShape) {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserInterface) DeviceScaleFactor() float64 {
|
||||
if u.deviceScaleFactor != 0 {
|
||||
return u.deviceScaleFactor
|
||||
}
|
||||
|
||||
ratio := window.Get("devicePixelRatio").Float()
|
||||
if ratio == 0 {
|
||||
ratio = 1
|
||||
}
|
||||
u.deviceScaleFactor = ratio
|
||||
return u.deviceScaleFactor
|
||||
}
|
||||
|
||||
func (u *UserInterface) outsideSize() (float64, float64) {
|
||||
if document.Truthy() {
|
||||
body := document.Get("body")
|
||||
@ -365,11 +350,11 @@ func (u *UserInterface) updateImpl(force bool) error {
|
||||
|
||||
w, h := u.outsideSize()
|
||||
if force {
|
||||
if err := u.context.forceUpdateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u); err != nil {
|
||||
if err := u.context.forceUpdateFrame(u.graphicsDriver, w, h, theMonitor.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, theMonitor.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -771,8 +756,9 @@ func (u *UserInterface) initOnMainThread(options *RunOptions) error {
|
||||
func (u *UserInterface) updateScreenSize() {
|
||||
if document.Truthy() {
|
||||
body := document.Get("body")
|
||||
bw := int(body.Get("clientWidth").Float() * u.DeviceScaleFactor())
|
||||
bh := int(body.Get("clientHeight").Float() * u.DeviceScaleFactor())
|
||||
f := theMonitor.DeviceScaleFactor()
|
||||
bw := int(body.Get("clientWidth").Float() * f)
|
||||
bh := int(body.Get("clientHeight").Float() * f)
|
||||
canvas.Set("width", bw)
|
||||
canvas.Set("height", bh)
|
||||
}
|
||||
@ -787,7 +773,9 @@ func (u *UserInterface) Window() Window {
|
||||
return &nullWindow{}
|
||||
}
|
||||
|
||||
type Monitor struct{}
|
||||
type Monitor struct {
|
||||
deviceScaleFactor float64
|
||||
}
|
||||
|
||||
var theMonitor = &Monitor{}
|
||||
|
||||
@ -795,6 +783,19 @@ func (m *Monitor) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
if m.deviceScaleFactor != 0 {
|
||||
return m.deviceScaleFactor
|
||||
}
|
||||
|
||||
ratio := window.Get("devicePixelRatio").Float()
|
||||
if ratio == 0 {
|
||||
ratio = 1
|
||||
}
|
||||
m.deviceScaleFactor = ratio
|
||||
return m.deviceScaleFactor
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
@ -123,11 +123,11 @@ func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int, error) {
|
||||
}
|
||||
|
||||
func dipFromGLFWPixel(x float64, monitor *Monitor) float64 {
|
||||
return x / monitor.deviceScaleFactor()
|
||||
return x / monitor.DeviceScaleFactor()
|
||||
}
|
||||
|
||||
func dipToGLFWPixel(x float64, monitor *Monitor) float64 {
|
||||
return x * monitor.deviceScaleFactor()
|
||||
return x * monitor.DeviceScaleFactor()
|
||||
}
|
||||
|
||||
func (u *UserInterface) adjustWindowPosition(x, y int, monitor *Monitor) (int, int) {
|
||||
|
@ -89,9 +89,6 @@ type userInterfaceImpl struct {
|
||||
outsideWidth float64
|
||||
outsideHeight float64
|
||||
|
||||
deviceScaleFactorOnce sync.Once
|
||||
deviceScaleFactor float64
|
||||
|
||||
foreground int32
|
||||
errCh chan error
|
||||
|
||||
@ -179,8 +176,11 @@ func (u *UserInterface) update() error {
|
||||
renderEndCh <- struct{}{}
|
||||
}()
|
||||
|
||||
// The device scale factor can be obtained after the main function starts, especially on Android.
|
||||
theMonitor.initDeviceScaleFactorIfNeeded()
|
||||
|
||||
w, h := u.outsideSize()
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, u.DeviceScaleFactor(), u); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, w, h, theMonitor.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -256,14 +256,6 @@ func (u *UserInterface) updateExplicitRenderingModeIfNeeded(fpsMode FPSModeType)
|
||||
u.renderRequester.SetExplicitRenderingMode(fpsMode == FPSModeVsyncOffMinimum)
|
||||
}
|
||||
|
||||
func (u *UserInterface) DeviceScaleFactor() float64 {
|
||||
// Assume that the device scale factor never changes on mobiles.
|
||||
u.deviceScaleFactorOnce.Do(func() {
|
||||
u.deviceScaleFactor = deviceScaleFactorImpl()
|
||||
})
|
||||
return u.deviceScaleFactor
|
||||
}
|
||||
|
||||
func (u *UserInterface) readInputState(inputState *InputState) {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
@ -274,7 +266,11 @@ func (u *UserInterface) Window() Window {
|
||||
return &nullWindow{}
|
||||
}
|
||||
|
||||
type Monitor struct{}
|
||||
type Monitor struct {
|
||||
deviceScaleFactor float64
|
||||
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
var theMonitor = &Monitor{}
|
||||
|
||||
@ -282,6 +278,22 @@ func (m *Monitor) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Monitor) initDeviceScaleFactorIfNeeded() {
|
||||
// Assume that the device scale factor never changes on mobiles.
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
if m.deviceScaleFactor != 0 {
|
||||
return
|
||||
}
|
||||
m.deviceScaleFactor = deviceScaleFactorImpl()
|
||||
}
|
||||
|
||||
func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
return m.deviceScaleFactor
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
@ -54,8 +54,6 @@ func (*graphicsDriverCreatorImpl) newPlayStation5() (graphicsdriver.Graphics, er
|
||||
return nil, errors.New("ui: PlayStation 5 is not supported in this environment")
|
||||
}
|
||||
|
||||
const deviceScaleFactor = 1
|
||||
|
||||
func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
@ -94,16 +92,12 @@ func (u *UserInterface) loopGame() error {
|
||||
for {
|
||||
recordProfilerHeartbeat()
|
||||
|
||||
if err := u.context.updateFrame(u.graphicsDriver, float64(C.kScreenWidth), float64(C.kScreenHeight), deviceScaleFactor, u); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, float64(C.kScreenWidth), float64(C.kScreenHeight), theMonitor.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (*UserInterface) DeviceScaleFactor() float64 {
|
||||
return deviceScaleFactor
|
||||
}
|
||||
|
||||
func (*UserInterface) IsFocused() bool {
|
||||
return true
|
||||
}
|
||||
@ -172,6 +166,10 @@ func (m *Monitor) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ const (
|
||||
// TODO: Get this value from the SDK.
|
||||
screenWidth = 3840
|
||||
screenHeight = 2160
|
||||
deviceScaleFactor = 1
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -82,17 +81,13 @@ func (u *UserInterface) initOnMainThread(options *RunOptions) error {
|
||||
|
||||
func (u *UserInterface) loopGame() error {
|
||||
for {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, screenWidth, screenHeight, deviceScaleFactor, u); err != nil {
|
||||
if err := u.context.updateFrame(u.graphicsDriver, screenWidth, screenHeight, theMonitor.DeviceScaleFactor(), u); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*UserInterface) DeviceScaleFactor() float64 {
|
||||
return deviceScaleFactor
|
||||
}
|
||||
|
||||
func (*UserInterface) IsFocused() bool {
|
||||
return true
|
||||
}
|
||||
@ -164,6 +159,10 @@ func (m *Monitor) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
@ -102,11 +102,11 @@ func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int, error) {
|
||||
}
|
||||
|
||||
func dipFromGLFWPixel(x float64, monitor *Monitor) float64 {
|
||||
return x / monitor.deviceScaleFactor()
|
||||
return x / monitor.DeviceScaleFactor()
|
||||
}
|
||||
|
||||
func dipToGLFWPixel(x float64, monitor *Monitor) float64 {
|
||||
return x * monitor.deviceScaleFactor()
|
||||
return x * monitor.DeviceScaleFactor()
|
||||
}
|
||||
|
||||
func (u *UserInterface) adjustWindowPosition(x, y int, monitor *Monitor) (int, int) {
|
||||
|
@ -113,7 +113,7 @@ func Resume() error {
|
||||
}
|
||||
|
||||
func DeviceScale() float64 {
|
||||
return ui.Get().DeviceScaleFactor()
|
||||
return ui.Get().Monitor().DeviceScaleFactor()
|
||||
}
|
||||
|
||||
type RenderRequester interface {
|
||||
|
14
monitor.go
14
monitor.go
@ -27,6 +27,20 @@ func (m *MonitorType) Name() string {
|
||||
return (*ui.Monitor)(m).Name()
|
||||
}
|
||||
|
||||
// DeviceScaleFactor returns the device scale factor of the monitor.
|
||||
//
|
||||
// DeviceScaleFactor returns a meaningful value on high-DPI display environment,
|
||||
// otherwise DeviceScaleFactor returns 1.
|
||||
//
|
||||
// DeviceScaleFactor might panic on init function on some devices like Android.
|
||||
// Then, it is not recommended to call DeviceScaleFactor from init functions.
|
||||
//
|
||||
// DeviceScaleFactor must be called on the main thread before the main loop,
|
||||
// and is concurrent-safe after the main loop.
|
||||
func (m *MonitorType) DeviceScaleFactor() float64 {
|
||||
return (*ui.Monitor)(m).DeviceScaleFactor()
|
||||
}
|
||||
|
||||
// Monitor returns the current monitor.
|
||||
func Monitor() *MonitorType {
|
||||
m := ui.Get().Monitor()
|
||||
|
6
run.go
6
run.go
@ -480,11 +480,11 @@ func SetRunnableOnUnfocused(runnableOnUnfocused bool) {
|
||||
// DeviceScaleFactor must be called on the main thread before the main loop, and is concurrent-safe after the main
|
||||
// loop.
|
||||
//
|
||||
// DeviceScaleFactor is concurrent-safe.
|
||||
//
|
||||
// BUG: DeviceScaleFactor value is not affected by SetWindowPosition before RunGame (#1575).
|
||||
//
|
||||
// Deprecated: as of v2.6. Use Monitor().DeviceScaleFactor() instead.
|
||||
func DeviceScaleFactor() float64 {
|
||||
return ui.Get().DeviceScaleFactor()
|
||||
return Monitor().DeviceScaleFactor()
|
||||
}
|
||||
|
||||
// IsVsyncEnabled returns a boolean value indicating whether
|
||||
|
Loading…
Reference in New Issue
Block a user