Fix scale option (it is slow)

This commit is contained in:
Sergey Stepanov 2023-05-27 17:36:57 +03:00
parent 7668ef7bd8
commit a6bcf5cd94
No known key found for this signature in database
GPG key ID: A56B4929BAA8556B
6 changed files with 25 additions and 19 deletions

View file

@ -22,7 +22,7 @@ type Emulator interface {
// Start is called after LoadGame
Start()
// SetViewport sets viewport size
SetViewport(width int, height int)
SetViewport(width int, height int, scale int)
// SetMainSaveName sets distinct name for saves naming
SetMainSaveName(name string)
// SaveGameState save game state

View file

@ -86,6 +86,11 @@ func (c *Canvas) Draw(encoding uint32, rot *Rotate, w, h, packedW, bpp int, data
// rescale
if dst.Rect.Dx() != c.w || dst.Rect.Dy() != c.h {
ww, hh := c.w, c.h
// w, h supposedly have been swapped before
if c.vertical {
ww, hh = hh, ww
}
out := c.Get(c.w, c.h)
Resize(ScaleNearestNeighbour, dst.RGBA, out.RGBA)
c.Put(dst)

View file

@ -189,10 +189,10 @@ func (f *Frontend) LoadGameState() error { return f.Load() }
func (f *Frontend) HasVerticalFrame() bool { return nano.rot != nil && nano.rot.IsEven }
func (f *Frontend) SaveGameState() error { return f.Save() }
func (f *Frontend) SetMainSaveName(name string) { f.storage.SetMainSaveName(name) }
func (f *Frontend) SetViewport(width int, height int) {
func (f *Frontend) SetViewport(width int, height int, scale int) {
f.mu.Lock()
f.vw, f.vh = width, height
size := int(nano.sysAvInfo.geometry.max_width * nano.sysAvInfo.geometry.max_height)
size := int(nano.sysAvInfo.geometry.max_width) * scale * int(nano.sysAvInfo.geometry.max_height) * scale
f.canvas = image.NewCanvas(width, height, size)
f.mu.Unlock()
}

View file

@ -111,7 +111,11 @@ func (emu *EmulatorMock) loadRom(game string) {
if err != nil {
log.Fatal(err)
}
emu.SetViewport(emu.GetFrameSize())
w, h := emu.GetFrameSize()
if emu.conf.Scale == 0 {
emu.conf.Scale = 1
}
emu.SetViewport(w, h, emu.conf.Scale)
}
// shutdownEmulator closes the emulator and cleans its resources.

View file

@ -118,11 +118,7 @@ func (r *Room) initAudio(srcHz int, conf config.Audio) {
r.log.Error().Err(err).Msgf("opus encode fail")
return
}
r.handleSample(data, frameDur, func(u *Session, s *webrtc.Sample) {
if err := u.SendAudio(s); err != nil {
r.log.Error().Err(err).Send()
}
})
r.handleSample(data, frameDur, func(u *Session, s *webrtc.Sample) error { return u.SendAudio(s) })
})
})
}
@ -156,18 +152,17 @@ func (r *Room) initVideo(width, height int, conf config.Video) {
r.vEncoder = encoder.NewVideoEncoder(enc, width, height, conf.Concurrency, r.log)
r.emulator.SetVideo(func(frame *emulator.GameFrame) {
if fr := r.vEncoder.Encode(frame.Data.RGBA); fr != nil {
r.handleSample(fr, frame.Duration, func(u *Session, s *webrtc.Sample) {
if err := u.SendVideo(s); err != nil {
r.log.Error().Err(err).Send()
}
})
r.emulator.SetVideo(func(raw *emulator.GameFrame) {
data := r.vEncoder.Encode(raw.Data.RGBA)
if data == nil {
r.log.Warn().Msgf("no data after video encoding")
return
}
r.handleSample(data, raw.Duration, func(u *Session, s *webrtc.Sample) error { return u.SendVideo(s) })
})
}
func (r *Room) handleSample(b []byte, d time.Duration, fn func(*Session, *webrtc.Sample)) {
func (r *Room) handleSample(b []byte, d time.Duration, fn func(*Session, *webrtc.Sample) error) {
sample, _ := samplePool.Get().(*webrtc.Sample)
if sample == nil {
sample = new(webrtc.Sample)
@ -176,7 +171,9 @@ func (r *Room) handleSample(b []byte, d time.Duration, fn func(*Session, *webrtc
sample.Duration = d
r.users.ForEach(func(u *Session) {
if u.IsConnected() {
fn(u, sample)
if err := fn(u, sample); err != nil {
r.log.Error().Err(err).Send()
}
}
})
samplePool.Put(sample)

View file

@ -65,7 +65,7 @@ func NewRoom(id string, game games.GameMetadata, onClose func(*Room), conf confi
if room.emulator.HasVerticalFrame() {
w, h = h, w
}
room.emulator.SetViewport(w, h)
room.emulator.SetViewport(w, h, conf.Emulator.Scale)
room.initVideo(w, h, conf.Encoder.Video)
room.initAudio(int(room.emulator.GetSampleRate()), conf.Encoder.Audio)