Showing the changes to interface/src/Application.cpp (1 of 45 files). Show all
Unified · Split
| @@ -44,6 +44,9 @@ · 43 unmodified lines | |||
| 44 | 44 | ||
| 45 | #include <QtNetwork/QNetworkDiskCache> | 45 | #include <QtNetwork/QNetworkDiskCache> |
| 46 | 46 | ||
| 47 | #include <gl/Config.h> | ||
| 48 | #include <QtGui/QOpenGLContext> | ||
| 49 | |||
| 47 | #include <AccountManager.h> | 50 | #include <AccountManager.h> |
| 48 | #include <AddressManager.h> | 51 | #include <AddressManager.h> |
| 49 | #include <ApplicationVersion.h> | 52 | #include <ApplicationVersion.h> |
| @@ -617,6 +620,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 567 unmodified lines | |||
| 617 | 620 | ||
| 618 | // enable mouse tracking; otherwise, we only get drag events | 621 | // enable mouse tracking; otherwise, we only get drag events |
| 619 | _glWidget->setMouseTracking(true); | 622 | _glWidget->setMouseTracking(true); |
| 623 | _glWidget->makeCurrent(); | ||
| 624 | _glWidget->initializeGL(); | ||
| 620 | 625 | ||
| 621 | _offscreenContext = new OffscreenGLCanvas(); | 626 | _offscreenContext = new OffscreenGLCanvas(); |
| 622 | _offscreenContext->create(_glWidget->context()->contextHandle()); | 627 | _offscreenContext->create(_glWidget->context()->contextHandle()); |
| @@ -1136,7 +1141,7 @@ void Application::paintGL() { · 513 unmodified lines | |||
| 1136 | _lastInstantaneousFps = instantaneousFps; | 1141 | _lastInstantaneousFps = instantaneousFps; |
| 1137 | 1142 | ||
| 1138 | auto displayPlugin = getActiveDisplayPlugin(); | 1143 | auto displayPlugin = getActiveDisplayPlugin(); |
| 1139 | displayPlugin->preRender(); | 1144 | // FIXME not needed anymore? |
| 1140 | _offscreenContext->makeCurrent(); | 1145 | _offscreenContext->makeCurrent(); |
| 1141 | 1146 | ||
| 1142 | // update the avatar with a fresh HMD pose | 1147 | // update the avatar with a fresh HMD pose |
| @@ -1191,6 +1196,9 @@ void Application::paintGL() { · 48 unmodified lines | |||
| 1191 | QSize size = getDeviceSize(); | 1196 | QSize size = getDeviceSize(); |
| 1192 | renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); | 1197 | renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); |
| 1193 | _applicationOverlay.renderOverlay(&renderArgs); | 1198 | _applicationOverlay.renderOverlay(&renderArgs); |
| 1199 | gpu::FramebufferPointer overlayFramebuffer = _applicationOverlay.getOverlayFramebuffer(); | ||
| 1200 | |||
| 1201 | |||
| 1194 | } | 1202 | } |
| 1195 | 1203 | ||
| 1196 | { | 1204 | { |
| @@ -1304,6 +1312,13 @@ void Application::paintGL() { · 107 unmodified lines | |||
| 1304 | auto baseProjection = renderArgs._viewFrustum->getProjection(); | 1312 | auto baseProjection = renderArgs._viewFrustum->getProjection(); |
| 1305 | auto hmdInterface = DependencyManager::get<HMDScriptingInterface>(); | 1313 | auto hmdInterface = DependencyManager::get<HMDScriptingInterface>(); |
| 1306 | float IPDScale = hmdInterface->getIPDScale(); | 1314 | float IPDScale = hmdInterface->getIPDScale(); |
| 1315 | |||
| 1316 | // Tell the plugin what pose we're using to render. In this case we're just using the | ||
| 1317 | // unmodified head pose because the only plugin that cares (the Oculus plugin) uses it | ||
| 1318 | // for rotational timewarp. If we move to support positonal timewarp, we need to | ||
| 1319 | // ensure this contains the full pose composed with the eye offsets. | ||
| 1320 | mat4 headPose = displayPlugin->getHeadPose(_frameCount); | ||
| 1321 | |||
| 1307 | // FIXME we probably don't need to set the projection matrix every frame, | 1322 | // FIXME we probably don't need to set the projection matrix every frame, |
| 1308 | // only when the display plugin changes (or in non-HMD modes when the user | 1323 | // only when the display plugin changes (or in non-HMD modes when the user |
| 1309 | // changes the FOV manually, which right now I don't think they can. | 1324 | // changes the FOV manually, which right now I don't think they can. |
| @@ -1319,12 +1334,7 @@ void Application::paintGL() { · 9 unmodified lines | |||
| 1319 | mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); | 1334 | mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); |
| 1320 | eyeOffsets[eye] = eyeOffsetTransform; | 1335 | eyeOffsets[eye] = eyeOffsetTransform; |
| 1321 | 1336 | ||
| 1322 | // Tell the plugin what pose we're using to render. In this case we're just using the | 1337 | displayPlugin->setEyeRenderPose(_frameCount, eye, headPose); |
| 1323 | // unmodified head pose because the only plugin that cares (the Oculus plugin) uses it | ||
| 1324 | // for rotational timewarp. If we move to support positonal timewarp, we need to | ||
| 1325 | // ensure this contains the full pose composed with the eye offsets. | ||
| 1326 | mat4 headPose = displayPlugin->getHeadPose(); | ||
| 1327 | displayPlugin->setEyeRenderPose(eye, headPose); | ||
| 1328 | 1338 | ||
| 1329 | eyeProjections[eye] = displayPlugin->getProjection(eye, baseProjection); | 1339 | eyeProjections[eye] = displayPlugin->getProjection(eye, baseProjection); |
| 1330 | }); | 1340 | }); |
| @@ -1339,6 +1349,7 @@ void Application::paintGL() { · 8 unmodified lines | |||
| 1339 | } | 1349 | } |
| 1340 | 1350 | ||
| 1341 | // Overlay Composition, needs to occur after screen space effects have completed | 1351 | // Overlay Composition, needs to occur after screen space effects have completed |
| 1352 | // FIXME migrate composition into the display plugins | ||
| 1342 | { | 1353 | { |
| 1343 | PROFILE_RANGE(__FUNCTION__ "/compositor"); | 1354 | PROFILE_RANGE(__FUNCTION__ "/compositor"); |
| 1344 | PerformanceTimer perfTimer("compositor"); | 1355 | PerformanceTimer perfTimer("compositor"); |
| @@ -1367,44 +1378,40 @@ void Application::paintGL() { · 22 unmodified lines | |||
| 1367 | { | 1378 | { |
| 1368 | PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); | 1379 | PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); |
| 1369 | PerformanceTimer perfTimer("pluginOutput"); | 1380 | PerformanceTimer perfTimer("pluginOutput"); |
| 1370 | auto primaryFbo = framebufferCache->getPrimaryFramebuffer(); | 1381 | auto primaryFramebuffer = framebufferCache->getPrimaryFramebuffer(); |
| 1371 | GLuint finalTexture = gpu::GLBackend::getTextureID(primaryFbo->getRenderBuffer(0)); | 1382 | auto scratchFramebuffer = framebufferCache->getFramebuffer(); |
| 1372 | // Ensure the rendering context commands are completed when rendering | 1383 | gpu::doInBatch(renderArgs._context, [=](gpu::Batch& batch) { |
| 1373 | GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); | 1384 | gpu::Vec4i rect; |
| 1374 | // Ensure the sync object is flushed to the driver thread before releasing the context | 1385 | rect.z = size.width(); |
| 1375 | // CRITICAL for the mac driver apparently. | 1386 | rect.w = size.height(); |
| 1376 | glFlush(); | 1387 | batch.setFramebuffer(scratchFramebuffer); |
| 1377 | _offscreenContext->doneCurrent(); | 1388 | batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); |
| 1378 | 1389 | batch.blit(primaryFramebuffer, rect, scratchFramebuffer, rect); | |
| 1379 | // Switches to the display plugin context | 1390 | batch.setFramebuffer(nullptr); |
| 1380 | displayPlugin->preDisplay(); | 1391 | }); |
| 1381 | // Ensure all operations from the previous context are complete before we try to read the fbo | 1392 | auto finalTexturePointer = scratchFramebuffer->getRenderBuffer(0); |
| 1382 | glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); | 1393 | GLuint finalTexture = gpu::GLBackend::getTextureID(finalTexturePointer); |
| 1383 | glDeleteSync(sync); | 1394 | Q_ASSERT(0 != finalTexture); |
| 1384 | uint64_t displayStart = usecTimestampNow(); | ||
| 1385 | 1395 | ||
| 1386 | { | 1396 | Q_ASSERT(!_lockedFramebufferMap.contains(finalTexture)); |
| 1387 | PROFILE_RANGE(__FUNCTION__ "/pluginDisplay"); | 1397 | _lockedFramebufferMap[finalTexture] = scratchFramebuffer; |
| 1388 | PerformanceTimer perfTimer("pluginDisplay"); | ||
| 1389 | displayPlugin->display(finalTexture, toGlm(size)); | ||
| 1390 | } | ||
| 1391 | 1398 | ||
| 1399 | uint64_t displayStart = usecTimestampNow(); | ||
| 1400 | Q_ASSERT(QOpenGLContext::currentContext() == _offscreenContext->getContext()); | ||
| 1392 | { | 1401 | { |
| 1393 | PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); | 1402 | PROFILE_RANGE(__FUNCTION__ "/pluginSubmitScene"); |
| 1394 | PerformanceTimer perfTimer("bufferSwap"); | 1403 | PerformanceTimer perfTimer("pluginSubmitScene"); |
| 1395 | displayPlugin->finishFrame(); | 1404 | displayPlugin->submitSceneTexture(_frameCount, finalTexture, toGlm(size)); |
| 1396 | } | 1405 | } |
| 1406 | Q_ASSERT(QOpenGLContext::currentContext() == _offscreenContext->getContext()); | ||
| 1407 | |||
| 1397 | uint64_t displayEnd = usecTimestampNow(); | 1408 | uint64_t displayEnd = usecTimestampNow(); |
| 1398 | const float displayPeriodUsec = (float)(displayEnd - displayStart); // usecs | 1409 | const float displayPeriodUsec = (float)(displayEnd - displayStart); // usecs |
| 1399 | _lastPaintWait = displayPeriodUsec / (float)USECS_PER_SECOND; | 1410 | _lastPaintWait = displayPeriodUsec / (float)USECS_PER_SECOND; |
| 1400 | |||
| 1401 | } | 1411 | } |
| 1402 | 1412 | ||
| 1403 | { | 1413 | { |
| 1404 | PerformanceTimer perfTimer("makeCurrent"); | ||
| 1405 | _offscreenContext->makeCurrent(); | ||
| 1406 | Stats::getInstance()->setRenderDetails(renderArgs._details); | 1414 | Stats::getInstance()->setRenderDetails(renderArgs._details); |
| 1407 | |||
| 1408 | // Reset the gpu::Context Stages | 1415 | // Reset the gpu::Context Stages |
| 1409 | // Back to the default framebuffer; | 1416 | // Back to the default framebuffer; |
| 1410 | gpu::doInBatch(renderArgs._context, [=](gpu::Batch& batch) { | 1417 | gpu::doInBatch(renderArgs._context, [=](gpu::Batch& batch) { |
| @@ -2612,7 +2619,7 @@ void Application::updateMyAvatarLookAtPosition() { · 1201 unmodified lines | |||
| 2612 | lookAtPosition.x = -lookAtPosition.x; | 2619 | lookAtPosition.x = -lookAtPosition.x; |
| 2613 | } | 2620 | } |
| 2614 | if (isHMD) { | 2621 | if (isHMD) { |
| 2615 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); | 2622 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(_frameCount); |
| 2616 | glm::quat hmdRotation = glm::quat_cast(headPose); | 2623 | glm::quat hmdRotation = glm::quat_cast(headPose); |
| 2617 | lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); | 2624 | lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); |
| 2618 | } else { | 2625 | } else { |
| @@ -4503,7 +4510,7 @@ void Application::takeSnapshot() { · 1884 unmodified lines | |||
| 4503 | player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath())); | 4510 | player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath())); |
| 4504 | player->play(); | 4511 | player->play(); |
| 4505 | 4512 | ||
| 4506 | QString fileName = Snapshot::saveSnapshot(_glWidget->grabFrameBuffer()); | 4513 | QString fileName = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot()); |
| 4507 | 4514 | ||
| 4508 | AccountManager& accountManager = AccountManager::getInstance(); | 4515 | AccountManager& accountManager = AccountManager::getInstance(); |
| 4509 | if (!accountManager.isLoggedIn()) { | 4516 | if (!accountManager.isLoggedIn()) { |
| @@ -4514,7 +4521,6 @@ void Application::takeSnapshot() { · 4 unmodified lines | |||
| 4514 | _snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget); | 4521 | _snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget); |
| 4515 | } | 4522 | } |
| 4516 | _snapshotShareDialog->show(); | 4523 | _snapshotShareDialog->show(); |
| 4517 | |||
| 4518 | } | 4524 | } |
| 4519 | 4525 | ||
| 4520 | float Application::getRenderResolutionScale() const { | 4526 | float Application::getRenderResolutionScale() const { |
| @@ -4697,10 +4703,6 @@ const DisplayPlugin* Application::getActiveDisplayPlugin() const { · 176 unmodified lines | |||
| 4697 | return ((Application*)this)->getActiveDisplayPlugin(); | 4703 | return ((Application*)this)->getActiveDisplayPlugin(); |
| 4698 | } | 4704 | } |
| 4699 | 4705 | ||
| 4700 | bool _activatingDisplayPlugin{ false }; | ||
| 4701 | QVector<QPair<QString, QString>> _currentDisplayPluginActions; | ||
| 4702 | QVector<QPair<QString, QString>> _currentInputPluginActions; | ||
| 4703 | |||
| 4704 | static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { | 4706 | static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { |
| 4705 | auto menu = Menu::getInstance(); | 4707 | auto menu = Menu::getInstance(); |
| 4706 | QString name = displayPlugin->getName(); | 4708 | QString name = displayPlugin->getName(); |
| @@ -4730,9 +4732,10 @@ void Application::updateDisplayMode() { · 23 unmodified lines | |||
| 4730 | bool first = true; | 4732 | bool first = true; |
| 4731 | foreach(auto displayPlugin, displayPlugins) { | 4733 | foreach(auto displayPlugin, displayPlugins) { |
| 4732 | addDisplayPluginToMenu(displayPlugin, first); | 4734 | addDisplayPluginToMenu(displayPlugin, first); |
| 4733 | QObject::connect(displayPlugin.get(), &DisplayPlugin::requestRender, [this] { | 4735 | // This must be a queued connection to avoid a deadlock |
| 4734 | paintGL(); | 4736 | QObject::connect(displayPlugin.get(), &DisplayPlugin::requestRender, |
| 4735 | }); | 4737 | this, &Application::paintGL, Qt::QueuedConnection); |
| 4738 | |||
| 4736 | QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, [this](const QSize & size) { | 4739 | QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, [this](const QSize & size) { |
| 4737 | resizeGL(); | 4740 | resizeGL(); |
| 4738 | }); | 4741 | }); |
| @@ -4774,19 +4777,18 @@ void Application::updateDisplayMode() { · 35 unmodified lines | |||
| 4774 | return; | 4777 | return; |
| 4775 | } | 4778 | } |
| 4776 | 4779 | ||
| 4777 | if (!_currentDisplayPluginActions.isEmpty()) { | 4780 | |
| 4781 | if (!_pluginContainer->currentDisplayActions().isEmpty()) { | ||
| 4778 | auto menu = Menu::getInstance(); | 4782 | auto menu = Menu::getInstance(); |
| 4779 | foreach(auto itemInfo, _currentDisplayPluginActions) { | 4783 | foreach(auto itemInfo, _pluginContainer->currentDisplayActions()) { |
| 4780 | menu->removeMenuItem(itemInfo.first, itemInfo.second); | 4784 | menu->removeMenuItem(itemInfo.first, itemInfo.second); |
| 4781 | } | 4785 | } |
| 4782 | _currentDisplayPluginActions.clear(); | 4786 | _pluginContainer->currentDisplayActions().clear(); |
| 4783 | } | 4787 | } |
| 4784 | 4788 | ||
| 4785 | if (newDisplayPlugin) { | 4789 | if (newDisplayPlugin) { |
| 4786 | _offscreenContext->makeCurrent(); | 4790 | _offscreenContext->makeCurrent(); |
| 4787 | _activatingDisplayPlugin = true; | ||
| 4788 | newDisplayPlugin->activate(); | 4791 | newDisplayPlugin->activate(); |
| 4789 | _activatingDisplayPlugin = false; | ||
| 4790 | _offscreenContext->makeCurrent(); | 4792 | _offscreenContext->makeCurrent(); |
| 4791 | offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize())); | 4793 | offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize())); |
| 4792 | _offscreenContext->makeCurrent(); | 4794 | _offscreenContext->makeCurrent(); |
| @@ -4912,7 +4914,7 @@ mat4 Application::getEyeOffset(int eye) const { · 119 unmodified lines | |||
| 4912 | 4914 | ||
| 4913 | mat4 Application::getHMDSensorPose() const { | 4915 | mat4 Application::getHMDSensorPose() const { |
| 4914 | if (isHMDMode()) { | 4916 | if (isHMDMode()) { |
| 4915 | return getActiveDisplayPlugin()->getHeadPose(); | 4917 | return getActiveDisplayPlugin()->getHeadPose(_frameCount); |
| 4916 | } | 4918 | } |
| 4917 | return mat4(); | 4919 | return mat4(); |
| 4918 | } | 4920 | } |