From 349e915e10805bffbd859fc414fa52c9ac324ccf Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 19 Apr 2020 15:33:36 +0200 Subject: [PATCH] OpenGL: Link contexts to device --- include/Nazara/OpenGLRenderer/OpenGLDevice.hpp | 8 ++++++++ include/Nazara/OpenGLRenderer/OpenGLDevice.inl | 11 +++++++++++ include/Nazara/OpenGLRenderer/Wrapper/Context.hpp | 10 ++++++++-- include/Nazara/OpenGLRenderer/Wrapper/Context.inl | 9 +++++++++ include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp | 9 +++++++-- .../OpenGLRenderer/Wrapper/Win32/WGLContext.hpp | 2 +- .../OpenGLRenderer/Wrapper/Win32/WGLContext.inl | 6 ++++++ .../OpenGLRenderer/Wrapper/Win32/WGLLoader.hpp | 4 ++-- src/Nazara/OpenGLRenderer/OpenGLDevice.cpp | 14 +++++++++++--- src/Nazara/OpenGLRenderer/Wrapper/Context.cpp | 9 +++++++++ .../OpenGLRenderer/Wrapper/Win32/WGLContext.cpp | 5 ----- .../OpenGLRenderer/Wrapper/Win32/WGLLoader.cpp | 12 ++++++------ 12 files changed, 78 insertions(+), 21 deletions(-) diff --git a/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp b/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp index a7d599f98..2434549b2 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp +++ b/include/Nazara/OpenGLRenderer/OpenGLDevice.hpp @@ -12,12 +12,15 @@ #include #include #include +#include #include namespace Nz { class NAZARA_OPENGLRENDERER_API OpenGLDevice : public RenderDevice { + friend GL::Context; + public: OpenGLDevice(GL::Loader& loader); OpenGLDevice(const OpenGLDevice&) = delete; @@ -37,11 +40,16 @@ namespace Nz std::unique_ptr InstantiateTexture(const TextureInfo& params) override; std::unique_ptr InstantiateTextureSampler(const TextureSamplerInfo& params) override; + inline void NotifyTextureDestruction(GLuint texture) const; + OpenGLDevice& operator=(const OpenGLDevice&) = delete; OpenGLDevice& operator=(OpenGLDevice&&) = delete; ///TODO? private: + inline void NotifyContextDestruction(const GL::Context& context) const; + std::unique_ptr m_referenceContext; + mutable std::unordered_set m_contexts; GL::Loader& m_loader; }; } diff --git a/include/Nazara/OpenGLRenderer/OpenGLDevice.inl b/include/Nazara/OpenGLRenderer/OpenGLDevice.inl index 1dc0fe4ac..0c77347a6 100644 --- a/include/Nazara/OpenGLRenderer/OpenGLDevice.inl +++ b/include/Nazara/OpenGLRenderer/OpenGLDevice.inl @@ -11,6 +11,17 @@ namespace Nz { return *m_referenceContext; } + + inline void OpenGLDevice::NotifyTextureDestruction(GLuint texture) const + { + for (const GL::Context* context : m_contexts) + context->NotifyTextureDestruction(texture); + } + + inline void OpenGLDevice::NotifyContextDestruction(const GL::Context& context) const + { + m_contexts.erase(&context); + } } #include diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp index 17cb668cf..691099911 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp @@ -14,6 +14,11 @@ #include #include +namespace Nz +{ + class OpenGLDevice; +} + namespace Nz::GL { enum class ContextType @@ -55,13 +60,13 @@ namespace Nz::GL class Context { public: - Context() = default; + inline Context(const OpenGLDevice* device); virtual ~Context(); - virtual bool Activate() = 0; virtual void EnableVerticalSync(bool enabled) = 0; + inline const OpenGLDevice* GetDevice() const; inline ExtensionStatus GetExtensionStatus(Extension extension) const; inline const ContextParams& GetParams() const; @@ -95,6 +100,7 @@ namespace Nz::GL std::array m_extensionStatus; std::unordered_set m_supportedExtensions; + const OpenGLDevice* m_device; }; } diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Context.inl b/include/Nazara/OpenGLRenderer/Wrapper/Context.inl index c384dbc31..ff296f5ec 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Context.inl +++ b/include/Nazara/OpenGLRenderer/Wrapper/Context.inl @@ -7,6 +7,15 @@ namespace Nz::GL { + inline Context::Context(const OpenGLDevice* device) : + m_device(device) + { + } + + inline const OpenGLDevice* Context::GetDevice() const + { + return m_device; + } inline ExtensionStatus Context::GetExtensionStatus(Extension extension) const { diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp index 13eeafb53..2db76c99c 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Loader.hpp @@ -13,6 +13,11 @@ #include #include +namespace Nz +{ + class OpenGLDevice; +} + namespace Nz::GL { class Context; @@ -25,8 +30,8 @@ namespace Nz::GL Loader() = default; virtual ~Loader(); - virtual std::unique_ptr CreateContext(const ContextParams& params, Context* shareContext = nullptr) const = 0; - virtual std::unique_ptr CreateContext(const ContextParams& params, WindowHandle handle, Context* shareContext = nullptr) const = 0; + 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 GLFunction LoadFunction(const char* name) const = 0; }; diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.hpp index 7c300a92c..7f684af03 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.hpp @@ -26,7 +26,7 @@ namespace Nz::GL class WGLContext : public Context { public: - WGLContext(const WGLLoader& loader); + inline WGLContext(const OpenGLDevice* device, const WGLLoader& loader); WGLContext(const WGLContext&) = delete; WGLContext(WGLContext&&) = delete; ~WGLContext(); diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.inl b/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.inl index a4bdc6bda..5dc6e0b31 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.inl +++ b/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.inl @@ -7,6 +7,12 @@ namespace Nz::GL { + inline GL::WGLContext::WGLContext(const OpenGLDevice* device, const WGLLoader& loader) : + Context(device), + m_loader(loader) + { + } + inline bool WGLContext::HasPlatformExtension(const std::string& str) const { return m_supportedPlatformExtensions.find(str) != m_supportedPlatformExtensions.end(); diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.hpp index a733233af..e5ad9395d 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.hpp @@ -24,8 +24,8 @@ namespace Nz::GL WGLLoader(DynLib& openglLib); ~WGLLoader() = default; - std::unique_ptr CreateContext(const ContextParams& params, Context* shareContext) const override; - std::unique_ptr CreateContext(const ContextParams& params, WindowHandle handle, Context* shareContext) const override; + 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; GLFunction LoadFunction(const char* name) const override; diff --git a/src/Nazara/OpenGLRenderer/OpenGLDevice.cpp b/src/Nazara/OpenGLRenderer/OpenGLDevice.cpp index afc0da3d5..a5df5efcb 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLDevice.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLDevice.cpp @@ -14,21 +14,29 @@ namespace Nz OpenGLDevice::OpenGLDevice(GL::Loader& loader) : m_loader(loader) { - m_referenceContext = loader.CreateContext({}); + m_referenceContext = loader.CreateContext(this, {}); if (!m_referenceContext) throw std::runtime_error("failed to create reference context"); + + m_contexts.insert(m_referenceContext.get()); } OpenGLDevice::~OpenGLDevice() = default; std::unique_ptr OpenGLDevice::CreateContext(const GL::ContextParams& params) const { - return m_loader.CreateContext(params, m_referenceContext.get()); + auto contextPtr = m_loader.CreateContext(this, params, m_referenceContext.get()); + m_contexts.insert(contextPtr.get()); + + return contextPtr; } std::unique_ptr OpenGLDevice::CreateContext(const GL::ContextParams& params, WindowHandle handle) const { - return m_loader.CreateContext(params, handle, m_referenceContext.get()); + auto contextPtr = m_loader.CreateContext(this, params, handle, m_referenceContext.get()); + m_contexts.insert(contextPtr.get()); + + return contextPtr; } std::unique_ptr OpenGLDevice::InstantiateBuffer(BufferType type) diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp index 08e8077db..4259b8924 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp @@ -4,8 +4,11 @@ #include #include +#include #include +#include #include +#include #include #include @@ -13,6 +16,12 @@ namespace Nz::GL { thread_local const Context* s_currentContext = nullptr; + Context::~Context() + { + if (m_device) + m_device->NotifyContextDestruction(*this); + } + bool Context::Initialize(const ContextParams& params) { diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.cpp index d732a5da6..8f056bc62 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLContext.cpp @@ -12,11 +12,6 @@ namespace Nz::GL { - GL::WGLContext::WGLContext(const WGLLoader& loader) : - m_loader(loader) - { - } - WGLContext::~WGLContext() { Destroy(); diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.cpp index bc37dc061..e30bde76b 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Win32/WGLLoader.cpp @@ -11,7 +11,7 @@ namespace Nz::GL { WGLLoader::WGLLoader(DynLib& openglLib) : m_opengl32Lib(openglLib), - m_baseContext(*this) + m_baseContext(nullptr, *this) { if (!m_gdi32Lib.Load("gdi32.dll")) throw std::runtime_error("failed to load gdi32.dll: " + m_gdi32Lib.GetLastError()); @@ -42,7 +42,7 @@ namespace Nz::GL #undef NAZARA_OPENGLRENDERER_EXT_FUNC // In order to load OpenGL functions, we have to create a context first - WGLContext loadContext(*this); + WGLContext loadContext(nullptr, *this); if (!loadContext.Create(nullptr, {})) throw std::runtime_error("failed to create load context"); @@ -56,9 +56,9 @@ namespace Nz::GL throw std::runtime_error("failed to load OpenGL functions"); } - std::unique_ptr WGLLoader::CreateContext(const ContextParams& params, Context* shareContext) const + std::unique_ptr WGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const { - auto context = std::make_unique(*this); + auto context = std::make_unique(device, *this); if (!context->Create(&m_baseContext, params, static_cast(shareContext))) { NazaraError("failed to create context"); @@ -74,9 +74,9 @@ namespace Nz::GL return context; } - std::unique_ptr WGLLoader::CreateContext(const ContextParams& params, WindowHandle handle, Context* shareContext) const + std::unique_ptr WGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const { - auto context = std::make_unique(*this); + auto context = std::make_unique(device, *this); if (!context->Create(&m_baseContext, params, handle, static_cast(shareContext))) { NazaraError("failed to create context");