mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
More SDL GL context refactor
This commit is contained in:
1 parent
1c0740c4b9
commit
0f4f1d7091
4 files changed
+73
-75
No files matched your search
Vendored
+5
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user