219 std::vector<MetricIndex>& visibleMetricsIndex,
220 std::vector<MetricDisplayState>& metricDisplayStates,
223 static bool locked =
false;
224 ImGui::Checkbox(
"Lock scrolling", &locked);
225 ImGui::BeginTable(
"##sparks table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY, ImVec2{-1, -1});
226 ImGui::TableSetupColumn(
"##close button", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 25);
227 ImGui::TableSetupColumn(
"##plot name", ImGuiTableColumnFlags_WidthFixed, 200);
228 ImGui::TableSetupColumn(
"##plot", ImGuiTableColumnFlags_WidthFixed, 0);
229 ImGui::TableSetupScrollFreeze(2, 0);
230 for (
size_t i = 0;
i < visibleMetricsIndex.size(); ++
i) {
231 auto&
index = visibleMetricsIndex[
i];
232 auto& metricsInfos = metricStore.
metrics[
index.storeIndex];
233 auto& metricsInfo = metricsInfos[
index.deviceIndex];
234 auto& metric = metricsInfo.metrics[
index.metricIndex];
235 auto&
state = metricDisplayStates[
index.stateIndex];
237 ImGui::TableNextColumn();
238 ImGui::PushID(
index.stateIndex);
239 state.visible = !ImGui::Button(
"-");
241 ImGui::TableNextColumn();
242 ImGui::TextUnformatted(
state.legend.c_str());
243 ImGui::TableNextColumn();
244 static ImPlotAxisFlags rtx_axis = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickMarks;
245 static ImPlotAxisFlags rty_axis = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickMarks;
246 ImGui::PushID(
index.stateIndex);
250 data.size = metric.filledMetrics;
254 ImPlot::SetNextAxisLimits(ImAxis_X1, (startTime + ImGui::GetTime() - 100) * 1000, (startTime + ImGui::GetTime()) * 1000, ImGuiCond_Always);
255 ImPlot::SetNextAxisLimits(ImAxis_Y1, metricsInfo.min[
index.metricIndex], metricsInfo.max[
index.metricIndex] * 1.1, ImGuiCond_Always);
256 rty_axis |= ImPlotAxisFlags_LockMin;
258 if (ImPlot::BeginPlot(
"##sparks", ImVec2(700, 100), 0)) {
259 ImPlot::SetupAxes(
"time",
"value", rtx_axis, rty_axis);
260 ImPlot::SetAxis(
state.axis);
261 switch (metric.type) {
262 case MetricType::Enum: {
263 data.points = (
void*)metricsInfo.enumMetrics[metric.storeIdx].data();
264 data.time = metricsInfo.enumTimestamps[metric.storeIdx].data();
266 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
267 auto histoData =
reinterpret_cast<HistoData*
>(hData);
268 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
270 return ImPlotPoint(histoData->time[
pos], ((int8_t*)(histoData->points))[
pos]);
272 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod);
274 case MetricType::Int: {
275 data.points = (
void*)metricsInfo.intMetrics[metric.storeIdx].data();
276 data.time = metricsInfo.intTimestamps[metric.storeIdx].data();
278 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
279 auto histoData =
reinterpret_cast<HistoData*
>(hData);
280 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
282 return ImPlotPoint(histoData->time[
pos], ((
int*)(histoData->points))[
pos]);
284 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod);
286 case MetricType::Uint64: {
287 data.points = (
void*)metricsInfo.uint64Metrics[metric.storeIdx].data();
288 data.time = metricsInfo.uint64Timestamps[metric.storeIdx].data();
290 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
291 auto histoData =
reinterpret_cast<HistoData*
>(hData);
292 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
294 return ImPlotPoint(histoData->time[
pos], ((uint64_t*)histoData->points)[
pos]);
296 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod, 0);
298 case MetricType::Float: {
299 data.points = (
void*)metricsInfo.floatMetrics[metric.storeIdx].data();
300 data.time = metricsInfo.floatTimestamps[metric.storeIdx].data();
302 auto getter = [](
int idx,
void* hData) -> ImPlotPoint {
303 auto histoData =
reinterpret_cast<HistoData*
>(hData);
304 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
306 return ImPlotPoint(histoData->time[
pos], ((
float*)histoData->points)[
pos]);
308 ImPlot::PlotLineG(
"##plot", getter, &
data,
data.mod, 0);
358 std::vector<MetricDisplayState>& state,
360 DriverInfo
const& driverInfo)
362 std::vector<void*> metricsToDisplay;
363 std::vector<const char*> deviceNames;
364 std::vector<MultiplotData> userData;
367 assert(metricsStore.metrics[si].size() == metricStore.
specs[si].size());
370 float maxValue[3] = {std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest()};
371 float minValue[3] = {0, 0, 0};
372 size_t maxDomain = std::numeric_limits<size_t>::lowest();
373 size_t minDomain = std::numeric_limits<size_t>::max();
376 ImPlotAxisFlags axisFlags = 0;
379 gsl::span<DeviceMetricsInfo const> metricsInfos = metricStore.
metrics[si];
380 gsl::span<TopologyNodeInfo const> specs = metricStore.
specs[si];
381 for (
int di = 0;
di < metricsInfos.size(); ++
di) {
382 for (
size_t mi = 0; mi < metricsInfos[
di].metrics.size(); ++mi) {
383 if (
state[gmi].visible ==
false) {
387 auto& metric = metricsInfos[
di].metrics[mi];
388 deviceNames.push_back(specs[
di].
label.c_str());
392 data.type = metric.type;
394 minValue[
data.axis] = std::min(minValue[
data.axis], metricsInfos[
di].min[mi]);
395 maxValue[
data.axis] = std::max(maxValue[
data.axis], metricsInfos[
di].max[mi]);
396 minDomain = std::min(minDomain, metricsInfos[
di].minDomain[mi]);
397 maxDomain = std::max(maxDomain, metricsInfos[
di].maxDomain[mi]);
398 axisFlags |=
data.axis == 1 ? (ImPlotFlags_)ImPlotFlags_YAxis2 : ImPlotFlags_None;
399 axisFlags |=
data.axis == 2 ? (ImPlotFlags_)ImPlotFlags_YAxis3 : ImPlotFlags_None;
400 switch (metric.type) {
401 case MetricType::Int: {
402 data.Y = metricsInfos[
di].intMetrics[metric.storeIdx].data();
403 auto& timestamps = metricsInfos[
di].intTimestamps[metric.storeIdx];
404 data.mod = std::min(metric.filledMetrics, timestamps.size());
406 data.X = timestamps.data();
408 case MetricType::Enum: {
409 data.Y = metricsInfos[
di].enumMetrics[metric.storeIdx].data();
410 auto& timestamps = metricsInfos[
di].enumTimestamps[metric.storeIdx];
411 data.mod = std::min(metric.filledMetrics, timestamps.size());
413 data.X = timestamps.data();
415 case MetricType::Uint64: {
416 data.Y = metricsInfos[
di].uint64Metrics[metric.storeIdx].data();
417 auto& timestamps = metricsInfos[
di].uint64Timestamps[metric.storeIdx];
418 data.mod = std::min(metric.filledMetrics, timestamps.size());
420 data.X = timestamps.data();
422 case MetricType::Float: {
423 data.Y = metricsInfos[
di].floatMetrics[metric.storeIdx].data();
424 auto& timestamps = metricsInfos[
di].floatTimestamps[metric.storeIdx];
425 data.mod = std::min(metric.filledMetrics, timestamps.size());
427 data.X = timestamps.data();
429 case MetricType::Unknown:
430 case MetricType::String: {
432 data.type = MetricType::String;
436 userData.emplace_back(
data);
442 maxDomain = std::max(minDomain + 1024, maxDomain);
443 for (
size_t ai = 0; ai < 3; ++ai) {
444 maxValue[ai] = std::max(minValue[ai] + 1.f, maxValue[ai]);
448 if (userData.empty()) {
451 for (
size_t ui = 0; ui < userData.size(); ++ui) {
452 metricsToDisplay.push_back(&(userData[ui]));
455 auto getterXY = [](
int idx,
void* hData) -> ImPlotPoint {
456 auto histoData =
reinterpret_cast<const MultiplotData*
>(hData);
457 size_t pos = (histoData->first +
static_cast<size_t>(idx)) % histoData->
mod;
458 double x =
static_cast<const size_t*
>(histoData->X)[
pos];
460 if (histoData->type == MetricType::Int) {
461 y =
static_cast<const int*
>(histoData->Y)[
pos];
462 }
else if (histoData->type == MetricType::Uint64) {
463 y =
static_cast<const uint64_t*
>(histoData->Y)[
pos];
464 }
else if (histoData->type == MetricType::Float) {
465 y =
static_cast<const float*
>(histoData->Y)[
pos];
466 }
else if (histoData->type == MetricType::Enum) {
467 y =
static_cast<const int8_t*
>(histoData->Y)[
pos];
469 auto point = ImPlotPoint{
x,
y};
472 static bool logScale =
false;
473 ImGui::Checkbox(
"Log scale", &logScale);
475 ImPlot::SetNextAxisLimits(ImAxis_X1, minDomain, maxDomain, ImGuiCond_Once);
477 auto axisPadding = 0.;
478 if (displayType == MetricsDisplayStyle::Lines) {
482 ImPlot::SetNextAxisLimits(ImAxis_Y1, minValue[0] - (maxValue[0] - minValue[0]) * axisPadding,
483 maxValue[0] * (1. + axisPadding), ImGuiCond_Always);
484 ImPlot::SetNextAxisLimits(ImAxis_Y2, minValue[1] - (maxValue[1] - minValue[1]) * axisPadding,
485 maxValue[1] * (1. + axisPadding), ImGuiCond_Always);
486 ImPlot::SetNextAxisLimits(ImAxis_Y3, minValue[2] - (maxValue[2] - minValue[2]) * axisPadding,
487 maxValue[2] * (1. + axisPadding), ImGuiCond_Always);
489 switch (displayType) {
490 case MetricsDisplayStyle::Histos:
491 if (ImPlot::BeginPlot(
"##Some plot")) {
492 ImPlot::SetupAxes(
"time",
"value");
493 ImPlot::SetupAxisFormat(ImAxis_Y1,
formatSI,
nullptr);
494 ImPlot::SetupAxisFormat(ImAxis_Y2,
formatSI,
nullptr);
495 ImPlot::SetupAxisFormat(ImAxis_Y3,
formatSI,
nullptr);
496 ImPlot::SetupAxisFormat(ImAxis_X1,
formatTimeSinceStart, (
void*)&driverInfo.startTimeMsFromEpoch);
497 for (
size_t pi = 0; pi < metricsToDisplay.size(); ++pi) {
501 ImPlot::PlotBarsG(
label, getterXY, metricsToDisplay[pi],
data->mod, 1, 0);
508 case MetricsDisplayStyle::Lines: {
509 auto xAxisFlags = ImPlotAxisFlags_None;
510 auto yAxisFlags = ImPlotAxisFlags_LockMin;
512 if (ImPlot::BeginPlot(
"##Some plot", {-1, -1}, axisFlags)) {
513 ImPlot::SetupAxes(
"time",
"value", xAxisFlags, yAxisFlags);
514 ImPlot::SetupAxisFormat(ImAxis_Y1,
formatSI,
nullptr);
515 ImPlot::SetupAxisFormat(ImAxis_Y2,
formatSI,
nullptr);
516 ImPlot::SetupAxisFormat(ImAxis_Y3,
formatSI,
nullptr);
517 ImPlot::SetupAxisFormat(ImAxis_X1,
formatTimeSinceStart, (
void*)&driverInfo.startTimeMsFromEpoch);
518 for (
size_t pi = 0; pi < metricsToDisplay.size(); ++pi) {
521 ImPlot::SetAxis(
data->axis);
522 ImPlot::PlotLineG(
data->legend, getterXY, metricsToDisplay[pi],
data->mod, 0);
528 case MetricsDisplayStyle::Stems:
529 if (ImPlot::BeginPlot(
"##Some plot")) {
530 ImPlot::SetupAxes(
"time",
"value");
531 for (
size_t pi = 0; pi < userData.size(); ++pi) {
534 if (
data->type == MetricType::Uint64) {
536 ImPlot::PlotScatterG(((
MultiplotData*)metricsToDisplay[pi])->legend, getterXY, metricsToDisplay[pi],
data->mod, 0);
626 DriverInfo
const& driverInfo,
627 std::vector<DeviceInfo>
const& infos,
628 std::vector<DataProcessorInfo>
const& metadata,
629 std::vector<DeviceControl>& controls,
632 if (
state.bottomPaneVisible ==
false) {
635 auto metricDisplayPos = 0;
636 static bool metricSelectorVisible =
true;
637 static std::vector<MetricDisplayState> metricDisplayState;
642 constexpr size_t MAX_QUERY_SIZE = 256;
643 static char query[MAX_QUERY_SIZE];
644 static char lastSelectedQuery[MAX_QUERY_SIZE];
646 size_t totalMetrics = 0;
647 for (
auto& metricsInfos : metricsStore.
metrics) {
648 for (
auto& metricInfo : metricsInfos) {
649 totalMetrics += metricInfo.metrics.size();
653 if (totalMetrics != metricDisplayState.size() || strcmp(lastSelectedQuery, query)) {
655 std::vector<MetricDisplayState> newMetricDisplayStates;
656 newMetricDisplayStates.resize(totalMetrics);
657 static std::vector<int> order;
658 order.resize(metricDisplayState.size());
659 std::iota(order.begin(), order.end(), 0);
660 std::sort(order.begin(), order.end(), [](
int a,
int b) {
661 return metricDisplayState[a].legend < metricDisplayState[b].legend;
665 auto& metricsInfos = metricsStore.
metrics[si];
666 auto& specs = metricsStore.
specs[si];
667 for (
size_t di = 0;
di < metricsInfos.size(); ++
di) {
668 auto& metricInfo = metricsInfos[
di];
669 auto& spec = specs[
di];
670 for (
size_t li = 0; li != metricInfo.metricLabels.size(); ++li) {
671 char const* metricLabel = metricInfo.metricLabels[li].label;
673 auto low = std::lower_bound(order.begin(), order.end(), spec.label, [](
int a, std::string
const&
b) {
674 return metricDisplayState[a].legend < b;
676 auto up = std::upper_bound(low, order.end(), spec.label, [](std::string
const&
a,
int b) {
677 return a < metricDisplayState[b].legend;
679 std::string legend = fmt::format(
"{}/{}", spec.label, metricLabel);
680 auto old = std::lower_bound(low, up, legend, [](
int a, std::string
const&
b) {
681 return metricDisplayState[
a].legend <
b;
683 if (old != order.end() && metricDisplayState[*old].legend == legend) {
684 newMetricDisplayStates[gmi].visible = metricDisplayState[*old].visible;
685 newMetricDisplayStates[gmi].axis = metricDisplayState[*old].axis;
687 newMetricDisplayStates[gmi].visible =
false;
690 newMetricDisplayStates[gmi].selected =
hasAll(metricLabel, query);
691 newMetricDisplayStates[gmi].legend = legend;
696 metricDisplayState.swap(newMetricDisplayStates);
697 strcpy(lastSelectedQuery, query);
700 static std::vector<MetricIndex> selectedMetricIndex;
702 if (metricSelectorVisible) {
703 selectedMetricIndex.clear();
706 auto& metricsInfos = metricsStore.
metrics[si];
708 for (
size_t di = 0;
di < metricsInfos.size(); ++
di) {
709 auto& metricInfo = metricsInfos[
di];
710 for (
size_t li = 0; li != metricInfo.metricLabels.size(); ++li) {
711 auto&
state = metricDisplayState[gmi];
712 if (
state.selected) {
713 selectedMetricIndex.emplace_back(
MetricIndex{si,
di, li, gmi});
720 metricDisplayPos = ImGui::GetIO().DisplaySize.x / 4;
721 ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y -
state.bottomPaneSize), 0);
722 ImGui::SetNextWindowSize(ImVec2(metricDisplayPos,
state.bottomPaneSize), 0);
723 ImGui::Begin(
"Available metrics",
nullptr, ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
725 ImGui::Text(ICON_FA_FILTER);
727 ImGui::InputText(
"##query-metrics", query, MAX_QUERY_SIZE);
728 size_t metricSize = 0;
729 for (
auto deviceMetrics : metricsStore.
metrics) {
730 metricSize += DeviceMetricsInfoHelpers::metricsStorageSize(deviceMetrics);
733 ImGui::Text(
"%zu/%zu matching", selectedMetricIndex.size(), totalMetrics);
735 static const char* possibleAxis[] = {
740 if (ImGui::BeginTable(
"##metrics-table", 3, ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY, ImVec2{-1, -1})) {
741 ImGui::TableSetupColumn(
"##close button", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 20);
742 ImGui::TableSetupColumn(
"##axis kind", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 30);
743 ImGui::TableSetupScrollFreeze(1, 0);
744 ImGuiListClipper clipper;
745 clipper.Begin(selectedMetricIndex.size());
746 while (clipper.Step()) {
747 for (
size_t i = clipper.DisplayStart;
i < clipper.DisplayEnd; ++
i) {
748 auto&
index = selectedMetricIndex[
i];
749 auto& metricsInfos = metricsStore.
metrics[
index.storeIndex];
751 auto& metricInfo = metricsInfos[
index.deviceIndex];
753 auto&
label = metricInfo.metricLabels[
index.metricIndex];
754 ImGui::PushID(
index.stateIndex);
755 ImGui::TableNextRow();
756 ImGui::TableNextColumn();
757 ImGui::Checkbox(
"##checkbox", &metricDisplayState[
index.stateIndex].visible);
758 ImGui::TableNextColumn();
759 if (metricDisplayState[
index.stateIndex].visible) {
760 if (ImGui::BeginCombo(
"##Select style", possibleAxis[metricDisplayState[
index.stateIndex].axis], ImGuiComboFlags_NoArrowButton)) {
761 for (
int n = 0;
n < IM_ARRAYSIZE(possibleAxis);
n++) {
762 bool is_selected = (metricDisplayState[
index.stateIndex].axis ==
n);
763 if (ImGui::Selectable(possibleAxis[
n], is_selected)) {
764 metricDisplayState[
index.stateIndex].axis =
n;
767 ImGui::SetItemDefaultFocus();
773 ImGui::TableNextColumn();
774 ImGui::Text(
"%s/%s", node.label.c_str(),
label.label);
782 ImGui::SetNextWindowPos(ImVec2(metricDisplayPos, ImGui::GetIO().DisplaySize.y -
state.bottomPaneSize), 0);
783 ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x - metricDisplayPos,
state.bottomPaneSize), 0);
785 ImGui::Begin(
"Devices",
nullptr, ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
787 if (!metricSelectorVisible) {
788 metricSelectorVisible = ImGui::Button(ICON_FA_CHEVRON_RIGHT
"Show metric selector");
790 metricSelectorVisible = !ImGui::Button(ICON_FA_CHEVRON_LEFT
"Hide metric selector");
792 static char const* plotStyles[] = {
800 static char const* currentStyleStr = plotStyles[0];
801 ImGui::TextUnformatted(
"Metric display style:");
803 ImGui::PushItemWidth(100);
804 if (ImGui::BeginCombo(
"##Select style", currentStyleStr)) {
805 for (
int n = 0;
n < IM_ARRAYSIZE(plotStyles);
n++) {
806 bool is_selected = (currentStyleStr == plotStyles[
n]);
807 if (ImGui::Selectable(plotStyles[
n], is_selected)) {
808 currentStyleStr = plotStyles[
n];
812 ImGui::SetItemDefaultFocus();
817 ImGui::PopItemWidth();
820 int visibleMetrics = 0;
821 static std::vector<int> visibleDevicesIndex;
822 static std::vector<MetricIndex> visibleMetricsIndex;
824 visibleDevicesIndex.reserve(totalMetrics);
825 visibleDevicesIndex.clear();
826 visibleMetricsIndex.clear();
829 auto& metricsInfos = metricsStore.
metrics[si];
830 for (
size_t di = 0;
di < metricsInfos.size(); ++
di) {
831 auto& metricInfo = metricsInfos[
di];
832 bool deviceVisible =
false;
833 for (
size_t mi = 0; mi < metricInfo.metrics.size(); ++mi) {
834 auto&
state = metricDisplayState[gmi];
836 deviceVisible =
true;
838 auto& metric = metricInfo.metrics[mi];
839 size_t const* timestamps =
nullptr;
840 switch (metric.type) {
841 case MetricType::Int:
842 timestamps = metricInfo.intTimestamps[metric.storeIdx].data();
844 case MetricType::Float:
845 timestamps = metricInfo.floatTimestamps[metric.storeIdx].data();
847 case MetricType::String:
848 timestamps = metricInfo.stringTimestamps[metric.storeIdx].data();
850 case MetricType::Uint64:
851 timestamps = metricInfo.uint64Timestamps[metric.storeIdx].data();
853 case MetricType::Enum:
854 timestamps = metricInfo.enumTimestamps[metric.storeIdx].data();
857 throw std::runtime_error(
"Unknown metric type");
862 size_t curMinTime = timestamps[minRangePos];
863 if (curMinTime == 0) {
866 minTime = minTime < curMinTime ? minTime : curMinTime;
867 if (minTime != 0 && minTime != -1) {
872 size_t curMaxTime = timestamps[maxRangePos];
873 maxTime = std::max(maxTime, curMaxTime);
879 visibleDevicesIndex.push_back(
di);
883 if (visibleMetricsIndex.empty()) {
889 switch (currentStyle) {
890 case MetricsDisplayStyle::Stems:
891 case MetricsDisplayStyle::Histos:
892 case MetricsDisplayStyle::Lines: {
894 minTime, maxTime, 1024,
895 currentStyle, metricDisplayState, metricsStore, driverInfo);
897 case MetricsDisplayStyle::Sparks: {
898 displaySparks(
state.startTime, visibleMetricsIndex, metricDisplayState, metricsStore);
900 case MetricsDisplayStyle::Table: {
901 static std::vector<float> visibleDevicesOffsets;
902 visibleDevicesOffsets.clear();
903 visibleDevicesOffsets.resize(visibleDevicesIndex.size());
905 size_t lastDevice = -1;
906 int visibleDeviceCount = -1;
908 for (
auto index : visibleMetricsIndex) {
909 auto& metricsInfos = metricsStore.
metrics[
index.storeIndex];
910 if (lastDevice !=
index.deviceIndex) {
911 visibleDeviceCount++;
912 lastDevice =
index.deviceIndex;
914 auto label = metricsInfos[
index.deviceIndex].metricLabels[
index.metricIndex].label;
915 visibleDevicesOffsets[visibleDeviceCount] += ImGui::CalcTextSize(
label,
nullptr,
true).x;
918 if (ImGui::BeginTable(
"##metrics-table", visibleMetricsIndex.size() + 1, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX, ImVec2{-1, -1})) {
919 ImGui::TableSetupColumn(
"##close button", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed, 20);
920 for (
int i = 0;
i < visibleMetricsIndex.size(); ++
i) {
921 ImGui::TableSetupColumn(
"##device-header", ImGuiTableColumnFlags_WidthFixed, 100);
923 ImGui::TableSetupScrollFreeze(1, 2);
924 ImGui::TableNextRow();
925 ImGui::TableNextColumn();
926 ImGui::TextUnformatted(
"");
927 visibleDeviceCount = -1;
929 for (
auto index : visibleMetricsIndex) {
930 ImGui::TableNextColumn();
931 auto& devices = metricsStore.
specs[
index.storeIndex];
932 if (lastDevice ==
index.deviceIndex) {
935 visibleDeviceCount++;
936 lastDevice =
index.deviceIndex;
937 auto& spec = devices[
index.deviceIndex];
939 ImGui::TextUnformatted(spec.label.c_str());
943 ImGui::TableNextRow();
944 ImGui::TableNextColumn();
945 ImGui::TextUnformatted(
"#");
947 for (
auto index : visibleMetricsIndex) {
948 ImGui::TableNextColumn();
949 auto& metricsInfos = metricsStore.
metrics[
index.storeIndex];
950 auto& metric = metricsInfos[
index.deviceIndex];
951 auto label = metricsInfos[
index.deviceIndex].metricLabels[
index.metricIndex].label;
952 ImGui::Text(
"%s (%" PRIu64
")",
label, (uint64_t)metric.metrics[
index.metricIndex].filledMetrics);
956 ImGuiListClipper clipper;
960 while (clipper.Step()) {
961 for (
size_t i = clipper.DisplayStart;
i < clipper.DisplayEnd; ++
i) {
962 ImGui::TableNextRow();
976 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.);
977 if (info.
active ==
false) {
978 ImGui::PushStyleColor(ImGuiCol_TitleBg, PaletteHelpers::DARK_RED);
979 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, PaletteHelpers::RED);
980 ImGui::PushStyleColor(ImGuiCol_TitleBgCollapsed, PaletteHelpers::RED);
984 case LogLevel::Critical:
985 ImGui::PushStyleColor(ImGuiCol_TitleBg, PaletteHelpers::SHADED_RED);
986 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, PaletteHelpers::RED);
987 ImGui::PushStyleColor(ImGuiCol_TitleBgCollapsed, PaletteHelpers::SHADED_RED);
989 case LogLevel::Error:
990 ImGui::PushStyleColor(ImGuiCol_TitleBg, PaletteHelpers::SHADED_RED);
991 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, PaletteHelpers::RED);
992 ImGui::PushStyleColor(ImGuiCol_TitleBgCollapsed, PaletteHelpers::SHADED_RED);
994 case LogLevel::Alarm:
995 ImGui::PushStyleColor(ImGuiCol_TitleBg, PaletteHelpers::SHADED_YELLOW);
996 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, PaletteHelpers::YELLOW);
997 ImGui::PushStyleColor(ImGuiCol_TitleBgCollapsed, PaletteHelpers::SHADED_YELLOW);
999 case LogLevel::Warning:
1000 ImGui::PushStyleColor(ImGuiCol_TitleBg, PaletteHelpers::SHADED_YELLOW);
1001 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, PaletteHelpers::YELLOW);
1002 ImGui::PushStyleColor(ImGuiCol_TitleBgCollapsed, PaletteHelpers::SHADED_YELLOW);
1004 case LogLevel::Info:
1005 ImGui::PushStyleColor(ImGuiCol_TitleBg, PaletteHelpers::SHADED_GREEN);
1006 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, PaletteHelpers::GREEN);
1007 ImGui::PushStyleColor(ImGuiCol_TitleBgCollapsed, PaletteHelpers::SHADED_GREEN);
1010 ImGui::PushStyleColor(ImGuiCol_TitleBg, PaletteHelpers::SHADED_BLUE);
1011 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, PaletteHelpers::BLUE);
1012 ImGui::PushStyleColor(ImGuiCol_TitleBgCollapsed, PaletteHelpers::SHADED_BLUE);
1130 std::vector<DeviceSpec>
const& devices,
1131 std::vector<DataProcessingStates>
const& allStates,
1132 std::vector<DataProcessorInfo>
const& metadata,
1133 std::vector<DeviceMetricsInfo>
const& metricsInfos,
1134 DriverInfo
const& driverInfo,
1135 std::vector<DeviceControl>& controls,
1144 guiState.
devices.resize(infos.size());
1145 for (
size_t i = 0;
i < guiState.
devices.size(); ++
i) {
1158 clock_gettime(CLOCK_REALTIME, &now);
1159 guiState.
startTime = now.tv_sec - ImGui::GetTime();
1160 std::vector<TopologyNodeInfo> deviceNodesInfos;
1161 for (
auto& device : devices) {
1164 std::vector<TopologyNodeInfo> driverNodesInfos;
1167 return [&infos, &devices, &allStates, &metadata, &controls, &metricsInfos, &driverInfo, &driverControl, deviceNodesInfos, driverNodesInfos]() {
1168 ImGuiStyle& style = ImGui::GetStyle();
1169 style.FrameRounding = 0.;
1170 style.WindowRounding = 0.;
1171 style.Colors[ImGuiCol_WindowBg] = ImVec4(0x1b / 255.f, 0x1b / 255.f, 0x1b / 255.f, 1.00f);
1172 style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0x1b / 255.f, 0x1b / 255.f, 0x1b / 255.f, 1.00f);
1182 displayMetrics(guiState, driverInfo, infos, metadata, controls, metricsStore);
1185 int windowPosStepping = (ImGui::GetIO().DisplaySize.y - 500) / guiState.
devices.size();
1187 for (
size_t i = 0;
i < guiState.
devices.size(); ++
i) {
1189 assert(
i < infos.size());
1190 assert(
i < devices.size());
1193 assert(controls.size() == devices.size());
1198 ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x / 3 * 2,
i * windowPosStepping), ImGuiCond_Once);
1199 ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x / 3, ImGui::GetIO().DisplaySize.y - 300),
1206 ImGui::Checkbox(
"Stop logging", &control.
quiet);
1209 control.
logLevel = LogParsingHelpers::LogLevel::Debug;
1211 ImGui::Combo(
"Log level",
reinterpret_cast<int*
>(&control.
logLevel), LogParsingHelpers::LOG_LEVELS,
1212 (
int)LogParsingHelpers::LogLevel::Size, 5);
1215 ImGui::BeginChild(
"ScrollingRegion", ImVec2(0, -ImGui::GetTextLineHeightWithSpacing()),
false,
1216 ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NoMove);