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 | 257 | void run() override { |
| 258 | 258 | while (!_quit) { |
| 259 | 259 | QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); |
| 260 | − | |
| 260 | + // Don't do heartbeat detection under nsight | |
| 261 | + if (nsightActive()) { | |
| 262 | + continue; | |
| 263 | + } | |
| 261 | 264 | uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us |
| 262 | 265 | uint64_t now = usecTimestampNow(); |
| 263 | 266 | auto lastHeartbeatAge = (now > lastHeartbeat) ? now - lastHeartbeat : 0; |
| @@ -305,8 +308,6 @@ public: · 41 unmodified lines | ||
| 305 | 308 | // Don't actually crash in debug builds, in case this apparent deadlock is simply from |
| 306 | 309 | // the developer actively debugging code |
| 307 | 310 | #ifdef NDEBUG |
| 308 | − | |
| 309 | − | |
| 310 | 311 | deadlockDetectionCrash(); |
| 311 | 312 | #endif |
| 312 | 313 | } |
| @@ -779,16 +780,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 466 unmodified lines | ||
| 779 | 780 | _glWidget->makeCurrent(); |
| 780 | 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 | 783 | initializeGL(); |
| 791 | − _offscreenContext->makeCurrent(); | |
| 792 | 784 | // Make sure we don't time out during slow operations at startup |
| 793 | 785 | updateHeartbeat(); |
| 794 | 786 | |
| @@ -1498,11 +1490,18 @@ void Application::initializeGL() { · 703 unmodified lines | ||
| 1498 | 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 | 1500 | gpu::Context::init<gpu::gl::GLBackend>(); |
| 1502 | 1501 | _gpuContext = std::make_shared<gpu::Context>(); |
| 1503 | 1502 | // The gpu context can make child contexts for transfers, so |
| 1504 | 1503 | // we need to restore primary rendering context |
| 1505 | − _offscreenContext->makeCurrent(); | |
| 1504 | + _glWidget->makeCurrent(); | |
| 1506 | 1505 | |
| 1507 | 1506 | initDisplay(); |
| 1508 | 1507 | qCDebug(interfaceapp, "Initialized Display."); |
| @@ -1521,7 +1520,8 @@ void Application::initializeGL() { · 12 unmodified lines | ||
| 1521 | 1520 | // Needs to happen AFTER the render engine initialization to access its configuration |
| 1522 | 1521 | initializeUi(); |
| 1523 | 1522 | qCDebug(interfaceapp, "Initialized Offscreen UI."); |
| 1524 | − _offscreenContext->makeCurrent(); | |
| 1523 | + _glWidget->makeCurrent(); | |
| 1524 | + | |
| 1525 | 1525 | |
| 1526 | 1526 | // call Menu getInstance static method to set up the menu |
| 1527 | 1527 | // Needs to happen AFTER the QML UI initialization |
| @@ -1537,8 +1537,13 @@ void Application::initializeGL() { · 9 unmodified lines | ||
| 1537 | 1537 | |
| 1538 | 1538 | _idleLoopStdev.reset(); |
| 1539 | 1539 | |
| 1540 | + _offscreenContext = new OffscreenGLCanvas(); | |
| 1541 | + _offscreenContext->create(_glWidget->context()->contextHandle()); | |
| 1542 | + _offscreenContext->makeCurrent(); | |
| 1543 | + | |
| 1540 | 1544 | // update before the first render |
| 1541 | 1545 | update(0); |
| 1546 | + | |
| 1542 | 1547 | } |
| 1543 | 1548 | |
| 1544 | 1549 | FrameTimingsScriptingInterface _frameTimingsScriptingInterface; |
| @@ -1555,7 +1560,7 @@ void Application::initializeUi() { · 10 unmodified lines | ||
| 1555 | 1560 | |
| 1556 | 1561 | |
| 1557 | 1562 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 1558 | − offscreenUi->create(_offscreenContext->getContext()); | |
| 1563 | + offscreenUi->create(_glWidget->context()->contextHandle()); | |
| 1559 | 1564 | |
| 1560 | 1565 | auto rootContext = offscreenUi->getRootContext(); |
| 1561 | 1566 | |
| @@ -1726,17 +1731,7 @@ void Application::paintGL() { · 164 unmodified lines | ||
| 1726 | 1731 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); |
| 1727 | 1732 | resizeGL(); |
| 1728 | 1733 | |
| 1729 | − // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened | |
| 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()); | |
| 1734 | + _gpuContext->beginFrame(getHMDSensorPose()); | |
| 1740 | 1735 | // Reset the gpu::Context Stages |
| 1741 | 1736 | // Back to the default framebuffer; |
| 1742 | 1737 | gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { |
| @@ -1866,7 +1861,10 @@ void Application::paintGL() { · 123 unmodified lines | ||
| 1866 | 1861 | getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform()); |
| 1867 | 1862 | |
| 1868 | 1863 | // Primary rendering pass |
| 1864 | + auto framebufferCache = DependencyManager::get<FramebufferCache>(); | |
| 1869 | 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 | 1870 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); |
| @@ -1891,7 +1889,6 @@ void Application::paintGL() { · 18 unmodified lines | ||
| 1891 | 1889 | auto baseProjection = renderArgs.getViewFrustum().getProjection(); |
| 1892 | 1890 | auto hmdInterface = DependencyManager::get<HMDScriptingInterface>(); |
| 1893 | 1891 | float IPDScale = hmdInterface->getIPDScale(); |
| 1894 | − mat4 headPose = displayPlugin->getHeadPose(); | |
| 1895 | 1892 | |
| 1896 | 1893 | // FIXME we probably don't need to set the projection matrix every frame, |
| 1897 | 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 | 1904 | // Apply IPD scaling |
| 1908 | 1905 | mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); |
| 1909 | 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 | 1907 | eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); |
| 1918 | 1908 | }); |
| 1919 | 1909 | renderArgs._context->setStereoProjections(eyeProjections); |
| @@ -1921,36 +1911,26 @@ void Application::paintGL() { · 1 unmodified line | ||
| 1921 | 1911 | } |
| 1922 | 1912 | renderArgs._blitFramebuffer = finalFramebuffer; |
| 1923 | 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 | 1925 | PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); |
| 1939 | 1926 | PerformanceTimer perfTimer("pluginOutput"); |
| 1940 | − | |
| 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())); | |
| 1927 | + displayPlugin->submitFrame(frame); | |
| 1952 | 1928 | } |
| 1953 | 1929 | |
| 1930 | + // Reset the framebuffer and stereo state | |
| 1931 | + renderArgs._blitFramebuffer.reset(); | |
| 1932 | + renderArgs._context->enableStereo(false); | |
| 1933 | + | |
| 1954 | 1934 | { |
| 1955 | 1935 | Stats::getInstance()->setRenderDetails(renderArgs._details); |
| 1956 | 1936 | } |
| @@ -5405,6 +5385,7 @@ void Application::updateDisplayMode() { · 3448 unmodified lines | ||
| 5405 | 5385 | DisplayPluginList advanced; |
| 5406 | 5386 | DisplayPluginList developer; |
| 5407 | 5387 | foreach(auto displayPlugin, displayPlugins) { |
| 5388 | + displayPlugin->setContext(_gpuContext); | |
| 5408 | 5389 | auto grouping = displayPlugin->getGrouping(); |
| 5409 | 5390 | switch (grouping) { |
| 5410 | 5391 | case Plugin::ADVANCED: |
| @@ -5474,9 +5455,6 @@ void Application::updateDisplayMode() { · 63 unmodified lines | ||
| 5474 | 5455 | _displayPlugin->deactivate(); |
| 5475 | 5456 | } |
| 5476 | 5457 | |
| 5477 | − // FIXME probably excessive and useless context switching | |
| 5478 | − _offscreenContext->makeCurrent(); | |
| 5479 | − | |
| 5480 | 5458 | bool active = newDisplayPlugin->activate(); |
| 5481 | 5459 | |
| 5482 | 5460 | if (!active) { |
| @@ -5621,20 +5599,6 @@ bool Application::makeRenderingContextCurrent() { · 138 unmodified lines | ||
| 5621 | 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 | 5602 | bool Application::isForeground() const { |
| 5639 | 5603 | return _isForeground && !_window->isMinimized(); |
| 5640 | 5604 | } |