diff --git a/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp b/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp index 068c0c0b5..a6909faa6 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp +++ b/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp @@ -29,8 +29,8 @@ namespace Nz OpenGLDevice(OpenGLDevice&&) = delete; ///TODO? ~OpenGLDevice(); - std::unique_ptr CreateContext(GL::ContextParams params) const; - std::unique_ptr CreateContext(GL::ContextParams params, WindowHandle handle) const; + std::shared_ptr CreateContext(GL::ContextParams params) const; + std::shared_ptr CreateContext(GL::ContextParams params, WindowHandle handle) const; const RenderDeviceInfo& GetDeviceInfo() const override; const RenderDeviceFeatures& GetEnabledFeatures() const override; @@ -62,7 +62,7 @@ namespace Nz private: inline void NotifyContextDestruction(const GL::Context& context) const; - std::unique_ptr m_referenceContext; + std::shared_ptr m_referenceContext; mutable std::unordered_set m_contexts; RenderDeviceInfo m_deviceInfo; GL::Loader& m_loader; diff --git a/include/Nazara/OpenGLRenderer/OpenGLSwapchain.hpp b/include/Nazara/OpenGLRenderer/OpenGLSwapchain.hpp index 5d088ec8f..1bf7ab0b3 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLSwapchain.hpp +++ b/include/Nazara/OpenGLRenderer/OpenGLSwapchain.hpp @@ -45,7 +45,7 @@ namespace Nz std::optional m_renderPass; std::size_t m_currentFrame; std::vector> m_renderImage; - std::unique_ptr m_context; + std::shared_ptr m_context; OpenGLWindowFramebuffer m_framebuffer; Vector2ui m_size; bool m_sizeInvalidated; diff --git a/include/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.hpp b/include/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.hpp index fc877867c..19b1cd550 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.hpp @@ -25,8 +25,8 @@ namespace Nz::GL EGLLoader(const Renderer::Config& config); ~EGLLoader(); - std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const override; - std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override; + std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const override; + std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override; inline EGLDisplay GetDefaultDisplay() const; ContextType GetPreferredContextType() const override; diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp index a79f3696e..39ab0f5e1 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp @@ -31,8 +31,8 @@ namespace Nz::GL Loader() = default; virtual ~Loader(); - virtual std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext = nullptr) const = 0; - virtual std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext = nullptr) const = 0; + virtual std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext = nullptr) const = 0; + virtual std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext = nullptr) const = 0; virtual ContextType GetPreferredContextType() const = 0; diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Shader.inl b/include/Nazara/OpenGLRenderer/Wrapper/Shader.inl index 07666ec12..d0bc828b7 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Shader.inl +++ b/include/Nazara/OpenGLRenderer/Wrapper/Shader.inl @@ -102,7 +102,7 @@ namespace Nz::GL inline void Shader::DestroyHelper(OpenGLDevice& /*device*/, const Context& context, GLuint objectId) { - // context.glDeleteShader(objectId); + context.glDeleteShader(objectId); } } diff --git a/include/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.hpp b/include/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.hpp index 6ba9d90af..05f00388f 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.hpp @@ -24,8 +24,8 @@ namespace Nz::GL WGLLoader(const Renderer::Config& config); ~WGLLoader() = default; - std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const override; - std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override; + std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const override; + std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override; ContextType GetPreferredContextType() const override; diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp index bcf9610c6..1edfe0134 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp @@ -65,9 +65,7 @@ namespace Nz::GL Fallback fallbacks; //< m_ omitted std::unordered_set m_supportedPlatformExtensions; - static EMSCRIPTEN_WEBGL_CONTEXT_HANDLE s_handle; - static size_t s_handleCounter; - bool m_ownsDisplay; + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE m_handle; }; } diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.inl b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.inl index 648a856b8..adc87d62e 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.inl +++ b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.inl @@ -10,8 +10,7 @@ namespace Nz::GL inline WebContext::WebContext(const OpenGLDevice* device, const WebLoader& loader) : Context(device), m_loader(loader), - //m_handle(0), - m_ownsDisplay(false) + m_handle(0) { } diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.hpp index 4f08ff10c..da1d466ce 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.hpp @@ -21,8 +21,8 @@ namespace Nz::GL friend SymbolLoader; public: - std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const override; - std::unique_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override; + std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const override; + std::shared_ptr CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override; ContextType GetPreferredContextType() const override; diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index b402e9e84..cdfd3e29b 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -136,10 +136,7 @@ namespace Nz std::strcpy(m_cpuBrandString.data(), "CPU from unknown vendor - cpuid not supported"); if (!HardwareInfoImpl::IsCpuidSupported()) - { - NazaraWarning("Cpuid is not supported"); return; - } // To begin, we get the id of the constructor and the id of maximal functions supported by the CPUID std::array registers; diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp index 0b18659a7..321cc8c1e 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp @@ -147,14 +147,11 @@ namespace Nz::GL GLenum Context::BindFramebuffer(GLuint fbo) const { - // it looks like emscripten wants us to rebind the FBO everytime -#ifndef NAZARA_PLATFORM_WEB if (m_state.boundDrawFBO == fbo) return GL_DRAW_FRAMEBUFFER; else if (m_state.boundReadFBO == fbo) return GL_READ_FRAMEBUFFER; else -#endif { if (!SetCurrentContext(this)) throw std::runtime_error("failed to activate context"); @@ -169,10 +166,7 @@ namespace Nz::GL void Context::BindFramebuffer(FramebufferTarget target, GLuint fbo) const { auto& currentFbo = (target == FramebufferTarget::Draw) ? m_state.boundDrawFBO : m_state.boundReadFBO; - // it looks like emscripten wants us to rebind the FBO everytime -#ifndef NAZARA_PLATFORM_WEB if (currentFbo != fbo) -#endif { if (!SetCurrentContext(this)) throw std::runtime_error("failed to activate context"); diff --git a/src/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.cpp b/src/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.cpp index a659781b7..509ca943e 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/EGL/EGLLoader.cpp @@ -133,14 +133,14 @@ namespace Nz::GL eglTerminate(m_defaultDisplay); } - std::unique_ptr EGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const + std::shared_ptr EGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const { - std::unique_ptr context; + std::shared_ptr context; #ifdef NAZARA_PLATFORM_WINDOWS // On Windows context sharing seems to work only with window contexts - context = std::make_unique(device, *this); + context = std::make_shared(device, *this); #else - context = std::make_unique(device, *this); + context = std::make_shared(device, *this); #endif if (!context->Create(params, static_cast(shareContext))) @@ -158,9 +158,9 @@ namespace Nz::GL return context; } - std::unique_ptr EGLLoader::CreateContext([[maybe_unused]] const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const + std::shared_ptr EGLLoader::CreateContext([[maybe_unused]] const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const { - std::unique_ptr context; + std::shared_ptr context; switch (handle.type) { case WindowBackend::Invalid: @@ -169,19 +169,19 @@ namespace Nz::GL case WindowBackend::X11: #ifdef NAZARA_PLATFORM_LINUX - context = std::make_unique(device, *this); + context = std::make_shared(device, *this); #endif break; case WindowBackend::Windows: #ifdef NAZARA_PLATFORM_WINDOWS - context = std::make_unique(device, *this); + context = std::make_shared(device, *this); #endif break; case WindowBackend::Wayland: #ifdef NAZARA_PLATFORM_LINUX - context = std::make_unique(device, *this); + context = std::make_shared(device, *this); #endif break; } diff --git a/src/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.cpp b/src/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.cpp index e9257265a..d8071334f 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/WGL/WGLLoader.cpp @@ -93,9 +93,9 @@ namespace Nz::GL throw std::runtime_error("failed to create or initialize base context"); } - std::unique_ptr WGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const + std::shared_ptr WGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const { - auto context = std::make_unique(device, *this); + auto context = std::make_shared(device, *this); if (!context->Create(&m_baseContext, params, static_cast(shareContext))) { NazaraError("failed to create context"); @@ -111,9 +111,9 @@ namespace Nz::GL return context; } - std::unique_ptr WGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const + std::shared_ptr WGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const { - auto context = std::make_unique(device, *this); + auto context = std::make_shared(device, *this); if (!context->Create(&m_baseContext, params, handle, static_cast(shareContext))) { NazaraError("failed to create context"); diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.cpp index 302cc902d..ffe611a1b 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.cpp @@ -25,55 +25,6 @@ namespace Nz::GL m_params = params; - std::size_t configCount; - std::array configs; - if (!ChooseConfig(configs.data(), configs.size(), &configCount)) - return false; - - std::size_t configIndex = 0; - - return CreateInternal(configs[configIndex], shareContext); - } - - bool WebContext::Create(const ContextParams& params, WindowHandle /*window*/, const WebContext* /*shareContext*/) - { - /*NazaraError("Unexpected context creation call"); - return false;*/ - - return Create(params, nullptr); - } - - void WebContext::Destroy() - { - if (s_handle > 0) - { - assert(s_handle > 0); - - OnContextRelease(); - NotifyContextDestruction(this); - - s_handleCounter--; - - if(s_handleCounter == 0) - { - emscripten_webgl_destroy_context(s_handle); - s_handle = 0; - } - } - } - - void WebContext::EnableVerticalSync(bool /*enabled*/) - { - // TODO - } - - void WebContext::SwapBuffers() - { - emscripten_webgl_commit_frame(); - } - - bool WebContext::ChooseConfig(EmscriptenWebGLContextAttributes* configs, std::size_t maxConfigCount, std::size_t* configCount) - { EmscriptenWebGLContextAttributes configAttributes; emscripten_webgl_init_context_attributes(&configAttributes); @@ -93,23 +44,38 @@ namespace Nz::GL configAttributes.renderViaOffscreenBackBuffer = false; // todo configAttributes.proxyContextToMainThread = false; // todo - size_t numConfig = 1; + return CreateInternal(configAttributes, shareContext); + } - configs[0] = configAttributes; + bool WebContext::Create(const ContextParams& params, WindowHandle /*window*/, const WebContext* /*shareContext*/) + { + return Create(params, nullptr); + } - *configCount = numConfig; + void WebContext::Destroy() + { + if (m_handle != 0) + { + OnContextRelease(); + NotifyContextDestruction(this); - return true; + emscripten_webgl_destroy_context(m_handle); + m_handle = 0; + } + } + + void WebContext::EnableVerticalSync(bool /*enabled*/) + { + // TODO + } + + void WebContext::SwapBuffers() + { + emscripten_webgl_commit_frame(); } bool WebContext::CreateInternal(EmscriptenWebGLContextAttributes config, const WebContext* shareContext) { - if(s_handleCounter > 0) - { - s_handleCounter++; - return true; - } - if (shareContext) { NazaraWarning(std::string("shared contexes are not supported by WebGL but shareContext is not null")); @@ -145,8 +111,8 @@ namespace Nz::GL config.majorVersion = version.major; config.minorVersion = version.minor; - s_handle = emscripten_webgl_create_context("canvas", &config); - if (s_handle > 0) + m_handle = emscripten_webgl_create_context("canvas", &config); + if (m_handle > 0) { break; } @@ -158,15 +124,13 @@ namespace Nz::GL return false; } - if (s_handle <= 0) + if (m_handle <= 0) { - NazaraError(std::string("failed to create Web context: ") + WebLoader::TranslateError(static_cast(s_handle))); + NazaraError(std::string("failed to create Web context: ") + WebLoader::TranslateError(static_cast(m_handle))); return false; } LoadExt(); - - s_handleCounter++; return true; } @@ -197,7 +161,7 @@ namespace Nz::GL bool WebContext::Activate() const { - EMSCRIPTEN_RESULT succeeded = emscripten_webgl_make_context_current(s_handle); + EMSCRIPTEN_RESULT succeeded = emscripten_webgl_make_context_current(m_handle); if (succeeded != EMSCRIPTEN_RESULT_SUCCESS) { NazaraError("failed to activate context"); @@ -226,6 +190,8 @@ namespace Nz::GL return false; char* extensionString = emscripten_webgl_get_supported_extensions(); + CallOnExit releaseStr([&] { free(extensionString); }); + if (extensionString) { SplitString(extensionString, " ", [&](std::string_view extension) @@ -234,20 +200,14 @@ namespace Nz::GL std::string ext(extension); - emscripten_webgl_enable_extension(s_handle, ext.c_str()); + emscripten_webgl_enable_extension(m_handle, ext.c_str()); return true; }); } - free(extensionString); - return true; } - - - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE WebContext::s_handle = 0; - size_t WebContext::s_handleCounter = 0; } #if defined(NAZARA_PLATFORM_WINDOWS) diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.cpp index e3b238f6b..c6b7dd9cd 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Web/WebLoader.cpp @@ -43,9 +43,9 @@ namespace Nz::GL WebLoader& loader; }; - std::unique_ptr WebLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const + std::shared_ptr WebLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const { - std::unique_ptr context = std::make_unique(device, *this); + std::shared_ptr context = std::make_shared(device, *this); if (!context->Create(params, static_cast(shareContext))) { @@ -62,25 +62,15 @@ namespace Nz::GL return context; } - std::unique_ptr WebLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const + std::shared_ptr WebLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const { - std::unique_ptr context; - switch (handle.type) - { - case WindowBackend::Invalid: - break; - - case WindowBackend::Web: - context = std::make_unique(device, *this); - break; - } - - if (!context) + if (handle.type != WindowBackend::Web) { NazaraError("unsupported window type"); return {}; } + std::shared_ptr context = std::make_shared(device, *this); if (!context->Create(params, handle, static_cast(shareContext))) { NazaraError("failed to create context"); @@ -103,15 +93,7 @@ namespace Nz::GL GLFunction WebLoader::LoadFunction(const char* name) const { - /*GLFunction func = reinterpret_cast(m_WebLib.GetSymbol(name)); - if (!func && WebGetProcAddress) - func = reinterpret_cast(WebGetProcAddress(name)); - - return func;*/ - return reinterpret_cast(emscripten_webgl_get_proc_address(name)); - - //return nullptr; } const char* WebLoader::TranslateError(EMSCRIPTEN_RESULT errorId) diff --git a/src/Nazara/Platform/SDL2/WindowImpl.cpp b/src/Nazara/Platform/SDL2/WindowImpl.cpp index 0d673e60e..5844c459d 100644 --- a/src/Nazara/Platform/SDL2/WindowImpl.cpp +++ b/src/Nazara/Platform/SDL2/WindowImpl.cpp @@ -196,6 +196,8 @@ namespace Nz { #ifdef NAZARA_PLATFORM_WEB WindowHandle handle; + handle.type = WindowBackend::Web; + return handle; #else SDL_SysWMinfo wmInfo;