Allowing multiple OpenGL contextes.

This commit is contained in:
Nicolas Pixel Noble 2023-06-25 19:32:07 -07:00
parent 74e62f47b3
commit 4cb379f62e
3 changed files with 30 additions and 5 deletions

View file

@ -123,6 +123,12 @@ extern "C" void pcsxStaticImguiAssert(int exp, const char* msg) {
if (!exp) thrower(msg);
}
static GLFWwindow* getGLFWwindowFromImGuiViewport(ImGuiViewport* viewport) {
// absolutely horrendous hack, but the only way we have to grab the
// GLFWwindow pointer from an ImGuiViewport without changing the backend...
return *reinterpret_cast<GLFWwindow**>(viewport->PlatformUserData);
}
PCSX::GUI* PCSX::GUI::s_gui = nullptr;
void PCSX::GUI::setFullscreen(bool fullscreen) {
@ -516,16 +522,27 @@ void PCSX::GUI::init() {
m_createWindowOldCallback = platform_io.Platform_CreateWindow;
platform_io.Platform_CreateWindow = [](ImGuiViewport* viewport) {
if (s_gui->m_createWindowOldCallback) s_gui->m_createWindowOldCallback(viewport);
// absolutely horrendous hack, but the only way we have to grab the
// newly created GLFWwindow pointer...
auto window = *reinterpret_cast<GLFWwindow**>(viewport->PlatformUserData);
auto window = getGLFWwindowFromImGuiViewport(viewport);
glfwSetKeyCallback(window, glfwKeyCallbackTrampoline);
auto id = viewport->ID;
s_gui->m_nvgSubContextes[id] = nvgCreateSubContextGL(s_gui->m_nvgContext);
};
m_onChangedViewportOldCallback = platform_io.Platform_OnChangedViewport;
platform_io.Platform_OnChangedViewport = [](ImGuiViewport* viewport) {
if (s_gui->m_onChangedViewportOldCallback) s_gui->m_onChangedViewportOldCallback(viewport);
s_gui->changeScale(viewport->DpiScale);
};
m_destroyWindowOldCallback = platform_io.Platform_DestroyWindow;
platform_io.Platform_DestroyWindow = [](ImGuiViewport* viewport) {
auto id = viewport->ID;
auto& subContextes = s_gui->m_nvgSubContextes;
auto subContext = subContextes.find(id);
if (subContext != subContextes.end()) {
nvgDeleteSubContextGL(subContext->second);
subContextes.erase(subContext);
}
if (s_gui->m_destroyWindowOldCallback) s_gui->m_destroyWindowOldCallback(viewport);
};
glfwSetKeyCallback(m_window, glfwKeyCallbackTrampoline);
// Some bad GPU drivers (*cough* Intel) don't like mixed shaders versions,
// and will silently fail to execute them.
@ -656,6 +673,10 @@ void PCSX::GUI::close() {
ImGui::DestroyContext();
glfwDestroyWindow(m_window);
glfwTerminate();
for (auto& subContext : m_nvgSubContextes) {
nvgDeleteSubContextGL(subContext.second);
}
m_nvgSubContextes.clear();
nvgDeleteGLES3(m_nvgContext);
}
@ -1646,6 +1667,7 @@ the update and manually apply it.)")));
glfwGetWindowSize(m_window, &winWidth, &winHeight);
glfwGetFramebufferSize(m_window, &fbWidth, &fbHeight);
pxRatio = (float)fbWidth / (float)winWidth;
nvgSwitchMainContextGL(vg);
nvgBeginFrame(vg, winWidth, winHeight, pxRatio);
while (L.gettop()) L.pop();
L.getfieldtable("nvg", LUA_GLOBALSINDEX);
@ -1687,10 +1709,11 @@ the update and manually apply it.)")));
if (platform_io.Platform_RenderWindow) platform_io.Platform_RenderWindow(viewport, nullptr);
if (platform_io.Renderer_RenderWindow) platform_io.Renderer_RenderWindow(viewport, nullptr);
if (vg) {
auto window = *reinterpret_cast<GLFWwindow**>(viewport->PlatformUserData);
auto window = getGLFWwindowFromImGuiViewport(viewport);
glfwGetWindowSize(window, &winWidth, &winHeight);
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
pxRatio = (float)fbWidth / (float)winWidth;
nvgSwitchSubContextGL(vg, m_nvgSubContextes[viewport->ID]);
nvgBeginFrame(vg, winWidth, winHeight, pxRatio);
L.getfieldtable("nvg", LUA_GLOBALSINDEX);
L.getfield("_processQueueForViewportId", -1);

View file

@ -160,6 +160,7 @@ class GUI final : public UI {
static GUI *s_gui;
void (*m_createWindowOldCallback)(ImGuiViewport *viewport) = nullptr;
void (*m_onChangedViewportOldCallback)(ImGuiViewport *viewport) = nullptr;
void (*m_destroyWindowOldCallback)(ImGuiViewport *viewport) = nullptr;
static void glfwKeyCallbackTrampoline(GLFWwindow *window, int key, int scancode, int action, int mods) {
s_gui->glfwKeyCallback(window, key, scancode, action, mods);
}
@ -304,6 +305,7 @@ class GUI final : public UI {
int &m_glfwSizeY = settings.get<WindowSizeY>().value;
GLuint m_VRAMTexture = 0;
NVGcontext *m_nvgContext = nullptr;
std::map<unsigned, void *> m_nvgSubContextes;
unsigned int m_offscreenFrameBuffer = 0;
unsigned int m_offscreenTextures[2] = {0, 0};

2
third_party/nanovg vendored

@ -1 +1 @@
Subproject commit ad3c1229f7665e2d80db1c768f882f5fae1ae1f5
Subproject commit 7c021819bbd4843a1a3091fe47346d3fcb2a3e1a