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