zgui/libs/imgui_test_engine/imgui_te_perftool.h

132 lines
7.7 KiB
C
Raw Permalink Normal View History

// dear imgui test engine
// (performance tool)
// Browse and visualize samples recorded by ctx->PerfCapture() calls.
// User access via 'Test Engine UI -> Tools -> Perf Tool'
#pragma once
#include "imgui.h"
// Forward Declaration
struct ImGuiPerfToolColumnInfo;
struct ImGuiTestEngine;
struct ImGuiCsvParser;
// Configuration
#define IMGUI_PERFLOG_DEFAULT_FILENAME "output/imgui_perflog.csv"
// [Internal] Perf log entry. Changes to this struct should be reflected in ImGuiTestContext::PerfCapture() and ImGuiTestEngine_Start().
// This struct assumes strings stored here will be available until next ImGuiPerfTool::Clear() call. Fortunately we do not have to actively
// manage lifetime of these strings. New entries are created only in two cases:
// 1. ImGuiTestEngine_PerfToolAppendToCSV() call after perf test has run. This call receives ImGuiPerfToolEntry with const strings stored indefinitely by application.
// 2. As a consequence of ImGuiPerfTool::LoadCSV() call, we persist the ImGuiCSVParser instance, which keeps parsed CSV text, from which strings are referenced.
// As a result our solution also doesn't make many allocations.
struct IMGUI_API ImGuiPerfToolEntry
{
ImU64 Timestamp = 0; // Title of a particular batch of perftool entries.
const char* Category = NULL; // Name of category perf test is in.
const char* TestName = NULL; // Name of perf test.
double DtDeltaMs = 0.0; // Result of perf test.
double DtDeltaMsMin = +FLT_MAX; // May be used by perftool.
double DtDeltaMsMax = -FLT_MAX; // May be used by perftool.
int NumSamples = 1; // Number aggregated samples.
int PerfStressAmount = 0; //
const char* GitBranchName = NULL; // Build information.
const char* BuildType = NULL; //
const char* Cpu = NULL; //
const char* OS = NULL; //
const char* Compiler = NULL; //
const char* Date = NULL; // Date of this entry or min date of combined entries.
//const char* DateMax = NULL; // Max date of combined entries, or NULL.
double VsBaseline = 0.0; // Percent difference vs baseline.
int LabelIndex = 0; // Index of TestName in ImGuiPerfTool::_LabelsVisible.
ImGuiPerfToolEntry() { }
ImGuiPerfToolEntry(const ImGuiPerfToolEntry& rhs) { Set(rhs); }
ImGuiPerfToolEntry& operator=(const ImGuiPerfToolEntry& rhs){ Set(rhs); return *this; }
void Set(const ImGuiPerfToolEntry& rhs);
};
// [Internal] Perf log batch.
struct ImGuiPerfToolBatch
{
ImU64 BatchID = 0; // Timestamp of the batch, or unique ID of the build in combined mode.
int NumSamples = 0; // A number of unique batches aggregated.
int BranchIndex = 0; // For per-branch color mapping.
ImVector<ImGuiPerfToolEntry> Entries; // Aggregated perf test entries. Order follows ImGuiPerfTool::_LabelsVisible order.
~ImGuiPerfToolBatch() { Entries.clear_destruct(); } // FIXME: Misleading: nothing to destruct in that struct?
};
enum ImGuiPerfToolDisplayType : int
{
ImGuiPerfToolDisplayType_Simple, // Each run will be displayed individually.
ImGuiPerfToolDisplayType_PerBranchColors, // Use one bar color per branch.
ImGuiPerfToolDisplayType_CombineByBuildInfo, // Entries with same build information will be averaged.
};
//
struct IMGUI_API ImGuiPerfTool
{
ImVector<ImGuiPerfToolEntry> _SrcData; // Raw entries from CSV file (with string pointer into CSV data).
ImVector<const char*> _Labels;
ImVector<const char*> _LabelsVisible; // ImPlot requires a pointer of all labels beforehand. Always contains a dummy "" entry at the end!
ImVector<ImGuiPerfToolBatch> _Batches;
ImGuiStorage _LabelBarCounts; // Number bars each label will render.
int _NumVisibleBuilds = 0; // Cached number of visible builds.
int _NumUniqueBuilds = 0; // Cached number of unique builds.
ImGuiPerfToolDisplayType _DisplayType = ImGuiPerfToolDisplayType_CombineByBuildInfo;
int _BaselineBatchIndex = 0; // Index of baseline build.
ImU64 _BaselineTimestamp = 0;
ImU64 _BaselineBuildId = 0;
char _Filter[128]; // Context menu filtering substring.
char _FilterDateFrom[11] = {};
char _FilterDateTo[11] = {};
float _InfoTableHeight = 180.0f;
int _AlignStress = 0; // Alignment values for build info components, so they look aligned in the legend.
int _AlignType = 0;
int _AlignOs = 0;
int _AlignCpu = 0;
int _AlignCompiler = 0;
int _AlignBranch = 0;
int _AlignSamples = 0;
bool _InfoTableSortDirty = false;
ImVector<ImU64> _InfoTableSort; // _InfoTableSort[_LabelsVisible.Size * _Batches.Size]. Contains sorted batch indices for each label.
const ImGuiTableSortSpecs* _InfoTableSortSpecs = NULL; // Current table sort specs.
ImGuiStorage _TempSet; // Used as a set
int _TableHoveredTest = -1; // Index within _VisibleLabelPointers array.
int _TableHoveredBatch = -1;
int _PlotHoverTest = -1;
int _PlotHoverBatch = -1;
bool _PlotHoverTestLabel = false;
bool _ReportGenerating = false;
ImGuiStorage _Visibility;
ImGuiCsvParser* _CsvParser = NULL; // We keep this around and point to its fields
ImGuiPerfTool();
~ImGuiPerfTool();
void Clear();
bool LoadCSV(const char* filename = NULL);
void AddEntry(ImGuiPerfToolEntry* entry);
void ShowPerfToolWindow(ImGuiTestEngine* engine, bool* p_open);
void ViewOnly(const char* perf_name);
void ViewOnly(const char** perf_names);
ImGuiPerfToolEntry* GetEntryByBatchIdx(int idx, const char* perf_name = NULL);
bool SaveHtmlReport(const char* file_name, const char* image_file = NULL);
inline bool Empty() { return _SrcData.empty(); }
void _Rebuild();
bool _IsVisibleBuild(ImGuiPerfToolBatch* batch);
bool _IsVisibleBuild(ImGuiPerfToolEntry* batch);
bool _IsVisibleTest(const char* test_name);
void _CalculateLegendAlignment();
void _ShowEntriesPlot();
void _ShowEntriesTable();
void _SetBaseline(int batch_index);
void _AddSettingsHandler();
void _UnpackSortedKey(ImU64 key, int* batch_index, int* entry_index, int* monotonic_index = NULL);
};
IMGUI_API void ImGuiTestEngine_PerfToolAppendToCSV(ImGuiPerfTool* perf_log, ImGuiPerfToolEntry* entry, const char* filename = NULL);