Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions GPU/GPUTracking/Definitions/GPUSettingsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,11 @@ AddOptionVec(filterMacros, std::string, "", 0, "ROOT macros used as track filter
AddOption(guiReplyTimeout, uint32_t, 100, "", 0, "Time in ms the Qt GUI waits at most for the display to process its update")
AddOption(guiMaxUpdatesAhead, uint32_t, 3, "", 0, "Number of updates the Qt GUI may send ahead of the last one the display has processed, before it waits for the display")
AddOption(listFrontendOptionHandling, bool, false, "", 0, "List all assigned keys in frontend, Configurable settings in Qt GUI, and missing configuration options")
AddOption(consoleDelay, float, 0.5f, "", 0, "Time in seconds to open / close the console (^ key)")
AddOption(consoleAlpha, float, 0.8f, "", 0, "Opacity of the console background")
AddOption(consoleVertical, float, 0.5f, "", 0, "Fraction of the window height covered by the fully opened console")
AddOption(runScript, std::string, "", "", 0, "Console script file, run before the first frame of the display")
AddOption(consoleHistorySize, uint32_t, 1000000, "", 0, "Number of console lines kept, the history is shortened to this when it reaches twice the size")
AddSubConfig(GPUSettingsDisplayLight, light)
AddSubConfig(GPUSettingsDisplayHeavy, heavy)
AddSubConfig(GPUSettingsDisplayRenderer, renderer)
Expand Down
1 change: 1 addition & 0 deletions GPU/GPUTracking/display/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ set(SRCS ../utils/qsem.cxx
GPUDisplay.cxx
helpers/GPUDisplayMagneticField.cxx
frontend/GPUDisplayFrontend.cxx
frontend/GPUDisplayConsole.cxx
frontend/GPUDisplayFrontendNone.cxx
backend/GPUDisplayBackend.cxx
backend/GPUDisplayBackendNone.cxx)
Expand Down
34 changes: 26 additions & 8 deletions GPU/GPUTracking/display/GPUDisplay.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,22 @@ int32_t GPUDisplay::InitDisplay(bool initFailure)
if (!initFailure) {
retVal = InitDisplay_internal();
}
if (retVal == 0) {
buildConfig();
if (mConfig.listFrontendOptionHandling) {
mFrontend->listConfig();
}
}
} catch (const std::runtime_error& e) {
GPUError("%s", e.what());
retVal = 1;
}
mInitResult = retVal == 0 ? 1 : -1;
mOldCfg = {mCfgH, mCfgL, mCfgR};
std::unique_lock lock(mFrontend->mExitStateMutex);
mInitResult = retVal == 0 ? 1 : -1;
mFrontend->mDisplayRunning = retVal == 0; // Only after successful initialization, StopDisplay waits for it to become false again
mFrontend->mInitCV.notify_all();
mFrontend->mInitCV.wait(lock, [this] { return mFrontend->mStartDisplayDone; }); // Both threads have finished their initialization
return (retVal);
}

Expand Down Expand Up @@ -727,9 +737,23 @@ void GPUDisplay::DrawGLScene_internal(bool suspended, float animateTime, bool re
mFramesDoneFPS = 0;
}

const float consoleFraction = consoleVerticalFraction();
const bool drawText = (mCfgC.mPrintInfoText & 1) || consoleFraction > 0.f;
if (drawText) {
mBackend->updateFontScale(mFrontend->getDisplayScale());
mBackend->prepareText();
}
if (mCfgC.mPrintInfoText & 1 || mCfgC.mPrintInfoTextGUI) {
showInfo(info);
}
if (consoleFraction > 0.f) {
const bool cursor = mCfgC.showConsole && std::fmod(mConsoleTimer.GetCurrentElapsedTime(), 1.0) < 0.5; // Blinking, the timer runs while the console is open
mBackend->GLDrawConsole(consoleFraction, mFrontend->mConsole->mConsoleHistory, mFrontend->mConsole->shownText(), cursor ? (int32_t)mFrontend->mConsole->mConsoleTextPos : -1);
}
if (drawText) {
mBackend->finishText();
}
mFrontend->mConsole->consoleLimitHistory(mConfig.consoleHistorySize);
}

mBackend->finishFrame(doScreenshot, renderToMixBuffer, mixSlaveImage);
Expand Down Expand Up @@ -776,11 +800,5 @@ void GPUDisplay::WaitTillEventShown()
int32_t GPUDisplay::StartDisplay()
{
mLoadAndShowEvent = true;
if (mFrontend->StartDisplay()) {
return (1);
}
while (mInitResult == 0) {
Sleep(10);
}
return (mInitResult != 1);
return mFrontend->StartDisplay();
}
14 changes: 8 additions & 6 deletions GPU/GPUTracking/display/GPUDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class GPUDisplay : public GPUDisplayInterface
void UpdateCalib(const GPUCalibObjectsConst* calib) override { mCalib = calib; }
void UpdateParam(const GPUParam* param) override { mParam = param; }

void HandleKey(uint8_t key);
void HandleKey(uint8_t key, bool external = false); // external: from the Qt GUI or the console, not typed into the event display console
int32_t DrawGLScene(bool suspended = false);
void HandleExternalGUIKey(int32_t key);
int32_t InitDisplay(bool initFailure = false);
Expand Down Expand Up @@ -198,6 +198,7 @@ class GPUDisplay : public GPUDisplayInterface
void startAnimation();
int32_t animateCamera(bool suspended, float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix);
void showInfo(const char* info);
float consoleVerticalFraction(); // Fraction of the window covered by the console (animated), 0 if hidden
void ActivateColor();
void SetColorTRD();
void SetColorTOF();
Expand Down Expand Up @@ -321,14 +322,15 @@ class GPUDisplay : public GPUDisplayInterface
opengl_spline mAnimationSplines[8];

char mInfoText2[1024];
std::string mGUIInfoStatus; // Latest status line (FPS etc.) for the Qt GUI
std::string mGUIInfoText; // Latest info message (SetInfo) for the Qt GUI
uint64_t mGUIInfoTextCounter = 0; // Number of info messages, the GUI shows a new one for some seconds
HighResTimer mInfoText2Timer, mInfoHelpTimer;
std::string mGUIInfoStatus; // Latest status line (FPS etc.) for the Qt GUI
std::string mGUIInfoText; // Latest info message (SetInfo) for the Qt GUI
uint64_t mGUIInfoTextCounter = 0; // Number of info messages, the GUI shows a new one for some seconds
HighResTimer mInfoText2Timer, mInfoHelpTimer, mConsoleTimer; // mConsoleTimer: opening / closing animation of the console
bool mConsoleShown = false; // showConsole of the last checkAndApplyConfigChanges

std::vector<threadVertexBuffer> mThreadBuffers;
std::vector<std::vector<std::array<std::array<vecpod<int32_t>, 2>, NSECTORS>>> mThreadTracks;
volatile int32_t mInitResult = 0;
int32_t mInitResult = 0; // 1 success, -1 failure, protected by mFrontend->mExitStateMutex

float mFPSScale = 1, mFPSScaleadjust = 0;
int32_t mFramesDone = 0, mFramesDoneFPS = 0;
Expand Down
1 change: 1 addition & 0 deletions GPU/GPUTracking/display/GPUDisplayControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ BeginHiddenConfig(GPUDisplayControl, control)
AddVariable(mGLAnimationFile, std::string, "glanimation.tmp") // File for saving / loading the animation path
AddVariable(mGuiDarkMode, int8_t, -1) // Dark mode of the Qt GUI, -1 = not yet set: the GUI reports the system scheme when it starts
AddVariable(mGuiScale, float, 1.f) // Scale factor of text and elements of the Qt GUI (on top of the system scaling), Ctrl + mouse wheel / Ctrl + 0 in the GUI
AddVariable(showConsole, bool, false) // Console shown (^ key): all other keys go to the console
AddVariable(dummy, bool, false) // dummy value to reference for keys that do not change variables
EndConfig()
EndNamespace() // o2::gpu
43 changes: 42 additions & 1 deletion GPU/GPUTracking/display/backend/GPUDisplayBackend.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void GPUDisplayBackend::loadFont()
mFontRasterScale = mDisplay->frontend()->getDisplayScale();
FT_Set_Pixel_Sizes(face, 0, (uint32_t)(fontSize * mFontRasterScale + 0.5f)); // Rasterize at physical pixel size for HiDPI

for (uint32_t i = 0; i < 128; i++) {
for (uint32_t i = 0; i < SOLID_GLYPH; i++) {
if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
GPUError("Error loading freetype symbol");
FT_Done_Face(face);
Expand All @@ -145,6 +145,8 @@ void GPUDisplayBackend::loadFont()
}
addFontSymbol(i, glyph->bitmap.width, glyph->bitmap.rows, glyph->bitmap_left, glyph->bitmap_top, glyph->advance.x, glyph->bitmap.buffer);
}
std::vector<uint8_t> solid(8 * 8, 255);
addFontSymbol(SOLID_GLYPH, 8, 8, 0, 0, 0, solid.data());
initializeTextDrawing();
FT_Done_Face(face);
FT_Done_FreeType(ft);
Expand Down Expand Up @@ -207,3 +209,42 @@ bool GPUDisplayBackend::smoothFont()
{
return mDisplay->cfg().smoothFont < 0 ? (mDisplay->cfg().fontSize > 12) : mDisplay->cfg().smoothFont;
}

void GPUDisplayBackend::GLDrawLine(float x0, float y0, float x1, float y1, float width, const float* color)
{
const float dx = x1 - x0, dy = y1 - y0, length = std::sqrt(dx * dx + dy * dy);
if (length == 0.f) {
return;
}
const float nx = -dy / length * width * 0.5f, ny = dx / length * width * 0.5f; // Perpendicular, half the width
GLDrawQuad({{x0 + nx, y0 + ny}, {x0 - nx, y0 - ny}, {x1 - nx, y1 - ny}, {x1 + nx, y1 + ny}}, color);
}

void GPUDisplayBackend::GLDrawConsole(float verticalFraction, std::span<const std::string> previous, const std::string& current, int32_t cursorPos)
{
if (!mFreetypeInitialized) {
return;
}
const float scale = mDisplay->frontend()->getDisplayScale();
const float colorValue = mDisplay->cfgL().invertColors ? 0.f : 1.f;
float textColor[4] = {colorValue, colorValue, colorValue, 1.f};
const float backgroundColor[4] = {1.f - colorValue, 1.f - colorValue, 1.f - colorValue, mDisplay->cfg().consoleAlpha};
const float width = mScreenWidth, top = mScreenHeight, bottom = top * (1.f - verticalFraction);
GLDrawQuad({{0.f, bottom}, {width, bottom}, {width, top}, {0.f, top}}, backgroundColor);
GLDrawLine(0.f, bottom, width, bottom, scale, textColor);

static constexpr float MARGIN = 6.f; // Logical pixels from the text to the left border and to the line
const float lineHeight = std::max(20, mDisplay->drawTextFontSize() + 4) * scale; // As the info text of GPUDisplay
const float descent = 0.25f * mDisplay->drawTextFontSize() * scale; // Below the baseline, approximately
const size_t maxChars = mFontCharWidth > 0.f ? std::max(0.f, (width / scale - 2 * MARGIN) / mFontCharWidth) : SIZE_MAX; // Longer lines are cut
float y = bottom + (0.5f + MARGIN) * scale + descent; // Baseline of the lowest line, MARGIN above the line (half its width)
if (cursorPos >= 0 && (size_t)cursorPos < maxChars && mFontCharWidth > 0.f) { // Monospace font: position from the character width
GLPrintText("_", (MARGIN + cursorPos * mFontCharWidth) * scale, y, textColor, scale / mFontRasterScale, 0);
}
for (size_t i = 0; i <= previous.size() && y + lineHeight - descent <= top; i++, y += lineHeight) {
const std::string& text = i == 0 ? current : previous[previous.size() - i];
if (!text.empty() && maxChars) {
GLPrintText(text.c_str(), MARGIN * scale, y, textColor, scale / mFontRasterScale, std::min(text.size(), maxChars));
}
}
}
12 changes: 9 additions & 3 deletions GPU/GPUTracking/display/backend/GPUDisplayBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "GPUCommonDef.h"
#include "../utils/vecpod.h"
#include <span>
#include <string>
#include <array>
#include <cstddef>
#include <memory>
Expand Down Expand Up @@ -99,7 +101,10 @@ class GPUDisplayBackend
const char* backendName() const { return mBackendName; }
virtual void resizeScene(uint32_t width, uint32_t height) {}
virtual size_t needMultiVBO() { return 0; }
virtual void GLPrintText(const char* s, float x, float y, float* color, float scale, uint32_t nCharacters) = 0; // nCharacters > 0: at most that many characters, otherwise until the terminating 0
virtual void GLPrintText(const char* s, float x, float y, float* color, float scale, uint32_t nCharacters) = 0; // nCharacters > 0: at most that many characters, otherwise until the terminating 0
virtual void GLDrawQuad(const float (&corners)[4][2], const float* color) = 0; // Filled quad with the corners counterclockwise, in pixels with y from the bottom, drawn with the text (SOLID_GLYPH)
void GLDrawLine(float x0, float y0, float x1, float y1, float width, const float* color); // As GLDrawQuad
void GLDrawConsole(float verticalFraction, std::span<const std::string> previous, const std::string& current, int32_t cursorPos); // Console over the top verticalFraction of the window: current text in the lowest line, previous ones above (last one lowest), cursor _ at cursorPos (< 0: none)
static GPUDisplayBackend* getBackend(const char* type);
std::vector<char> getPixels();
virtual float getYFactor() const { return 1.0f; }
Expand All @@ -119,8 +124,9 @@ class GPUDisplayBackend
std::vector<int32_t> mIndirectSectorOffset;
vecpod<DrawArraysIndirectCommand> mCmdBuffer;
bool mFreetypeInitialized = false;
float mFontRasterScale = 1.f; // Display scale the font was rasterized for
float mFontCharWidth = 0.f; // Advance of a character of the (monospace) font in logical pixels, 0 without Freetype font
float mFontRasterScale = 1.f; // Display scale the font was rasterized for
static constexpr int32_t SOLID_GLYPH = 128; // Fully opaque glyph after the characters (0 - 127), for quads drawn with the text
float mFontCharWidth = 0.f; // Advance of a character of the (monospace) font in logical pixels, 0 without Freetype font
std::vector<char> mScreenshotPixels;

static constexpr float SMOOTH_POINT_EXTRA_SIZE = 0.6f;
Expand Down
1 change: 1 addition & 0 deletions GPU/GPUTracking/display/backend/GPUDisplayBackendNone.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class GPUDisplayBackendNone : public GPUDisplayBackend
void pointSizeFactor(float factor) override {}
void lineWidthFactor(float factor) override {}
void GLPrintText(const char* s, float x, float y, float* color, float scale, uint32_t nCharacters) override {}
void GLDrawQuad(const float (&corners)[4][2], const float* color) override {}
void addFontSymbol(int32_t symbol, int32_t sizex, int32_t sizey, int32_t offsetx, int32_t offsety, int32_t advance, void* data) override {}
void initializeTextDrawing() override {}
};
Expand Down
38 changes: 31 additions & 7 deletions GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,8 @@ void GPUDisplayBackendOpenGL::GLPrintText(const char* s, float x, float y, float
scale *= 0.25f; // Font size is 48 to have nice bitmap, scale to size 12
}
for (const unsigned char* c = (const unsigned char*)s; *c && (nCharacters == 0 || c < (const unsigned char*)s + nCharacters); c++) {
if ((int32_t)*c >= (int32_t)mFontSymbols.size()) {
GPUError("Trying to draw unsupported symbol: %d > %d\n", (int32_t)*c, (int32_t)mFontSymbols.size());
if (*c < 32 || *c >= SOLID_GLYPH) { // Printable ASCII only, SOLID_GLYPH is not a character
GPUError("Trying to draw unsupported symbol: %d", (int32_t)*c);
continue;
}
FontSymbolOpenGL sym = mFontSymbols[*c];
Expand All @@ -701,11 +701,7 @@ void GPUDisplayBackendOpenGL::GLPrintText(const char* s, float x, float y, float
{xpos, ypos + h, 0.0f, 0.0f},
{xpos + w, ypos, 1.0f, 1.0f},
{xpos + w, ypos + h, 1.0f, 0.0f}};
CHKERR(glBindTexture(GL_TEXTURE_2D, sym.texId));
CHKERR(glBindBuffer(GL_ARRAY_BUFFER, VBO_text));
CHKERR(glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices));
CHKERR(glBindBuffer(GL_ARRAY_BUFFER, 0));
CHKERR(glDrawArrays(GL_TRIANGLES, 0, 6));
drawTextVertices(vertices, sym.texId);
}
x += (sym.advance >> 6) * scale; // shift is in 1/64th of a pixel
}
Expand All @@ -714,6 +710,34 @@ void GPUDisplayBackendOpenGL::GLPrintText(const char* s, float x, float y, float
}
}

void GPUDisplayBackendOpenGL::drawTextVertices(const float (&vertices)[6][4], uint32_t texId)
{
CHKERR(glBindTexture(GL_TEXTURE_2D, texId));
CHKERR(glBindBuffer(GL_ARRAY_BUFFER, VBO_text));
CHKERR(glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices));
CHKERR(glBindBuffer(GL_ARRAY_BUFFER, 0));
CHKERR(glDrawArrays(GL_TRIANGLES, 0, 6));
}

void GPUDisplayBackendOpenGL::GLDrawQuad(const float (&corners)[4][2], const float* color)
{
if (!mFreetypeInitialized) {
return;
}
CHKERR(glUniform4fv(UNIFORM_LOCATION_COLOR, 1, color));
static constexpr int32_t order[6] = {0, 1, 2, 0, 2, 3};
float vertices[6][4];
for (int32_t i = 0; i < 6; i++) {
vertices[i][0] = corners[order[i]][0];
vertices[i][1] = corners[order[i]][1];
vertices[i][2] = vertices[i][3] = 0.5f; // Center of the opaque glyph
}
drawTextVertices(vertices, mFontSymbols[SOLID_GLYPH].texId);
if (!mDisplay->useMultiVBO()) {
CHKERR(glBindBuffer(GL_ARRAY_BUFFER, mVBOId[0])); // As in GLPrintText
}
}

void GPUDisplayBackendOpenGL::ClearOffscreenBuffers()
{
if (mMixBuffer.created) {
Expand Down
2 changes: 2 additions & 0 deletions GPU/GPUTracking/display/backend/GPUDisplayBackendOpenGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class GPUDisplayBackendOpenGL : public GPUDisplayBackend
void initializeTextDrawing() override;
void clearFontSymbols() override;
void GLPrintText(const char* s, float x, float y, float* color, float scale, uint32_t nCharacters) override;
void GLDrawQuad(const float (&corners)[4][2], const float* color) override;
void drawTextVertices(const float (&vertices)[6][4], uint32_t texId); // One quad with the text shader, after GLPrintText / GLDrawQuad set the color

struct FontSymbolOpenGL : public FontSymbol {
uint32_t texId;
Expand Down
24 changes: 22 additions & 2 deletions GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1900,8 +1900,8 @@ void GPUDisplayBackendVulkan::GLPrintText(const char* s, float x, float y, float
}

for (const unsigned char* c = (const unsigned char*)s; *c && (nCharacters == 0 || c < (const unsigned char*)s + nCharacters); c++) {
if ((int32_t)*c >= (int32_t)mFontSymbols.size()) {
GPUError("Trying to draw unsupported symbol: %d > %d\n", (int32_t)*c, (int32_t)mFontSymbols.size());
if (*c < 32 || *c >= SOLID_GLYPH) { // Printable ASCII only, SOLID_GLYPH is not a character
GPUError("Trying to draw unsupported symbol: %d", (int32_t)*c);
continue;
}
const FontSymbolVulkan& sym = mFontSymbols[*c];
Expand All @@ -1925,6 +1925,11 @@ void GPUDisplayBackendVulkan::GLPrintText(const char* s, float x, float y, float
x += (sym.advance >> 6) * scale; // shift is in 1/64th of a pixel
}

addTextDrawCommand(firstVertex, color);
}

void GPUDisplayBackendVulkan::addTextDrawCommand(size_t firstVertex, const float* color)
{
size_t nVertices = mFontVertexBufferHost.size() / 4 - firstVertex;

if (nVertices) {
Expand All @@ -1937,6 +1942,21 @@ void GPUDisplayBackendVulkan::GLPrintText(const char* s, float x, float y, float
}
}

void GPUDisplayBackendVulkan::GLDrawQuad(const float (&corners)[4][2], const float* color)
{
if (!mFreetypeInitialized) {
return;
}
const FontSymbolVulkan& sym = mFontSymbols[SOLID_GLYPH];
const float u = (sym.x0 + sym.x1) * 0.5f, v = (sym.y0 + sym.y1) * 0.5f; // Center of the opaque glyph in the font atlas
const size_t firstVertex = mFontVertexBufferHost.size() / 4;
for (int32_t i : {0, 2, 1, 0, 3, 2}) { // Winding as the glyph quads of GLPrintText, the text pipeline culls back faces
mFontVertexBufferHost.insert(mFontVertexBufferHost.end(), {corners[i][0], mScreenHeight - 1 - corners[i][1], u, v});
}
mHasDrawnText = true;
addTextDrawCommand(firstVertex, color);
}

void GPUDisplayBackendVulkan::readImageToPixels(vk::Image image, vk::ImageView view, vk::ImageLayout layout, std::vector<char>& pixels)
{
const vk::Format format = mSurfaceFormat.format;
Expand Down
2 changes: 2 additions & 0 deletions GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend
void initializeTextDrawing() override;
void clearFontSymbols() override;
void GLPrintText(const char* s, float x, float y, float* color, float scale, uint32_t nCharacters) override;
void GLDrawQuad(const float (&corners)[4][2], const float* color) override;
void addTextDrawCommand(size_t firstVertex, const float* color); // Draw the text vertices from firstVertex on with this color

uint32_t mGraphicsFamily;
SwapChainSupportDetails mSwapChainDetails;
Expand Down
Loading
Loading