FPS Counter at the end of the display chain

1) Gives actual refresh rate of the window

2) FPS display based on profiler data, toggleable by pressing the the h key
on the keyboard, use Shift + h to modify FPS text scale (x1, x2 or x4)

3) Fix linux build by updating the gtk window

4) Fix linux build again, include microprofiler header directly and correct
parameters sent to ImGui::Text

5) Fix linux build by using a define to hide undefined functions on linux
This commit is contained in:
IceTDrinker 2019-04-27 13:08:19 +02:00 committed by illusion
parent 4d709dccd2
commit d360c80094
7 changed files with 81 additions and 7 deletions

View File

@ -100,6 +100,13 @@ bool EmulatorWindow::Initialize() {
window_->on_key_down.AddListener([this](KeyEvent* e) {
bool handled = true;
switch (e->key_code()) {
case 0x48: { // h
if (e->is_shift_pressed()) {
window_->FPSTextScale();
} else {
window_->ToggleFPS();
}
} break;
case 0x4F: { // o
if (e->is_ctrl_pressed()) {
FileOpen();

View File

@ -17,6 +17,8 @@
#include "xenia/base/logging.h"
#include "xenia/ui/imgui_drawer.h"
#include "xenia/base/profiling.h"
namespace xe {
namespace ui {
@ -183,6 +185,33 @@ void Window::OnPaint(UIEvent* e) {
tick_frequency));
fps_update_time_ticks_ = now_ticks;
fps_frame_count_ = 0;
#if XE_OPTION_PROFILING
// This means FPS counter will not work with profiling disabled (e.g. on
// Linux)
float fToMs =
MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu());
uint64_t nFlipTicks = 0;
{
std::lock_guard<std::recursive_mutex> lock(MicroProfileGetMutex());
MicroProfile& S = *MicroProfileGet();
nFlipTicks = S.nFlipTicks;
}
float fMs = fToMs * nFlipTicks;
if (fMs != 0.0f) {
game_fps_ = static_cast<uint32_t>(1000.0f / fMs);
}
#endif
title_fps_text_ = base_title_;
title_fps_text_ += " | ";
title_fps_text_ += std::to_string(game_fps_);
title_fps_text_ += " FPS";
set_title(title_fps_text_, false);
osd_fps_text_ = std::to_string(game_fps_);
osd_fps_text_ += " FPS";
}
GraphicsContextLock context_lock(context_.get());
@ -213,6 +242,20 @@ void Window::OnPaint(UIEvent* e) {
ForEachListener([e](auto listener) { listener->OnPaint(e); });
on_paint(e);
if (display_fps_) {
ImGui::Begin("FPS", (bool*)0,
ImGuiWindowFlags_::ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_::ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_::ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_::ImGuiWindowFlags_NoScrollbar |
ImGuiWindowFlags_::ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_::ImGuiWindowFlags_NoInputs);
ImGui::SetWindowFontScale(fps_font_scale_);
ImGui::Text("%s", osd_fps_text_.c_str());
ImGui::SetWindowSize({0.0f, 0.0f}); // Resize to fit content
ImGui::End();
}
// Flush ImGui buffers before we swap.
ImGui::Render();
imgui_drawer_->RenderDrawLists();

View File

@ -47,15 +47,27 @@ class Window {
virtual void EnableMainMenu() = 0;
virtual void DisableMainMenu() = 0;
const std::string& title() const { return title_; }
virtual bool set_title(const std::string& title) {
virtual bool set_title(const std::string& title,
bool set_base_title = true) {
if (title == title_) {
return false;
}
title_ = title;
if (set_base_title) {
base_title_ = title;
}
return true;
}
void ToggleFPS() { display_fps_ = !display_fps_; }
void FPSTextScale() {
fps_font_scale_ = fps_font_scale_ * 2.0f;
fps_font_scale_ = (fps_font_scale_ > 4.0f) ? 1.0f : fps_font_scale_;
}
virtual bool SetIcon(const void* buffer, size_t size) = 0;
void ResetIcon() { SetIcon(nullptr, 0); }
@ -171,7 +183,10 @@ class Window {
Loop* loop_ = nullptr;
std::unique_ptr<MenuItem> main_menu_;
std::string title_;
std::string base_title_;
int32_t width_ = 0;
int32_t height_ = 0;
bool has_focus_ = true;
@ -187,6 +202,13 @@ class Window {
uint64_t fps_frame_count_ = 0;
uint64_t last_paint_time_ticks_ = 0;
bool display_fps_ = false;
uint32_t game_fps_ = 0;
float fps_font_scale_ = 1.0f;
std::string title_fps_text_;
std::string osd_fps_text_;
bool modifier_shift_pressed_ = false;
bool modifier_cntrl_pressed_ = false;
bool modifier_alt_pressed_ = false;

View File

@ -99,8 +99,8 @@ void GTKWindow::OnClose() {
super::OnClose();
}
bool GTKWindow::set_title(const std::string& title) {
if (!super::set_title(title)) {
bool GTKWindow::set_title(const std::string& title, bool set_base_title) {
if (!super::set_title(title, set_base_title)) {
return false;
}
gtk_window_set_title(GTK_WINDOW(window_), (gchar*)title.c_str());

View File

@ -38,7 +38,8 @@ class GTKWindow : public Window {
void EnableMainMenu() override {}
void DisableMainMenu() override {}
bool set_title(const std::string& title) override;
bool set_title(const std::string& title,
bool set_base_title = true) override;
bool SetIcon(const void* buffer, size_t size) override;

View File

@ -198,8 +198,8 @@ void Win32Window::DisableMainMenu() {
}
}
bool Win32Window::set_title(const std::string& title) {
if (!super::set_title(title)) {
bool Win32Window::set_title(const std::string& title, bool set_base_title) {
if (!super::set_title(title, set_base_title)) {
return false;
}
SetWindowTextW(hwnd_, reinterpret_cast<LPCWSTR>(xe::to_utf16(title).c_str()));

View File

@ -34,7 +34,8 @@ class Win32Window : public Window {
void EnableMainMenu() override;
void DisableMainMenu() override;
bool set_title(const std::string& title) override;
bool set_title(const std::string& title,
bool set_base_title = true) override;
bool SetIcon(const void* buffer, size_t size) override;