diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 47cde80ab3..8d9cdc980a 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -117,9 +117,7 @@ void Application::paintGL() { if (!displayPlugin->areAllProgramsLoaded()) { gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) { - batch.enableStereo(false); batch.setFramebuffer(finalFramebuffer); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 0, 0, 1 }); batch.enableSkybox(true); batch.enableStereo(isStereo); batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index f562efbe22..45e0bbc2a6 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -634,18 +633,26 @@ void OpenGLDisplayPlugin::internalPresent() { _presentRate.increment(); } +std::atomic OpenGLDisplayPlugin::_allProgramsLoaded { false }; +unsigned int OpenGLDisplayPlugin::_currentLoadingProgramIndex { 0 }; + +bool OpenGLDisplayPlugin::areAllProgramsLoaded() const { + return OpenGLDisplayPlugin::_allProgramsLoaded.load(); +} + void OpenGLDisplayPlugin::present() { auto frameId = (uint64_t)presentCount(); PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId) uint64_t startPresent = usecTimestampNow(); - if (!_allProgramsLoaded) { + if (!OpenGLDisplayPlugin::_allProgramsLoaded.load()) { const auto& programIDs = shader::allPrograms(); - if (_currentLoadingProgramIndex < programIDs.size()) { - auto shader = gpu::Shader::createProgram(programIDs.at(_currentLoadingProgramIndex++)); - gpu::gl::GLShader::sync(*getGLBackend(), *shader); + if (OpenGLDisplayPlugin::_currentLoadingProgramIndex < programIDs.size()) { + gpu::doInBatch("createAndSyncProgram", _gpuContext, [&programIDs](gpu::Batch& batch) { + batch.createAndSyncProgram(programIDs.at(OpenGLDisplayPlugin::_currentLoadingProgramIndex++)); + }); } else { - _allProgramsLoaded = true; + OpenGLDisplayPlugin::_allProgramsLoaded.store(true); } } @@ -841,10 +848,6 @@ void OpenGLDisplayPlugin::render(std::function f) { _gpuContext->executeBatch(batch); } -OpenGLDisplayPlugin::OpenGLDisplayPlugin() : DisplayPlugin() { - _allProgramsLoaded = false; -} - OpenGLDisplayPlugin::~OpenGLDisplayPlugin() { } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 1e3983d366..acb12aa69a 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -38,7 +38,6 @@ protected: using Lock = std::unique_lock; using Condition = std::condition_variable; public: - OpenGLDisplayPlugin(); ~OpenGLDisplayPlugin(); // These must be final to ensure proper ordering of operations // between the main thread and the presentation thread @@ -84,6 +83,8 @@ public: void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override; + bool areAllProgramsLoaded() const override; + protected: friend class PresentThread; @@ -182,6 +183,7 @@ protected: mutable Mutex _presentMutex; float _hudAlpha{ 1.0f }; - size_t _currentLoadingProgramIndex { 0 }; + static std::atomic _allProgramsLoaded; + static unsigned int _currentLoadingProgramIndex; }; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index c1ce05c18b..415c5135d9 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -102,6 +102,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::gl::GLBackend::do_pushProfileRange), (&::gpu::gl::GLBackend::do_popProfileRange), + + (&::gpu::gl::GLBackend::do_createAndSyncProgram), }; #define GL_GET_INTEGER(NAME) glGetIntegerv(GL_##NAME, &const_cast(NAME)); @@ -706,6 +708,11 @@ void GLBackend::do_glColor4f(const Batch& batch, size_t paramOffset) { (void)CHECK_GL_ERROR(); } +void GLBackend::do_createAndSyncProgram(const Batch& batch, size_t paramOffset) { + auto shader = gpu::Shader::createProgram(batch._params[paramOffset + 0]._uint); + gpu::gl::GLShader::sync(*this, *shader); +} + void GLBackend::releaseBuffer(GLuint id, Size size) const { Lock lock(_trashMutex); _currentFrameTrash.buffersTrash.push_back({ id, size }); diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 37dde5b08e..0a2c1b92ff 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -380,6 +380,8 @@ public: virtual void do_setStateBlendFactor(const Batch& batch, size_t paramOffset) final; virtual void do_setStateScissorRect(const Batch& batch, size_t paramOffset) final; + virtual void do_createAndSyncProgram(const Batch& batch, size_t paramOffset) final; + virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0; virtual GLuint getTextureID(const TexturePointer& texture) final; virtual GLuint getBufferID(const Buffer& buffer) = 0; diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index e3ea210ecb..43c1c69287 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -760,3 +760,9 @@ void Batch::flush() { buffer->flush(); } } + +void Batch::createAndSyncProgram(unsigned int programID) { + ADD_COMMAND(createAndSyncProgram); + + _params.emplace_back(programID); +} \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 96a45d3111..aff6cf5ddd 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -289,6 +289,8 @@ public: void _glColor4f(float red, float green, float blue, float alpha); + void createAndSyncProgram(unsigned int programID); + // Maybe useful but shoudln't be public. Please convince me otherwise // Well porting to gles i need it... void runLambda(std::function f); @@ -368,6 +370,8 @@ public: COMMAND_pushProfileRange, COMMAND_popProfileRange, + COMMAND_createAndSyncProgram, + NUM_COMMANDS, }; typedef std::vector Commands; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index e925309042..e9fbd71689 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -217,7 +217,7 @@ public: static const QString& MENU_PATH(); - bool areAllProgramsLoaded() { return _allProgramsLoaded; } + virtual bool areAllProgramsLoaded() const { return true; } signals: void recommendedFramebufferSizeChanged(const QSize& size); @@ -235,8 +235,6 @@ protected: float _renderResolutionScale { 1.0f }; - std::atomic _allProgramsLoaded { true }; - private: QMutex _presentMutex; QWaitCondition _presentCondition;