Qt: More updates.

This commit is contained in:
BearOso 2023-08-05 16:59:56 -05:00
parent 876eaa8fb2
commit 2fd8b52163
32 changed files with 186 additions and 48 deletions

View File

@ -25,7 +25,6 @@ WGLContext::~WGLContext()
void WGLContext::deinit() void WGLContext::deinit()
{ {
if (wglMakeCurrent)
wglMakeCurrent(nullptr, nullptr); wglMakeCurrent(nullptr, nullptr);
if (hglrc) if (hglrc)
wglDeleteContext(hglrc); wglDeleteContext(hglrc);

View File

@ -22,7 +22,7 @@ class WGLContext : public OpenGLContext
void swap_buffers() override; void swap_buffers() override;
void swap_interval(int frames) override; void swap_interval(int frames) override;
void make_current() override; void make_current() override;
bool ready(); bool ready() override;
void deinit(); void deinit();
HWND hwnd; HWND hwnd;

2
external/glslang vendored

@ -1 +1 @@
Subproject commit 9c7fd1a33e5cecbe465e1cd70170167d5e40d398 Subproject commit 3ebb72cc7429f0ab8218104dc3687c659c0f364d

View File

@ -76,6 +76,7 @@ add_library(snes9x-core ${SNES9X_CORE_SOURCES})
target_include_directories(snes9x-core PRIVATE ../) target_include_directories(snes9x-core PRIVATE ../)
target_compile_definitions(snes9x-core PRIVATE ZLIB HAVE_STDINT_H ALLOW_CPU_OVERCLOCK) target_compile_definitions(snes9x-core PRIVATE ZLIB HAVE_STDINT_H ALLOW_CPU_OVERCLOCK)
find_package(Qt6 REQUIRED COMPONENTS Widgets Gui) find_package(Qt6 REQUIRED COMPONENTS Widgets Gui)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL REQUIRED sdl2) pkg_check_modules(SDL REQUIRED sdl2)
@ -153,8 +154,10 @@ if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
else() else()
list(APPEND PLATFORM_SOURCES list(APPEND PLATFORM_SOURCES
../common/video/wgl_context.cpp ../common/video/wgl_context.cpp
../external/glad/src/wgl.c) ../external/glad/src/wgl.c
src/resources/snes9x_icon.rc)
list(APPEND LIBS opengl32) list(APPEND LIBS opengl32)
list(APPEND DEFINES SDL_MAIN_HANDLED)
endif() endif()
set(QT_UI_FILES set(QT_UI_FILES
@ -170,6 +173,7 @@ set(QT_UI_FILES
set(USE_SANITIZERS CACHE BOOL OFF) set(USE_SANITIZERS CACHE BOOL OFF)
set(BUILD_TESTS CACHE BOOL OFF) set(BUILD_TESTS CACHE BOOL OFF)
set(BUILD_TOOLS CACHE BOOL OFF) set(BUILD_TOOLS CACHE BOOL OFF)
set(BUNDLE_SPEEX FORCE BOOL ON)
add_subdirectory("../external/cubeb" "cubeb" EXCLUDE_FROM_ALL) add_subdirectory("../external/cubeb" "cubeb" EXCLUDE_FROM_ALL)
list(APPEND LIBS cubeb) list(APPEND LIBS cubeb)
list(APPEND INCLUDES "../external/cubeb/include") list(APPEND INCLUDES "../external/cubeb/include")
@ -255,6 +259,10 @@ list(APPEND SOURCES ../external/imgui/imgui.cpp
list(APPEND INCLUDES ../external/imgui) list(APPEND INCLUDES ../external/imgui)
add_executable(snes9x-qt ${QT_GUI_SOURCES} ${SOURCES} ${PLATFORM_SOURCES} src/resources/snes9x.qrc) add_executable(snes9x-qt ${QT_GUI_SOURCES} ${SOURCES} ${PLATFORM_SOURCES} src/resources/snes9x.qrc)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set_target_properties(snes9x-qt PROPERTIES WIN32_EXECUTABLE True)
endif()
target_link_libraries(snes9x-qt snes9x-core ${LIBS}) target_link_libraries(snes9x-qt snes9x-core ${LIBS})
target_compile_definitions(snes9x-qt PRIVATE ${DEFINES}) target_compile_definitions(snes9x-qt PRIVATE ${DEFINES})
target_compile_options(snes9x-qt PRIVATE ${FLAGS}) target_compile_options(snes9x-qt PRIVATE ${FLAGS})

37
qt/QtStaticBuildVars.txt Normal file
View File

@ -0,0 +1,37 @@
-DBUILD_SHARED_LIBS=0
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_INSTALL_PREFIX="C:/Qt"
-DFEATURE_androiddeployqt=0
-DFEATURE_brotli=0
-DFEATURE_dbus=0
-DFEATURE_freetype=0
-DFEATURE_harfbuzz=0
-DFEATURE_imageformat_ppm=0
-DFEATURE_islamiccivilcalendar=0
-DFEATURE_jalalicalendar=0
-DFEATURE_lcdnumber=0
-DFEATURE_movie=0
-DFEATURE_openssl_linked=0
-DFEATURE_openssl_runtime=0
-DFEATURE_optimize_size=1
-DFEATURE_pdf=0
-DFEATURE_printsupport=0
-DFEATURE_shani=0
-DFEATURE_sql=0
-DFEATURE_static=1
-DFEATURE_system_doubleconversion=0
-DFEATURE_system_freetype=0
-DFEATURE_system_harfbuzz=0
-DFEATURE_system_jpeg=0
-DFEATURE_system_libb2=0
-DFEATURE_system_png=0
-DFEATURE_system_proxies=0
-DFEATURE_system_textmarkdownreader=0
-DFEATURE_system_zlib=0
-DFEATURE_testlib=0
-DFEATURE_textodfwriter=0
-DFEATURE_vkgen=0
-DFEATURE_vulkan=0
-DFEATURE_zstd=0
-DQT_BUILD_EXAMPLES_BY_DEFAULT=0
-DQT_BUILD_TESTS_BY_DEFAULT=0

View File

@ -1,4 +1,5 @@
#include "BindingPanel.hpp" #include "BindingPanel.hpp"
#include "EmuApplication.hpp"
#include <QTimer> #include <QTimer>
BindingPanel::BindingPanel(EmuApplication *app) BindingPanel::BindingPanel(EmuApplication *app)

View File

@ -1,8 +1,10 @@
#pragma once #pragma once
#include <QtEvents>
#include <QIcon> #include <QWidget>
#include <QTableWidget> #include <QTableWidget>
#include "EmuApplication.hpp" #include "EmuBinding.hpp"
class EmuApplication;
class BindingPanel : public QWidget class BindingPanel : public QWidget
{ {

View File

@ -1,5 +1,7 @@
#include "ControllerPanel.hpp" #include "ControllerPanel.hpp"
#include "SDLInputManager.hpp" #include "SDLInputManager.hpp"
#include "EmuApplication.hpp"
#include "EmuConfig.hpp"
#include "SDL_gamecontroller.h" #include "SDL_gamecontroller.h"
#include <optional> #include <optional>
#include <QtEvents> #include <QtEvents>

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "ui_ControllerPanel.h" #include "ui_ControllerPanel.h"
#include "BindingPanel.hpp" #include "BindingPanel.hpp"
#include "EmuApplication.hpp"
#include <QMenu> #include <QMenu>
class EmuApplication;
class ControllerPanel : class ControllerPanel :
public Ui::ControllerPanel, public Ui::ControllerPanel,
public BindingPanel public BindingPanel

View File

@ -1,4 +1,6 @@
#include "DisplayPanel.hpp" #include "DisplayPanel.hpp"
#include "EmuMainWindow.hpp"
#include "EmuConfig.hpp"
#include <QFileDialog> #include <QFileDialog>
DisplayPanel::DisplayPanel(EmuApplication *app_) DisplayPanel::DisplayPanel(EmuApplication *app_)

View File

@ -1,4 +1,7 @@
#include "EmuApplication.hpp" #include "EmuApplication.hpp"
#include "EmuMainWindow.hpp"
#include "SDLInputManager.hpp"
#include "Snes9xController.hpp"
#include "common/audio/s9x_sound_driver_sdl.hpp" #include "common/audio/s9x_sound_driver_sdl.hpp"
#include "common/audio/s9x_sound_driver_cubeb.hpp" #include "common/audio/s9x_sound_driver_cubeb.hpp"
#include <qlabel.h> #include <qlabel.h>
@ -135,13 +138,14 @@ void EmuApplication::startGame()
core->screen_output_function = [&](uint16_t *data, int width, int height, int stride_bytes, double frame_rate) { core->screen_output_function = [&](uint16_t *data, int width, int height, int stride_bytes, double frame_rate) {
if (window->canvas) if (window->canvas)
{ {
QMetaObject::invokeMethod(window.get(), "output", Qt::ConnectionType::DirectConnection, window->output((uint8_t *)data, width, height, QImage::Format_RGB16, stride_bytes, frame_rate);
Q_ARG(uint8_t *, (uint8_t *)data), // QMetaObject::invokeMethod(window.get(), "output", Qt::ConnectionType::DirectConnection,
Q_ARG(int, width), // Q_ARG(uint8_t *, (uint8_t *)data),
Q_ARG(int, height), // Q_ARG(int, width),
Q_ARG(QImage::Format, QImage::Format_RGB16), // Q_ARG(int, height),
Q_ARG(int, stride_bytes), // Q_ARG(QImage::Format, QImage::Format_RGB16),
Q_ARG(double, frame_rate)); // Q_ARG(int, stride_bytes),
// Q_ARG(double, frame_rate));
} }
}; };

View File

@ -3,11 +3,12 @@
#include <QTimer> #include <QTimer>
#include <QThread> #include <QThread>
#include "EmuMainWindow.hpp" class EmuMainWindow;
#include "EmuConfig.hpp" class EmuConfig;
#include "SDLInputManager.hpp" class EmuBinding;
#include "Snes9xController.hpp" class SDLInputManager;
#include "common/audio/s9x_sound_driver.hpp" class Snes9xController;
class S9xSoundDriver;
struct EmuThread : public QThread struct EmuThread : public QThread
{ {

View File

@ -1,4 +1,5 @@
#include "EmuCanvas.hpp" #include "EmuCanvas.hpp"
#include "EmuConfig.hpp"
#include <qnamespace.h> #include <qnamespace.h>
#include <qwidget.h> #include <qwidget.h>

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include <QWidget> #include <QWidget>
#include <QImage> #include <QImage>
#include "EmuConfig.hpp"
#include "../../vulkan/std_chrono_throttle.hpp" #include "../../vulkan/std_chrono_throttle.hpp"
class EmuConfig;
class EmuCanvas : public QWidget class EmuCanvas : public QWidget
{ {
public: public:
@ -33,7 +34,7 @@ class EmuCanvas : public QWidget
struct Parameter struct Parameter
{ {
bool operator==(const Parameter &other) bool operator==(const Parameter &other) const
{ {
if (name == other.name && if (name == other.name &&
id == other.id && id == other.id &&

View File

@ -17,6 +17,7 @@ using namespace QNativeInterface;
#include "EmuMainWindow.hpp" #include "EmuMainWindow.hpp"
#include "snes9x_imgui.h" #include "snes9x_imgui.h"
#include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3.h"
#include <locale.h>
static const char *stock_vertex_shader_140 = R"( static const char *stock_vertex_shader_140 = R"(
#version 140 #version 140

View File

@ -1,6 +1,10 @@
#include "EmuCanvasQt.hpp" #include "EmuCanvasQt.hpp"
#include "EmuConfig.hpp"
#include <QGuiApplication> #include <QGuiApplication>
#include <QtEvents> #include <QtEvents>
#include <QThread>
#include <qguiapplication.h>
EmuCanvasQt::EmuCanvasQt(EmuConfig *config, QWidget *parent, QWidget *main_window) EmuCanvasQt::EmuCanvasQt(EmuConfig *config, QWidget *parent, QWidget *main_window)
: EmuCanvas(config, parent, main_window) : EmuCanvas(config, parent, main_window)
@ -19,8 +23,11 @@ void EmuCanvasQt::deinit()
void EmuCanvasQt::draw() void EmuCanvasQt::draw()
{ {
QWidget::repaint(0, 0, width(), height()); qimage_mutex.lock();
qimage = QImage((const uchar *)output_data.buffer, output_data.width, output_data.height, output_data.bytes_per_line, output_data.format);
qimage_mutex.unlock();
throttle(); throttle();
update();
} }
void EmuCanvasQt::paintEvent(QPaintEvent *event) void EmuCanvasQt::paintEvent(QPaintEvent *event)
@ -34,7 +41,6 @@ void EmuCanvasQt::paintEvent(QPaintEvent *event)
} }
QPainter paint(this); QPainter paint(this);
QImage image((const uchar *)output_data.buffer, output_data.width, output_data.height, output_data.bytes_per_line, output_data.format);
paint.setRenderHint(QPainter::SmoothPixmapTransform, config->bilinear_filter); paint.setRenderHint(QPainter::SmoothPixmapTransform, config->bilinear_filter);
QRect dest = { 0, 0, width(), height() }; QRect dest = { 0, 0, width(), height() };
if (config->maintain_aspect_ratio) if (config->maintain_aspect_ratio)
@ -43,7 +49,9 @@ void EmuCanvasQt::paintEvent(QPaintEvent *event)
dest = applyAspect(dest); dest = applyAspect(dest);
} }
paint.drawImage(dest, image, QRect(0, 0, output_data.width, output_data.height)); qimage_mutex.lock();
paint.drawImage(dest, qimage, QRect(0, 0, output_data.width, output_data.height));
qimage_mutex.unlock();
} }
void EmuCanvasQt::resizeEvent(QResizeEvent *event) void EmuCanvasQt::resizeEvent(QResizeEvent *event)

View File

@ -4,6 +4,7 @@
#include "EmuCanvas.hpp" #include "EmuCanvas.hpp"
#include <QPainter> #include <QPainter>
#include <mutex>
class EmuCanvasQt : public EmuCanvas class EmuCanvasQt : public EmuCanvas
{ {
@ -16,6 +17,9 @@ class EmuCanvasQt : public EmuCanvas
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
std::mutex qimage_mutex;
QImage qimage;
}; };
#endif #endif

View File

@ -185,8 +185,10 @@ void EmuCanvasVulkan::draw()
throttle(); throttle();
context->swapchain->swap(); context->swapchain->swap();
if (config->reduce_input_lag) if (config->reduce_input_lag)
{
context->wait_idle(); context->wait_idle();
} }
}
} }
void EmuCanvasVulkan::resizeEvent(QResizeEvent *event) void EmuCanvasVulkan::resizeEvent(QResizeEvent *event)

View File

@ -16,7 +16,7 @@ class EmuCanvasVulkan : public EmuCanvas
EmuCanvasVulkan(EmuConfig *config, QWidget *parent, QWidget *main_window); EmuCanvasVulkan(EmuConfig *config, QWidget *parent, QWidget *main_window);
~EmuCanvasVulkan(); ~EmuCanvasVulkan();
void createContext(); void createContext() override;
void deinit() override; void deinit() override;
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
@ -30,7 +30,7 @@ class EmuCanvasVulkan : public EmuCanvas
void draw() override; void draw() override;
bool initImGui(); bool initImGui();
void recreateUIAssets(); void recreateUIAssets() override;
vk::UniqueRenderPass imgui_render_pass; vk::UniqueRenderPass imgui_render_pass;
vk::UniqueDescriptorPool imgui_descriptor_pool; vk::UniqueDescriptorPool imgui_descriptor_pool;

View File

@ -2,6 +2,8 @@
#define __EMU_CONFIG_HPP #define __EMU_CONFIG_HPP
#include <string> #include <string>
#include <vector>
#include "EmuBinding.hpp" #include "EmuBinding.hpp"
struct EmuConfig struct EmuConfig

View File

@ -13,6 +13,7 @@
#include "EmuMainWindow.hpp" #include "EmuMainWindow.hpp"
#include "EmuSettingsWindow.hpp" #include "EmuSettingsWindow.hpp"
#include "EmuApplication.hpp" #include "EmuApplication.hpp"
#include "EmuBinding.hpp"
#include "EmuCanvasVulkan.hpp" #include "EmuCanvasVulkan.hpp"
#include "EmuCanvasOpenGL.hpp" #include "EmuCanvasOpenGL.hpp"
#include "EmuCanvasQt.hpp" #include "EmuCanvasQt.hpp"
@ -464,10 +465,13 @@ bool EmuMainWindow::event(QEvent *event)
switch (event->type()) switch (event->type())
{ {
case QEvent::Close: case QEvent::Close:
app->suspendThread();
if (isFullScreen()) if (isFullScreen())
{ {
toggleFullscreen(); toggleFullscreen();
} }
QGuiApplication::processEvents();
QGuiApplication::sync();
app->stopThread(); app->stopThread();
if (canvas) if (canvas)
canvas->deinit(); canvas->deinit();

View File

@ -1,10 +1,11 @@
#include "EmuSettingsWindow.hpp" #include "EmuSettingsWindow.hpp"
#include "src/EmuMainWindow.hpp" #include "EmuMainWindow.hpp"
#include "EmuConfig.hpp"
#include <QScrollArea> #include <QScrollArea>
EmuSettingsWindow::EmuSettingsWindow(QWidget *parent, EmuApplication *app) EmuSettingsWindow::EmuSettingsWindow(QWidget *parent, EmuApplication *app_)
: QDialog(parent), app(app) : QDialog(parent), app(app_)
{ {
setupUi(this); setupUi(this);
@ -35,13 +36,19 @@ EmuSettingsWindow::EmuSettingsWindow(QWidget *parent, EmuApplication *app)
stackedWidget->setCurrentIndex(0); stackedWidget->setCurrentIndex(0);
closeButton->connect(closeButton, &QPushButton::clicked, [&](bool) { connect(closeButton, &QPushButton::clicked, [&](bool) {
this->close(); this->close();
}); });
panelList->connect(panelList, &QListWidget::currentItemChanged, [&](QListWidgetItem *prev, QListWidgetItem *cur) { connect(panelList, &QListWidget::currentItemChanged, [&](QListWidgetItem *prev, QListWidgetItem *cur) {
stackedWidget->setCurrentIndex(panelList->currentRow()); stackedWidget->setCurrentIndex(panelList->currentRow());
}); });
connect(defaultsButton, &QPushButton::clicked, [&](bool) {
app->config->setDefaults(stackedWidget->currentIndex());
stackedWidget->currentWidget()->hide();
stackedWidget->currentWidget()->show();
});
} }
EmuSettingsWindow::~EmuSettingsWindow() EmuSettingsWindow::~EmuSettingsWindow()

View File

@ -1,4 +1,7 @@
#include "EmulationPanel.hpp" #include "EmulationPanel.hpp"
#include "EmuApplication.hpp"
#include "EmuConfig.hpp"
EmulationPanel::EmulationPanel(EmuApplication *app_) EmulationPanel::EmulationPanel(EmuApplication *app_)
: app(app_) : app(app_)
{ {

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "ui_EmulationPanel.h" #include "ui_EmulationPanel.h"
#include "EmuApplication.hpp"
class EmuApplication;
class EmulationPanel : class EmulationPanel :
public Ui::EmulationPanel, public Ui::EmulationPanel,

View File

@ -1,4 +1,6 @@
#include "FoldersPanel.hpp" #include "FoldersPanel.hpp"
#include "EmuBinding.hpp"
#include "EmuConfig.hpp"
#include <QSpinBox> #include <QSpinBox>
#include <QFileDialog> #include <QFileDialog>

View File

@ -1,4 +1,6 @@
#include "GeneralPanel.hpp" #include "GeneralPanel.hpp"
#include "EmuApplication.hpp"
#include "EmuConfig.hpp"
GeneralPanel::GeneralPanel(EmuApplication *app_) GeneralPanel::GeneralPanel(EmuApplication *app_)
: app(app_) : app(app_)

View File

@ -145,9 +145,10 @@ void ShaderParametersDialog::save()
saved_parameters = *parameters; saved_parameters = *parameters;
auto filename = config->findConfigDir() + "/customized_shader" + extension; QDir dir(config->findConfigDir().c_str());
canvas->saveParameters(filename); auto filename = dir.absoluteFilePath(QString::fromStdString("customized_shader" + extension));
config->shader = filename; canvas->saveParameters(filename.toStdString());
config->shader = QDir::toNativeSeparators(filename).toStdString();
} }
void ShaderParametersDialog::saveAs() void ShaderParametersDialog::saveAs()
@ -155,7 +156,7 @@ void ShaderParametersDialog::saveAs()
auto folder = config->last_shader_folder; auto folder = config->last_shader_folder;
auto filename = QFileDialog::getSaveFileName(this, tr("Save Shader Preset As"), folder.c_str()); auto filename = QFileDialog::getSaveFileName(this, tr("Save Shader Preset As"), folder.c_str());
canvas->saveParameters(filename.toStdString()); canvas->saveParameters(filename.toStdString());
config->shader = filename.toStdString(); config->shader = QDir::toNativeSeparators(filename).toStdString();
} }
void ShaderParametersDialog::refreshWidgets() void ShaderParametersDialog::refreshWidgets()

View File

@ -1,4 +1,6 @@
#include "SoundPanel.hpp" #include "SoundPanel.hpp"
#include "EmuApplication.hpp"
#include "EmuConfig.hpp"
static const int playback_rates[] = { 96000, 48000, 44100 }; static const int playback_rates[] = { 96000, 48000, 44100 };

View File

@ -1,11 +1,25 @@
#include "EmuApplication.hpp" #include "EmuApplication.hpp"
#include "EmuConfig.hpp"
#include "EmuMainWindow.hpp"
#include "SDLInputManager.hpp"
#include <QStyle>
#include <QStyleHints>
#include <qnamespace.h>
#ifndef _WIN32 #ifndef _WIN32
#include <csignal> #include <csignal>
#endif #endif
#ifdef _WIN32
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, const char *lpCmdLine, int nShowCmd)
{
char **argv = nullptr;
int argc = 0;
#else
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
#endif
EmuApplication emu; EmuApplication emu;
emu.qtapp = std::make_unique<QApplication>(argc, argv); emu.qtapp = std::make_unique<QApplication>(argc, argv);

BIN
qt/src/resources/snes9x.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1 @@
IDI_ICON1 ICON "snes9x.ico"

View File

@ -22,25 +22,50 @@ microseconds Throttle::remaining()
#include <windows.h> #include <windows.h>
void Throttle::wait_for_frame() void Throttle::wait_for_frame()
{ {
static HANDLE timer = nullptr; static UINT (WINAPI *NtDelayExecution)(BOOL, LARGE_INTEGER *) = nullptr;
static UINT (WINAPI *NtQueryTimerResolution) (ULONG *, ULONG *, ULONG *) = nullptr;
static UINT (WINAPI *NtSetTimerResolution) (ULONG, BOOL, ULONG *) = nullptr;
static int timer_resolution = 12500;
if (timer == nullptr) if (NtDelayExecution == nullptr)
timer = CreateWaitableTimer(nullptr, true, nullptr); {
HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll");
if (ntdll)
{
NtDelayExecution = reinterpret_cast<typeof NtDelayExecution>(GetProcAddress(ntdll, "NtDelayExecution"));
NtQueryTimerResolution = reinterpret_cast<typeof NtQueryTimerResolution>(GetProcAddress(ntdll, "NtQueryTimerResolution"));
NtSetTimerResolution = reinterpret_cast<typeof NtSetTimerResolution>(GetProcAddress(ntdll, "NtSetTimerResolution"));
}
if (NtQueryTimerResolution)
{
ULONG min, max, current;
NtQueryTimerResolution(&min, &max, &current);
if (NtSetTimerResolution)
NtSetTimerResolution(max, true, &current);
timer_resolution = current * 5 / 4;
}
}
auto time_to_wait = remaining(); auto time_to_wait = remaining();
if (time_to_wait < -frame_duration_us) if (time_to_wait < -(frame_duration_us / 8))
{ {
reset(); reset();
return; return;
} }
if (time_to_wait.count() > 2000) if (NtDelayExecution)
{
if (time_to_wait.count() * 10 > timer_resolution)
{ {
LARGE_INTEGER li; LARGE_INTEGER li;
li.QuadPart = -(time_to_wait.count() - 2000) * 10; li.QuadPart = -(time_to_wait.count() * 10 - timer_resolution);
SetWaitableTimer(timer, &li, 0, nullptr, nullptr, false); NtDelayExecution(false, &li);
WaitForSingleObject(timer, INFINITE); }
} }
time_to_wait = remaining(); time_to_wait = remaining();
@ -64,7 +89,7 @@ void Throttle::wait_for_frame()
} }
if (time_to_wait.count() > 1000) if (time_to_wait.count() > 1000)
std::this_thread::sleep_for(time_to_wait - 1ms); std::this_thread::sleep_for(time_to_wait - 1000us);
time_to_wait = remaining(); time_to_wait = remaining();
while (time_to_wait.count() > 0) while (time_to_wait.count() > 0)