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