Open markusgritsch opened 2 years ago
Are you seeing this behaviour on Linux? We've seen similar before on Linux where vsync doesn't appear to be supported correctly.
No, I'm using Windows 10 on an Intel HD Graphics 2000. The fan of my Notebook makes high CPU usage very noticable :)
Perhaps we can do something to determine if vsync is working correctly or not, if the time between loops is super short (and not close to vsync frequency), we could disable vsync mode and use the wait timer instead
Hmm, I would not prefer having the wait timer approach being automatically turned on, as it has the mentioned drawbacks on its own. The proposed kludge fixes the vsync CPU issue for me, and I can enjoy smooth scrolling. If it does not gets mainlined, I can live with it too :)
If you're getting high CPU usage with vsync mode it's likely vsync is not working correctly. We've encountered a bunch of cases where some setups do not actually do vsync and thus return instantly and create high CPU load. So I think some form of detection as to whether vsync is working may be necessary.
But it's working when relying on vsync just a little bit later, by using the delay(1)
.
Also, I don't think vsync is broken on my hardware per se, because a) it can be "fixed" with the above workaround, and b) I don't experience any issues when using Pyxel. I tried the same example to test smooth screen updates with Pyxel and with Nico:
import pyxel
x = 0
def update():
pass
def draw():
global x
pyxel.cls(0)
pyxel.line(x, 0, x, 128, 7)
x += 1
x %= 128
pyxel.init(128, 128, title="Pyxel", fps=60)
pyxel.mouse(True)
pyxel.run(update, draw)
import nico
var x = 0
proc gameInit() =
# setVSync(false)
setColor(8)
proc gameUpdate(dt: Pfloat) =
discard
proc gameDraw() =
cls()
line(x,0,x,64)
x += 1
x = x mod 128
nico.init("nico", "test")
fixedSize(true)
integerScale(true)
nico.createWindow("nico", 128, 128, 4)
nico.run(gameInit, gameUpdate, gameDraw)
Skipped screen updates are immediately visible by jumps in the moving line when uncomminting setVSync(false)
. It runs super smooth when not disabling vsync.
The Pyxel version runs with 1.5% CPU usage out of the box (also smooth). With the fix applied, CPU usage stays low at 2.5% also with the Nico version.
I use the same SDL2.dll
on both examples.
I haven't looked into what Pyxel does different from Nico regarding the SDL configuration.
I noticed that the CPU usage increases over time when using
setVSync(true)
, which is the default. This happens even for a simple example likelines.nim
.When using
setVSync(false)
, this does not happen, but of course this has the drawback of tearing or not smooth screen updates.The main difference when using
setVSync(false)
is inproc run*()
where waiting is done manually usingdelay()
. However, it seems that when solely relying on vsync, CPU usage seems to increase over time.As a solution this pull request adds a delay(1) even for the vsync case, if
sleepTime
is not smaller than 1.0 ms. This fixes the reported CPU usage problem.