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
+73 -75

No files matched your search

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