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