Merge remote-tracking branch 'upstream/master' into 13.0
This commit is contained in:
@@ -25,8 +25,16 @@
|
||||
#include "game/game_instance.hpp"
|
||||
|
||||
#include "widgets/framerate_widget.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
static std::mutex _sound_perf_lock;
|
||||
static std::atomic<bool> _sound_perf_pending;
|
||||
static std::vector<TimingMeasurement> _sound_perf_measurements;
|
||||
|
||||
/**
|
||||
* Private declarations for performance measurement implementation
|
||||
@@ -251,6 +259,20 @@ PerformanceMeasurer::~PerformanceMeasurer()
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this->elem == PFE_SOUND) {
|
||||
/* PFE_SOUND measurements are made from the mixer thread.
|
||||
* _pf_data cannot be concurrently accessed from the mixer thread
|
||||
* and the main thread, so store the measurement results in a
|
||||
* mutex-protected queue which is drained by the main thread.
|
||||
* See: ProcessPendingPerformanceMeasurements() */
|
||||
TimingMeasurement end = GetPerformanceTimer();
|
||||
std::lock_guard lk(_sound_perf_lock);
|
||||
if (_sound_perf_measurements.size() >= NUM_FRAMERATE_POINTS * 2) return;
|
||||
_sound_perf_measurements.push_back(this->start_time);
|
||||
_sound_perf_measurements.push_back(end);
|
||||
_sound_perf_pending.store(true, std::memory_order_release);
|
||||
return;
|
||||
}
|
||||
_pf_data[this->elem].Add(this->start_time, GetPerformanceTimer());
|
||||
}
|
||||
|
||||
@@ -358,7 +380,7 @@ static const NWidgetPart _framerate_window_widgets[] = {
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0),
|
||||
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),
|
||||
@@ -366,8 +388,8 @@ static const NWidgetPart _framerate_window_widgets[] = {
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||
NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, 8, 0),
|
||||
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),
|
||||
@@ -425,7 +447,6 @@ struct FramerateWindow : Window {
|
||||
CachedDecimal times_shortterm[PFE_MAX]; ///< cached short term average times
|
||||
CachedDecimal times_longterm[PFE_MAX]; ///< cached long term average times
|
||||
|
||||
static constexpr int VSPACING = 3; ///< space between column heading and values
|
||||
static constexpr int MIN_ELEMENTS = 5; ///< smallest number of elements to display
|
||||
|
||||
FramerateWindow(WindowDesc *desc, WindowNumber number) : Window(desc)
|
||||
@@ -545,7 +566,7 @@ struct FramerateWindow : Window {
|
||||
|
||||
case WID_FRW_TIMES_NAMES: {
|
||||
size->width = 0;
|
||||
size->height = FONT_HEIGHT_NORMAL + VSPACING + MIN_ELEMENTS * FONT_HEIGHT_NORMAL;
|
||||
size->height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal + MIN_ELEMENTS * FONT_HEIGHT_NORMAL;
|
||||
resize->width = 0;
|
||||
resize->height = FONT_HEIGHT_NORMAL;
|
||||
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
|
||||
@@ -571,7 +592,7 @@ struct FramerateWindow : Window {
|
||||
SetDParam(1, 2);
|
||||
Dimension item_size = GetStringBoundingBox(STR_FRAMERATE_MS_GOOD);
|
||||
size->width = std::max(size->width, item_size.width);
|
||||
size->height += FONT_HEIGHT_NORMAL * MIN_ELEMENTS + VSPACING;
|
||||
size->height += FONT_HEIGHT_NORMAL * MIN_ELEMENTS + WidgetDimensions::scaled.vsep_normal;
|
||||
resize->width = 0;
|
||||
resize->height = FONT_HEIGHT_NORMAL;
|
||||
break;
|
||||
@@ -587,7 +608,7 @@ struct FramerateWindow : Window {
|
||||
int drawable = this->num_displayed;
|
||||
int y = r.top;
|
||||
DrawString(r.left, r.right, y, heading_str, TC_FROMSTRING, SA_CENTER, true);
|
||||
y += FONT_HEIGHT_NORMAL + VSPACING;
|
||||
y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
|
||||
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
|
||||
if (_pf_data[e].num_valid == 0) continue;
|
||||
if (skip > 0) {
|
||||
@@ -609,7 +630,7 @@ struct FramerateWindow : Window {
|
||||
int drawable = this->num_displayed;
|
||||
int y = r.top;
|
||||
DrawString(r.left, r.right, y, STR_FRAMERATE_MEMORYUSE, TC_FROMSTRING, SA_CENTER, true);
|
||||
y += FONT_HEIGHT_NORMAL + VSPACING;
|
||||
y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
|
||||
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
|
||||
if (_pf_data[e].num_valid == 0) continue;
|
||||
if (skip > 0) {
|
||||
@@ -641,7 +662,7 @@ struct FramerateWindow : Window {
|
||||
const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR);
|
||||
uint16 skip = sb->GetPosition();
|
||||
int drawable = this->num_displayed;
|
||||
int y = r.top + FONT_HEIGHT_NORMAL + VSPACING; // first line contains headings in the value columns
|
||||
int y = r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; // first line contains headings in the value columns
|
||||
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
|
||||
if (_pf_data[e].num_valid == 0) continue;
|
||||
if (skip > 0) {
|
||||
@@ -683,7 +704,7 @@ struct FramerateWindow : Window {
|
||||
case WID_FRW_TIMES_AVERAGE: {
|
||||
/* Open time graph windows when clicking detail measurement lines */
|
||||
const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR);
|
||||
int line = sb->GetScrolledRowFromWidget(pt.y, this, widget, VSPACING + FONT_HEIGHT_NORMAL);
|
||||
int line = sb->GetScrolledRowFromWidget(pt.y, this, widget, WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL);
|
||||
if (line != INT_MAX) {
|
||||
line++;
|
||||
/* Find the visible line that was clicked */
|
||||
@@ -703,7 +724,7 @@ struct FramerateWindow : Window {
|
||||
void OnResize() override
|
||||
{
|
||||
auto *wid = this->GetWidget<NWidgetResizeBase>(WID_FRW_TIMES_NAMES);
|
||||
this->num_displayed = (wid->current_y - wid->min_y - VSPACING) / FONT_HEIGHT_NORMAL - 1; // subtract 1 for headings
|
||||
this->num_displayed = (wid->current_y - wid->min_y - WidgetDimensions::scaled.vsep_normal) / FONT_HEIGHT_NORMAL - 1; // subtract 1 for headings
|
||||
this->GetScrollbar(WID_FRW_SCROLLBAR)->SetCapacity(this->num_displayed);
|
||||
}
|
||||
};
|
||||
@@ -1079,3 +1100,22 @@ void ConPrintFramerate()
|
||||
IConsolePrint(CC_ERROR, "No performance measurements have been taken yet.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This drains the PFE_SOUND measurement data queue into _pf_data.
|
||||
* PFE_SOUND measurements are made by the mixer thread and so cannot be stored
|
||||
* into _pf_data directly, because this would not be thread safe and would violate
|
||||
* the invariants of the FPS and frame graph windows.
|
||||
* @see PerformanceMeasurement::~PerformanceMeasurement()
|
||||
*/
|
||||
void ProcessPendingPerformanceMeasurements()
|
||||
{
|
||||
if (_sound_perf_pending.load(std::memory_order_acquire)) {
|
||||
std::lock_guard lk(_sound_perf_lock);
|
||||
for (size_t i = 0; i < _sound_perf_measurements.size(); i += 2) {
|
||||
_pf_data[PFE_SOUND].Add(_sound_perf_measurements[i], _sound_perf_measurements[i + 1]);
|
||||
}
|
||||
_sound_perf_measurements.clear();
|
||||
_sound_perf_pending.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user