mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/ui: make adjustPosition concurrent-safe
This commit is contained in:
parent
31aa01131d
commit
a2cb9fda82
@ -16,6 +16,7 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/buffered"
|
"github.com/hajimehoshi/ebiten/v2/internal/buffered"
|
||||||
@ -34,10 +35,13 @@ type Context interface {
|
|||||||
type contextImpl struct {
|
type contextImpl struct {
|
||||||
context Context
|
context Context
|
||||||
|
|
||||||
|
// The following members must be protected by the mutex m.
|
||||||
outsideWidth float64
|
outsideWidth float64
|
||||||
outsideHeight float64
|
outsideHeight float64
|
||||||
offscreenWidth int
|
offscreenWidth int
|
||||||
offscreenHeight int
|
offscreenHeight int
|
||||||
|
|
||||||
|
m sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContextImpl(context Context) *contextImpl {
|
func newContextImpl(context Context) *contextImpl {
|
||||||
@ -56,16 +60,12 @@ func (c *contextImpl) forceUpdateFrame(deviceScaleFactor float64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64) error {
|
func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64) error {
|
||||||
ow, oh := c.context.UpdateOffscreen(c.outsideWidth, c.outsideHeight, deviceScaleFactor)
|
|
||||||
c.offscreenWidth = ow
|
|
||||||
c.offscreenHeight = oh
|
|
||||||
|
|
||||||
if err := theGlobalState.err(); err != nil {
|
if err := theGlobalState.err(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForceUpdate can be invoked even if the context is not initialized yet (#1591).
|
// ForceUpdate can be invoked even if the context is not initialized yet (#1591).
|
||||||
if c.outsideWidth == 0 || c.outsideHeight == 0 {
|
if w, h := c.updateOffscreenSize(deviceScaleFactor); w == 0 || h == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +75,7 @@ func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
screenScale := c.screenScale(deviceScaleFactor)
|
screenScale, offsetX, offsetY := c.screenScaleAndOffsets(deviceScaleFactor)
|
||||||
offsetX, offsetY := c.offsets(deviceScaleFactor)
|
|
||||||
if err := c.context.UpdateFrame(updateCount, screenScale, offsetX, offsetY); err != nil {
|
if err := c.context.UpdateFrame(updateCount, screenScale, offsetX, offsetY); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -91,6 +90,16 @@ func (c *contextImpl) updateFrameImpl(updateCount int, deviceScaleFactor float64
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *contextImpl) updateOffscreenSize(deviceScaleFactor float64) (int, int) {
|
||||||
|
c.m.Lock()
|
||||||
|
defer c.m.Unlock()
|
||||||
|
|
||||||
|
w, h := c.context.UpdateOffscreen(c.outsideWidth, c.outsideHeight, deviceScaleFactor)
|
||||||
|
c.offscreenWidth = w
|
||||||
|
c.offscreenHeight = h
|
||||||
|
return w, h
|
||||||
|
}
|
||||||
|
|
||||||
func (c *contextImpl) layout(outsideWidth, outsideHeight float64) {
|
func (c *contextImpl) layout(outsideWidth, outsideHeight float64) {
|
||||||
// The given outside size can be 0 e.g. just after restoring from the fullscreen mode on Windows (#1589)
|
// The given outside size can be 0 e.g. just after restoring from the fullscreen mode on Windows (#1589)
|
||||||
// Just ignore such cases. Otherwise, creating a zero-sized framebuffer causes a panic.
|
// Just ignore such cases. Otherwise, creating a zero-sized framebuffer causes a panic.
|
||||||
@ -98,14 +107,14 @@ func (c *contextImpl) layout(outsideWidth, outsideHeight float64) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.m.Lock()
|
||||||
|
defer c.m.Unlock()
|
||||||
c.outsideWidth = outsideWidth
|
c.outsideWidth = outsideWidth
|
||||||
c.outsideHeight = outsideHeight
|
c.outsideHeight = outsideHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make adjustPosition concurrent-safe.
|
|
||||||
func (c *contextImpl) adjustPosition(x, y float64, deviceScaleFactor float64) (float64, float64) {
|
func (c *contextImpl) adjustPosition(x, y float64, deviceScaleFactor float64) (float64, float64) {
|
||||||
ox, oy := c.offsets(deviceScaleFactor)
|
s, ox, oy := c.screenScaleAndOffsets(deviceScaleFactor)
|
||||||
s := c.screenScale(deviceScaleFactor)
|
|
||||||
// The scale 0 indicates that the offscreen is not initialized yet.
|
// The scale 0 indicates that the offscreen is not initialized yet.
|
||||||
// As any cursor values don't make sense, just return NaN.
|
// As any cursor values don't make sense, just return NaN.
|
||||||
if s == 0 {
|
if s == 0 {
|
||||||
@ -114,25 +123,22 @@ func (c *contextImpl) adjustPosition(x, y float64, deviceScaleFactor float64) (f
|
|||||||
return (x*deviceScaleFactor - ox) / s, (y*deviceScaleFactor - oy) / s
|
return (x*deviceScaleFactor - ox) / s, (y*deviceScaleFactor - oy) / s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *contextImpl) offsets(deviceScaleFactor float64) (float64, float64) {
|
func (c *contextImpl) screenScaleAndOffsets(deviceScaleFactor float64) (float64, float64, float64) {
|
||||||
if c.offscreenWidth == 0 || c.offscreenHeight == 0 {
|
c.m.Lock()
|
||||||
return 0, 0
|
defer c.m.Unlock()
|
||||||
}
|
|
||||||
s := c.screenScale(deviceScaleFactor)
|
|
||||||
width := float64(c.offscreenWidth) * s
|
|
||||||
height := float64(c.offscreenHeight) * s
|
|
||||||
x := (c.outsideWidth*deviceScaleFactor - width) / 2
|
|
||||||
y := (c.outsideHeight*deviceScaleFactor - height) / 2
|
|
||||||
return x, y
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *contextImpl) screenScale(deviceScaleFactor float64) float64 {
|
|
||||||
if c.offscreenWidth == 0 || c.offscreenHeight == 0 {
|
if c.offscreenWidth == 0 || c.offscreenHeight == 0 {
|
||||||
return 0
|
return 0, 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
scaleX := c.outsideWidth / float64(c.offscreenWidth) * deviceScaleFactor
|
scaleX := c.outsideWidth / float64(c.offscreenWidth) * deviceScaleFactor
|
||||||
scaleY := c.outsideHeight / float64(c.offscreenHeight) * deviceScaleFactor
|
scaleY := c.outsideHeight / float64(c.offscreenHeight) * deviceScaleFactor
|
||||||
return math.Min(scaleX, scaleY)
|
scale := math.Min(scaleX, scaleY)
|
||||||
|
width := float64(c.offscreenWidth) * scale
|
||||||
|
height := float64(c.offscreenHeight) * scale
|
||||||
|
x := (c.outsideWidth*deviceScaleFactor - width) / 2
|
||||||
|
y := (c.outsideHeight*deviceScaleFactor - height) / 2
|
||||||
|
return scale, x, y
|
||||||
}
|
}
|
||||||
|
|
||||||
var theGlobalState = globalState{
|
var theGlobalState = globalState{
|
||||||
|
Loading…
Reference in New Issue
Block a user