diff --git a/CMakeLists.txt b/CMakeLists.txt index 6247d4df..32d42bc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ set(SOURCES "widgets/time.cpp" "widgets/vehicleparams.cpp" "widgets/trainingcard.cpp" +"widgets/perfgraphs.cpp" "ref/glad/src/glad.c" diff --git a/PyInt.cpp b/PyInt.cpp index 5e5da3d1..901b711f 100644 --- a/PyInt.cpp +++ b/PyInt.cpp @@ -98,12 +98,21 @@ void render_task::upload() { if (m_target->image) { + static bool width = 0; + glBindTexture(GL_TEXTURE_2D, m_target->shared_tex); - glTexImage2D( - GL_TEXTURE_2D, 0, - m_target->format, - m_target->width, m_target->height, 0, - m_target->components, GL_UNSIGNED_BYTE, m_target->image); + if (!width != m_target->width) { + glTexImage2D( + GL_TEXTURE_2D, 0, + m_target->format, + m_target->width, m_target->height, 0, + m_target->components, GL_UNSIGNED_BYTE, m_target->image); + width = m_target->width; + } + else { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_target->width, m_target->height, m_target->components, GL_UNSIGNED_BYTE, m_target->image); + } + if (Global.python_mipmaps) { diff --git a/Timer.h b/Timer.h index 033b518b..539f422b 100644 --- a/Timer.h +++ b/Timer.h @@ -33,18 +33,23 @@ public: m_start = std::chrono::steady_clock::now(); } std::chrono::duration stop() { - auto duration = std::chrono::duration_cast( ( std::chrono::steady_clock::now() - m_start ) ); - m_accumulator = 0.95f * m_accumulator + duration.count() / 1000.f; - return duration; + m_last = std::chrono::duration_cast( ( std::chrono::steady_clock::now() - m_start ) ); + m_accumulator = 0.95f * m_accumulator + m_last.count() / 1000.f; + return m_last; } float average() const { return m_accumulator / 20.f;} + std::chrono::microseconds + last() const { + return m_last; + } private: // members std::chrono::time_point m_start { std::chrono::steady_clock::now() }; float m_accumulator { 1000.f / 30.f * 20.f }; // 20 last samples, initial 'neutral' rate of 30 fps + std::chrono::microseconds m_last; }; struct subsystem_stopwatches { diff --git a/driveruilayer.cpp b/driveruilayer.cpp index d522a115..ff9e8f15 100644 --- a/driveruilayer.cpp +++ b/driveruilayer.cpp @@ -33,6 +33,7 @@ driver_ui::driver_ui() { add_external_panel( &m_timepanel ); add_external_panel( &m_mappanel ); add_external_panel( &m_logpanel ); + add_external_panel( &m_perfgraphpanel ); m_logpanel.is_open = false; m_aidpanel.title = locale::strings[ locale::string::driver_aid_header ]; @@ -61,6 +62,7 @@ void driver_ui::render_menu_contents() { ImGui::MenuItem(m_mappanel.name().c_str(), "Tab", &m_mappanel.is_open); ImGui::MenuItem(m_vehiclelist.name().c_str(), nullptr, &m_vehiclelist.is_open); ImGui::MenuItem(m_trainingcardpanel.name().c_str(), nullptr, &m_trainingcardpanel.is_open); + ImGui::MenuItem(m_perfgraphpanel.name().c_str(), nullptr, &m_perfgraphpanel.is_open); if (ImGui::MenuItem(m_timepanel.name().c_str())) m_timepanel.open(); diff --git a/driveruilayer.h b/driveruilayer.h index a2b7556c..ce6cae71 100644 --- a/driveruilayer.h +++ b/driveruilayer.h @@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/. #include "widgets/map.h" #include "widgets/time.h" #include "widgets/trainingcard.h" +#include "widgets/perfgraphs.h" class driver_ui : public ui_layer { @@ -57,6 +58,7 @@ private: debug_panel m_debugpanel { "Debug Data", false }; transcripts_panel m_transcriptspanel { "Transcripts", true }; // voice transcripts trainingcard_panel m_trainingcardpanel; + perfgraph_panel m_perfgraphpanel; bool m_paused { false }; bool m_pause_modal_opened { false }; diff --git a/widgets/perfgraphs.cpp b/widgets/perfgraphs.cpp new file mode 100644 index 00000000..4ce6e413 --- /dev/null +++ b/widgets/perfgraphs.cpp @@ -0,0 +1,62 @@ +#include "stdafx.h" +#include "widgets/perfgraphs.h" +#include "Timer.h" + +perfgraph_panel::perfgraph_panel() + : ui_panel("Perf", false) +{ + +} + +void perfgraph_panel::render_contents() { + if (ImGui::BeginCombo("Timer", timer_label[current_timer].c_str())) // The second parameter is the label previewed before opening the combo. + { + for (size_t i = 0; i < (size_t)TIMER_MAX; i++) + { + bool is_selected = (current_timer == (timers_e)i); + if (ImGui::Selectable(timer_label[i].c_str(), is_selected)) + current_timer = (timers_e)i; + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + Timer::stopwatch *stopwatch = nullptr; + + if (current_timer == gfx_total) + stopwatch = &Timer::subsystem.gfx_total; + else if (current_timer == gfx_color) + stopwatch = &Timer::subsystem.gfx_color; + else if (current_timer == gfx_shadows) + stopwatch = &Timer::subsystem.gfx_shadows; + else if (current_timer == gfx_reflections) + stopwatch = &Timer::subsystem.gfx_reflections; + else if (current_timer == gfx_swap) + stopwatch = &Timer::subsystem.gfx_swap; + else if (current_timer == gfx_gui) + stopwatch = &Timer::subsystem.gfx_gui; + else if (current_timer == sim_total) + stopwatch = &Timer::subsystem.sim_total; + else if (current_timer == sim_dynamics) + stopwatch = &Timer::subsystem.sim_dynamics; + else if (current_timer == sim_events) + stopwatch = &Timer::subsystem.sim_events; + else if (current_timer == sim_ai) + stopwatch = &Timer::subsystem.sim_ai; + else if (current_timer == mainloop_total) + stopwatch = &Timer::subsystem.mainloop_total; + + if (!stopwatch) + return; + + history[pos] = stopwatch->last().count() / 1000.0; + const std::string label = std::to_string(history[pos]) + "ms"; + + pos++; + if (pos >= history.size()) + pos = 0; + + ImGui::SliderFloat("Range", &max, 0.1f, 250.0f); + ImGui::PlotLines("##timer", &history[0], history.size(), pos, label.c_str(), 0.0f, max, ImVec2(500, 200)); +} diff --git a/widgets/perfgraphs.h b/widgets/perfgraphs.h new file mode 100644 index 00000000..56a10a3c --- /dev/null +++ b/widgets/perfgraphs.h @@ -0,0 +1,45 @@ +#include "uilayer.h" + +class perfgraph_panel : public ui_panel +{ + std::array history; + size_t pos = 0; + + enum timers_e { + gfx_total = 0, + gfx_color, + gfx_shadows, + gfx_reflections, + gfx_swap, + gfx_gui, + sim_total, + sim_dynamics, + sim_events, + sim_ai, + mainloop_total, + TIMER_MAX + }; + + float max = 50.0f; + timers_e current_timer = mainloop_total; + + std::vector timer_label = + { + "gfx_total", + "gfx_color", + "gfx_shadows", + "gfx_reflections", + "gfx_swap", + "gfx_gui", + "sim_total", + "sim_dynamics", + "sim_events", + "sim_ai", + "mainloop_total" + }; + + public: + perfgraph_panel(); + + void render_contents() override; +};