start actually implementing multi-window feature, still rough around the edges

fix crash when closing main window if sub windows are involved

fix OpenGL context handling, still need to fix when changing display type
This commit is contained in:
Arisotura 2024-10-27 01:14:29 +02:00
parent f375099613
commit 881a740cab
8 changed files with 49 additions and 33 deletions

View File

@ -199,6 +199,10 @@ void EmuInstance::createWindow()
numWindows++;
emuThread->attachWindow(win);
// if creating a secondary window, we may need to initialize its OpenGL context here
if (win->hasOpenGL() && (win != topWindow))
emuThread->initContext(id);
}
void EmuInstance::deleteWindow(int id, bool close)
@ -208,12 +212,8 @@ void EmuInstance::deleteWindow(int id, bool close)
MainWindow* win = windowList[id];
if (!win) return;
if (win->hasOpenGL() && win == mainWindow)
{
// we intentionally don't unpause here
emuThread->emuPause();
emuThread->deinitContext();
}
if (win->hasOpenGL())
emuThread->deinitContext(id);
emuThread->detachWindow(win);
@ -226,9 +226,10 @@ void EmuInstance::deleteWindow(int id, bool close)
if (close)
win->close();
if ((!mainWindow) && (!deleting))
if (numWindows == 0)
{
// if we closed this instance's main window, delete the instance
// if we closed the last window, delete the instance
// if the main window is closed, Qt will take care of closing any secondary windows
deleteEmuInstance(instanceID);
}
}
@ -292,24 +293,18 @@ bool EmuInstance::usesOpenGL()
(globalCfg.GetInt("3D.Renderer") != renderer3D_Software);
}
void EmuInstance::initOpenGL()
void EmuInstance::initOpenGL(int win)
{
for (int i = 0; i < kMaxWindows; i++)
{
if (windowList[i])
windowList[i]->initOpenGL();
}
if (windowList[win])
windowList[win]->initOpenGL();
setVSyncGL(true);
}
void EmuInstance::deinitOpenGL()
void EmuInstance::deinitOpenGL(int win)
{
for (int i = 0; i < kMaxWindows; i++)
{
if (windowList[i])
windowList[i]->deinitOpenGL();
}
if (windowList[win])
windowList[win]->deinitOpenGL();
}
void EmuInstance::setVSyncGL(bool vsync)

View File

@ -103,8 +103,8 @@ public:
void emuStop(melonDS::Platform::StopReason reason);
bool usesOpenGL();
void initOpenGL();
void deinitOpenGL();
void initOpenGL(int win);
void deinitOpenGL(int win);
void setVSyncGL(bool vsync);
void makeCurrentGL();
void drawScreenGL();

View File

@ -115,7 +115,7 @@ void EmuThread::run()
if (emuInstance->usesOpenGL())
{
emuInstance->initOpenGL();
emuInstance->initOpenGL(0);
useOpenGL = true;
videoRenderer = globalCfg.GetInt("3D.Renderer");
@ -547,12 +547,12 @@ void EmuThread::handleMessages()
break;
case msg_InitGL:
emuInstance->initOpenGL();
emuInstance->initOpenGL(msg.param.value<int>());
useOpenGL = true;
break;
case msg_DeInitGL:
emuInstance->deinitOpenGL();
emuInstance->deinitOpenGL(msg.param.value<int>());
useOpenGL = false;
break;
@ -650,15 +650,15 @@ void EmuThread::changeWindowTitle(char* title)
emit windowTitleChange(QString(title));
}
void EmuThread::initContext()
void EmuThread::initContext(int win)
{
sendMessage(msg_InitGL);
sendMessage({.type = msg_InitGL, .param = win});
waitMessage();
}
void EmuThread::deinitContext()
void EmuThread::deinitContext(int win)
{
sendMessage(msg_DeInitGL);
sendMessage({.type = msg_DeInitGL, .param = win});
waitMessage();
}

View File

@ -127,8 +127,8 @@ public:
bool emuIsRunning();
bool emuIsActive();
void initContext();
void deinitContext();
void initContext(int win);
void deinitContext(int win);
void updateVideoSettings() { videoSettingsDirty = true; }
void updateVideoRenderer() { videoSettingsDirty = true; lastVideoRenderer = -1; }

View File

@ -736,6 +736,8 @@ ScreenPanelGL::ScreenPanelGL(QWidget* parent) : ScreenPanel(parent)
setAttribute(Qt::WA_KeyCompression, false);
setFocusPolicy(Qt::StrongFocus);
setMinimumSize(screenGetMinSize());
glInited = false;
}
ScreenPanelGL::~ScreenPanelGL()
@ -781,6 +783,7 @@ void ScreenPanelGL::setSwapInterval(int intv)
void ScreenPanelGL::initOpenGL()
{
if (!glContext) return;
if (glInited) return;
glContext->MakeCurrent();
@ -877,11 +880,13 @@ void ScreenPanelGL::initOpenGL()
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0));
transferLayout();
glInited = true;
}
void ScreenPanelGL::deinitOpenGL()
{
if (!glContext) return;
if (!glInited) return;
glDeleteTextures(1, &screenTexture);
@ -906,6 +911,7 @@ void ScreenPanelGL::deinitOpenGL()
glContext->DoneCurrent();
lastScreenWidth = lastScreenHeight = -1;
glInited = false;
}
void ScreenPanelGL::makeCurrentGL()

View File

@ -197,6 +197,7 @@ private:
void setupScreenLayout() override;
std::unique_ptr<GL::Context> glContext;
bool glInited;
GLuint screenVertexBuffer, screenVertexArray;
GLuint screenTexture;

View File

@ -588,6 +588,13 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) :
}
}
menu->addSeparator();
actNewWindow = menu->addAction("Open new window");
connect(actNewWindow, &QAction::triggered, this, &MainWindow::onOpenNewWindow);
menu->addSeparator();
actScreenFiltering = menu->addAction("Screen filtering");
actScreenFiltering->setCheckable(true);
connect(actScreenFiltering, &QAction::triggered, this, &MainWindow::onChangeScreenFiltering);
@ -1950,6 +1957,11 @@ void MainWindow::onChangeIntegerScaling(bool checked)
emit screenLayoutChange();
}
void MainWindow::onOpenNewWindow()
{
emuInstance->createWindow();
}
void MainWindow::onChangeScreenFiltering(bool checked)
{
windowCfg.SetBool("ScreenFilter", checked);
@ -2077,7 +2089,7 @@ void MainWindow::onUpdateVideoSettings(bool glchange)
if (glchange)
{
emuThread->emuPause();
if (hasOGL) emuThread->deinitContext();
if (hasOGL) emuThread->deinitContext(windowID);
delete panel;
createScreenPanel();
@ -2088,7 +2100,7 @@ void MainWindow::onUpdateVideoSettings(bool glchange)
if (glchange)
{
if (hasOGL) emuThread->initContext();
if (hasOGL) emuThread->initContext(windowID);
emuThread->emuUnpause();
}
}

View File

@ -208,6 +208,7 @@ private slots:
void onChangeScreenSizing(QAction* act);
void onChangeScreenAspect(QAction* act);
void onChangeIntegerScaling(bool checked);
void onOpenNewWindow();
void onChangeScreenFiltering(bool checked);
void onChangeShowOSD(bool checked);
void onChangeLimitFramerate(bool checked);
@ -325,6 +326,7 @@ public:
QAction** actScreenAspectTop;
QActionGroup* grpScreenAspectBot;
QAction** actScreenAspectBot;
QAction* actNewWindow;
QAction* actScreenFiltering;
QAction* actShowOSD;
QAction* actLimitFramerate;