keep framerate stable even without vsync (#2165)

This commit is contained in:
Vinicius Rangel 2025-01-16 21:10:17 -03:00 committed by GitHub
parent 56a6c95730
commit 8695383d35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 38 additions and 17 deletions

View file

@ -37,6 +37,10 @@ public:
void Start(); void Start();
void End(); void End();
std::chrono::nanoseconds GetTotalWait() const {
return total_wait;
}
}; };
} // namespace Common } // namespace Common

View file

@ -165,7 +165,7 @@ public:
debug_message_popup.push(std::move(message)); debug_message_popup.push(std::move(message));
} }
bool& ShowingDebugMenuBar() { bool& IsShowingDebugMenuBar() {
return showing_debug_menu_bar; return showing_debug_menu_bar;
} }

View file

@ -253,7 +253,7 @@ void L::DrawAdvanced() {
void L::DrawSimple() { void L::DrawSimple() {
const float frameRate = DebugState.Framerate; const float frameRate = DebugState.Framerate;
Text("%d FPS (%.1f ms)", static_cast<int>(std::round(1.0f / frameRate)), frameRate * 1000.0f); Text("%d FPS (%.1f ms)", static_cast<int>(std::round(frameRate)), 1000.0f / frameRate);
} }
static void LoadSettings(const char* line) { static void LoadSettings(const char* line) {
@ -264,7 +264,7 @@ static void LoadSettings(const char* line) {
return; return;
} }
if (sscanf(line, "show_advanced_debug=%d", &i) == 1) { if (sscanf(line, "show_advanced_debug=%d", &i) == 1) {
DebugState.ShowingDebugMenuBar() = i != 0; DebugState.IsShowingDebugMenuBar() = i != 0;
return; return;
} }
if (sscanf(line, "show_frame_graph=%d", &i) == 1) { if (sscanf(line, "show_frame_graph=%d", &i) == 1) {
@ -309,7 +309,7 @@ void L::SetupSettings() {
handler.WriteAllFn = [](ImGuiContext*, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) { handler.WriteAllFn = [](ImGuiContext*, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) {
buf->appendf("[%s][Data]\n", handler->TypeName); buf->appendf("[%s][Data]\n", handler->TypeName);
buf->appendf("fps_scale=%f\n", fps_scale); buf->appendf("fps_scale=%f\n", fps_scale);
buf->appendf("show_advanced_debug=%d\n", DebugState.ShowingDebugMenuBar()); buf->appendf("show_advanced_debug=%d\n", DebugState.IsShowingDebugMenuBar());
buf->appendf("show_frame_graph=%d\n", frame_graph.is_open); buf->appendf("show_frame_graph=%d\n", frame_graph.is_open);
buf->appendf("dump_frame_count=%d\n", dump_frame_count); buf->appendf("dump_frame_count=%d\n", dump_frame_count);
buf->append("\n"); buf->append("\n");
@ -340,7 +340,7 @@ void L::Draw() {
if (IsKeyPressed(ImGuiKey_F10, false)) { if (IsKeyPressed(ImGuiKey_F10, false)) {
if (io.KeyCtrl) { if (io.KeyCtrl) {
DebugState.ShowingDebugMenuBar() ^= true; DebugState.IsShowingDebugMenuBar() ^= true;
} else { } else {
show_simple_fps = !show_simple_fps; show_simple_fps = !show_simple_fps;
} }
@ -375,7 +375,7 @@ void L::Draw() {
End(); End();
} }
if (DebugState.ShowingDebugMenuBar()) { if (DebugState.IsShowingDebugMenuBar()) {
PushFont(io.Fonts->Fonts[IMGUI_FONT_MONO]); PushFont(io.Fonts->Fonts[IMGUI_FONT_MONO]);
PushID("DevtoolsLayer"); PushID("DevtoolsLayer");
DrawAdvanced(); DrawAdvanced();

View file

@ -9,6 +9,7 @@
#include "core/libraries/kernel/time.h" #include "core/libraries/kernel/time.h"
#include "core/libraries/videoout/driver.h" #include "core/libraries/videoout/driver.h"
#include "core/libraries/videoout/videoout_error.h" #include "core/libraries/videoout/videoout_error.h"
#include "imgui/renderer/imgui_core.h"
#include "video_core/renderer_vulkan/vk_presenter.h" #include "video_core/renderer_vulkan/vk_presenter.h"
extern std::unique_ptr<Vulkan::Presenter> presenter; extern std::unique_ptr<Vulkan::Presenter> presenter;
@ -297,10 +298,12 @@ void VideoOutDriver::PresentThread(std::stop_token token) {
if (vblank_status.count % (main_port.flip_rate + 1) == 0) { if (vblank_status.count % (main_port.flip_rate + 1) == 0) {
const auto request = receive_request(); const auto request = receive_request();
if (!request) { if (!request) {
if (!main_port.is_open) { if (timer.GetTotalWait().count() < 0) { // Dont draw too fast
DrawBlankFrame(); if (!main_port.is_open) {
} else { DrawBlankFrame();
DrawLastFrame(); } else if (ImGui::Core::MustKeepDrawing()) {
DrawLastFrame();
}
} }
} else { } else {
Flip(request); Flip(request);

View file

@ -187,7 +187,7 @@ ImGuiID NewFrame(bool is_reusing_frame) {
ImGui::NewFrame(); ImGui::NewFrame();
ImGuiWindowFlags flags = ImGuiDockNodeFlags_PassthruCentralNode; ImGuiWindowFlags flags = ImGuiDockNodeFlags_PassthruCentralNode;
if (!DebugState.ShowingDebugMenuBar()) { if (!DebugState.IsShowingDebugMenuBar()) {
flags |= ImGuiDockNodeFlags_NoTabBar; flags |= ImGuiDockNodeFlags_NoTabBar;
} }
ImGuiID dockId = DockSpaceOverViewport(0, GetMainViewport(), flags); ImGuiID dockId = DockSpaceOverViewport(0, GetMainViewport(), flags);
@ -237,6 +237,10 @@ void Render(const vk::CommandBuffer& cmdbuf, const vk::ImageView& image_view,
} }
} }
bool MustKeepDrawing() {
return layers.size() > 1 || DebugState.IsShowingDebugMenuBar();
}
} // namespace Core } // namespace Core
void Layer::AddLayer(Layer* layer) { void Layer::AddLayer(Layer* layer) {

View file

@ -31,4 +31,6 @@ ImGuiID NewFrame(bool is_reusing_frame = false);
void Render(const vk::CommandBuffer& cmdbuf, const vk::ImageView& image_view, void Render(const vk::CommandBuffer& cmdbuf, const vk::ImageView& image_view,
const vk::Extent2D& extent); const vk::Extent2D& extent);
bool MustKeepDrawing(); // Force the emulator redraw
} // namespace ImGui::Core } // namespace ImGui::Core

View file

@ -46,6 +46,11 @@ struct SdlData {
ImVector<SDL_Gamepad*> gamepads{}; ImVector<SDL_Gamepad*> gamepads{};
GamepadMode gamepad_mode{}; GamepadMode gamepad_mode{};
bool want_update_gamepads_list{}; bool want_update_gamepads_list{};
// Framerate counting (based on ImGui impl)
std::array<float, 60> framerateSecPerFrame;
int framerateSecPerFrameIdx{};
float framerateSecPerFrameAcc{};
}; };
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui // Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui
@ -812,12 +817,15 @@ void NewFrame(bool is_reusing_frame) {
: 1.0f / 60.0f; : 1.0f / 60.0f;
bd->nonReusedtime = current_time; bd->nonReusedtime = current_time;
DebugState.FrameDeltaTime = deltaTime; DebugState.FrameDeltaTime = deltaTime;
float distribution = 0.016f / deltaTime / 10.0f;
if (distribution > 1.0f) { int& frameIdx = bd->framerateSecPerFrameIdx;
distribution = 1.0f; float& framerateSec = bd->framerateSecPerFrame[frameIdx];
} float& acc = bd->framerateSecPerFrameAcc;
DebugState.Framerate = int count = bd->framerateSecPerFrame.size();
deltaTime * distribution + DebugState.Framerate * (1.0f - distribution); acc += deltaTime - framerateSec;
framerateSec = deltaTime;
frameIdx = (frameIdx + 1) % count;
DebugState.Framerate = acc > 0.0f ? 1.0f / (acc / (float)count) : FLT_MAX;
} }
if (bd->mouse_pending_leave_frame && bd->mouse_pending_leave_frame >= ImGui::GetFrameCount() && if (bd->mouse_pending_leave_frame && bd->mouse_pending_leave_frame >= ImGui::GetFrameCount() &&