Improved OpenGL context implementation

Former-commit-id: 20988bd4a0fa85b7c073a189e71dab25571be617
This commit is contained in:
Lynix 2014-04-25 14:03:01 +02:00
parent 7ac3fee3a5
commit fe8ff688e8
2 changed files with 39 additions and 42 deletions

View File

@ -11,6 +11,8 @@
#include <Nazara/Core/Resource.hpp> #include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceRef.hpp> #include <Nazara/Core/ResourceRef.hpp>
#include <Nazara/Renderer/ContextParameters.hpp> #include <Nazara/Renderer/ContextParameters.hpp>
#include <memory>
#include <vector>
class NzContext; class NzContext;
@ -48,7 +50,8 @@ class NAZARA_API NzContext : public NzResource
NzContextParameters m_parameters; NzContextParameters m_parameters;
NzContextImpl* m_impl = nullptr; NzContextImpl* m_impl = nullptr;
static NzContext* s_reference; static std::unique_ptr<NzContext> s_reference;
static std::vector<std::unique_ptr<NzContext>> s_contexts;
}; };
#endif // NAZARA_CONTEXT_HPP #endif // NAZARA_CONTEXT_HPP

View File

@ -8,6 +8,7 @@
#include <Nazara/Core/StringStream.hpp> #include <Nazara/Core/StringStream.hpp>
#include <Nazara/Renderer/Config.hpp> #include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/OpenGL.hpp> #include <Nazara/Renderer/OpenGL.hpp>
#include <memory>
#include <vector> #include <vector>
#if defined(NAZARA_PLATFORM_WINDOWS) #if defined(NAZARA_PLATFORM_WINDOWS)
@ -22,10 +23,8 @@
namespace namespace
{ {
thread_local const NzContext* currentContext = nullptr; thread_local const NzContext* s_currentContext = nullptr;
thread_local const NzContext* threadContext = nullptr; thread_local const NzContext* s_threadContext = nullptr;
std::vector<NzContext*> contexts;
void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, const void* userParam) void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, const void* userParam)
{ {
@ -141,15 +140,12 @@ bool NzContext::Create(const NzContextParameters& parameters)
m_parameters = parameters; m_parameters = parameters;
if (m_parameters.shared && !m_parameters.shareContext) if (m_parameters.shared && !m_parameters.shareContext)
m_parameters.shareContext = s_reference; m_parameters.shareContext = s_reference.get();
m_impl = new NzContextImpl; std::unique_ptr<NzContextImpl> impl(new NzContextImpl);
if (!m_impl->Create(m_parameters)) if (!impl->Create(m_parameters))
{ {
NazaraError("Failed to create context implementation"); NazaraError("Failed to create context implementation");
delete m_impl;
m_impl = nullptr;
return false; return false;
} }
@ -216,7 +212,7 @@ bool NzContext::IsActive() const
} }
#endif #endif
return currentContext == this; return s_currentContext == this;
} }
bool NzContext::SetActive(bool active) const bool NzContext::SetActive(bool active) const
@ -230,7 +226,7 @@ bool NzContext::SetActive(bool active) const
#endif #endif
// Si le contexte est déjà activé/désactivé // Si le contexte est déjà activé/désactivé
if ((currentContext == this) == active) if ((s_currentContext == this) == active)
return true; return true;
if (active) if (active)
@ -238,17 +234,17 @@ bool NzContext::SetActive(bool active) const
if (!m_impl->Activate()) if (!m_impl->Activate())
return false; return false;
currentContext = this; s_currentContext = this;
} }
else else
{ {
if (!NzContextImpl::Desactivate()) if (!NzContextImpl::Desactivate())
return false; return false;
currentContext = nullptr; s_currentContext = nullptr;
} }
NzOpenGL::OnContextChanged(currentContext); NzOpenGL::OnContextChanged(s_currentContext);
return true; return true;
} }
@ -274,25 +270,23 @@ void NzContext::SwapBuffers()
bool NzContext::EnsureContext() bool NzContext::EnsureContext()
{ {
if (!currentContext) if (!s_currentContext)
{ {
if (!threadContext) if (!s_threadContext)
{ {
NzContext* context = new NzContext; std::unique_ptr<NzContext> context(new NzContext);
if (!context->Create()) if (!context->Create())
{ {
NazaraError("Failed to create context"); NazaraError("Failed to create context");
delete context;
return false; return false;
} }
contexts.push_back(context); s_threadContext = context.get();
threadContext = context; s_contexts.emplace_back(std::move(context));
} }
if (!threadContext->SetActive(true)) if (!s_threadContext->SetActive(true))
{ {
NazaraError("Failed to active thread context"); NazaraError("Failed to active thread context");
return false; return false;
@ -304,19 +298,19 @@ bool NzContext::EnsureContext()
const NzContext* NzContext::GetCurrent() const NzContext* NzContext::GetCurrent()
{ {
return currentContext; return s_currentContext;
} }
const NzContext* NzContext::GetReference() const NzContext* NzContext::GetReference()
{ {
return s_reference; return s_reference.get();
} }
const NzContext* NzContext::GetThreadContext() const NzContext* NzContext::GetThreadContext()
{ {
EnsureContext(); EnsureContext();
return threadContext; return s_threadContext;
} }
bool NzContext::Initialize() bool NzContext::Initialize()
@ -324,32 +318,32 @@ bool NzContext::Initialize()
NzContextParameters parameters; NzContextParameters parameters;
parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même
s_reference = new NzContext; std::unique_ptr<NzContext> reference(new NzContext);
if (!s_reference->Create(parameters)) if (!reference->Create(parameters))
{ {
delete s_reference; NazaraError("Failed to create reference context");
s_reference = nullptr;
return false; return false;
} }
// Le contexte de référence doit rester désactivé pour le partage // Le contexte de référence doit rester désactivé pour le partage
s_reference->SetActive(false); if (!reference->SetActive(false))
{
NazaraError("Failed to desactive reference context");
return false;
}
NzContextParameters::defaultShareContext = s_reference; s_reference = std::move(reference);
// Le contexte de référence est partagé par défaut avec les autres contextes
NzContextParameters::defaultShareContext = s_reference.get();
return true; return true;
} }
void NzContext::Uninitialize() void NzContext::Uninitialize()
{ {
for (NzContext* context : contexts) s_contexts.clear(); // On supprime tous les contextes créés
delete context; s_reference.reset();
contexts.clear(); // On supprime tous les contextes créés
delete s_reference;
s_reference = nullptr;
} }
NzContext* NzContext::s_reference = nullptr; std::unique_ptr<NzContext> NzContext::s_reference;
std::vector<std::unique_ptr<NzContext>> NzContext::s_contexts;