Project
Loading...
Searching...
No Matches
GPUDisplayGUIChannel.h
Go to the documentation of this file.
1// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#ifndef GPUDISPLAYGUICHANNEL_H
16#define GPUDISPLAYGUICHANNEL_H
17
18#define GPUSETTINGS_DISPLAY
19#define GPUSETTINGS_DISPLAYCONTROL
20#include "GPUSettings.h"
21#include <algorithm>
22#include <chrono>
23#include <condition_variable>
24#include <cstdint>
25#include <functional>
26#include <mutex>
27#include <optional>
28#include <string>
29#include <utility>
30#include <variant>
31#include <vector>
32
33namespace o2::gpu
34{
35using GPUDisplayGUIValue = std::variant<int64_t, double, std::string, GPUDisplayMultiSliderValue>; // Value of a Qt GUI element
36static_assert(sizeof(GPUDisplayGUIValue) == sizeof(std::variant<int64_t, double, std::string>), "GPUDisplayMultiSliderValue must not enlarge GPUDisplayGUIValue");
37
38struct GPUDisplayGUIUpdate { // GUI → display
39 uint64_t id = 0;
40 std::vector<int32_t> keys; // Keys pressed in the GUI and not handled by it, display key codes
41 std::vector<std::pair<uint32_t, GPUDisplayGUIValue>> values; // Elements changed in the GUI: element id, new value
42 std::optional<float> guiScale; // GUI scale changed with Ctrl + mouse wheel / Ctrl + 0
43 std::optional<int8_t> guiDarkMode; // System color scheme, reported when the GUI starts if not yet set
44 bool empty() const { return keys.empty() && values.empty() && !guiScale && !guiDarkMode; }
45 void setValue(uint32_t element, GPUDisplayGUIValue value) // Replaces an earlier value of the same element
46 {
47 auto it = std::find_if(values.begin(), values.end(), [element](const auto& v) { return v.first == element; });
48 if (it != values.end()) {
49 it->second = std::move(value);
50 } else {
51 values.emplace_back(element, std::move(value));
52 }
53 }
54 void merge(const GPUDisplayGUIUpdate& other) // Newer changes on top of this update, id not changed
55 {
56 keys.insert(keys.end(), other.keys.begin(), other.keys.end());
57 for (const auto& [element, value] : other.values) {
59 }
60 guiScale = other.guiScale ? other.guiScale : guiScale;
61 guiDarkMode = other.guiDarkMode ? other.guiDarkMode : guiDarkMode;
62 }
63};
64
65// Communication between the Qt GUI thread (GPUDisplayGUI) and the display thread (GPUDisplayFrontend::HandleExternalGUISignals), Qt-free.
66// The GUI sends at most one update per timer tick, the display processes it once per frame and publishes the complete settings with the id of the last processed update.
67// If the GUI went to sleep with an update ready and the display picks it up, the GUI waits for the reply when it wakes up, so it continues with the settings including its update.
69 struct Settings { // Copy of the config structs of GPUDisplay, with the same names, the GUI reads the values of its elements from it
70 GPUSettingsDisplayHeavy mCfgH;
71 GPUSettingsDisplayLight mCfgL;
72 GPUSettingsDisplayRenderer mCfgR;
73 GPUDisplayOptions mCfgO;
74 GPUDisplayControl mCfgC;
75 };
84
85 struct Options { // Dynamic range (slider) or choices (dropdown) of an element, returned by its option lambda
86 double min = 0, max = 0;
87 std::vector<std::pair<std::string, GPUDisplayGUIValue>> choices;
88 };
89 struct Element { // GUI element for one option, from GUI_LAMBDA in GPUDisplayFrontendConfigQtGUI.inc
90 std::string name; // Label
91 std::string description; // Tooltip, from the RTTI description of the option
92 uint32_t rttiIndex; // Option in the display config RTTI, invalid for options without RTTI (GPUDisplayControl)
93 ElementType type; // Widget type
94 uint32_t id; // Index of the element in Update::values
95 bool isInteger; // Integer / bool option, otherwise floating point
96 bool isString = false; // String option (text field sends the text)
97 bool horizontal = false; // In a row with the neighbouring horizontal elements, wrapping at the window border, otherwise an own row
98 uint32_t lines = 0; // Text edit: initial number of lines
99 bool hasRange = false; // Text field: value limited to min / max
100 double min = 0, max = 0; // Slider range / text field range (if hasRange), from the min / max of the option
101 double step = 0; // Slider with range / multi slider: positions are multiples of it (if > 0, required for the multi slider), multi slider handles at least that far apart
102 std::vector<std::pair<std::string, GPUDisplayGUIValue>> choices; // Radio buttons / dropdown / slider with only these values: name -> value
103 std::function<Options()> dynamicOptions; // Called by the GUI only while the display waits for it (see optionsRevision), reads display data
104 std::function<GPUDisplayGUIValue(const Settings&)> get; // Value of the option from a copy of the settings, callable from the GUI thread
105 };
106 struct Frame { // One add_gui_binding call
107 std::string description;
108 std::vector<Element> elements;
109 };
111 struct State { // display → GUI
113 std::string infoStatus; // Status line for the bottom of the GUI, empty if not sent
114 std::string infoText; // Latest info message, empty if not sent
115 uint64_t infoTextCounter = 0; // Incremented with every info message
116 uint64_t optionsRevision = 0; // Incremented when the GUI must call the dynamic option lambdas again (new event, GUI started)
117 uint64_t appliedUpdate = 0; // Id of the last GUI update included in cfg
118 uint64_t counter = 0; // Incremented with every published state
119 };
120
121 std::mutex mutex; // Protects all members below
122 std::condition_variable stateUpdated; // Notified when a new state is published or the GUI shall stop
123 std::condition_variable optionsRead; // Notified by the GUI when it called the dynamic option lambdas
124 uint64_t optionsReadRevision = 0; // optionsRevision for which the GUI called the dynamic option lambdas
125 bool displayWaitingForOptions = false; // Display waits until the GUI called the dynamic option lambdas, only then the GUI may call them
126 std::optional<Update> update; // Pending update, not yet picked up by the display
127 State state; // Latest state published by the display
128 bool guiSleeping = false; // GUI waits for its next timer tick with an update ready
129 bool displayProcessingCurrentUpdate = false; // Display processes the update the GUI went to sleep with, GUI waits for the reply
130 bool stop = false; // GUI shall close
131 std::chrono::milliseconds replyTimeout; // Maximum time the GUI waits for a reply
132 uint32_t maxUpdatesAhead = 0; // GUI waits for the reply if it is that many updates ahead of the last one it applied
133 std::chrono::milliseconds infoTextTime{5000}; // How long the GUI shows an info message: setInfoTime + setInfoTransition of the display
134 std::string windowName; // Name of the display window, set when starting the GUI
135 std::vector<Frame> layout; // GUI elements, set when starting the GUI
136 std::function<void()> updatePosted; // Set by the display, called by the GUI (without holding mutex) after posting an update, wakes up the display
137};
138} // namespace o2::gpu
139
140#endif // GPUDISPLAYGUICHANNEL_H
atype::type element
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
const GLdouble * v
Definition glcorearb.h:832
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
std::variant< int64_t, double, std::string, GPUDisplayMultiSliderValue > GPUDisplayGUIValue
std::function< GPUDisplayGUIValue(const Settings &)> get
std::vector< std::pair< std::string, GPUDisplayGUIValue > > choices
std::vector< std::pair< std::string, GPUDisplayGUIValue > > choices
std::function< void()> updatePosted
std::chrono::milliseconds replyTimeout
std::chrono::milliseconds infoTextTime
std::condition_variable stateUpdated
std::condition_variable optionsRead
std::optional< float > guiScale
void setValue(uint32_t element, GPUDisplayGUIValue value)
std::vector< std::pair< uint32_t, GPUDisplayGUIValue > > values
void merge(const GPUDisplayGUIUpdate &other)
std::optional< int8_t > guiDarkMode
VectorOfTObjectPtrs other