More SDL GL context refactor

This commit is contained in:
Henrik Rydgård committed 2026-08-03 17:52:56 +02:00
1 parent 1c0740c4b9
commit 0f4f1d7091
4 files changed
+74 -76

No files matched your search

+5
View File
@@ -5,6 +5,7 @@
"name": "(gdb) Launch PPSSPPSDL (WSL)", "name": "(gdb) Launch PPSSPPSDL (WSL)",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"preLaunchTask": "Build PPSSPP (WSL debug)",
"program": "/home/hrydg/ppsspp/build/PPSSPPSDL", "program": "/home/hrydg/ppsspp/build/PPSSPPSDL",
"osx": { "osx": {
"program": "${workspaceFolder}/build/PPSSPPSDL.app/Contents/MacOS/PPSSPPSDL" "program": "${workspaceFolder}/build/PPSSPPSDL.app/Contents/MacOS/PPSSPPSDL"
@@ -20,6 +21,10 @@
}, },
"environment": [], "environment": [],
"externalConsole": false, "externalConsole": false,
"internalConsoleOptions": "openOnSessionStart",
"logging": {
"programOutput": true
},
"MIMode": "gdb", "MIMode": "gdb",
"pipeTransport": { "pipeTransport": {
"pipeProgram": "wsl.exe", "pipeProgram": "wsl.exe",
+33 -43
View File
@@ -286,12 +286,15 @@ void EGL_Close() {
#endif // USING_EGL #endif // USING_EGL
SDL_Window *CreateSDLGLWindowAndContext(int x, int y, int w, int h, int mode, int forceGLVersion, SDL_GLContext *glContextOut) {
// We start hidden because we have to try several windows.
// TODO: All this stuff doesn't really belong here. // On Mac, full screen animates so each attempt is slow.
bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *data2, std::string *error_message) { mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
SDL_Window *window = *(SDL_Window **)data1; SDL_Window *window = SDL_CreateWindow("Initializing graphics...", w, h, (SDL_WindowFlags)mode);
int mode = (int)(uintptr_t)data2; if (!window) {
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
exit(1);
}
struct GLVersionPair { struct GLVersionPair {
int major; int major;
int minor; int minor;
@@ -305,24 +308,14 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
#endif #endif
}; };
// We start hidden because we have to try several windows. SDL_GLContext glContext{};
// On Mac, full screen animates so each attempt is slow.
mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
int x;
int y;
int w;
int h;
SDL_GetWindowPosition(window, &x, &y);
SDL_GetWindowSize(window, &w, &h);
glContext_ = nullptr;
for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) { for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) {
const auto &ver = attemptVersions[i]; const auto &ver = attemptVersions[i];
// If we force a specific OpenGL version, skip the ones // If we force a specific OpenGL version, skip the ones
// that do not match, which may be all of them - e.g. // that do not match, which may be all of them - e.g.
// requesting nonsensical "--graphics=opengl0" reliably // requesting nonsensical "--graphics=opengl0" reliably
// skips straight to fallback code below. // skips straight to fallback code below.
if (force_gl_version_ >= 0 && 10 * ver.major + ver.minor != force_gl_version_) if (forceGLVersion >= 0 && 10 * ver.major + ver.minor != forceGLVersion)
continue; continue;
// Make sure to request a somewhat modern GL context at least - the // Make sure to request a somewhat modern GL context at least - the
// latest supported by MacOS X (really, really sad...) // latest supported by MacOS X (really, really sad...)
@@ -345,12 +338,8 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
continue; continue;
} }
if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) { glContext = SDL_GL_CreateContext(window);
SDL_SetWindowPosition(window, x, y); if (glContext != nullptr) {
}
glContext_ = SDL_GL_CreateContext(window);
if (glContext_ != nullptr) {
// Victory, got one. // Victory, got one.
break; break;
} }
@@ -360,7 +349,7 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
} }
if (glContext_ == nullptr) { if (glContext == nullptr) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
@@ -368,28 +357,22 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
window = SDL_CreateWindow("PPSSPP", w, h, (SDL_WindowFlags)mode); window = SDL_CreateWindow("PPSSPP", w, h, (SDL_WindowFlags)mode);
if (window == nullptr) { if (window == nullptr) {
NativeShutdown();
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
SDL_Quit(); return nullptr;
return false;
} }
if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) { glContext = SDL_GL_CreateContext(window);
SDL_SetWindowPosition(window, x, y); if (glContext == nullptr) {
}
glContext_ = SDL_GL_CreateContext(window);
if (glContext_ == nullptr) {
// OK, now we really have tried everything. // OK, now we really have tried everything.
NativeShutdown();
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError()); fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
SDL_Quit(); return nullptr;
return false;
} }
} }
// At this point, we have a window that we can show finally. // For some reason we have to set the position here, can't wait until after the window is shown (??).
SDL_ShowWindow(window); if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) {
SDL_SetWindowPosition(window, x, y);
}
#ifdef USING_EGL #ifdef USING_EGL
if (EGL_Open(window) != 0) { if (EGL_Open(window) != 0) {
@@ -411,7 +394,7 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
// glx is not required, igore. // glx is not required, igore.
if (glew_err != GLEW_OK && glew_err != GLEW_ERROR_NO_GLX_DISPLAY) { if (glew_err != GLEW_OK && glew_err != GLEW_ERROR_NO_GLX_DISPLAY) {
fprintf(stderr, "Failed to initialize glew!\n"); fprintf(stderr, "Failed to initialize glew!\n");
return false; return nullptr;
} }
// Unfortunately, glew will generate an invalid enum error, ignore. // Unfortunately, glew will generate an invalid enum error, ignore.
if (gl_extensions.IsCoreContext) if (gl_extensions.IsCoreContext)
@@ -421,9 +404,17 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
fprintf(stderr, "OpenGL 2.0 or higher.\n"); fprintf(stderr, "OpenGL 2.0 or higher.\n");
} else { } else {
fprintf(stderr, "Sorry, this program requires OpenGL 2.0.\n"); fprintf(stderr, "Sorry, this program requires OpenGL 2.0.\n");
return false; return nullptr;
} }
#endif #endif
*glContextOut = glContext;
return window;
}
bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *data2, std::string *error_message) {
SDL_Window *window = (SDL_Window *)data1;
SDL_GLContext glContext = (SDL_GLContext)data2;
glContext_ = glContext;
// Finally we can do the regular initialization. // Finally we can do the regular initialization.
CheckGLExtensions(); CheckGLExtensions();
@@ -443,7 +434,6 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
SDL_GL_SwapWindow(window_); SDL_GL_SwapWindow(window_);
#endif #endif
}); });
renderManager_->SetSwapIntervalFunction([&](int interval) { renderManager_->SetSwapIntervalFunction([&](int interval) {
INFO_LOG(Log::G3D, "SDL SwapInterval: %d", interval); INFO_LOG(Log::G3D, "SDL SwapInterval: %d", interval);
SDL_GL_SetSwapInterval(interval); SDL_GL_SetSwapInterval(interval);
@@ -459,7 +449,7 @@ void SDLGLGraphicsContext::ShutdownSurface() {
renderManager_ = nullptr; renderManager_ = nullptr;
} }
bool SDLGLGraphicsContext::InitAPI(void *wnd, std::string *deviceName, std::string *errorMessage) { bool SDLGLGraphicsContext::InitAPI(void *ctx, std::string *deviceName, std::string *errorMessage) {
return true; return true;
} }
+4 -3
View File
@@ -9,13 +9,13 @@
class SDLGLGraphicsContext : public GraphicsContext { class SDLGLGraphicsContext : public GraphicsContext {
public: public:
SDLGLGraphicsContext(int force_gl_version) : force_gl_version_(force_gl_version) {} SDLGLGraphicsContext() {}
bool InitAPI(void *wnd, std::string *deviceName, std::string *errorMessage) override; bool InitAPI(void *wnd, std::string *deviceName, std::string *errorMessage) override;
void ShutdownAPI() override; void ShutdownAPI() override;
// Returns 0 on success. // Returns 0 on success.
// data1 should be a *pointer* to the SDL_Window pointer, data2 is the SDL_WindowFlags. // data1 should be the SDL_Window pointer, data2 is the SDL_WindowFlags.
bool InitSurface(WindowSystem winsys, void *data1, void *data2, std::string *error_message) override; bool InitSurface(WindowSystem winsys, void *data1, void *data2, std::string *error_message) override;
void ShutdownSurface() override; void ShutdownSurface() override;
@@ -43,6 +43,7 @@ private:
Draw::DrawContext *draw_ = nullptr; Draw::DrawContext *draw_ = nullptr;
SDL_Window *window_ = nullptr; SDL_Window *window_ = nullptr;
SDL_GLContext glContext_ = nullptr; SDL_GLContext glContext_ = nullptr;
int force_gl_version_ = 0;
GLRenderManager *renderManager_ = nullptr; GLRenderManager *renderManager_ = nullptr;
}; };
SDL_Window *CreateSDLGLWindowAndContext(int x, int y, int w, int h, int mode, int forceGLVersion, SDL_GLContext *glContextOut);
+32 -30
View File
@@ -2031,9 +2031,6 @@ int main(int argc, char *argv[]) {
h = g_Config.iWindowHeight; h = g_Config.iWindowHeight;
} }
GraphicsContext *graphicsContext = nullptr;
SDL_Window *window = nullptr;
// Switch away from Vulkan if not available. // Switch away from Vulkan if not available.
int fallbackGPUBackend = -1; int fallbackGPUBackend = -1;
switch ((GPUBackend)g_Config.iGPUBackend) { switch ((GPUBackend)g_Config.iGPUBackend) {
@@ -2055,54 +2052,56 @@ int main(int argc, char *argv[]) {
break; break;
} }
SDL_Window *window = nullptr;
auto initializeBackend = [&](GPUBackend backend, GraphicsContext **graphicsContext, std::string *errorMessage) -> bool { auto initializeBackend = [&](GPUBackend backend, GraphicsContext **graphicsContext, std::string *errorMessage) -> bool {
// Surface init params. // Surface init params.
WindowSystem windowSystem = WINDOWSYSTEM_NONE; WindowSystem windowSystem = WINDOWSYSTEM_NONE;
void *data1 = &window; void *data1 = nullptr;
void *data2 = (void *)(uintptr_t)mode; void *data2 = nullptr;
GraphicsContext *ctx = nullptr;
if (backend == GPUBackend::OPENGL) { if (backend == GPUBackend::OPENGL) {
mode |= SDL_WINDOW_OPENGL; SDL_GLContext glContext = nullptr;
window = SDL_CreateWindow("Initializing graphics...", w, h, (SDL_WindowFlags)mode); window = CreateSDLGLWindowAndContext(x, y, w, h, mode, cmdLineOptions.force_gl_version, &glContext);
if (!window) {
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
exit(1);
}
SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext(cmdLineOptions.force_gl_version); data1 = (void *)window;
*graphicsContext = glctx; data2 = (void *)glContext;
glctx->InitAPI(nullptr, nullptr, errorMessage); ctx = new SDLGLGraphicsContext();
if (!glctx->InitSurface(windowSystem, data1, data2, errorMessage)) {
fprintf(stderr, "OpenGL surface creation failed: %s\n", errorMessage->c_str());
return false;
}
} else { } else {
mode |= SDL_WINDOW_VULKAN; mode |= SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN;
window = SDL_CreateWindow("Initializing graphics...", w, h, (SDL_WindowFlags)mode); window = SDL_CreateWindow("Initializing graphics...", w, h, (SDL_WindowFlags)mode);
if (!window) { if (!window) {
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError()); fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
exit(1); exit(1);
} }
if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) {
SDL_SetWindowPosition(window, x, y);
}
// Overwrite the surface init params with what we need for Vulkan.. // Overwrite the surface init params with what we need for Vulkan..
if (!DetermineVulkanWindowSystem(window, &windowSystem, &data1, &data2)) { if (!DetermineVulkanWindowSystem(window, &windowSystem, &data1, &data2)) {
return false; return false;
} }
// NOTE : This should match the lines below in the Vulkan case. // NOTE : This should match the lines below in the Vulkan case.
VulkanGraphicsContext *vkctx = new VulkanGraphicsContext(); ctx = new VulkanGraphicsContext();
if (!vkctx->InitAPI(nullptr, &g_Config.sVulkanDevice, errorMessage)) {
fprintf(stderr, "Vulkan initialization failed: %s\n", errorMessage->c_str());
return false;
}
if (!vkctx->InitSurface(windowSystem, data1, data2, errorMessage)) {
fprintf(stderr, "Vulkan surface creation failed: %s\n", errorMessage->c_str());
return false;
}
*graphicsContext = vkctx;
} }
if (!ctx->InitAPI(nullptr, &g_Config.sVulkanDevice, errorMessage)) {
fprintf(stderr, "Graphics initialization failed: %s\n", errorMessage->c_str());
return false;
}
if (!ctx->InitSurface(windowSystem, data1, data2, errorMessage)) {
fprintf(stderr, "Surface creation failed: %s\n", errorMessage->c_str());
return false;
}
*graphicsContext = ctx;
return true; return true;
}; };
GraphicsContext *graphicsContext = nullptr;
std::string error_message; std::string error_message;
if (!initializeBackend((GPUBackend)g_Config.iGPUBackend, &graphicsContext, &error_message)) { if (!initializeBackend((GPUBackend)g_Config.iGPUBackend, &graphicsContext, &error_message)) {
fprintf(stderr, "Failed to initialize graphics backend: %s\n", error_message.c_str()); fprintf(stderr, "Failed to initialize graphics backend: %s\n", error_message.c_str());
@@ -2112,18 +2111,21 @@ int main(int argc, char *argv[]) {
error_message.clear(); error_message.clear();
if (!initializeBackend((GPUBackend)g_Config.iGPUBackend, &graphicsContext, &error_message)) { if (!initializeBackend((GPUBackend)g_Config.iGPUBackend, &graphicsContext, &error_message)) {
fprintf(stderr, "Fallback failed: %s\n", error_message.c_str()); fprintf(stderr, "Fallback failed: %s\n", error_message.c_str());
SDL_Quit();
return 1; return 1;
} }
} else { } else {
fprintf(stderr, "No fallback GPU backend available. Exiting.\n"); fprintf(stderr, "No fallback GPU backend available. Exiting.\n");
SDL_Quit();
return 1; return 1;
} }
} }
// At this point, we have a window that we can show finally.
SDL_ShowWindow(window);
if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) { if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) {
SDL_SetWindowPosition(window, x, y); SDL_SetWindowPosition(window, x, y);
} }
UpdateScreenDPI(window); UpdateScreenDPI(window);
float dpi_scale = 1.0f / (g_ForcedDPI == 0.0f ? g_DesktopDPI : g_ForcedDPI); float dpi_scale = 1.0f / (g_ForcedDPI == 0.0f ? g_DesktopDPI : g_ForcedDPI);