diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 9828a8beda..5e1c720ba3 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -109,6 +109,21 @@ bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() { return Parent::internalActivate(); } +gpu::PipelinePointer Basic2DWindowOpenGLDisplayPlugin::getCompositeScenePipeline() { +#if defined(Q_OS_ANDROID) + return _linearToSRGBPipeline; +#endif + return _SRGBToLinearPipeline; +} + +gpu::Element Basic2DWindowOpenGLDisplayPlugin::getCompositeFBColorSpace() { +#if defined(Q_OS_ANDROID) + return gpu::Element::COLOR_SRGBA_32; +#endif + return gpu::Element::COLOR_RGBA_32; +} + + 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 cc304c19c2..7f654915e1 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -37,6 +37,9 @@ public: virtual void pluginUpdate() override {}; + virtual gpu::PipelinePointer getCompositeScenePipeline() override; + virtual gpu::Element getCompositeFBColorSpace() 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 6c6c2aee80..aa1233ce22 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -48,12 +48,16 @@ #include "CompositorHelper.h" #include "Logging.h" #include "RefreshRateController.h" + +using namespace shader::gpu::program; + extern QThread* RENDER_THREAD; class PresentThread : public QThread, public Dependency { using Mutex = std::mutex; using Condition = std::condition_variable; using Lock = std::unique_lock; + public: PresentThread() { @@ -380,57 +384,45 @@ void OpenGLDisplayPlugin::customizeContext() { } } - if (!_presentPipeline) { + if (!_drawTexturePipeline) { gpu::StatePointer blendState = gpu::StatePointer(new gpu::State()); blendState->setDepthTest(gpu::State::DepthTest(false)); blendState->setBlendFunction(true, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, + gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, + gpu::State::ONE); gpu::StatePointer scissorState = gpu::StatePointer(new gpu::State()); scissorState->setDepthTest(gpu::State::DepthTest(false)); scissorState->setScissorEnable(true); - { -#ifdef Q_OS_ANDROID - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB); -#else - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture); -#endif - _simplePipeline = gpu::Pipeline::create(program, scissorState); - } - { -#ifdef Q_OS_ANDROID - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB); -#else - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaSRGBToLinear); -#endif - _presentPipeline = gpu::Pipeline::create(program, scissorState); - } + _drawTexturePipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), scissorState); - { - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture); - _hudPipeline = gpu::Pipeline::create(program, blendState); - } - { - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX); - _mirrorHUDPipeline = gpu::Pipeline::create(program, blendState); - } + _linearToSRGBPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaLinearToSRGB), scissorState); - { - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTransformedTexture); - _cursorPipeline = gpu::Pipeline::create(program, blendState); - } + _SRGBToLinearPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaSRGBToLinear), scissorState); + + _hudPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), blendState); + + _mirrorHUDPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureMirroredX), blendState); + + _cursorPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTransformedTexture), blendState); } + updateCompositeFramebuffer(); } void OpenGLDisplayPlugin::uncustomizeContext() { - _presentPipeline.reset(); - _cursorPipeline.reset(); + + _drawTexturePipeline.reset(); + _linearToSRGBPipeline.reset(); + _SRGBToLinearPipeline.reset(); _hudPipeline.reset(); _mirrorHUDPipeline.reset(); + _cursorPipeline.reset(); _compositeFramebuffer.reset(); + withPresentThreadLock([&] { _currentFrame.reset(); _lastFrame = nullptr; @@ -535,11 +527,9 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur batch.setStateScissorRect(scissor); batch.setViewportTransform(viewport); batch.setResourceTexture(0, texture); -#ifndef USE_GLES - batch.setPipeline(_presentPipeline); -#else - batch.setPipeline(_simplePipeline); -#endif + + batch.setPipeline(_drawTexturePipeline); + batch.draw(gpu::TRIANGLE_STRIP, 4); if (copyFbo) { gpu::Vec4i copyFboRect(0, 0, copyFbo->getWidth(), copyFbo->getHeight()); @@ -644,6 +634,11 @@ void OpenGLDisplayPlugin::compositePointer() { }); } +// Overridden by Basic2DWindowDisplayPlugin and OculusDisplayPlugin +gpu::PipelinePointer OpenGLDisplayPlugin::getCompositeScenePipeline() { + return _drawTexturePipeline; +} + void OpenGLDisplayPlugin::compositeScene() { render([&](gpu::Batch& batch) { batch.enableStereo(false); @@ -652,7 +647,7 @@ void OpenGLDisplayPlugin::compositeScene() { batch.setStateScissorRect(ivec4(uvec2(), _compositeFramebuffer->getSize())); batch.resetViewTransform(); batch.setProjectionTransform(mat4()); - batch.setPipeline(_simplePipeline); + batch.setPipeline(getCompositeScenePipeline()); batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); }); @@ -924,11 +919,17 @@ 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", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y)); - // _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_SRGBA_32, renderSize.x, renderSize.y)); + _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", getCompositeFBColorSpace(), renderSize.x, renderSize.y)); } } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 562c5af5cf..672d9a4beb 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -106,6 +106,9 @@ protected: virtual void compositePointer(); virtual void compositeExtra() {}; + virtual gpu::PipelinePointer getCompositeScenePipeline(); + virtual gpu::Element getCompositeFBColorSpace(); + // These functions must only be called on the presentation thread virtual void customizeContext(); virtual void uncustomizeContext(); @@ -149,9 +152,11 @@ protected: gpu::PipelinePointer _hudPipeline; gpu::PipelinePointer _mirrorHUDPipeline; gpu::ShaderPointer _mirrorHUDPS; - gpu::PipelinePointer _simplePipeline; - gpu::PipelinePointer _presentPipeline; + gpu::PipelinePointer _drawTexturePipeline; + gpu::PipelinePointer _linearToSRGBPipeline; + gpu::PipelinePointer _SRGBToLinearPipeline; gpu::PipelinePointer _cursorPipeline; + gpu::TexturePointer _displayTexture{}; float _compositeHUDAlpha { 1.0f }; diff --git a/libraries/pointers/src/PickManager.cpp b/libraries/pointers/src/PickManager.cpp index 0cf5f90e3d..aadfbc41a0 100644 --- a/libraries/pointers/src/PickManager.cpp +++ b/libraries/pointers/src/PickManager.cpp @@ -122,22 +122,22 @@ void PickManager::update() { // FIXME: give each type its own expiry // Each type will update at least one pick, regardless of the expiry { - PROFILE_RANGE(picks, "StylusPicks"); + PROFILE_RANGE_EX(picks, "StylusPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Stylus]); PerformanceTimer perfTimer("StylusPicks"); _updatedPickCounts[PickQuery::Stylus] = _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false); } { - PROFILE_RANGE(picks, "RayPicks"); + PROFILE_RANGE_EX(picks, "RayPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Ray]); PerformanceTimer perfTimer("RayPicks"); _updatedPickCounts[PickQuery::Ray] = _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); } { - PROFILE_RANGE(picks, "ParabolaPick"); - PerformanceTimer perfTimer("ParabolaPick"); + PROFILE_RANGE_EX(picks, "ParabolaPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Parabola]); + PerformanceTimer perfTimer("ParabolaPicks"); _updatedPickCounts[PickQuery::Parabola] = _parabolaPickCacheOptimizer.update(cachedPicks[PickQuery::Parabola], _nextPickToUpdate[PickQuery::Parabola], expiry, shouldPickHUD); } { - PROFILE_RANGE(picks, "CollisoinPicks"); + PROFILE_RANGE_EX(picks, "CollisionPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Collision]); PerformanceTimer perfTimer("CollisionPicks"); _updatedPickCounts[PickQuery::Collision] = _collisionPickCacheOptimizer.update(cachedPicks[PickQuery::Collision], _nextPickToUpdate[PickQuery::Collision], expiry, false); } diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index df01591639..c493588992 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -124,6 +124,10 @@ void OculusDisplayPlugin::uncustomizeContext() { Parent::uncustomizeContext(); } +gpu::PipelinePointer OculusDisplayPlugin::getCompositeScenePipeline() { + return _SRGBToLinearPipeline; +} + static const uint64_t FRAME_BUDGET = (11 * USECS_PER_MSEC); static const uint64_t FRAME_OVER_BUDGET = (15 * USECS_PER_MSEC); @@ -163,7 +167,7 @@ void OculusDisplayPlugin::hmdPresent() { batch.setStateScissorRect(ivec4(uvec2(), _outputFramebuffer->getSize())); batch.resetViewTransform(); batch.setProjectionTransform(mat4()); - batch.setPipeline(_presentPipeline); + batch.setPipeline(_drawTexturePipeline); batch.setResourceTexture(0, _compositeFramebuffer->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); }); diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 9209fd373e..8eda599fa9 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -34,6 +34,8 @@ protected: void uncustomizeContext() override; void cycleDebugOutput() override; + virtual gpu::PipelinePointer getCompositeScenePipeline() override; + private: static const char* NAME; ovrTextureSwapChain _textureSwapChain;