clock: Refactoring: Move frames calculation to clock

This commit is contained in:
Hajime Hoshi 2017-08-06 00:18:38 +09:00
parent 288a7ede8d
commit b7d559fdf3
3 changed files with 49 additions and 51 deletions

View File

@ -262,7 +262,7 @@ func (c *Context) loop() {
c.pingCount-- c.pingCount--
c.m.Unlock() c.m.Unlock()
c.frames++ c.frames++
clock.Tick() clock.Inc()
bytesPerFrame := c.sampleRate * bytesPerSample * channelNum / loop.FPS bytesPerFrame := c.sampleRate * bytesPerSample * channelNum / loop.FPS
l := (c.frames * int64(bytesPerFrame)) - c.writtenBytes l := (c.frames * int64(bytesPerFrame)) - c.writtenBytes
l &= mask l &= mask

View File

@ -15,32 +15,63 @@
package clock package clock
import ( import (
"time"
"github.com/hajimehoshi/ebiten/internal/sync" "github.com/hajimehoshi/ebiten/internal/sync"
) )
var ( var (
m sync.Mutex m sync.Mutex
valid bool valid bool
now int64 tick int64
lastTick int64
frames int64
) )
func IsValid() bool { func Inc() {
m.Lock()
v := valid
m.Unlock()
return v
}
func Tick() {
m.Lock() m.Lock()
valid = true valid = true
now++ tick++
m.Unlock() m.Unlock()
} }
func Now() int64 { func Frames(timeDuration time.Duration, fps int) (int, bool) {
m.Lock() m.Lock()
n := now defer m.Unlock()
m.Unlock()
return n count := 0
sync := false
if valid && lastTick != tick {
if frames < tick {
count = int(tick - frames)
}
lastTick = tick
sync = true
} else {
// Use system clock when
// 1) Inc() is not called, or
// 2) tick is not updated yet.
// As tick can be updated discountinuously, use system clock supplementarily.
if int64(timeDuration) > 5*int64(time.Second)/int64(fps) {
// The previous time is too old. Let's assume that the window was unfocused.
return 0, true
}
count = int(int64(timeDuration) * int64(fps) / int64(time.Second))
}
// Stabilize FPS.
if count == 0 && (int64(time.Second)/int64(fps)/2) < int64(timeDuration) {
count = 1
}
if count == 2 && (int64(time.Second)/int64(fps)*3/2) > int64(timeDuration) {
count = 1
}
if count > 3 {
count = 3
}
frames += int64(count)
return count, sync
} }

View File

@ -34,11 +34,9 @@ func CurrentFPS() float64 {
type runContext struct { type runContext struct {
currentFPS float64 currentFPS float64
runningSlowly bool runningSlowly bool
frames int64
framesForFPS int64 framesForFPS int64
lastUpdated int64 lastUpdated int64
lastFPSUpdated int64 lastFPSUpdated int64
lastClockFrame int64
ping func() ping func()
m sync.RWMutex m sync.RWMutex
} }
@ -81,42 +79,12 @@ func End() {
} }
func (c *runContext) updateCount(now int64) int { func (c *runContext) updateCount(now int64) int {
count := 0
sync := false
t := now - c.lastUpdated t := now - c.lastUpdated
if t < 0 { if t < 0 {
return 0 return 0
} }
if clock.IsValid() && c.lastClockFrame != clock.Now() { count, sync := clock.Frames(time.Duration(t), FPS)
sync = true
f := clock.Now()
if c.frames < f {
count = int(f - c.frames)
}
c.lastClockFrame = f
} else {
if t > 5*int64(time.Second)/int64(FPS) {
// The previous time is too old. Let's assume that the window was unfocused.
count = 0
sync = true
} else {
count = int(t * int64(FPS) / int64(time.Second))
}
}
// Stabilize FPS.
if count == 0 && (int64(time.Second)/int64(FPS)/2) < t {
count = 1
}
if count == 2 && (int64(time.Second)/int64(FPS)*3/2) > t {
count = 1
}
if count > 3 {
count = 3
}
if sync { if sync {
c.lastUpdated = now c.lastUpdated = now
@ -124,7 +92,6 @@ func (c *runContext) updateCount(now int64) int {
c.lastUpdated += int64(count) * int64(time.Second) / int64(FPS) c.lastUpdated += int64(count) * int64(time.Second) / int64(FPS)
} }
c.frames += int64(count)
return count return count
} }