mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Allow re-creation of the shared context as a core context if the user indicates they want a core profile context. Sharing of compatibility and core profile contexts is not possible on macOS which is why we need to have a way to re-create the shared context as a core context if required in this case.
This commit is contained in:
parent
3f4bc3683b
commit
ac98be760b
@ -212,6 +212,55 @@ namespace
|
||||
// Supported OpenGL extensions
|
||||
std::vector<std::string> extensions;
|
||||
|
||||
// Load our extensions vector with the supported extensions
|
||||
void loadExtensions()
|
||||
{
|
||||
extensions.clear();
|
||||
|
||||
// Check whether a >= 3.0 context is available
|
||||
int majorVersion = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
|
||||
|
||||
if (glGetError() == GL_INVALID_ENUM)
|
||||
{
|
||||
// Try to load the < 3.0 way
|
||||
const char* extensionString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
|
||||
|
||||
do
|
||||
{
|
||||
const char* extension = extensionString;
|
||||
|
||||
while (*extensionString && (*extensionString != ' '))
|
||||
extensionString++;
|
||||
|
||||
extensions.push_back(std::string(extension, extensionString));
|
||||
}
|
||||
while (*extensionString++);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to load the >= 3.0 way
|
||||
glGetStringiFuncType glGetStringiFunc = NULL;
|
||||
glGetStringiFunc = reinterpret_cast<glGetStringiFuncType>(sf::priv::GlContext::getFunction("glGetStringi"));
|
||||
|
||||
if (glGetStringiFunc)
|
||||
{
|
||||
int numExtensions = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
|
||||
|
||||
if (numExtensions)
|
||||
{
|
||||
for (unsigned int i = 0; i < static_cast<unsigned int>(numExtensions); ++i)
|
||||
{
|
||||
const char* extensionString = reinterpret_cast<const char*>(glGetStringiFunc(GL_EXTENSIONS, i));
|
||||
|
||||
extensions.push_back(extensionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to parse OpenGL version strings
|
||||
bool parseVersionString(const char* version, const char* prefix, unsigned int &major, unsigned int &minor)
|
||||
{
|
||||
@ -260,50 +309,7 @@ void GlContext::initResource()
|
||||
sharedContext->initialize(ContextSettings());
|
||||
|
||||
// Load our extensions vector
|
||||
extensions.clear();
|
||||
|
||||
// Check whether a >= 3.0 context is available
|
||||
int majorVersion = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
|
||||
|
||||
if (glGetError() == GL_INVALID_ENUM)
|
||||
{
|
||||
// Try to load the < 3.0 way
|
||||
const char* extensionString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
|
||||
|
||||
do
|
||||
{
|
||||
const char* extension = extensionString;
|
||||
|
||||
while(*extensionString && (*extensionString != ' '))
|
||||
extensionString++;
|
||||
|
||||
extensions.push_back(std::string(extension, extensionString));
|
||||
}
|
||||
while (*extensionString++);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to load the >= 3.0 way
|
||||
glGetStringiFuncType glGetStringiFunc = NULL;
|
||||
glGetStringiFunc = reinterpret_cast<glGetStringiFuncType>(getFunction("glGetStringi"));
|
||||
|
||||
if (glGetStringiFunc)
|
||||
{
|
||||
int numExtensions = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
|
||||
|
||||
if (numExtensions)
|
||||
{
|
||||
for (unsigned int i = 0; i < static_cast<unsigned int>(numExtensions); ++i)
|
||||
{
|
||||
const char* extensionString = reinterpret_cast<const char*>(glGetStringiFunc(GL_EXTENSIONS, i));
|
||||
|
||||
extensions.push_back(extensionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loadExtensions();
|
||||
|
||||
// Deactivate the shared context so that others can activate it when necessary
|
||||
sharedContext->setActive(false);
|
||||
@ -417,6 +423,25 @@ GlContext* GlContext::create(const ContextSettings& settings, const WindowImpl*
|
||||
|
||||
Lock lock(mutex);
|
||||
|
||||
// If resourceCount is 1 we know that we are inside sf::Context or sf::Window
|
||||
// Only in this situation we allow the user to indirectly re-create the shared context as a core context
|
||||
|
||||
// Check if we need to convert our shared context into a core context
|
||||
if ((resourceCount == 1) &&
|
||||
(settings.attributeFlags & ContextSettings::Core) &&
|
||||
!(sharedContext->m_settings.attributeFlags & ContextSettings::Core))
|
||||
{
|
||||
// Re-create our shared context as a core context
|
||||
ContextSettings sharedSettings(0, 0, 0, settings.majorVersion, settings.minorVersion, settings.attributeFlags);
|
||||
|
||||
delete sharedContext;
|
||||
sharedContext = new ContextType(NULL, sharedSettings, 1, 1);
|
||||
sharedContext->initialize(sharedSettings);
|
||||
|
||||
// Reload our extensions vector
|
||||
loadExtensions();
|
||||
}
|
||||
|
||||
GlContext* context = NULL;
|
||||
|
||||
// We don't use acquireTransientContext here since we have
|
||||
@ -446,6 +471,25 @@ GlContext* GlContext::create(const ContextSettings& settings, unsigned int width
|
||||
|
||||
Lock lock(mutex);
|
||||
|
||||
// If resourceCount is 1 we know that we are inside sf::Context or sf::Window
|
||||
// Only in this situation we allow the user to indirectly re-create the shared context as a core context
|
||||
|
||||
// Check if we need to convert our shared context into a core context
|
||||
if ((resourceCount == 1) &&
|
||||
(settings.attributeFlags & ContextSettings::Core) &&
|
||||
!(sharedContext->m_settings.attributeFlags & ContextSettings::Core))
|
||||
{
|
||||
// Re-create our shared context as a core context
|
||||
ContextSettings sharedSettings(0, 0, 0, settings.majorVersion, settings.minorVersion, settings.attributeFlags);
|
||||
|
||||
delete sharedContext;
|
||||
sharedContext = new ContextType(NULL, sharedSettings, 1, 1);
|
||||
sharedContext->initialize(sharedSettings);
|
||||
|
||||
// Reload our extensions vector
|
||||
loadExtensions();
|
||||
}
|
||||
|
||||
GlContext* context = NULL;
|
||||
|
||||
// We don't use acquireTransientContext here since we have
|
||||
|
@ -84,19 +84,15 @@ m_deviceContext(NULL),
|
||||
m_context (NULL),
|
||||
m_ownsWindow (false)
|
||||
{
|
||||
// TODO: Delegate to the other constructor in C++11
|
||||
|
||||
// Save the creation settings
|
||||
m_settings = ContextSettings();
|
||||
|
||||
// Make sure that extensions are initialized if this is not the shared context
|
||||
// The shared context is the context used to initialize the extensions
|
||||
if (shared && shared->m_deviceContext)
|
||||
ensureExtensionsInit(shared->m_deviceContext);
|
||||
|
||||
// Create the rendering surface (window or pbuffer if supported)
|
||||
createSurface(shared, 1, 1, VideoMode::getDesktopMode().bitsPerPixel);
|
||||
|
||||
// Create the context
|
||||
if (m_deviceContext)
|
||||
createContext(shared);
|
||||
}
|
||||
|
||||
@ -112,16 +108,10 @@ m_ownsWindow (false)
|
||||
// Save the creation settings
|
||||
m_settings = settings;
|
||||
|
||||
// Make sure that extensions are initialized if this is not the shared context
|
||||
// The shared context is the context used to initialize the extensions
|
||||
if (shared && shared->m_deviceContext)
|
||||
ensureExtensionsInit(shared->m_deviceContext);
|
||||
|
||||
// Create the rendering surface from the owner window
|
||||
createSurface(owner->getSystemHandle(), bitsPerPixel);
|
||||
|
||||
// Create the context
|
||||
if (m_deviceContext)
|
||||
createContext(shared);
|
||||
}
|
||||
|
||||
@ -137,16 +127,10 @@ m_ownsWindow (false)
|
||||
// Save the creation settings
|
||||
m_settings = settings;
|
||||
|
||||
// Make sure that extensions are initialized if this is not the shared context
|
||||
// The shared context is the context used to initialize the extensions
|
||||
if (shared && shared->m_deviceContext)
|
||||
ensureExtensionsInit(shared->m_deviceContext);
|
||||
|
||||
// Create the rendering surface (window or pbuffer if supported)
|
||||
createSurface(shared, width, height, VideoMode::getDesktopMode().bitsPerPixel);
|
||||
|
||||
// Create the context
|
||||
if (m_deviceContext)
|
||||
createContext(shared);
|
||||
}
|
||||
|
||||
@ -594,6 +578,10 @@ void WglContext::createSurface(HWND window, unsigned int bitsPerPixel)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WglContext::createContext(WglContext* shared)
|
||||
{
|
||||
// We can't create an OpenGL context if we don't have a DC
|
||||
if (!m_deviceContext)
|
||||
return;
|
||||
|
||||
// Get a working copy of the context settings
|
||||
ContextSettings settings = m_settings;
|
||||
|
||||
@ -730,6 +718,15 @@ void WglContext::createContext(WglContext* shared)
|
||||
err() << "Failed to share the OpenGL context: " << getErrorString(GetLastError()).toAnsiString() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are the shared context, initialize extensions now
|
||||
// This enables us to re-create the shared context using extensions if we need to
|
||||
if (!shared && m_context)
|
||||
{
|
||||
makeCurrent(true);
|
||||
ensureExtensionsInit(m_deviceContext);
|
||||
makeCurrent(false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
Loading…
Reference in New Issue
Block a user