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