diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 4258d4db75..b8912d95b6 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -109,23 +109,20 @@ bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() { return Parent::internalActivate(); } -gpu::PipelinePointer Basic2DWindowOpenGLDisplayPlugin::getCompositeScenePipeline() { +gpu::PipelinePointer Basic2DWindowOpenGLDisplayPlugin::getRenderTexturePipeline() { #if defined(Q_OS_ANDROID) - return _linearToSRGBPipeline; + return _linearToSRGBPipeline; #else - return _SRGBToLinearPipeline; + +#ifndef USE_GLES + return _SRGBToLinearPipeline; +#else + return _drawTexturePipeline; +#endif + #endif } -gpu::Element Basic2DWindowOpenGLDisplayPlugin::getCompositeFBColorSpace() { -#if defined(Q_OS_ANDROID) - return gpu::Element::COLOR_SRGBA_32; -#else - return gpu::Element::COLOR_RGBA_32; -#endif -} - - void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() { #if defined(Q_OS_ANDROID) auto& virtualPadManager = VirtualPad::Manager::instance(); diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index 7f654915e1..68301ff8b4 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -37,8 +37,7 @@ public: virtual void pluginUpdate() override {}; - virtual gpu::PipelinePointer getCompositeScenePipeline() override; - virtual gpu::Element getCompositeFBColorSpace() override; + virtual gpu::PipelinePointer getRenderTexturePipeline() override; protected: mutable bool _isThrottled = false; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 73bc1d0aad..75cdf5ebef 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -62,7 +62,7 @@ public: PresentThread() { connect(qApp, &QCoreApplication::aboutToQuit, [this] { - shutdown(); + shutdown(); }); setObjectName("Present"); @@ -82,12 +82,11 @@ public: Lock lock(_mutex); _shutdown = true; - _condition.wait(lock, [&] { return !_shutdown; }); + _condition.wait(lock, [&] { return !_shutdown; }); qCDebug(displayPlugins) << "Present thread shutdown"; } } - void setNewDisplayPlugin(OpenGLDisplayPlugin* plugin) { Lock lock(_mutex); if (isRunning()) { @@ -104,7 +103,6 @@ public: _context->moveToThread(this); } - virtual void run() override { PROFILE_SET_THREAD_NAME("Present Thread"); @@ -131,7 +129,6 @@ public: _condition.notify_one(); } - { // Main thread does it's thing while we wait on the lock to release Lock lock(_mutex); @@ -201,7 +198,7 @@ public: #if defined(Q_OS_MAC) _context->doneCurrent(); #endif - + _refreshRateController->sleepThreadIfNeeded(this, currentPlugin->isHmd()); } @@ -235,7 +232,6 @@ public: _condition.notify_one(); } - private: void makeCurrent(); void doneCurrent(); @@ -245,7 +241,6 @@ private: // Used to allow the main thread to perform context operations Condition _condition; - QThread* _targetOperationThread { nullptr }; bool _pendingOtherThreadOperation { false }; bool _finishedOtherThreadOperation { false }; @@ -302,7 +297,6 @@ bool OpenGLDisplayPlugin::activate() { return false; } - // This should not return until the new context has been customized // and the old context (if any) has been uncustomized presentThread->setNewDisplayPlugin(this); @@ -334,7 +328,7 @@ void OpenGLDisplayPlugin::deactivate() { _container->showDisplayPluginsTools(false); if (!_container->currentDisplayActions().isEmpty()) { - foreach(auto itemInfo, _container->currentDisplayActions()) { + foreach (auto itemInfo, _container->currentDisplayActions()) { _container->removeMenuItem(itemInfo.first, itemInfo.second); } _container->currentDisplayActions().clear(); @@ -368,7 +362,6 @@ void OpenGLDisplayPlugin::customizeContext() { image = image.convertToFormat(QImage::Format_ARGB32); } if ((image.width() > 0) && (image.height() > 0)) { - cursorData.texture = gpu::Texture::createStrict( gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.width(), image.height(), @@ -384,7 +377,7 @@ void OpenGLDisplayPlugin::customizeContext() { } } - if (!_drawTexturePipeline) { + if (!_linearToSRGBPipeline) { gpu::StatePointer blendState = gpu::StatePointer(new gpu::State()); blendState->setDepthTest(gpu::State::DepthTest(false)); blendState->setBlendFunction(true, @@ -397,17 +390,17 @@ void OpenGLDisplayPlugin::customizeContext() { scissorState->setDepthTest(gpu::State::DepthTest(false)); scissorState->setScissorEnable(true); - _drawTexturePipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), scissorState); + _drawTexturePipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), scissorState); - _linearToSRGBPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaLinearToSRGB), scissorState); + _linearToSRGBPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaLinearToSRGB), scissorState); - _SRGBToLinearPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaSRGBToLinear), scissorState); + _SRGBToLinearPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaSRGBToLinear), scissorState); - _hudPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), blendState); + _hudPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), blendState); - _mirrorHUDPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureMirroredX), blendState); + _mirrorHUDPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureMirroredX), blendState); - _cursorPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTransformedTexture), blendState); + _cursorPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTransformedTexture), blendState); } updateCompositeFramebuffer(); @@ -418,9 +411,9 @@ void OpenGLDisplayPlugin::uncustomizeContext() { _drawTexturePipeline.reset(); _linearToSRGBPipeline.reset(); _SRGBToLinearPipeline.reset(); + _cursorPipeline.reset(); _hudPipeline.reset(); _mirrorHUDPipeline.reset(); - _cursorPipeline.reset(); _compositeFramebuffer.reset(); withPresentThreadLock([&] { @@ -433,7 +426,6 @@ void OpenGLDisplayPlugin::uncustomizeContext() { }); } - // Pressing Alt (and Meta) key alone activates the menubar because its style inherits the // SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to // receive keyPress events for the Alt (and Meta) key in a reliable manner. @@ -514,11 +506,18 @@ void OpenGLDisplayPlugin::captureFrame(const std::string& filename) const { }); } -void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor) { +void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, + const gpu::TexturePointer& texture, + const glm::ivec4& viewport, + const glm::ivec4& scissor) { renderFromTexture(batch, texture, viewport, scissor, nullptr); } -void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& copyFbo /*=gpu::FramebufferPointer()*/) { +void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, + const gpu::TexturePointer& texture, + const glm::ivec4& viewport, + const glm::ivec4& scissor, + const gpu::FramebufferPointer& copyFbo /*=gpu::FramebufferPointer()*/) { auto fbo = gpu::FramebufferPointer(); batch.enableStereo(false); batch.resetViewTransform(); @@ -528,13 +527,13 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur batch.setViewportTransform(viewport); batch.setResourceTexture(0, texture); - batch.setPipeline(_drawTexturePipeline); - + batch.setPipeline(getRenderTexturePipeline()); + batch.draw(gpu::TRIANGLE_STRIP, 4); if (copyFbo) { gpu::Vec4i copyFboRect(0, 0, copyFbo->getWidth(), copyFbo->getHeight()); gpu::Vec4i sourceRect(scissor.x, scissor.y, scissor.x + scissor.z, scissor.y + scissor.w); - float aspectRatio = (float)scissor.w / (float) scissor.z; // height/width + float aspectRatio = (float)scissor.w / (float)scissor.z; // height/width // scale width first int xOffset = 0; int yOffset = 0; @@ -635,11 +634,6 @@ void OpenGLDisplayPlugin::compositePointer() { }); } -// Overridden by Basic2DWindowDisplayPlugin and OculusDisplayPlugin -gpu::PipelinePointer OpenGLDisplayPlugin::getCompositeScenePipeline() { - return _drawTexturePipeline; -} - void OpenGLDisplayPlugin::compositeScene() { render([&](gpu::Batch& batch) { batch.enableStereo(false); @@ -682,7 +676,7 @@ void OpenGLDisplayPlugin::internalPresent() { render([&](gpu::Batch& batch) { // Note: _displayTexture must currently be the same size as the display. uvec2 dims = _displayTexture ? uvec2(_displayTexture->getDimensions()) : getSurfacePixels(); - auto viewport = ivec4(uvec2(0), dims); + auto viewport = ivec4(uvec2(0), dims); renderFromTexture(batch, _displayTexture ? _displayTexture : _compositeFramebuffer->getRenderBuffer(0), viewport, viewport); }); swapBuffers(); @@ -765,7 +759,7 @@ float OpenGLDisplayPlugin::presentRate() const { return _presentRate.rate(); } -std::function OpenGLDisplayPlugin::getRefreshRateOperator() { +std::function OpenGLDisplayPlugin::getRefreshRateOperator() { return [](int targetRefreshRate) { auto refreshRateController = DependencyManager::get()->getRefreshRateController(); refreshRateController->setRefreshRateLimitPeriod(targetRefreshRate); @@ -781,7 +775,6 @@ float OpenGLDisplayPlugin::renderRate() const { return _renderRate.rate(); } - void OpenGLDisplayPlugin::swapBuffers() { static auto context = _container->getPrimaryWidget()->context(); context->swapBuffers(); @@ -909,17 +902,10 @@ void OpenGLDisplayPlugin::render(std::function f) { OpenGLDisplayPlugin::~OpenGLDisplayPlugin() { } -// Added this to allow desktop composite framebuffer to be RGBA while mobile is SRGBA -// Overridden by Basic2DWindowDisplayPlugin -// FIXME: Eventually it would be ideal to have both framebuffers be of the same type -gpu::Element OpenGLDisplayPlugin::getCompositeFBColorSpace() { - return gpu::Element::COLOR_RGBA_32; -} - void OpenGLDisplayPlugin::updateCompositeFramebuffer() { auto renderSize = glm::uvec2(getRecommendedRenderSize()); if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) { - _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", getCompositeFBColorSpace(), renderSize.x, renderSize.y)); + _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y)); } } @@ -950,14 +936,13 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); - // maintain aspect ratio, filling the width first if possible. If that makes the height too // much, fill height instead. TODO: only do this when texture changes GLint newX = 0; GLint newY = 0; float aspectRatio = (float)texHeight / (float)texWidth; GLint newWidth = target->width(); - GLint newHeight = std::round(aspectRatio * (float) target->width()); + GLint newHeight = std::round(aspectRatio * (float)target->width()); if (newHeight > target->height()) { newHeight = target->height(); newWidth = std::round((float)target->height() / aspectRatio); @@ -966,7 +951,7 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne newY = (target->height() - newHeight) / 2; } - glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newX + newWidth, newY + newHeight, GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newX + newWidth, newY + newHeight, GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, GL_NEAREST); // don't delete the textures! glDeleteFramebuffers(2, fbo); @@ -975,3 +960,11 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne #endif } +gpu::PipelinePointer OpenGLDisplayPlugin::getRenderTexturePipeline() { + return _drawTexturePipeline; +} + +gpu::PipelinePointer OpenGLDisplayPlugin::getCompositeScenePipeline() { + return _drawTexturePipeline; +} + diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index eae9f86710..777c74822a 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -23,11 +23,9 @@ #include -namespace gpu { - namespace gl { - class GLBackend; - } -} +namespace gpu { namespace gl { +class GLBackend; +}} // namespace gpu::gl class RefreshRateController; @@ -35,10 +33,12 @@ class OpenGLDisplayPlugin : public DisplayPlugin { Q_OBJECT Q_PROPERTY(float hudAlpha MEMBER _hudAlpha) using Parent = DisplayPlugin; + protected: using Mutex = std::mutex; using Lock = std::unique_lock; using Condition = std::condition_variable; + public: ~OpenGLDisplayPlugin(); // These must be final to ensure proper ordering of operations @@ -55,13 +55,9 @@ public: void captureFrame(const std::string& outputName) const override; void submitFrame(const gpu::FramePointer& newFrame) override; - glm::uvec2 getRecommendedRenderSize() const override { - return getSurfacePixels(); - } + glm::uvec2 getRecommendedRenderSize() const override { return getSurfacePixels(); } - glm::uvec2 getRecommendedUiSize() const override { - return getSurfaceSize(); - } + glm::uvec2 getRecommendedUiSize() const override { return getSurfaceSize(); } virtual bool setDisplayTexture(const QString& name) override; virtual bool onDisplayTextureReset() { return false; }; @@ -84,9 +80,10 @@ public: // Three threads, one for rendering, one for texture transfers, one reserved for the GL driver int getRequiredThreadCount() const override { return 3; } - void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override; - virtual std::function getHUDOperator() override; + void copyTextureToQuickFramebuffer(NetworkTexturePointer source, + QOpenGLFramebufferObject* target, + GLsync* fenceSync) override; protected: friend class PresentThread; @@ -105,10 +102,7 @@ protected: virtual void compositeLayers(); virtual void compositeScene(); virtual void compositePointer(); - virtual void compositeExtra() {}; - - virtual gpu::PipelinePointer getCompositeScenePipeline(); - virtual gpu::Element getCompositeFBColorSpace(); + virtual void compositeExtra(){}; // These functions must only be called on the presentation thread virtual void customizeContext(); @@ -125,8 +119,15 @@ protected: // Plugin specific functionality to send the composed scene to the output window or device virtual void internalPresent(); - void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor, const gpu::FramebufferPointer& fbo); - void renderFromTexture(gpu::Batch& batch, const gpu::TexturePointer& texture, const glm::ivec4& viewport, const glm::ivec4& scissor); + void renderFromTexture(gpu::Batch& batch, + const gpu::TexturePointer& texture, + const glm::ivec4& viewport, + const glm::ivec4& scissor, + const gpu::FramebufferPointer& fbo); + void renderFromTexture(gpu::Batch& batch, + const gpu::TexturePointer& texture, + const glm::ivec4& viewport, + const glm::ivec4& scissor); virtual void updateFrameData(); virtual glm::mat4 getViewCorrection() { return glm::mat4(); } @@ -138,7 +139,7 @@ protected: void render(std::function f); - bool _vsyncEnabled { true }; + bool _vsyncEnabled{ true }; QThread* _presentThread{ nullptr }; std::queue _newFrameQueue; RateCounter<200> _droppedFrameRate; @@ -147,7 +148,7 @@ protected: RateCounter<200> _renderRate; gpu::FramePointer _currentFrame; - gpu::Frame* _lastFrame { nullptr }; + gpu::Frame* _lastFrame{ nullptr }; mat4 _prevRenderView; gpu::FramebufferPointer _compositeFramebuffer; gpu::PipelinePointer _hudPipeline; @@ -157,9 +158,11 @@ protected: gpu::PipelinePointer _linearToSRGBPipeline; gpu::PipelinePointer _SRGBToLinearPipeline; gpu::PipelinePointer _cursorPipeline; - gpu::TexturePointer _displayTexture{}; - float _compositeHUDAlpha { 1.0f }; + float _compositeHUDAlpha{ 1.0f }; + + virtual gpu::PipelinePointer getRenderTexturePipeline(); + virtual gpu::PipelinePointer getCompositeScenePipeline(); struct CursorData { QImage image; @@ -169,19 +172,19 @@ protected: }; std::map _cursorsData; - bool _lockCurrentTexture { false }; + bool _lockCurrentTexture{ false }; void assertNotPresentThread() const; void assertIsPresentThread() const; - template + template void withPresentThreadLock(F f) const { assertIsPresentThread(); Lock lock(_presentMutex); f(); } - template + template void withNonPresentThreadLock(F f) const { assertNotPresentThread(); Lock lock(_presentMutex); @@ -198,4 +201,3 @@ protected: QImage getScreenshot(float aspectRatio); QImage getSecondaryCameraScreenshot(); }; - diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index c493588992..f928ccb8a4 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -124,6 +124,11 @@ void OculusDisplayPlugin::uncustomizeContext() { Parent::uncustomizeContext(); } +gpu::PipelinePointer OculusDisplayPlugin::getRenderTexturePipeline() { + //return _SRGBToLinearPipeline; + return _drawTexturePipeline; +} + gpu::PipelinePointer OculusDisplayPlugin::getCompositeScenePipeline() { return _SRGBToLinearPipeline; } diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 8eda599fa9..a892d27534 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -24,6 +24,9 @@ public: virtual QJsonObject getHardwareStats() const; + virtual gpu::PipelinePointer getRenderTexturePipeline() override; + virtual gpu::PipelinePointer getCompositeScenePipeline() override; + protected: QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; } @@ -34,8 +37,6 @@ protected: void uncustomizeContext() override; void cycleDebugOutput() override; - virtual gpu::PipelinePointer getCompositeScenePipeline() override; - private: static const char* NAME; ovrTextureSwapChain _textureSwapChain;