mirror of https://github.com/OpenTTD/OpenTTD
Codechange: TicToc can now accumulate and output every tick
parent
fca75fd06a
commit
4beb23af30
50
src/debug.h
50
src/debug.h
|
@ -61,20 +61,49 @@ void SetDebugString(std::string_view s, SetDebugStringErrorFunc error_func);
|
|||
std::string GetDebugString();
|
||||
|
||||
/** TicToc profiling.
|
||||
* Usage:
|
||||
* Usage for max_count based output:
|
||||
* static TicToc::State state("A name", 1);
|
||||
* TicToc tt(state);
|
||||
* --Do your code--
|
||||
*
|
||||
* Usage for per-tick output:
|
||||
* static TicToc::State state("A name");
|
||||
* TicToc tt(state);
|
||||
* --Do your code--
|
||||
*/
|
||||
struct TicToc {
|
||||
/** Persistent state for TicToc profiling. */
|
||||
struct State {
|
||||
const std::string_view name;
|
||||
const uint32_t max_count;
|
||||
const std::optional<uint32_t> max_count;
|
||||
uint32_t count = 0;
|
||||
uint64_t chrono_sum = 0;
|
||||
|
||||
constexpr State(std::string_view name, uint32_t max_count) : name(name), max_count(max_count) { }
|
||||
using States = std::vector<State *>;
|
||||
|
||||
State(std::string_view name, std::optional<uint32_t> max_count = {}) : name(name), max_count(max_count)
|
||||
{
|
||||
GetStates().push_back(this);
|
||||
}
|
||||
|
||||
~State()
|
||||
{
|
||||
/* Container might be already destroyed. */
|
||||
if (!GetStates().empty()) std::erase(GetStates(), this);
|
||||
}
|
||||
|
||||
static States &GetStates()
|
||||
{
|
||||
thread_local static States s_states;
|
||||
return s_states;
|
||||
}
|
||||
|
||||
void OutputAndReset(const std::string_view prefix = "")
|
||||
{
|
||||
Debug(misc, 0, "[{}] [{}] {} calls in {} us [avg: {:.1f} us]", prefix, this->name, this->count, this->chrono_sum, this->chrono_sum / static_cast<double>(this->count));
|
||||
this->count = 0;
|
||||
this->chrono_sum = 0;
|
||||
}
|
||||
};
|
||||
|
||||
State &state;
|
||||
|
@ -85,10 +114,17 @@ struct TicToc {
|
|||
inline ~TicToc()
|
||||
{
|
||||
this->state.chrono_sum += (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - this->chrono_start)).count();
|
||||
if (++this->state.count == this->state.max_count) {
|
||||
Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", this->state.name, this->state.chrono_sum, this->state.chrono_sum / static_cast<double>(this->state.count));
|
||||
this->state.count = 0;
|
||||
this->state.chrono_sum = 0;
|
||||
this->state.count++;
|
||||
if (this->state.max_count.has_value() && this->state.count == this->state.max_count.value()) {
|
||||
this->state.OutputAndReset("MaxCount");
|
||||
}
|
||||
}
|
||||
|
||||
static void Tick(const std::string_view prefix)
|
||||
{
|
||||
for (auto state : State::GetStates()) {
|
||||
if (state->max_count.has_value() || state->count == 0) continue;
|
||||
state->OutputAndReset(prefix);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef VIDEO_VIDEO_DRIVER_HPP
|
||||
#define VIDEO_VIDEO_DRIVER_HPP
|
||||
|
||||
#include "../debug.h"
|
||||
#include "../driver.h"
|
||||
#include "../core/geometry_type.hpp"
|
||||
#include "../core/math_func.hpp"
|
||||
|
@ -318,6 +319,8 @@ protected:
|
|||
if (_ddc_fastforward) return std::chrono::microseconds(0);
|
||||
#endif /* DEBUG_DUMP_COMMANDS */
|
||||
|
||||
TicToc::Tick("GameTick");
|
||||
|
||||
/* If we are paused, run on normal speed. */
|
||||
if (_pause_mode.Any()) return std::chrono::milliseconds(MILLISECONDS_PER_TICK);
|
||||
/* Infinite speed, as quickly as you can. */
|
||||
|
@ -328,6 +331,8 @@ protected:
|
|||
|
||||
std::chrono::steady_clock::duration GetDrawInterval()
|
||||
{
|
||||
TicToc::Tick("DrawTick");
|
||||
|
||||
/* If vsync, draw interval is decided by the display driver */
|
||||
if (_video_vsync && this->uses_hardware_acceleration) return std::chrono::microseconds(0);
|
||||
return std::chrono::microseconds(1000000 / _settings_client.gui.refresh_rate);
|
||||
|
|
Loading…
Reference in New Issue