Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
#include "newgrf_sound.h"
|
||||
#include "window_gui.h"
|
||||
#include "window_func.h"
|
||||
#include "table/sprites.h"
|
||||
#include "string_func.h"
|
||||
#include "strings_func.h"
|
||||
#include "console_func.h"
|
||||
@@ -31,6 +30,8 @@
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
static std::mutex _sound_perf_lock;
|
||||
@@ -52,22 +53,22 @@ namespace {
|
||||
static const TimingMeasurement INVALID_DURATION = UINT64_MAX;
|
||||
|
||||
/** Time spent processing each cycle of the performance element, circular buffer */
|
||||
TimingMeasurement durations[NUM_FRAMERATE_POINTS];
|
||||
std::array<TimingMeasurement, NUM_FRAMERATE_POINTS> durations{};
|
||||
/** Start time of each cycle of the performance element, circular buffer */
|
||||
TimingMeasurement timestamps[NUM_FRAMERATE_POINTS];
|
||||
std::array<TimingMeasurement, NUM_FRAMERATE_POINTS> timestamps{};
|
||||
/** Expected number of cycles per second when the system is running without slowdowns */
|
||||
double expected_rate;
|
||||
double expected_rate = 0;
|
||||
/** Next index to write to in \c durations and \c timestamps */
|
||||
int next_index;
|
||||
int next_index = 0;
|
||||
/** Last index written to in \c durations and \c timestamps */
|
||||
int prev_index;
|
||||
int prev_index = 0;
|
||||
/** Number of data points recorded, clamped to \c NUM_FRAMERATE_POINTS */
|
||||
int num_valid;
|
||||
int num_valid = 0;
|
||||
|
||||
/** Current accumulated duration */
|
||||
TimingMeasurement acc_duration;
|
||||
TimingMeasurement acc_duration{};
|
||||
/** Start time for current accumulation cycle */
|
||||
TimingMeasurement acc_timestamp;
|
||||
TimingMeasurement acc_timestamp{};
|
||||
|
||||
/**
|
||||
* Initialize a data element with an expected collection rate
|
||||
@@ -75,7 +76,7 @@ namespace {
|
||||
* Expected number of cycles per second of the performance element. Use 1 if unknown or not relevant.
|
||||
* The rate is used for highlighting slow-running elements in the GUI.
|
||||
*/
|
||||
explicit PerformanceData(double expected_rate) : expected_rate(expected_rate), next_index(0), prev_index(0), num_valid(0) { }
|
||||
explicit PerformanceData(double expected_rate) : expected_rate(expected_rate) { }
|
||||
|
||||
/** Collect a complete measurement, given start and ending times for a processing block */
|
||||
void Add(TimingMeasurement start_time, TimingMeasurement end_time)
|
||||
@@ -376,27 +377,27 @@ static const char * GetAIName(int ai_index)
|
||||
static constexpr NWidgetPart _framerate_window_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_CAPTION, COLOUR_GREY, WID_FRW_CAPTION), SetDataTip(STR_FRAMERATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
|
||||
NWidget(WWT_CAPTION, COLOUR_GREY, WID_FRW_CAPTION),
|
||||
NWidget(WWT_SHADEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.frametext), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_GAMELOOP), SetDataTip(STR_FRAMERATE_RATE_GAMELOOP, STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_DRAWING), SetDataTip(STR_FRAMERATE_RATE_BLITTER, STR_FRAMERATE_RATE_BLITTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_FACTOR), SetDataTip(STR_FRAMERATE_SPEED_FACTOR, STR_FRAMERATE_SPEED_FACTOR_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR, WID_FRW_RATE_GAMELOOP), SetToolTip(STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR, WID_FRW_RATE_DRAWING), SetToolTip(STR_FRAMERATE_RATE_BLITTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR, WID_FRW_RATE_FACTOR), SetToolTip(STR_FRAMERATE_SPEED_FACTOR_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.frametext), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_NAMES), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_CURRENT), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_AVERAGE), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_ALLOCSIZE), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_FRW_TIMES_NAMES), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_FRW_TIMES_CURRENT), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_FRW_TIMES_AVERAGE), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_FRW_ALLOCSIZE), SetScrollbar(WID_FRW_SCROLLBAR),
|
||||
EndContainer(),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_INFO_DATA_POINTS), SetDataTip(STR_FRAMERATE_DATA_POINTS, 0x0), SetFill(1, 0), SetResize(1, 0),
|
||||
NWidget(WWT_TEXT, INVALID_COLOUR, WID_FRW_INFO_DATA_POINTS), SetFill(1, 0), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
@@ -407,9 +408,8 @@ static constexpr NWidgetPart _framerate_window_widgets[] = {
|
||||
};
|
||||
|
||||
struct FramerateWindow : Window {
|
||||
bool small;
|
||||
int num_active;
|
||||
int num_displayed;
|
||||
int num_active = 0;
|
||||
int num_displayed = 0;
|
||||
|
||||
struct CachedDecimal {
|
||||
StringID strid;
|
||||
@@ -431,25 +431,21 @@ struct FramerateWindow : Window {
|
||||
this->strid = (value < threshold_good) ? STR_FRAMERATE_MS_GOOD : (value > threshold_bad) ? STR_FRAMERATE_MS_BAD : STR_FRAMERATE_MS_WARN;
|
||||
}
|
||||
|
||||
inline void InsertDParams(uint n) const
|
||||
{
|
||||
SetDParam(n, this->value);
|
||||
SetDParam(n + 1, 2);
|
||||
}
|
||||
inline uint32_t GetValue() const { return this->value; }
|
||||
inline uint32_t GetDecimals() const { return 2; }
|
||||
};
|
||||
|
||||
CachedDecimal rate_gameloop; ///< cached game loop tick rate
|
||||
CachedDecimal rate_drawing; ///< cached drawing frame rate
|
||||
CachedDecimal speed_gameloop; ///< cached game loop speed factor
|
||||
CachedDecimal times_shortterm[PFE_MAX]; ///< cached short term average times
|
||||
CachedDecimal times_longterm[PFE_MAX]; ///< cached long term average times
|
||||
CachedDecimal rate_gameloop{}; ///< cached game loop tick rate
|
||||
CachedDecimal rate_drawing{}; ///< cached drawing frame rate
|
||||
CachedDecimal speed_gameloop{}; ///< cached game loop speed factor
|
||||
std::array<CachedDecimal, PFE_MAX> times_shortterm{}; ///< cached short term average times
|
||||
std::array<CachedDecimal, PFE_MAX> times_longterm{}; ///< cached long term average times
|
||||
|
||||
static constexpr int MIN_ELEMENTS = 5; ///< smallest number of elements to display
|
||||
static constexpr int MIN_ELEMENTS = 5; ///< smallest number of elements to display
|
||||
|
||||
FramerateWindow(WindowDesc &desc, WindowNumber number) : Window(desc)
|
||||
{
|
||||
this->InitNested(number);
|
||||
this->small = this->IsShaded();
|
||||
this->UpdateData();
|
||||
this->num_displayed = this->num_active;
|
||||
|
||||
@@ -457,17 +453,6 @@ struct FramerateWindow : Window {
|
||||
ResizeWindow(this, 0, (std::max(MIN_ELEMENTS, this->num_displayed) - MIN_ELEMENTS) * GetCharacterHeight(FS_NORMAL));
|
||||
}
|
||||
|
||||
void OnRealtimeTick([[maybe_unused]] uint delta_ms) override
|
||||
{
|
||||
/* Check if the shaded state has changed, switch caption text if it has */
|
||||
if (this->small != this->IsShaded()) {
|
||||
this->small = this->IsShaded();
|
||||
this->GetWidget<NWidgetLeaf>(WID_FRW_CAPTION)->SetDataTip(this->small ? STR_FRAMERATE_CAPTION_SMALL : STR_FRAMERATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
|
||||
this->UpdateData();
|
||||
this->SetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the window on a regular interval. */
|
||||
IntervalTimer<TimerWindow> update_interval = {std::chrono::milliseconds(100), [this](auto) {
|
||||
this->UpdateData();
|
||||
@@ -479,7 +464,7 @@ struct FramerateWindow : Window {
|
||||
double gl_rate = _pf_data[PFE_GAMELOOP].GetRate();
|
||||
this->rate_gameloop.SetRate(gl_rate, _pf_data[PFE_GAMELOOP].expected_rate);
|
||||
this->speed_gameloop.SetRate(gl_rate / _pf_data[PFE_GAMELOOP].expected_rate, 1.0);
|
||||
if (this->small) return; // in small mode, this is everything needed
|
||||
if (this->IsShaded()) return; // in small mode, this is everything needed
|
||||
|
||||
this->rate_drawing.SetRate(_pf_data[PFE_DRAWING].GetRate(), _settings_client.gui.refresh_rate);
|
||||
|
||||
@@ -500,31 +485,29 @@ struct FramerateWindow : Window {
|
||||
}
|
||||
}
|
||||
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_FRW_CAPTION:
|
||||
/* When the window is shaded, the caption shows game loop rate and speed factor */
|
||||
if (!this->small) break;
|
||||
SetDParam(0, this->rate_gameloop.strid);
|
||||
this->rate_gameloop.InsertDParams(1);
|
||||
this->speed_gameloop.InsertDParams(3);
|
||||
break;
|
||||
if (!this->IsShaded()) return GetString(STR_FRAMERATE_CAPTION);
|
||||
|
||||
return GetString(STR_FRAMERATE_CAPTION_SMALL, this->rate_gameloop.strid, this->rate_gameloop.GetValue(), this->rate_gameloop.GetDecimals(), this->speed_gameloop.GetValue(), this->speed_gameloop.GetDecimals());
|
||||
|
||||
case WID_FRW_RATE_GAMELOOP:
|
||||
SetDParam(0, this->rate_gameloop.strid);
|
||||
this->rate_gameloop.InsertDParams(1);
|
||||
break;
|
||||
return GetString(STR_FRAMERATE_RATE_GAMELOOP, this->rate_gameloop.strid, this->rate_gameloop.GetValue(), this->rate_gameloop.GetDecimals());
|
||||
|
||||
case WID_FRW_RATE_DRAWING:
|
||||
SetDParam(0, this->rate_drawing.strid);
|
||||
this->rate_drawing.InsertDParams(1);
|
||||
break;
|
||||
return GetString(STR_FRAMERATE_RATE_BLITTER, this->rate_drawing.strid, this->rate_drawing.GetValue(), this->rate_drawing.GetDecimals());
|
||||
|
||||
case WID_FRW_RATE_FACTOR:
|
||||
this->speed_gameloop.InsertDParams(0);
|
||||
break;
|
||||
return GetString(STR_FRAMERATE_SPEED_FACTOR, this->speed_gameloop.GetValue(), this->speed_gameloop.GetDecimals());
|
||||
|
||||
case WID_FRW_INFO_DATA_POINTS:
|
||||
SetDParam(0, NUM_FRAMERATE_POINTS);
|
||||
break;
|
||||
return GetString(STR_FRAMERATE_DATA_POINTS, NUM_FRAMERATE_POINTS);
|
||||
|
||||
default:
|
||||
return this->Window::GetWidgetString(widget, stringid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,21 +515,13 @@ struct FramerateWindow : Window {
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_FRW_RATE_GAMELOOP:
|
||||
SetDParam(0, STR_FRAMERATE_FPS_GOOD);
|
||||
SetDParamMaxDigits(1, 6);
|
||||
SetDParam(2, 2);
|
||||
size = GetStringBoundingBox(STR_FRAMERATE_RATE_GAMELOOP);
|
||||
size = GetStringBoundingBox(GetString(STR_FRAMERATE_RATE_GAMELOOP, STR_FRAMERATE_FPS_GOOD, GetParamMaxDigits(6), 2));
|
||||
break;
|
||||
case WID_FRW_RATE_DRAWING:
|
||||
SetDParam(0, STR_FRAMERATE_FPS_GOOD);
|
||||
SetDParamMaxDigits(1, 6);
|
||||
SetDParam(2, 2);
|
||||
size = GetStringBoundingBox(STR_FRAMERATE_RATE_BLITTER);
|
||||
size = GetStringBoundingBox(GetString(STR_FRAMERATE_RATE_BLITTER, STR_FRAMERATE_FPS_GOOD, GetParamMaxDigits(6), 2));
|
||||
break;
|
||||
case WID_FRW_RATE_FACTOR:
|
||||
SetDParamMaxDigits(0, 6);
|
||||
SetDParam(1, 2);
|
||||
size = GetStringBoundingBox(STR_FRAMERATE_SPEED_FACTOR);
|
||||
size = GetStringBoundingBox(GetString(STR_FRAMERATE_SPEED_FACTOR, GetParamMaxDigits(6), 2));
|
||||
break;
|
||||
|
||||
case WID_FRW_TIMES_NAMES: {
|
||||
@@ -560,9 +535,7 @@ struct FramerateWindow : Window {
|
||||
if (e < PFE_AI0) {
|
||||
line_size = GetStringBoundingBox(STR_FRAMERATE_GAMELOOP + e);
|
||||
} else {
|
||||
SetDParam(0, e - PFE_AI0 + 1);
|
||||
SetDParamStr(1, GetAIName(e - PFE_AI0));
|
||||
line_size = GetStringBoundingBox(STR_FRAMERATE_AI);
|
||||
line_size = GetStringBoundingBox(GetString(STR_FRAMERATE_AI, e - PFE_AI0 + 1, GetAIName(e - PFE_AI0)));
|
||||
}
|
||||
size.width = std::max(size.width, line_size.width);
|
||||
}
|
||||
@@ -573,9 +546,7 @@ struct FramerateWindow : Window {
|
||||
case WID_FRW_TIMES_AVERAGE:
|
||||
case WID_FRW_ALLOCSIZE: {
|
||||
size = GetStringBoundingBox(STR_FRAMERATE_CURRENT + (widget - WID_FRW_TIMES_CURRENT));
|
||||
SetDParamMaxDigits(0, 6);
|
||||
SetDParam(1, 2);
|
||||
Dimension item_size = GetStringBoundingBox(STR_FRAMERATE_MS_GOOD);
|
||||
Dimension item_size = GetStringBoundingBox(GetString(STR_FRAMERATE_MS_GOOD, GetParamMaxDigits(6), 2));
|
||||
size.width = std::max(size.width, item_size.width);
|
||||
size.height += GetCharacterHeight(FS_NORMAL) * MIN_ELEMENTS + WidgetDimensions::scaled.vsep_normal;
|
||||
resize.width = 0;
|
||||
@@ -586,7 +557,7 @@ struct FramerateWindow : Window {
|
||||
}
|
||||
|
||||
/** Render a column of formatted average durations */
|
||||
void DrawElementTimesColumn(const Rect &r, StringID heading_str, const CachedDecimal *values) const
|
||||
void DrawElementTimesColumn(const Rect &r, StringID heading_str, std::span<const CachedDecimal> values) const
|
||||
{
|
||||
const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR);
|
||||
int32_t skip = sb->GetPosition();
|
||||
@@ -599,8 +570,7 @@ struct FramerateWindow : Window {
|
||||
if (skip > 0) {
|
||||
skip--;
|
||||
} else {
|
||||
values[e].InsertDParams(0);
|
||||
DrawString(r.left, r.right, y, values[e].strid, TC_FROMSTRING, SA_RIGHT);
|
||||
DrawString(r.left, r.right, y, GetString(values[e].strid, values[e].GetValue(), values[e].GetDecimals()), TC_FROMSTRING, SA_RIGHT | SA_FORCE);
|
||||
y += GetCharacterHeight(FS_NORMAL);
|
||||
drawable--;
|
||||
if (drawable == 0) break;
|
||||
@@ -621,18 +591,13 @@ struct FramerateWindow : Window {
|
||||
if (skip > 0) {
|
||||
skip--;
|
||||
} else if (e == PFE_GAMESCRIPT || e >= PFE_AI0) {
|
||||
if (e == PFE_GAMESCRIPT) {
|
||||
SetDParam(0, Game::GetInstance()->GetAllocatedMemory());
|
||||
} else {
|
||||
SetDParam(0, Company::Get(e - PFE_AI0)->ai_instance->GetAllocatedMemory());
|
||||
}
|
||||
DrawString(r.left, r.right, y, STR_FRAMERATE_BYTES_GOOD, TC_FROMSTRING, SA_RIGHT);
|
||||
uint64_t value = e == PFE_GAMESCRIPT ? Game::GetInstance()->GetAllocatedMemory() : Company::Get(e - PFE_AI0)->ai_instance->GetAllocatedMemory();
|
||||
DrawString(r.left, r.right, y, GetString(STR_FRAMERATE_BYTES_GOOD, value), TC_FROMSTRING, SA_RIGHT | SA_FORCE);
|
||||
y += GetCharacterHeight(FS_NORMAL);
|
||||
drawable--;
|
||||
if (drawable == 0) break;
|
||||
} else if (e == PFE_SOUND) {
|
||||
SetDParam(0, GetSoundPoolAllocatedMemory());
|
||||
DrawString(r.left, r.right, y, STR_FRAMERATE_BYTES_GOOD, TC_FROMSTRING, SA_RIGHT);
|
||||
DrawString(r.left, r.right, y, GetString(STR_FRAMERATE_BYTES_GOOD, GetSoundPoolAllocatedMemory()), TC_FROMSTRING, SA_RIGHT | SA_FORCE);
|
||||
y += GetCharacterHeight(FS_NORMAL);
|
||||
drawable--;
|
||||
if (drawable == 0) break;
|
||||
@@ -662,9 +627,7 @@ struct FramerateWindow : Window {
|
||||
if (e < PFE_AI0) {
|
||||
DrawString(r.left, r.right, y, STR_FRAMERATE_GAMELOOP + e, TC_FROMSTRING, SA_LEFT);
|
||||
} else {
|
||||
SetDParam(0, e - PFE_AI0 + 1);
|
||||
SetDParamStr(1, GetAIName(e - PFE_AI0));
|
||||
DrawString(r.left, r.right, y, STR_FRAMERATE_AI, TC_FROMSTRING, SA_LEFT);
|
||||
DrawString(r.left, r.right, y, GetString(STR_FRAMERATE_AI, e - PFE_AI0 + 1, GetAIName(e - PFE_AI0)), TC_FROMSTRING, SA_LEFT);
|
||||
}
|
||||
y += GetCharacterHeight(FS_NORMAL);
|
||||
drawable--;
|
||||
@@ -723,7 +686,7 @@ struct FramerateWindow : Window {
|
||||
static WindowDesc _framerate_display_desc(
|
||||
WDP_AUTO, "framerate_display", 0, 0,
|
||||
WC_FRAMERATE_DISPLAY, WC_NONE,
|
||||
0,
|
||||
{},
|
||||
_framerate_window_widgets
|
||||
);
|
||||
|
||||
@@ -732,55 +695,48 @@ static WindowDesc _framerate_display_desc(
|
||||
static constexpr NWidgetPart _frametime_graph_window_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_CAPTION, COLOUR_GREY, WID_FGW_CAPTION), SetDataTip(STR_JUST_STRING2, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE),
|
||||
NWidget(WWT_CAPTION, COLOUR_GREY, WID_FGW_CAPTION), SetTextStyle(TC_WHITE),
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(NWID_VERTICAL), SetPadding(6),
|
||||
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FGW_GRAPH),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_FGW_GRAPH),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
struct FrametimeGraphWindow : Window {
|
||||
int vertical_scale; ///< number of TIMESTAMP_PRECISION units vertically
|
||||
int horizontal_scale; ///< number of half-second units horizontally
|
||||
int vertical_scale = TIMESTAMP_PRECISION / 10; ///< number of TIMESTAMP_PRECISION units vertically
|
||||
int horizontal_scale = 4; ///< number of half-second units horizontally
|
||||
|
||||
PerformanceElement element; ///< what element this window renders graph for
|
||||
Dimension graph_size; ///< size of the main graph area (excluding axis labels)
|
||||
PerformanceElement element{}; ///< what element this window renders graph for
|
||||
Dimension graph_size{}; ///< size of the main graph area (excluding axis labels)
|
||||
|
||||
FrametimeGraphWindow(WindowDesc &desc, WindowNumber number) : Window(desc)
|
||||
FrametimeGraphWindow(WindowDesc &desc, WindowNumber number) : Window(desc), element(static_cast<PerformanceElement>(number))
|
||||
{
|
||||
this->element = (PerformanceElement)number;
|
||||
this->horizontal_scale = 4;
|
||||
this->vertical_scale = TIMESTAMP_PRECISION / 10;
|
||||
|
||||
this->InitNested(number);
|
||||
this->UpdateScale();
|
||||
}
|
||||
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_FGW_CAPTION:
|
||||
if (this->element < PFE_AI0) {
|
||||
SetDParam(0, STR_FRAMETIME_CAPTION_GAMELOOP + this->element);
|
||||
} else {
|
||||
SetDParam(0, STR_FRAMETIME_CAPTION_AI);
|
||||
SetDParam(1, this->element - PFE_AI0 + 1);
|
||||
SetDParamStr(2, GetAIName(this->element - PFE_AI0));
|
||||
return GetString(STR_FRAMETIME_CAPTION_GAMELOOP + this->element);
|
||||
}
|
||||
break;
|
||||
return GetString(STR_FRAMETIME_CAPTION_AI, this->element - PFE_AI0 + 1, GetAIName(this->element - PFE_AI0));
|
||||
|
||||
default:
|
||||
return this->Window::GetWidgetString(widget, stringid);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
|
||||
{
|
||||
if (widget == WID_FGW_GRAPH) {
|
||||
SetDParam(0, 100);
|
||||
Dimension size_ms_label = GetStringBoundingBox(STR_FRAMERATE_GRAPH_MILLISECONDS);
|
||||
SetDParam(0, 100);
|
||||
Dimension size_s_label = GetStringBoundingBox(STR_FRAMERATE_GRAPH_SECONDS);
|
||||
Dimension size_ms_label = GetStringBoundingBox(GetString(STR_FRAMERATE_GRAPH_MILLISECONDS, 100));
|
||||
Dimension size_s_label = GetStringBoundingBox(GetString(STR_FRAMERATE_GRAPH_SECONDS, 100));
|
||||
|
||||
/* Size graph in height to fit at least 10 vertical labels with space between, or at least 100 pixels */
|
||||
graph_size.height = std::max(100u, 10 * (size_ms_label.height + 1));
|
||||
@@ -838,8 +794,8 @@ struct FrametimeGraphWindow : Window {
|
||||
/** Recalculate the graph scaling factors based on current recorded data */
|
||||
void UpdateScale()
|
||||
{
|
||||
const TimingMeasurement *durations = _pf_data[this->element].durations;
|
||||
const TimingMeasurement *timestamps = _pf_data[this->element].timestamps;
|
||||
const auto &durations = _pf_data[this->element].durations;
|
||||
const auto ×tamps = _pf_data[this->element].timestamps;
|
||||
int num_valid = _pf_data[this->element].num_valid;
|
||||
int point = _pf_data[this->element].prev_index;
|
||||
|
||||
@@ -889,7 +845,7 @@ struct FrametimeGraphWindow : Window {
|
||||
}
|
||||
|
||||
/** Scale and interpolate a value from a source range into a destination range */
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
static inline T Scinterlate(T dst_min, T dst_max, T src_min, T src_max, T value)
|
||||
{
|
||||
T dst_diff = dst_max - dst_min;
|
||||
@@ -900,8 +856,8 @@ struct FrametimeGraphWindow : Window {
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
if (widget == WID_FGW_GRAPH) {
|
||||
const TimingMeasurement *durations = _pf_data[this->element].durations;
|
||||
const TimingMeasurement *timestamps = _pf_data[this->element].timestamps;
|
||||
const auto &durations = _pf_data[this->element].durations;
|
||||
const auto ×tamps = _pf_data[this->element].timestamps;
|
||||
int point = _pf_data[this->element].prev_index;
|
||||
|
||||
const int x_zero = r.right - (int)this->graph_size.width;
|
||||
@@ -928,11 +884,13 @@ struct FrametimeGraphWindow : Window {
|
||||
GfxDrawLine(x_zero, y, x_max, y, c_grid);
|
||||
if (division % 2 == 0) {
|
||||
if ((TimingMeasurement)this->vertical_scale > TIMESTAMP_PRECISION) {
|
||||
SetDParam(0, this->vertical_scale * division / 10 / TIMESTAMP_PRECISION);
|
||||
DrawString(r.left, x_zero - 2, y - GetCharacterHeight(FS_SMALL), STR_FRAMERATE_GRAPH_SECONDS, TC_GREY, SA_RIGHT | SA_FORCE, false, FS_SMALL);
|
||||
DrawString(r.left, x_zero - 2, y - GetCharacterHeight(FS_SMALL),
|
||||
GetString(STR_FRAMERATE_GRAPH_SECONDS, this->vertical_scale * division / 10 / TIMESTAMP_PRECISION),
|
||||
TC_GREY, SA_RIGHT | SA_FORCE, false, FS_SMALL);
|
||||
} else {
|
||||
SetDParam(0, this->vertical_scale * division / 10 * 1000 / TIMESTAMP_PRECISION);
|
||||
DrawString(r.left, x_zero - 2, y - GetCharacterHeight(FS_SMALL), STR_FRAMERATE_GRAPH_MILLISECONDS, TC_GREY, SA_RIGHT | SA_FORCE, false, FS_SMALL);
|
||||
DrawString(r.left, x_zero - 2, y - GetCharacterHeight(FS_SMALL),
|
||||
GetString(STR_FRAMERATE_GRAPH_MILLISECONDS, this->vertical_scale * division / 10 * 1000 / TIMESTAMP_PRECISION),
|
||||
TC_GREY, SA_RIGHT | SA_FORCE, false, FS_SMALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -941,8 +899,9 @@ struct FrametimeGraphWindow : Window {
|
||||
int x = Scinterlate(x_zero, x_max, 0, (int)horz_divisions, (int)horz_divisions - (int)division);
|
||||
GfxDrawLine(x, y_max, x, y_zero, c_grid);
|
||||
if (division % 2 == 0) {
|
||||
SetDParam(0, division * horz_div_scl / 2);
|
||||
DrawString(x, x_max, y_zero + 2, STR_FRAMERATE_GRAPH_SECONDS, TC_GREY, SA_LEFT | SA_FORCE, false, FS_SMALL);
|
||||
DrawString(x, x_max, y_zero + 2,
|
||||
GetString(STR_FRAMERATE_GRAPH_SECONDS, division * horz_div_scl / 2),
|
||||
TC_GREY, SA_LEFT | SA_FORCE, false, FS_SMALL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,12 +958,12 @@ struct FrametimeGraphWindow : Window {
|
||||
if (points_drawn > 0 && peak_value > TIMESTAMP_PRECISION / 100 && 2 * peak_value > 3 * value_sum / points_drawn) {
|
||||
TextColour tc_peak = (TextColour)(TC_IS_PALETTE_COLOUR | c_peak);
|
||||
GfxFillRect(peak_point.x - 1, peak_point.y - 1, peak_point.x + 1, peak_point.y + 1, c_peak);
|
||||
SetDParam(0, peak_value * 1000 / TIMESTAMP_PRECISION);
|
||||
uint64_t value = peak_value * 1000 / TIMESTAMP_PRECISION;
|
||||
int label_y = std::max(y_max, peak_point.y - GetCharacterHeight(FS_SMALL));
|
||||
if (peak_point.x - x_zero > (int)this->graph_size.width / 2) {
|
||||
DrawString(x_zero, peak_point.x - 2, label_y, STR_FRAMERATE_GRAPH_MILLISECONDS, tc_peak, SA_RIGHT | SA_FORCE, false, FS_SMALL);
|
||||
DrawString(x_zero, peak_point.x - 2, label_y, GetString(STR_FRAMERATE_GRAPH_MILLISECONDS, value), tc_peak, SA_RIGHT | SA_FORCE, false, FS_SMALL);
|
||||
} else {
|
||||
DrawString(peak_point.x + 2, x_max, label_y, STR_FRAMERATE_GRAPH_MILLISECONDS, tc_peak, SA_LEFT | SA_FORCE, false, FS_SMALL);
|
||||
DrawString(peak_point.x + 2, x_max, label_y, GetString(STR_FRAMERATE_GRAPH_MILLISECONDS, value), tc_peak, SA_LEFT | SA_FORCE, false, FS_SMALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1014,7 +973,7 @@ struct FrametimeGraphWindow : Window {
|
||||
static WindowDesc _frametime_graph_window_desc(
|
||||
WDP_AUTO, "frametime_graph", 140, 90,
|
||||
WC_FRAMETIME_GRAPH, WC_NONE,
|
||||
0,
|
||||
{},
|
||||
_frametime_graph_window_widgets
|
||||
);
|
||||
|
||||
@@ -1030,7 +989,7 @@ void ShowFramerateWindow()
|
||||
void ShowFrametimeGraphWindow(PerformanceElement elem)
|
||||
{
|
||||
if (elem < PFE_FIRST || elem >= PFE_MAX) return; // maybe warn?
|
||||
AllocateWindowDescFront<FrametimeGraphWindow>(_frametime_graph_window_desc, elem, true);
|
||||
AllocateWindowDescFront<FrametimeGraphWindow>(_frametime_graph_window_desc, elem);
|
||||
}
|
||||
|
||||
/** Print performance statistics to game console */
|
||||
|
||||
Reference in New Issue
Block a user