From fd7d698ee0c7c50f8c540e3d06fb8662f6381600 Mon Sep 17 00:00:00 2001 From: wwylele Date: Sun, 4 Sep 2016 19:41:44 +0800 Subject: [PATCH] Hack VSync: use sleep --- src/citra_qt/bootmanager.cpp | 2 +- src/core/hw/gpu.cpp | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index d6c928fc7..c7e19429a 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -276,7 +276,7 @@ void GRenderWindow::InitRenderTarget() { QGLFormat fmt; fmt.setVersion(3, 3); fmt.setProfile(QGLFormat::CoreProfile); - fmt.setSwapInterval(Settings::values.use_vsync); + fmt.setSwapInterval(false); // Requests a forward-compatible context, which is required to get a 3.2+ context on OS X fmt.setOption(QGL::NoDeprecatedFunctions); diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index a4dfb7e43..671c353ff 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -2,8 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include +#include #include #include "common/color.h" @@ -411,6 +413,19 @@ static void VBlankCallback(u64 userdata, int cycles_late) { last_skip_frame = g_skip_frame; g_skip_frame = (frame_count & Settings::values.frame_skip) != 0; + if (Settings::values.use_vsync) { + using namespace std::chrono; + static auto frame_time = high_resolution_clock::now(); + static constexpr auto update_duration = duration_cast(16667us); + auto now = high_resolution_clock::now(); + if (now < frame_time) { + std::this_thread::sleep_until(frame_time); + frame_time += update_duration; + } else { + frame_time = now + update_duration; + } + } + // Swap buffers based on the frameskip mode, which is a little bit tricky. When // a frame is being skipped, nothing is being rendered to the internal framebuffer(s). // So, we should only swap frames if the last frame was rendered. The rules are: