Project
Loading...
Searching...
No Matches
GPUDisplay.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 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#include "GPUDisplay.h"
16#include "frontend/GPUDisplayInfo.inc"
17
18#include "GPUTPCDef.h"
19#include "HandMadeMath.h"
20
21#include <vector>
22#include <memory>
23#include <cstring>
24#include <stdexcept>
25#include <mutex>
26#include <condition_variable>
27
28#ifndef _WIN32
29#include "../utils/linux_helpers.h"
30#endif
31
32#include "GPUChainTracking.h"
33#include "GPUQA.h"
34#include "GPUTPCTrackingData.h"
35#include "GPUChainTracking.h"
36#include "GPUTPCTrack.h"
37#include "GPUTPCTracker.h"
38#include "GPUTPCGMMergedTrack.h"
39#include "GPUO2DataTypes.h"
40#include "GPUSettings.h"
41
44#include "helpers/GPUDisplayColors.inc"
45
46constexpr hmm_mat4 MY_HMM_IDENTITY = {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}};
47
48using namespace o2::gpu;
49
50const GPUSettingsDisplay& GPUDisplay::GetConfig(GPUChainTracking* chain)
51{
52 static GPUSettingsDisplay defaultConfig;
53 return (chain && chain->mConfigDisplay) ? *chain->mConfigDisplay : defaultConfig;
54}
55
56const GPUSettingsProcessing& GPUDisplay::GetProcessingConfig(GPUChainTracking* chain)
57{
58 static GPUSettingsProcessing defaultConfig;
59 return chain ? chain->GetProcessingSettings() : defaultConfig;
60}
61
62GPUDisplay::GPUDisplay(GPUDisplayFrontend* frontend, GPUChainTracking* chain, GPUQA* qa, const GPUParam* param, const GPUCalibObjectsConst* calib, const GPUSettingsDisplay* config, const GPUSettingsProcessing* proc) : GPUDisplayInterface(), mFrontend(frontend), mChain(chain), mConfig(config ? *config : GetConfig(chain)), mProcessingSettings(proc ? *proc : GetProcessingConfig(chain)), mQA(qa)
63{
64 mViewMatrix = std::make_unique<hmm_mat4>();
65 mModelMatrix = std::make_unique<hmm_mat4>();
66 mParam = param ? param : &mChain->GetParam();
67 mCalib = calib;
68 mCfgL = mConfig.light;
69 mCfgH = mConfig.heavy;
70 mCfgR = mConfig.renderer;
71 mBackend.reset(GPUDisplayBackend::getBackend(mConfig.displayRenderer.c_str()));
72 if (!mBackend) {
73 throw std::runtime_error("Error obtaining display backend");
74 }
75 mBackend->mDisplay = this;
76 frontend->mDisplay = this;
77 frontend->mBackend = mBackend.get();
78 mCfgR.rendererCompatSmoothing &= !mBackend->CoreProfile();
79}
80
81void GPUDisplay::calcXYZ(const float* matrix)
82{
83 mXYZ[0] = -(matrix[0] * matrix[12] + matrix[1] * matrix[13] + matrix[2] * matrix[14]);
84 mXYZ[1] = -(matrix[4] * matrix[12] + matrix[5] * matrix[13] + matrix[6] * matrix[14]);
85 mXYZ[2] = -(matrix[8] * matrix[12] + matrix[9] * matrix[13] + matrix[10] * matrix[14]);
86
87 mAngle[0] = -asinf(matrix[6]); // Invert rotY*rotX*rotZ
88 float A = cosf(mAngle[0]);
89 if (fabsf(A) > 0.005) {
90 mAngle[1] = atan2f(-matrix[2] / A, matrix[10] / A);
91 mAngle[2] = atan2f(matrix[4] / A, matrix[5] / A);
92 } else {
93 mAngle[1] = 0;
94 mAngle[2] = atan2f(-matrix[1], -matrix[0]);
95 }
96
97 mRPhiTheta[0] = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[1] * mXYZ[1] + mXYZ[2] * mXYZ[2]);
98 mRPhiTheta[1] = atan2f(mXYZ[0], mXYZ[2]);
99 mRPhiTheta[2] = atan2f(mXYZ[1], sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[2] * mXYZ[2]));
100
101 createQuaternionFromMatrix(mQuat, matrix);
102
103 /*float mAngle[1] = -asinf(matrix[2]); //Calculate Y-axis angle - for rotX*rotY*rotZ
104 float C = cosf( angle_y );
105 if (fabsf(C) > 0.005) //Gimball lock?
106 {
107 mAngle[0] = atan2f(-matrix[6] / C, matrix[10] / C);
108 mAngle[2] = atan2f(-matrix[1] / C, matrix[0] / C);
109 }
110 else
111 {
112 mAngle[0] = 0; //set x-angle
113 mAngle[2] = atan2f(matrix[4], matrix[5]);
114 }*/
115}
116
117void GPUDisplay::SetCollisionFirstCluster(uint32_t collision, int32_t sector, int32_t cluster)
118{
119 mNCollissions = std::max<uint32_t>(mNCollissions, collision + 1);
120 mOverlayTFClusters.resize(mNCollissions);
121 mOverlayTFClusters[collision][sector] = cluster;
122}
123
124void GPUDisplay::mAnimationCloseAngle(float& newangle, float lastAngle)
125{
126 const float delta = lastAngle > newangle ? (2 * CAMath::Pi()) : (-2 * CAMath::Pi());
127 while (fabsf(newangle + delta - lastAngle) < fabsf(newangle - lastAngle)) {
128 newangle += delta;
129 }
130}
131void GPUDisplay::mAnimateCloseQuaternion(float* v, float lastx, float lasty, float lastz, float lastw)
132{
133 float distPos2 = (lastx - v[0]) * (lastx - v[0]) + (lasty - v[1]) * (lasty - v[1]) + (lastz - v[2]) * (lastz - v[2]) + (lastw - v[3]) * (lastw - v[3]);
134 float distNeg2 = (lastx + v[0]) * (lastx + v[0]) + (lasty + v[1]) * (lasty + v[1]) + (lastz + v[2]) * (lastz + v[2]) + (lastw + v[3]) * (lastw + v[3]);
135 if (distPos2 > distNeg2) {
136 for (int32_t i = 0; i < 4; i++) {
137 v[i] = -v[i];
138 }
139 }
140}
141
142void GPUDisplay::ResizeScene(int32_t width, int32_t height, bool init)
143{
144 if (height == 0) { // Prevent A Divide By Zero By
145 height = 1; // Making Height Equal One
146 }
147
148 mBackend->resizeScene(width, height);
149
150 if (init) {
151 mResetScene = true;
152 *mViewMatrix = MY_HMM_IDENTITY;
153 *mModelMatrix = MY_HMM_IDENTITY;
154 }
155}
156
157void GPUDisplay::updateConfig()
158{
159 mBackend->setQuality();
160 mBackend->setDepthBuffer();
161}
162
163inline void GPUDisplay::drawVertices(const vboList& v, const GPUDisplayBackend::drawType t)
164{
165 mNDrawCalls += mBackend->drawVertices(v, t);
166}
167
168int32_t GPUDisplay::InitDisplay(bool initFailure)
169{
170 int32_t retVal = initFailure;
171 try {
172 if (!initFailure) {
173 retVal = InitDisplay_internal();
174 }
175 } catch (const std::runtime_error& e) {
176 GPUError("%s", e.what());
177 retVal = 1;
178 }
179 mInitResult = retVal == 0 ? 1 : -1;
180 return (retVal);
181}
182
183int32_t GPUDisplay::InitDisplay_internal()
184{
185 mThreadBuffers.resize(getNumThreads());
186 mThreadTracks.resize(getNumThreads());
187 if (mBackend->InitBackend()) {
188 return 1;
189 }
190 mYFactor = mBackend->getYFactor();
191 mDrawTextInCompatMode = !mBackend->mFreetypeInitialized && mFrontend->mCanDrawText == 1;
192 int32_t height = 0, width = 0;
193 mFrontend->getSize(width, height);
194 if (height == 0 || width == 0) {
197 }
198 ResizeScene(width, height, true);
199 return 0;
200}
201
203{
204 mBackend->ExitBackend();
205}
206
208{
209 // Make sure event gets not overwritten during display
210 mSemLockDisplay.Lock();
211
212 int32_t retVal = 0;
213 if (mChain) {
214 mIOPtrs = &mChain->mIOPtrs;
215 mCalib = &mChain->GetCalib();
216 }
217 if (!mIOPtrs) {
218 mNCollissions = 0;
219 } else if (!mOverlayTFClusters.size()) {
220 mNCollissions = std::max(1u, mIOPtrs->nMCInfosTPCCol);
221 }
222 try {
223 DrawGLScene_internal();
224 } catch (const std::runtime_error& e) {
225 GPUError("Runtime error %s during display", e.what());
226 retVal = 1;
227 }
228
229 if (mLoadAndShowEvent) {
230 {
231 std::lock_guard<std::mutex> lock(mMutexLoadAndShowEvent);
232 mLoadAndShowEvent = false;
233 }
234 mCVLoadAndShowEvent.notify_one();
235 }
236 mSemLockDisplay.Unlock();
237
238 return retVal;
239}
240
241void GPUDisplay::DrawGLScene_cameraAndAnimation(float animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix)
242{
243 HighResTimer timer(mUpdateVertexLists && mChain->GetProcessingSettings().debugLevel >= 2);
244 int32_t mMouseWheelTmp = mFrontend->mMouseWheel;
245 mFrontend->mMouseWheel = 0;
246 bool lookOrigin = mCfgR.camLookOrigin ^ mFrontend->mKeys[mFrontend->KEY_ALT];
247 bool yUp = mCfgR.camYUp ^ mFrontend->mKeys[mFrontend->KEY_CTRL] ^ lookOrigin;
248 bool rotateModel = mFrontend->mKeys[mFrontend->KEY_RCTRL] || mFrontend->mKeys[mFrontend->KEY_RALT];
249 bool rotateModelTPC = mFrontend->mKeys[mFrontend->KEY_RALT];
250
251 // Calculate rotation / translation scaling factors
252 float scalefactor = mFrontend->mKeys[mFrontend->KEY_SHIFT] ? 0.2f : 1.0f;
253 float rotatescalefactor = scalefactor * 0.25f;
254 if (mCfgL.drawSector != -1) {
255 scalefactor *= 0.2f;
256 }
257 float* const mViewMatrixP = &mViewMatrix->Elements[0][0];
258 float sqrdist = sqrtf(sqrtf(mViewMatrixP[12] * mViewMatrixP[12] + mViewMatrixP[13] * mViewMatrixP[13] + mViewMatrixP[14] * mViewMatrixP[14]) * GL_SCALE_FACTOR) * 0.8f;
259 if (sqrdist < 0.2f) {
260 sqrdist = 0.2f;
261 }
262 if (sqrdist > 5.f) {
263 sqrdist = 5.f;
264 }
265 scalefactor *= sqrdist;
266
267 // Perform new rotation / translation / animation
268
269 if (animateCamera(animateTime, mixSlaveImage, nextViewMatrix)) {
270 // Do nothing else
271 } else if (mResetScene) {
272 const float initialZpos = mCfgH.projectXY ? 16 : (mParam->par.continuousTracking ? (mMaxClusterZ * GL_SCALE_FACTOR + 8) : 8);
273 nextViewMatrix = nextViewMatrix * HMM_Translate({{0, 0, -initialZpos}});
274 *mViewMatrix = MY_HMM_IDENTITY;
275 *mModelMatrix = MY_HMM_IDENTITY;
276
277 mCfgL.pointSize = 2.0f;
278 mCfgL.lineWidth = 1.4f;
279 mCfgL.drawSector = -1;
280 mCfgL.showCollision = -1;
281 mCfgH.xAdd = mCfgH.zAdd = 0;
282 mCfgR.camLookOrigin = mCfgR.camYUp = false;
283 mAngleRollOrigin = -1e9f;
284 mCfgR.fov = 45.f;
285 mUpdateDrawCommands = true;
286
287 mResetScene = false;
288 } else {
289 float moveZ = scalefactor * ((float)mMouseWheelTmp / 150 + (float)(mFrontend->mKeys[(uint8_t)'W'] - mFrontend->mKeys[(uint8_t)'S']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]) * 0.2f * mFPSScale);
290 float moveY = scalefactor * ((float)(mFrontend->mKeys[mFrontend->KEY_PAGEDOWN] - mFrontend->mKeys[mFrontend->KEY_PAGEUP]) * 0.2f * mFPSScale);
291 float moveX = scalefactor * ((float)(mFrontend->mKeys[(uint8_t)'A'] - mFrontend->mKeys[(uint8_t)'D']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]) * 0.2f * mFPSScale);
292 float rotRoll = rotatescalefactor * mFPSScale * 2 * (mFrontend->mKeys[(uint8_t)'E'] - mFrontend->mKeys[(uint8_t)'F']) * (!mFrontend->mKeys[mFrontend->KEY_SHIFT]);
293 float rotYaw = rotatescalefactor * mFPSScale * 2 * (mFrontend->mKeys[mFrontend->KEY_RIGHT] - mFrontend->mKeys[mFrontend->KEY_LEFT]);
294 float rotPitch = rotatescalefactor * mFPSScale * 2 * (mFrontend->mKeys[mFrontend->KEY_DOWN] - mFrontend->mKeys[mFrontend->KEY_UP]);
295
296 float mouseScale = 1920.f / std::max<float>(1920.f, mBackend->mScreenWidth);
297 if (mFrontend->mMouseDnR && mFrontend->mMouseDn) {
298 moveZ += -scalefactor * mouseScale * ((float)mFrontend->mMouseMvY - (float)mFrontend->mMouseDnY) / 4;
299 rotRoll += -rotatescalefactor * mouseScale * ((float)mFrontend->mMouseMvX - (float)mFrontend->mMouseDnX);
300 } else if (mFrontend->mMouseDnR) {
301 moveX += scalefactor * 0.5f * mouseScale * ((float)mFrontend->mMouseDnX - (float)mFrontend->mMouseMvX) / 4;
302 moveY += scalefactor * 0.5f * mouseScale * ((float)mFrontend->mMouseMvY - (float)mFrontend->mMouseDnY) / 4;
303 } else if (mFrontend->mMouseDn) {
304 rotYaw += rotatescalefactor * mouseScale * ((float)mFrontend->mMouseMvX - (float)mFrontend->mMouseDnX);
305 rotPitch += rotatescalefactor * mouseScale * ((float)mFrontend->mMouseMvY - (float)mFrontend->mMouseDnY);
306 }
307
308 if (mFrontend->mKeys[(uint8_t)'<'] && !mFrontend->mKeysShift[(uint8_t)'<']) {
309 mAnimationDelay += moveX;
310 if (mAnimationDelay < 0.05f) {
311 mAnimationDelay = 0.05f;
312 }
313 moveX = 0.f;
314 moveY = 0.f;
315 SetInfo("Animation delay set to %1.2f", mAnimationDelay);
316 }
317
318 if (yUp) {
319 mAngleRollOrigin = 0;
320 } else if (!lookOrigin) {
321 mAngleRollOrigin = -1e6;
322 }
323 if (lookOrigin) {
324 if (!yUp) {
325 if (mAngleRollOrigin < -1e6) {
326 mAngleRollOrigin = yUp ? 0.f : -mAngle[2];
327 }
328 mAngleRollOrigin += rotRoll;
329 nextViewMatrix = nextViewMatrix * HMM_Rotate(mAngleRollOrigin, {{0, 0, 1}});
330 float tmpX = moveX, tmpY = moveY;
331 moveX = tmpX * cosf(mAngle[2]) - tmpY * sinf(mAngle[2]);
332 moveY = tmpX * sinf(mAngle[2]) + tmpY * cosf(mAngle[2]);
333 }
334
335 const float x = mXYZ[0], y = mXYZ[1], z = mXYZ[2];
336 float r = sqrtf(x * x + +y * y + z * z);
337 float r2 = sqrtf(x * x + z * z);
338 float phi = atan2f(z, x);
339 phi += moveX * 0.1f;
340 float theta = atan2f(mXYZ[1], r2);
341 theta -= moveY * 0.1f;
342 const float max_theta = CAMath::Pi() / 2 - 0.01f;
343 if (theta >= max_theta) {
344 theta = max_theta;
345 } else if (theta <= -max_theta) {
346 theta = -max_theta;
347 }
348 if (moveZ >= r - 0.1f) {
349 moveZ = r - 0.1f;
350 }
351 r -= moveZ;
352 r2 = r * cosf(theta);
353 mXYZ[0] = r2 * cosf(phi);
354 mXYZ[2] = r2 * sinf(phi);
355 mXYZ[1] = r * sinf(theta);
356
357 if (yUp) {
358 nextViewMatrix = MY_HMM_IDENTITY;
359 }
360 nextViewMatrix = nextViewMatrix * HMM_LookAt({{mXYZ[0], mXYZ[1], mXYZ[2]}}, {{0, 0, 0}}, {{0, 1, 0}});
361 } else {
362 nextViewMatrix = nextViewMatrix * HMM_Translate({{moveX, moveY * mYFactor, moveZ}});
363 if (!rotateModel) {
364 if (rotYaw != 0.f) {
365 nextViewMatrix = nextViewMatrix * HMM_Rotate(rotYaw, {{0, 1, 0}});
366 }
367 if (rotPitch != 0.f) {
368 nextViewMatrix = nextViewMatrix * HMM_Rotate(rotPitch * mYFactor, {{1, 0, 0}});
369 }
370 if (!yUp && rotRoll != 0.f) {
371 nextViewMatrix = nextViewMatrix * HMM_Rotate(rotRoll * mYFactor, {{0, 0, 1}});
372 }
373 }
374 nextViewMatrix = nextViewMatrix * *mViewMatrix; // Apply previous translation / rotation
375 if (yUp) {
376 calcXYZ(&nextViewMatrix.Elements[0][0]);
377 nextViewMatrix = HMM_Rotate(mAngle[2] * 180.f / CAMath::Pi(), {{0, 0, 1}}) * nextViewMatrix;
378 }
379 if (rotateModel) {
380 if (rotYaw != 0.f) {
381 *mModelMatrix = HMM_Rotate(rotYaw, {{nextViewMatrix.Elements[0][1], nextViewMatrix.Elements[1][1], nextViewMatrix.Elements[2][1]}}) * *mModelMatrix;
382 }
383 if (rotPitch != 0.f) {
384 *mModelMatrix = HMM_Rotate(rotPitch, {{nextViewMatrix.Elements[0][0], nextViewMatrix.Elements[1][0], nextViewMatrix.Elements[2][0]}}) * *mModelMatrix;
385 }
386 if (rotRoll != 0.f) {
387 if (rotateModelTPC) {
388 *mModelMatrix = HMM_Rotate(-rotRoll, {{0, 0, 1}}) * *mModelMatrix;
389 } else {
390 *mModelMatrix = HMM_Rotate(-rotRoll, {{nextViewMatrix.Elements[0][2], nextViewMatrix.Elements[1][2], nextViewMatrix.Elements[2][2]}}) * *mModelMatrix;
391 }
392 }
393 }
394 }
395
396 // Graphichs Options
397 float minSize = 0.4f / (mCfgR.drawQualityDownsampleFSAA > 1 ? mCfgR.drawQualityDownsampleFSAA : 1);
398 int32_t deltaLine = mFrontend->mKeys[(uint8_t)'+'] * mFrontend->mKeysShift[(uint8_t)'+'] - mFrontend->mKeys[(uint8_t)'-'] * mFrontend->mKeysShift[(uint8_t)'-'];
399 mCfgL.lineWidth += (float)deltaLine * mFPSScale * 0.02f * mCfgL.lineWidth;
400 if (mCfgL.lineWidth < minSize) {
401 mCfgL.lineWidth = minSize;
402 }
403 if (deltaLine) {
404 SetInfo("%s line width: %f", deltaLine > 0 ? "Increasing" : "Decreasing", mCfgL.lineWidth);
405 mUpdateDrawCommands = true;
406 }
407 minSize *= 2;
408 int32_t deltaPoint = mFrontend->mKeys[(uint8_t)'+'] * (!mFrontend->mKeysShift[(uint8_t)'+']) - mFrontend->mKeys[(uint8_t)'-'] * (!mFrontend->mKeysShift[(uint8_t)'-']);
409 mCfgL.pointSize += (float)deltaPoint * mFPSScale * 0.02f * mCfgL.pointSize;
410 if (mCfgL.pointSize < minSize) {
411 mCfgL.pointSize = minSize;
412 }
413 if (deltaPoint) {
414 SetInfo("%s point size: %f", deltaPoint > 0 ? "Increasing" : "Decreasing", mCfgL.pointSize);
415 mUpdateDrawCommands = true;
416 }
417 }
418
419 // Store position
420 if (animateTime < 0) {
421 *mViewMatrix = nextViewMatrix;
422 calcXYZ(&mViewMatrix->Elements[0][0]);
423 }
424
425 if (mFrontend->mMouseDn || mFrontend->mMouseDnR) {
426 mFrontend->mMouseDnX = mFrontend->mMouseMvX;
427 mFrontend->mMouseDnY = mFrontend->mMouseMvY;
428 }
429 if (timer.IsRunning()) {
430 GPUInfo("Display Time: Camera:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6);
431 }
432}
433
434void GPUDisplay::DrawGLScene_drawCommands()
435{
436#define LOOP_SECTOR for (int32_t iSector = (mCfgL.drawSector == -1 ? 0 : mCfgL.drawRelatedSectors ? (mCfgL.drawSector % (NSECTORS / 4)) : mCfgL.drawSector); iSector < NSECTORS; iSector += (mCfgL.drawSector == -1 ? 1 : mCfgL.drawRelatedSectors ? (NSECTORS / 4) : NSECTORS))
437#define LOOP_SECTOR2 for (int32_t iSector = (mCfgL.drawSector == -1 ? 0 : mCfgL.drawRelatedSectors ? (mCfgL.drawSector % (NSECTORS / 4)) : mCfgL.drawSector) % (NSECTORS / 2); iSector < NSECTORS / 2; iSector += (mCfgL.drawSector == -1 ? 1 : mCfgL.drawRelatedSectors ? (NSECTORS / 4) : NSECTORS))
438#define LOOP_COLLISION for (int32_t iCol = (mCfgL.showCollision == -1 ? 0 : mCfgL.showCollision); iCol < mNCollissions; iCol += (mCfgL.showCollision == -1 ? 1 : mNCollissions))
439#define LOOP_COLLISION_COL(cmd) \
440 LOOP_COLLISION \
441 { \
442 if (mCfgL.colorCollisions) { \
443 SetCollisionColor(iCol); \
444 } \
445 cmd; \
446 }
447
448 if (mCfgL.drawGrid) {
449 if (mCfgL.drawTPC) {
450 SetColorGrid();
451 LOOP_SECTOR drawVertices(mGlDLGrid[iSector], GPUDisplayBackend::LINES);
452 }
453 if (mCfgL.drawTRD) {
454 SetColorGridTRD();
455 LOOP_SECTOR2 drawVertices(mGlDLGridTRD[iSector], GPUDisplayBackend::LINES);
456 }
457 }
458 if (mCfgL.drawClusters) {
459 if (mCfgL.drawTRD) {
460 SetColorTRD();
461 mBackend->lineWidthFactor(2);
462 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tTRDCLUSTER][iCol], GPUDisplayBackend::LINES));
463 if (mCfgL.drawFinal && mCfgL.colorClusters) {
464 SetColorFinal();
465 }
466 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tTRDATTACHED][iCol], GPUDisplayBackend::LINES));
467 mBackend->lineWidthFactor(1);
468 }
469 if (mCfgL.drawTOF) {
470 SetColorTOF();
471 mBackend->pointSizeFactor(2);
472 // LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tTOFCLUSTER][iCol], GPUDisplayBackend::POINTS));
473 drawVertices(mGlDLPoints[0][tTOFCLUSTER][0], GPUDisplayBackend::POINTS);
474 mBackend->pointSizeFactor(1);
475 }
476 if (mCfgL.drawITS) {
477 SetColorITS();
478 // LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tITSCLUSTER][iCol], GPUDisplayBackend::POINTS));
479 drawVertices(mGlDLPoints[0][tITSCLUSTER][0], GPUDisplayBackend::POINTS);
480 }
481 if (mCfgL.drawTPC) {
482 SetColorClusters();
483 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tCLUSTER][iCol], GPUDisplayBackend::POINTS));
484
485 if (mCfgL.drawInitLinks) {
486 if (mCfgL.excludeClusters) {
487 goto skip1;
488 }
489 if (mCfgL.colorClusters) {
490 SetColorInitLinks();
491 }
492 }
493 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tINITLINK][iCol], GPUDisplayBackend::POINTS));
494
495 if (mCfgL.drawLinks) {
496 if (mCfgL.excludeClusters) {
497 goto skip1;
498 }
499 if (mCfgL.colorClusters) {
500 SetColorLinks();
501 }
502 } else {
503 SetColorClusters();
504 }
505 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tLINK][iCol], GPUDisplayBackend::POINTS));
506
507 if (mCfgL.drawSeeds) {
508 if (mCfgL.excludeClusters) {
509 goto skip1;
510 }
511 if (mCfgL.colorClusters) {
512 SetColorSeeds();
513 }
514 }
515 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tSEED][iCol], GPUDisplayBackend::POINTS));
516
517 skip1:
518 SetColorClusters();
519 if (mCfgL.drawTracklets) {
520 if (mCfgL.excludeClusters) {
521 goto skip2;
522 }
523 if (mCfgL.colorClusters) {
524 SetColorTracklets();
525 }
526 }
527 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tTRACKLET][iCol], GPUDisplayBackend::POINTS));
528
529 if (mCfgL.drawTracks) {
530 if (mCfgL.excludeClusters) {
531 goto skip2;
532 }
533 if (mCfgL.colorClusters) {
534 SetColorTracks();
535 }
536 }
537 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tSECTORTRACK][iCol], GPUDisplayBackend::POINTS));
538
539 skip2:;
540 if (mCfgL.drawExtrapolatedTracks) {
541 if (mCfgL.excludeClusters) {
542 goto skip3;
543 }
544 if (mCfgL.colorClusters) {
545 SetColorExtrapolatedTracks();
546 }
547 } else {
548 SetColorClusters();
549 }
550 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tEXTRAPOLATEDTRACK][iCol], GPUDisplayBackend::POINTS));
551 SetColorClusters();
552
553 if (mCfgL.drawFinal && mCfgL.propagateTracks < 2) {
554 if (mCfgL.excludeClusters) {
555 goto skip3;
556 }
557 if (mCfgL.colorClusters) {
558 SetColorFinal();
559 }
560 }
561 LOOP_SECTOR LOOP_COLLISION_COL(drawVertices(mGlDLPoints[iSector][tFINALTRACK][iCol], GPUDisplayBackend::POINTS));
562 skip3:;
563 }
564 }
565
566 if (!mCfgH.clustersOnly && mCfgL.excludeClusters != 1) {
567 if (mCfgL.drawTPC) {
568 if (mCfgL.drawInitLinks) {
569 SetColorInitLinks();
570 LOOP_SECTOR drawVertices(mGlDLLines[iSector][tINITLINK], GPUDisplayBackend::LINES);
571 }
572 if (mCfgL.drawLinks) {
573 SetColorLinks();
574 LOOP_SECTOR drawVertices(mGlDLLines[iSector][tLINK], GPUDisplayBackend::LINES);
575 }
576 if (mCfgL.drawSeeds) {
577 SetColorSeeds();
578 LOOP_SECTOR drawVertices(mGlDLLines[iSector][tSEED], GPUDisplayBackend::LINE_STRIP);
579 }
580 if (mCfgL.drawTracklets) {
581 SetColorTracklets();
582 LOOP_SECTOR drawVertices(mGlDLLines[iSector][tTRACKLET], GPUDisplayBackend::LINE_STRIP);
583 }
584 if (mCfgL.drawTracks) {
585 SetColorTracks();
586 LOOP_SECTOR drawVertices(mGlDLLines[iSector][tSECTORTRACK], GPUDisplayBackend::LINE_STRIP);
587 }
588 if (mCfgL.drawExtrapolatedTracks) {
589 SetColorExtrapolatedTracks();
590 LOOP_SECTOR drawVertices(mGlDLLines[iSector][tEXTRAPOLATEDTRACK], GPUDisplayBackend::LINE_STRIP);
591 }
592 }
593 if (mCfgL.drawFinal) {
594 SetColorFinal();
596 {
597 if (mCfgL.colorCollisions) {
598 SetCollisionColor(iCol);
599 }
600 if (mCfgL.propagateTracks < 2) {
601 drawVertices(mGlDLFinal[iSector][iCol][0], GPUDisplayBackend::LINE_STRIP);
602 }
603 if (mCfgL.propagateTracks > 0 && mCfgL.propagateTracks < 3) {
604 drawVertices(mGlDLFinal[iSector][iCol][1], GPUDisplayBackend::LINE_STRIP);
605 }
606 if (mCfgL.propagateTracks == 2) {
607 drawVertices(mGlDLFinal[iSector][iCol][2], GPUDisplayBackend::LINE_STRIP);
608 }
609 if (mCfgL.propagateTracks == 3) {
610 drawVertices(mGlDLFinal[iSector][iCol][3], GPUDisplayBackend::LINE_STRIP);
611 }
612 }
613 if (mCfgH.drawTracksAndFilter ? (mCfgH.drawTPCTracks || mCfgH.drawTRDTracks || mCfgH.drawTOFTracks) : mCfgH.drawITSTracks) {
614 drawVertices(mGlDLFinalITS, GPUDisplayBackend::LINE_STRIP);
615 }
616 }
617 if (mCfgH.markClusters || mCfgH.markAdjacentClusters || mCfgH.markFakeClusters) {
618 if (mCfgH.markFakeClusters) {
619 mBackend->pointSizeFactor(3);
620 }
621 SetColorMarked();
622 LOOP_SECTOR LOOP_COLLISION drawVertices(mGlDLPoints[iSector][tMARKED][iCol], GPUDisplayBackend::POINTS);
623 if (mCfgH.markFakeClusters) {
624 mBackend->pointSizeFactor(1);
625 }
626 }
627 }
628}
629
630void GPUDisplay::DrawGLScene_internal(float animateTime, bool renderToMixBuffer) // negative time = no mixing
631{
632 if (mRequestScreenshot || mAnimateScreenshot) {
633 const uint32_t factor = std::max(1, mCfgR.drawQualityDownsampleFSAA) * std::max(1, mCfgR.screenshotScaleFactor);
634 if (std::max(mBackend->mScreenWidth, mBackend->mScreenHeight) * factor > mBackend->mMaxRenderSize) {
635 GPUError("Screenshot not taken: requested render size %u x %u (window x FSAA x screenshot scale) exceeds the maximum size %u x %u", mBackend->mScreenWidth * factor, mBackend->mScreenHeight * factor, mBackend->mMaxRenderSize, mBackend->mMaxRenderSize);
636 mRequestScreenshot = false;
637 mAnimateScreenshot = 0;
638 }
639 }
640 bool doScreenshot = (mRequestScreenshot || mAnimateScreenshot) && animateTime < 0;
641
642 updateOptions();
643 if (animateTime < 0 && (mUpdateEventData || mResetScene || mUpdateVertexLists) && mIOPtrs) {
644 disableUnsupportedOptions();
645 }
646 if (mUpdateEventData || mUpdateVertexLists) {
647 mUpdateDrawCommands = true;
648 }
649
650 HighResTimer timerDraw(mUpdateVertexLists);
651 if (animateTime < 0 && (mUpdateEventData || mResetScene) && mIOPtrs) {
652 timerDraw.ResetStart();
653 DrawGLScene_updateEventData();
654 mTimerFPS.ResetStart();
655 mFramesDoneFPS = 0;
656 mFPSScaleadjust = 0;
657 mUpdateVertexLists = true;
658 mUpdateEventData = false;
659 }
660
661 hmm_mat4 nextViewMatrix = MY_HMM_IDENTITY;
662 float mixSlaveImage = 0.f;
663 DrawGLScene_cameraAndAnimation(animateTime, mixSlaveImage, nextViewMatrix);
664
665 // Prepare Event
666 if (mUpdateVertexLists && mIOPtrs) {
667 size_t totalVertizes = DrawGLScene_updateVertexList();
668 if (timerDraw.IsRunning()) {
669 printf("Event visualization time: %'d us (vertices %'ld / %'ld bytes)\n", (int32_t)(timerDraw.GetCurrentElapsedTime() * 1000000.), (int64_t)totalVertizes, (int64_t)(totalVertizes * sizeof(mVertexBuffer[0][0])));
670 }
671 }
672
673 // Draw Event
674 nextViewMatrix = nextViewMatrix * *mModelMatrix;
675 const float zFar = ((mParam->par.continuousTracking ? (mMaxClusterZ * GL_SCALE_FACTOR) : 8.f) + 50.f) * 2.f;
676 const hmm_mat4 proj = HMM_Perspective(mCfgR.fov, (float)mBackend->mRenderWidth / (float)mBackend->mRenderHeight, 0.1f, zFar);
677 if (!mBackend->prepareDraw(proj, nextViewMatrix, doScreenshot || mRequestScreenshot, renderToMixBuffer, mixSlaveImage)) {
678 return; // No image available (e.g. hidden window), retry with the next frame
679 }
680 mBackend->pointSizeFactor(1);
681 mBackend->lineWidthFactor(1);
682
683 if (mUpdateDrawCommands || mBackend->backendNeedRedraw()) {
684 mNDrawCalls = 0;
685 DrawGLScene_drawCommands();
686 }
687
688 if (mCfgL.drawField) {
689 mBackend->drawField();
690 }
691
692 mUpdateDrawCommands = false;
693 mUpdateRenderPipeline = false;
694 mBackend->finishDraw(doScreenshot, renderToMixBuffer, mixSlaveImage);
695
696 if (animateTime < 0) {
697 mFramesDone++;
698 mFramesDoneFPS++;
699 double fpstime = mTimerFPS.GetCurrentElapsedTime();
700 char info[1024];
701 float fps = (double)mFramesDoneFPS / fpstime;
702 snprintf(info, 1024,
703 "FPS: %6.2f (Sector: %d, 1:Clusters %d, 2:Prelinks %d, 3:Links %d, 4:Seeds %d, 5:Tracklets %d, 6:Tracks %d, 7:GTracks %d, 8:Merger %d) (%d frames, %d draw calls) "
704 "(X %1.2f Y %1.2f Z %1.2f / R %1.2f Phi %1.1f Theta %1.1f) / Yaw %1.1f Pitch %1.1f Roll %1.1f)",
705 fps, mCfgL.drawSector, mCfgL.drawClusters, mCfgL.drawInitLinks, mCfgL.drawLinks, mCfgL.drawSeeds, mCfgL.drawTracklets, mCfgL.drawTracks, mCfgL.drawExtrapolatedTracks, mCfgL.drawFinal, mFramesDone, mNDrawCalls, mXYZ[0], mXYZ[1], mXYZ[2], mRPhiTheta[0], mRPhiTheta[1] * 180 / CAMath::Pi(),
706 mRPhiTheta[2] * 180 / CAMath::Pi(), mAngle[1] * 180 / CAMath::Pi(), mAngle[0] * 180 / CAMath::Pi(), mAngle[2] * 180 / CAMath::Pi());
707 if (fpstime > 1.) {
708 if (mPrintInfoText & 2) {
709 GPUInfo("%s", info);
710 }
711 if (mFPSScaleadjust++) {
712 mFPSScale = 60 / fps;
713 }
714 mTimerFPS.ResetStart();
715 mFramesDoneFPS = 0;
716 }
717
718 if (mPrintInfoText & 1) {
719 showInfo(info);
720 }
721 }
722
723 mBackend->finishFrame(mRequestScreenshot, renderToMixBuffer, mixSlaveImage);
724 if (doScreenshot) {
725 mRequestScreenshot = false;
726 std::vector<char> pixels = mBackend->getPixels();
727 char tmpFileName[48];
728 if (mAnimateScreenshot) {
729 snprintf(tmpFileName, 48, "mAnimation%d_%05d.bmp", mAnimationExport, mAnimationFrame);
730 }
731 DoScreenshot(mAnimateScreenshot ? tmpFileName : mScreenshotFile.c_str(), pixels);
732 }
733}
734
736{
737 if (ptrs) {
738 mIOPtrs = ptrs;
739 }
740 if (mMaxClusterZ <= 0) {
741 mResetScene = true;
742 }
743 mFrontend->mNeedUpdate = 1;
744 mUpdateEventData = true;
745 mLoadAndShowEvent = true;
746 mSemLockDisplay.Unlock();
747}
748
749void GPUDisplay::BlockTillNextEvent() { mSemLockDisplay.Lock(); }
750
752{
753 mSemLockDisplay.Trylock();
754 mSemLockDisplay.Unlock();
755}
756
758{
759 std::unique_lock<std::mutex> lock(mMutexLoadAndShowEvent);
760 while (mLoadAndShowEvent) {
761 mCVLoadAndShowEvent.wait(lock);
762 }
763}
764
766{
767 mLoadAndShowEvent = true;
768 if (mFrontend->StartDisplay()) {
769 return (1);
770 }
771 while (mInitResult == 0) {
772 Sleep(10);
773 }
774 return (mInitResult != 1);
775}
size_t minSize
int32_t i
#define LOOP_COLLISION
#define LOOP_SECTOR2
constexpr hmm_mat4 MY_HMM_IDENTITY
#define LOOP_COLLISION_COL(cmd)
#define LOOP_SECTOR
uint32_t iSector
int32_t retVal
GPUChain * chain
HMM_INLINE hmm_mat4 HMM_Perspective(float FOV, float AspectRatio, float Near, float Far)
HMM_INLINE hmm_mat4 HMM_Translate(hmm_vec3 Translation)
HMM_EXTERN hmm_mat4 HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up)
HMM_EXTERN hmm_mat4 HMM_Rotate(float Angle, hmm_vec3 Axis)
Definition A.h:16
double GetCurrentElapsedTime(bool reset=false)
Definition timer.cxx:117
void ResetStart()
Definition timer.cxx:70
GPUTrackingInOutPointers & mIOPtrs
const GPUCalibObjectsConst & GetCalib() const
Definition GPUChain.h:65
const GPUSettingsProcessing & GetProcessingSettings() const
Definition GPUChain.h:76
const GPUParam & GetParam() const
Definition GPUChain.h:63
static GPUDisplayBackend * getBackend(const char *type)
static constexpr int32_t KEY_ALT
virtual void getSize(int32_t &width, int32_t &height)
static constexpr int32_t KEY_PAGEDOWN
static constexpr int32_t KEY_RALT
static constexpr int32_t KEY_LEFT
static constexpr int32_t KEY_CTRL
static constexpr int32_t INIT_WIDTH
static constexpr int32_t KEY_SHIFT
static constexpr int32_t KEY_PAGEUP
static constexpr int32_t KEY_UP
static constexpr int32_t KEY_DOWN
static constexpr int32_t INIT_HEIGHT
static constexpr int32_t KEY_RIGHT
static constexpr int32_t KEY_RCTRL
GPUDisplay(GPUDisplayFrontend *frontend, GPUChainTracking *chain, GPUQA *qa, const GPUParam *param=nullptr, const GPUCalibObjectsConst *calib=nullptr, const GPUSettingsDisplay *config=nullptr, const GPUSettingsProcessing *proc=nullptr)
void SetCollisionFirstCluster(uint32_t collision, int32_t sector, int32_t cluster) override
const GPUParam * param()
Definition GPUDisplay.h:83
int32_t StartDisplay() override
GPUDisplayFrontend * frontend()
Definition GPUDisplay.h:85
void BlockTillNextEvent() override
int32_t InitDisplay(bool initFailure=false)
void ShowNextEvent(const GPUTrackingInOutPointers *ptrs=nullptr) override
void WaitTillEventShown() override
void ResizeScene(int32_t width, int32_t height, bool init=false)
int32_t Trylock()
Definition qsem.cxx:57
int32_t Unlock()
Definition qsem.cxx:48
int32_t Lock()
Definition qsem.cxx:39
GLint GLenum GLint x
Definition glcorearb.h:403
GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar
Definition glcorearb.h:4077
const GLdouble * v
Definition glcorearb.h:832
GLint GLsizei GLsizei height
Definition glcorearb.h:270
GLint GLsizei width
Definition glcorearb.h:270
GLint y
Definition glcorearb.h:270
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
Definition glcorearb.h:275
GLboolean r
Definition glcorearb.h:1233
GLenum GLfloat param
Definition glcorearb.h:271
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
uint8_t itsSharedClusterMap uint8_t
float Elements[4][4]