Threaded rendering
Showing the changes to interface/src/Application.cpp (1 of 141 files). Show all
Unified · Split
| @@ -257,7 +257,10 @@ public: · 256 unmodified lines | |||
| 257 | void run() override { | 257 | void run() override { |
| 258 | while (!_quit) { | 258 | while (!_quit) { |
| 259 | QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); | 259 | QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); |
| 260 | 260 | // Don't do heartbeat detection under nsight | |
| 261 | if (nsightActive()) { | ||
| 262 | continue; | ||
| 263 | } | ||
| 261 | uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us | 264 | uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us |
| 262 | uint64_t now = usecTimestampNow(); | 265 | uint64_t now = usecTimestampNow(); |
| 263 | auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0; | 266 | auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0; |
| @@ -305,8 +308,6 @@ public: · 41 unmodified lines | |||
| 305 | // Don't actually crash in debug builds, in case this apparent deadlock is simply from | 308 | // Don't actually crash in debug builds, in case this apparent deadlock is simply from |
| 306 | // the developer actively debugging code | 309 | // the developer actively debugging code |
| 307 | #ifdef NDEBUG | 310 | #ifdef NDEBUG |
| 308 | |||
| 309 | |||
| 310 | deadlockDetectionCrash(); | 311 | deadlockDetectionCrash(); |
| 311 | #endif | 312 | #endif |
| 312 | } | 313 | } |
| @@ -779,16 +780,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 466 unmodified lines | |||
| 779 | _glWidget->makeCurrent(); | 780 | _glWidget->makeCurrent(); |
| 780 | _glWidget->initializeGL(); | 781 | _glWidget->initializeGL(); |
| 781 | 782 | ||
| 782 | _chromiumShareContext = new OffscreenGLCanvas(); | ||
| 783 | _chromiumShareContext->create(_glWidget->context()->contextHandle()); | ||
| 784 | _chromiumShareContext->makeCurrent(); | ||
| 785 | qt_gl_set_global_share_context(_chromiumShareContext->getContext()); | ||
| 786 | |||
| 787 | _offscreenContext = new OffscreenGLCanvas(); | ||
| 788 | _offscreenContext->create(_glWidget->context()->contextHandle()); | ||
| 789 | _offscreenContext->makeCurrent(); | ||
| 790 | initializeGL(); | 783 | initializeGL(); |
| 791 | _offscreenContext->makeCurrent(); | ||
| 792 | // Make sure we don't time out during slow operations at startup | 784 | // Make sure we don't time out during slow operations at startup |
| 793 | updateHeartbeat(); | 785 | updateHeartbeat(); |
| 794 | 786 | ||
| @@ -1498,11 +1490,18 @@ void Application::initializeGL() { · 703 unmodified lines | |||
| 1498 | _isGLInitialized = true; | 1490 | _isGLInitialized = true; |
| 1499 | } | 1491 | } |
| 1500 | 1492 | ||
| 1493 | _glWidget->makeCurrent(); | ||
| 1494 | _chromiumShareContext = new OffscreenGLCanvas(); | ||
| 1495 | _chromiumShareContext->create(_glWidget->context()->contextHandle()); | ||
| 1496 | _chromiumShareContext->makeCurrent(); | ||
| 1497 | qt_gl_set_global_share_context(_chromiumShareContext->getContext()); | ||
| 1498 | |||
| 1499 | _glWidget->makeCurrent(); | ||
| 1501 | gpu::Context::init<gpu::gl::GLBackend>(); | 1500 | gpu::Context::init<gpu::gl::GLBackend>(); |
| 1502 | _gpuContext = std::make_shared<gpu::Context>(); | 1501 | _gpuContext = std::make_shared<gpu::Context>(); |
| 1503 | // The gpu context can make child contexts for transfers, so | 1502 | // The gpu context can make child contexts for transfers, so |
| 1504 | // we need to restore primary rendering context | 1503 | // we need to restore primary rendering context |
| 1505 | _offscreenContext->makeCurrent(); | 1504 | _glWidget->makeCurrent(); |
| 1506 | 1505 | ||
| 1507 | initDisplay(); | 1506 | initDisplay(); |
| 1508 | qCDebug(interfaceapp, "Initialized Display."); | 1507 | qCDebug(interfaceapp, "Initialized Display."); |
| @@ -1521,7 +1520,8 @@ void Application::initializeGL() { · 12 unmodified lines | |||
| 1521 | // Needs to happen AFTER the render engine initialization to access its configuration | 1520 | // Needs to happen AFTER the render engine initialization to access its configuration |
| 1522 | initializeUi(); | 1521 | initializeUi(); |
| 1523 | qCDebug(interfaceapp, "Initialized Offscreen UI."); | 1522 | qCDebug(interfaceapp, "Initialized Offscreen UI."); |
| 1524 | _offscreenContext->makeCurrent(); | 1523 | _glWidget->makeCurrent(); |
| 1524 | |||
| 1525 | 1525 | ||
| 1526 | // call Menu getInstance static method to set up the menu | 1526 | // call Menu getInstance static method to set up the menu |
| 1527 | // Needs to happen AFTER the QML UI initialization | 1527 | // Needs to happen AFTER the QML UI initialization |
| @@ -1537,8 +1537,13 @@ void Application::initializeGL() { · 9 unmodified lines | |||
| 1537 | 1537 | ||
| 1538 | _idleLoopStdev.reset(); | 1538 | _idleLoopStdev.reset(); |
| 1539 | 1539 | ||
| 1540 | _offscreenContext = new OffscreenGLCanvas(); | ||
| 1541 | _offscreenContext->create(_glWidget->context()->contextHandle()); | ||
| 1542 | _offscreenContext->makeCurrent(); | ||
| 1543 | |||
| 1540 | // update before the first render | 1544 | // update before the first render |
| 1541 | update(0); | 1545 | update(0); |
| 1546 | |||
| 1542 | } | 1547 | } |
| 1543 | 1548 | ||
| 1544 | FrameTimingsScriptingInterface _frameTimingsScriptingInterface; | 1549 | FrameTimingsScriptingInterface _frameTimingsScriptingInterface; |
| @@ -1555,7 +1560,7 @@ void Application::initializeUi() { · 10 unmodified lines | |||
| 1555 | 1560 | ||
| 1556 | 1561 | ||
| 1557 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); | 1562 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 1558 | offscreenUi->create(_offscreenContext->getContext()); | 1563 | offscreenUi->create(_glWidget->context()->contextHandle()); |
| 1559 | 1564 | ||
| 1560 | auto rootContext = offscreenUi->getRootContext(); | 1565 | auto rootContext = offscreenUi->getRootContext(); |
| 1561 | 1566 | ||
| @@ -1726,17 +1731,7 @@ void Application::paintGL() { · 164 unmodified lines | |||
| 1726 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); | 1731 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); |
| 1727 | resizeGL(); | 1732 | resizeGL(); |
| 1728 | 1733 | ||
| 1729 | // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened | 1734 | _gpuContext->beginFrame(getHMDSensorPose()); |
| 1730 | { | ||
| 1731 | PerformanceTimer perfTimer("syncCache"); | ||
| 1732 | renderArgs._context->syncCache(); | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | auto framebufferCache = DependencyManager::get<FramebufferCache>(); | ||
| 1736 | // Final framebuffer that will be handled to the display-plugin | ||
| 1737 | auto finalFramebuffer = framebufferCache->getFramebuffer(); | ||
| 1738 | |||
| 1739 | _gpuContext->beginFrame(finalFramebuffer, getHMDSensorPose()); | ||
| 1740 | // Reset the gpu::Context Stages | 1735 | // Reset the gpu::Context Stages |
| 1741 | // Back to the default framebuffer; | 1736 | // Back to the default framebuffer; |
| 1742 | gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { | 1737 | gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { |
| @@ -1866,7 +1861,10 @@ void Application::paintGL() { · 123 unmodified lines | |||
| 1866 | getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform()); | 1861 | getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform()); |
| 1867 | 1862 | ||
| 1868 | // Primary rendering pass | 1863 | // Primary rendering pass |
| 1864 | auto framebufferCache = DependencyManager::get<FramebufferCache>(); | ||
| 1869 | const QSize size = framebufferCache->getFrameBufferSize(); | 1865 | const QSize size = framebufferCache->getFrameBufferSize(); |
| 1866 | // Final framebuffer that will be handled to the display-plugin | ||
| 1867 | auto finalFramebuffer = framebufferCache->getFramebuffer(); | ||
| 1870 | 1868 | ||
| 1871 | { | 1869 | { |
| 1872 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); | 1870 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); |
| @@ -1891,7 +1889,6 @@ void Application::paintGL() { · 18 unmodified lines | |||
| 1891 | auto baseProjection = renderArgs.getViewFrustum().getProjection(); | 1889 | auto baseProjection = renderArgs.getViewFrustum().getProjection(); |
| 1892 | auto hmdInterface = DependencyManager::get<HMDScriptingInterface>(); | 1890 | auto hmdInterface = DependencyManager::get<HMDScriptingInterface>(); |
| 1893 | float IPDScale = hmdInterface->getIPDScale(); | 1891 | float IPDScale = hmdInterface->getIPDScale(); |
| 1894 | mat4 headPose = displayPlugin->getHeadPose(); | ||
| 1895 | 1892 | ||
| 1896 | // FIXME we probably don't need to set the projection matrix every frame, | 1893 | // FIXME we probably don't need to set the projection matrix every frame, |
| 1897 | // only when the display plugin changes (or in non-HMD modes when the user | 1894 | // only when the display plugin changes (or in non-HMD modes when the user |
| @@ -1907,13 +1904,6 @@ void Application::paintGL() { · 9 unmodified lines | |||
| 1907 | // Apply IPD scaling | 1904 | // Apply IPD scaling |
| 1908 | mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); | 1905 | mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); |
| 1909 | eyeOffsets[eye] = eyeOffsetTransform; | 1906 | eyeOffsets[eye] = eyeOffsetTransform; |
| 1910 | |||
| 1911 | // Tell the plugin what pose we're using to render. In this case we're just using the | ||
| 1912 | // unmodified head pose because the only plugin that cares (the Oculus plugin) uses it | ||
| 1913 | // for rotational timewarp. If we move to support positonal timewarp, we need to | ||
| 1914 | // ensure this contains the full pose composed with the eye offsets. | ||
| 1915 | displayPlugin->setEyeRenderPose(_frameCount, eye, headPose * glm::inverse(eyeOffsetTransform)); | ||
| 1916 | |||
| 1917 | eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); | 1907 | eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); |
| 1918 | }); | 1908 | }); |
| 1919 | renderArgs._context->setStereoProjections(eyeProjections); | 1909 | renderArgs._context->setStereoProjections(eyeProjections); |
| @@ -1921,36 +1911,26 @@ void Application::paintGL() { · 1 unmodified line | |||
| 1921 | } | 1911 | } |
| 1922 | renderArgs._blitFramebuffer = finalFramebuffer; | 1912 | renderArgs._blitFramebuffer = finalFramebuffer; |
| 1923 | displaySide(&renderArgs, _myCamera); | 1913 | displaySide(&renderArgs, _myCamera); |
| 1924 | |||
| 1925 | renderArgs._blitFramebuffer.reset(); | ||
| 1926 | renderArgs._context->enableStereo(false); | ||
| 1927 | } | ||
| 1928 | |||
| 1929 | _gpuContext->endFrame(); | ||
| 1930 | |||
| 1931 | gpu::TexturePointer overlayTexture = _applicationOverlay.acquireOverlay(); | ||
| 1932 | if (overlayTexture) { | ||
| 1933 | displayPlugin->submitOverlayTexture(overlayTexture); | ||
| 1934 | } | 1914 | } |
| 1935 | 1915 | ||
| 1936 | // deliver final composited scene to the display plugin | 1916 | auto frame = _gpuContext->endFrame(); |
| 1917 | frame->frameIndex = _frameCount; | ||
| 1918 | frame->framebuffer = finalFramebuffer; | ||
| 1919 | frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ | ||
| 1920 | DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer); | ||
| 1921 | }; | ||
| 1922 | frame->overlay = _applicationOverlay.getOverlayTexture(); | ||
| 1923 | // deliver final scene rendering commands to the display plugin | ||
| 1937 | { | 1924 | { |
| 1938 | PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); | 1925 | PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); |
| 1939 | PerformanceTimer perfTimer("pluginOutput"); | 1926 | PerformanceTimer perfTimer("pluginOutput"); |
| 1940 | 1927 | displayPlugin->submitFrame(frame); | |
| 1941 | auto finalTexture = finalFramebuffer->getRenderBuffer(0); | ||
| 1942 | Q_ASSERT(!_lockedFramebufferMap.contains(finalTexture)); | ||
| 1943 | _lockedFramebufferMap[finalTexture] = finalFramebuffer; | ||
| 1944 | |||
| 1945 | Q_ASSERT(isCurrentContext(_offscreenContext->getContext())); | ||
| 1946 | { | ||
| 1947 | PROFILE_RANGE(__FUNCTION__ "/pluginSubmitScene"); | ||
| 1948 | PerformanceTimer perfTimer("pluginSubmitScene"); | ||
| 1949 | displayPlugin->submitSceneTexture(_frameCount, finalTexture); | ||
| 1950 | } | ||
| 1951 | Q_ASSERT(isCurrentContext(_offscreenContext->getContext())); | ||
| 1952 | } | 1928 | } |
| 1953 | 1929 | ||
| 1930 | // Reset the framebuffer and stereo state | ||
| 1931 | renderArgs._blitFramebuffer.reset(); | ||
| 1932 | renderArgs._context->enableStereo(false); | ||
| 1933 | |||
| 1954 | { | 1934 | { |
| 1955 | Stats::getInstance()->setRenderDetails(renderArgs._details); | 1935 | Stats::getInstance()->setRenderDetails(renderArgs._details); |
| 1956 | } | 1936 | } |
| @@ -5405,6 +5385,7 @@ void Application::updateDisplayMode() { · 3448 unmodified lines | |||
| 5405 | DisplayPluginList advanced; | 5385 | DisplayPluginList advanced; |
| 5406 | DisplayPluginList developer; | 5386 | DisplayPluginList developer; |
| 5407 | foreach(auto displayPlugin, displayPlugins) { | 5387 | foreach(auto displayPlugin, displayPlugins) { |
| 5388 | displayPlugin->setContext(_gpuContext); | ||
| 5408 | auto grouping = displayPlugin->getGrouping(); | 5389 | auto grouping = displayPlugin->getGrouping(); |
| 5409 | switch (grouping) { | 5390 | switch (grouping) { |
| 5410 | case Plugin::ADVANCED: | 5391 | case Plugin::ADVANCED: |
| @@ -5474,9 +5455,6 @@ void Application::updateDisplayMode() { · 63 unmodified lines | |||
| 5474 | _displayPlugin->deactivate(); | 5455 | _displayPlugin->deactivate(); |
| 5475 | } | 5456 | } |
| 5476 | 5457 | ||
| 5477 | // FIXME probably excessive and useless context switching | ||
| 5478 | _offscreenContext->makeCurrent(); | ||
| 5479 | |||
| 5480 | bool active = newDisplayPlugin->activate(); | 5458 | bool active = newDisplayPlugin->activate(); |
| 5481 | 5459 | ||
| 5482 | if (!active) { | 5460 | if (!active) { |
| @@ -5621,20 +5599,6 @@ bool Application::makeRenderingContextCurrent() { · 138 unmodified lines | |||
| 5621 | return _offscreenContext->makeCurrent(); | 5599 | return _offscreenContext->makeCurrent(); |
| 5622 | } | 5600 | } |
| 5623 | 5601 | ||
| 5624 | void Application::releaseSceneTexture(const gpu::TexturePointer& texture) { | ||
| 5625 | Q_ASSERT(QThread::currentThread() == thread()); | ||
| 5626 | auto& framebufferMap = _lockedFramebufferMap; | ||
| 5627 | Q_ASSERT(framebufferMap.contains(texture)); | ||
| 5628 | auto framebufferPointer = framebufferMap[texture]; | ||
| 5629 | framebufferMap.remove(texture); | ||
| 5630 | auto framebufferCache = DependencyManager::get<FramebufferCache>(); | ||
| 5631 | framebufferCache->releaseFramebuffer(framebufferPointer); | ||
| 5632 | } | ||
| 5633 | |||
| 5634 | void Application::releaseOverlayTexture(const gpu::TexturePointer& texture) { | ||
| 5635 | _applicationOverlay.releaseOverlay(texture); | ||
| 5636 | } | ||
| 5637 | |||
| 5638 | bool Application::isForeground() const { | 5602 | bool Application::isForeground() const { |
| 5639 | return _isForeground && !_window->isMinimized(); | 5603 | return _isForeground && !_window->isMinimized(); |
| 5640 | } | 5604 | } |