Skip to content

Commit

Permalink
[wpigui] Limit frame rate to 120 fps by default (wpilibsuite#5030)
Browse files Browse the repository at this point in the history
Limiting with vsync is apparently unreliable on a number of systems;
this resulted in high CPU/GPU usage.

Also add current actual frame rate to about dialog of GUI tools.
  • Loading branch information
PeterJohnson authored and Starlight220 committed Mar 2, 2023
1 parent 9e28e95 commit e95bd9c
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 2 deletions.
2 changes: 2 additions & 0 deletions datalogtool/src/main/native/cpp/App.cpp
Expand Up @@ -104,6 +104,8 @@ static void DisplayMainMenu() {
ImGui::Text("v%s", GetWPILibVersion());
ImGui::Separator();
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate,
ImGui::GetIO().Framerate);
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
}
Expand Down
2 changes: 2 additions & 0 deletions glass/src/app/native/cpp/main.cpp
Expand Up @@ -269,6 +269,8 @@ int main(int argc, char** argv) {
ImGui::Text("v%s", GetWPILibVersion());
ImGui::Separator();
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
ImGui::Text("%.3f ms/frame (%.1f FPS)",
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
}
Expand Down
2 changes: 2 additions & 0 deletions outlineviewer/src/main/native/cpp/main.cpp
Expand Up @@ -183,6 +183,8 @@ static void DisplayGui() {
ImGui::Text("v%s", GetWPILibVersion());
ImGui::Separator();
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate,
ImGui::GetIO().Framerate);
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
}
Expand Down
2 changes: 2 additions & 0 deletions roborioteamnumbersetter/src/main/native/cpp/App.cpp
Expand Up @@ -127,6 +127,8 @@ static void DisplayGui() {
static_cast<int>(multicastResolver->HasImplementation()));
ImGui::Separator();
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate,
ImGui::GetIO().Framerate);
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
}
Expand Down
47 changes: 45 additions & 2 deletions wpigui/src/main/native/cpp/wpigui.cpp
Expand Up @@ -4,9 +4,13 @@

#include "wpigui.h"

#include <stdint.h>

#include <algorithm>
#include <chrono>
#include <cstdio>
#include <cstring>
#include <thread>

#include <GLFW/glfw3.h>
#include <IconsFontAwesome6.h>
Expand Down Expand Up @@ -88,6 +92,8 @@ static void IniReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler,
impl->userScale = num;
} else if (std::strncmp(lineStr, "style=", 6) == 0) {
impl->style = num;
} else if (std::strncmp(lineStr, "fps=", 4) == 0) {
impl->fps = num;
}
}

Expand All @@ -98,9 +104,10 @@ static void IniWriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler,
}
out_buf->appendf(
"[MainWindow][GLOBAL]\nwidth=%d\nheight=%d\nmaximized=%d\n"
"xpos=%d\nypos=%d\nuserScale=%d\nstyle=%d\n\n",
"xpos=%d\nypos=%d\nuserScale=%d\nstyle=%d\nfps=%d\n\n",
gContext->width, gContext->height, gContext->maximized ? 1 : 0,
gContext->xPos, gContext->yPos, gContext->userScale, gContext->style);
gContext->xPos, gContext->yPos, gContext->userScale, gContext->style,
gContext->fps);
}

void gui::CreateContext() {
Expand Down Expand Up @@ -331,6 +338,8 @@ bool gui::Initialize(const char* title, int width, int height,
void gui::Main() {
// Main loop
while (!glfwWindowShouldClose(gContext->window) && !gContext->exit) {
double startTime = glfwGetTime();

// Poll and handle events (inputs, window resize, etc.)
glfwPollEvents();
gContext->isPlatformRendering = true;
Expand All @@ -351,6 +360,15 @@ void gui::Main() {
io.WantSaveIniSettings = false; // reset flag
}
}

// if FPS limiting, sleep until next frame time
if (gContext->fps != 0) {
double sleepTime = (1.0 / gContext->fps) - (glfwGetTime() - startTime);
if (sleepTime > 1e-6) {
std::this_thread::sleep_for(
std::chrono::microseconds(static_cast<int64_t>(sleepTime * 1e6)));
}
}
}

// Save (if custom save)
Expand Down Expand Up @@ -477,6 +495,10 @@ void gui::SetStyle(Style style) {
}
}

void gui::SetFPS(int fps) {
gContext->fps = fps;
}

void gui::SetClearColor(ImVec4 color) {
gContext->clearColor = color;
}
Expand Down Expand Up @@ -539,6 +561,27 @@ void gui::EmitViewMenu() {
ImGui::EndMenu();
}

if (ImGui::BeginMenu("Frame Rate")) {
bool selected;
selected = gContext->fps == 0;
if (ImGui::MenuItem("vsync", nullptr, &selected)) {
gContext->fps = 0;
}
selected = gContext->fps == 30;
if (ImGui::MenuItem("30 fps", nullptr, &selected)) {
gContext->fps = 30;
}
selected = gContext->fps == 60;
if (ImGui::MenuItem("60 fps", nullptr, &selected)) {
gContext->fps = 60;
}
selected = gContext->fps == 120;
if (ImGui::MenuItem("120 fps", nullptr, &selected)) {
gContext->fps = 120;
}
ImGui::EndMenu();
}

if (!gContext->saveSettings) {
ImGui::MenuItem("Reset UI on Exit?", nullptr, &gContext->resetOnExit);
}
Expand Down
7 changes: 7 additions & 0 deletions wpigui/src/main/native/include/wpigui.h
Expand Up @@ -162,6 +162,13 @@ enum Style { kStyleClassic = 0, kStyleDark, kStyleLight };
*/
void SetStyle(Style style);

/**
* Sets the FPS limit. Using this function makes this setting persistent.
*
* @param fps FPS (0=vsync)
*/
void SetFPS(int fps);

/**
* Sets the clear (background) color.
*
Expand Down
1 change: 1 addition & 0 deletions wpigui/src/main/native/include/wpigui_internal.h
Expand Up @@ -24,6 +24,7 @@ struct SavedSettings {
int yPos = -1;
int userScale = 2;
int style = 0;
int fps = 120;
};

constexpr int kFontScaledLevels = 9;
Expand Down

0 comments on commit e95bd9c

Please sign in to comment.