team-phoenix / Phoenix

A multi-system emulator and library manager designed to be both powerful and easy to use.
http://phoenix.vg
GNU General Public License v2.0
376 stars 40 forks source link

Explicit VSync control #220

Open athairus opened 8 years ago

athairus commented 8 years ago

We need the ability to turn VSync on or off on demand. To do this, we must implement our own custom QQuickRenderControl or at least bring back PhoenixWindow from the old code.

Presentation on how to use this: https://youtu.be/D-7fVGIBz6k?t=1972 Example: http://doc.qt.io/qt-5/qtquick-rendercontrol-example.html

athairus commented 8 years ago

With our own QQuickRenderControl we can block not only the GUI thread (which is done by the built-in render loops) but possibly a running game thread, too. We can then safely grab what we need to from this thread as if we were grabbing them from the GUI thread.

athairus commented 8 years ago

Use Looper when vsync is off. Also, find out what timing source the basic render loop uses.

athairus commented 8 years ago

The basic render loop is implemented in qtdeclarative/src/quick/scenegraph/qsgrenderloop.cpp as QSGGuiThreadRenderLoop. It uses QObject::startTimer() and QObject::event() at an interval of 5ms (line 451) to rate limit the update rate, which could be as fast as QSGRenderLoop::maybeUpdate() gets called (which is probably a lot)

athairus commented 8 years ago

Reposting this link here because I almost forgot it: http://stackoverflow.com/a/32717478/4190028

athairus commented 8 years ago

Okay, so I've managed to create a custom QQuickWindow that lets us toggle vsync on demand. I have to hard-code the threaded render loop because it's the only one that'll let me do the trick I use to reset the context.

Only problem is the vsync-driven animations now run at warp speed! I was told I need a custom animation driver as a plugin (how?) or to just change the scene graph and submit a patch upstream.

sletta, #qt-graphics on Freenode:

It should be pretty straight forward, I think.. There is logic in the driver to detect that we're lagging behind, so we could use similar logic to detect that we're well ahead and switch then too

athairus commented 8 years ago

Dynamic VSync example is live: https://github.com/athairus/QtVsyncControl

athairus commented 8 years ago

For the time being we're fine forcing the threaded render loop which handles VSync pretty well in either case.

athairus commented 8 years ago

Things work at warp speed on VMs where buffer swaps might not block. Need to think that one over more.