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