Qt: Move some functionalty from OpenGLDisplayWindow into QtDisplayWindow

This commit is contained in:
Connor McLaughlin 2020-01-02 17:45:25 +10:00
parent ac6a7bad3f
commit 9436ffc806
9 changed files with 211 additions and 78 deletions

View File

@ -20,6 +20,8 @@ add_executable(duckstation-qt
opengldisplaywindow.h opengldisplaywindow.h
portsettingswidget.cpp portsettingswidget.cpp
portsettingswidget.h portsettingswidget.h
qtdisplaywindow.cpp
qtdisplaywindow.h
qthostinterface.cpp qthostinterface.cpp
qthostinterface.h qthostinterface.h
qtsettingsinterface.cpp qtsettingsinterface.cpp

View File

@ -36,6 +36,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="consolesettingswidget.cpp" /> <ClCompile Include="consolesettingswidget.cpp" />
<ClCompile Include="qtdisplaywindow.cpp" />
<ClCompile Include="gamelistsettingswidget.cpp" /> <ClCompile Include="gamelistsettingswidget.cpp" />
<ClCompile Include="gamelistwidget.cpp" /> <ClCompile Include="gamelistwidget.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
@ -49,6 +50,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="portsettingswidget.h" /> <QtMoc Include="portsettingswidget.h" />
<QtMoc Include="qtdisplaywindow.h" />
<ClInclude Include="settingwidgetbinder.h" /> <ClInclude Include="settingwidgetbinder.h" />
<QtMoc Include="consolesettingswidget.h" /> <QtMoc Include="consolesettingswidget.h" />
<QtMoc Include="gamelistsettingswidget.h" /> <QtMoc Include="gamelistsettingswidget.h" />
@ -103,6 +105,7 @@
<ClCompile Include="$(IntDir)moc_mainwindow.cpp" /> <ClCompile Include="$(IntDir)moc_mainwindow.cpp" />
<ClCompile Include="$(IntDir)moc_opengldisplaywindow.cpp" /> <ClCompile Include="$(IntDir)moc_opengldisplaywindow.cpp" />
<ClCompile Include="$(IntDir)moc_portsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_portsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_qtdisplaywindow.cpp" />
<ClCompile Include="$(IntDir)moc_qthostinterface.cpp" /> <ClCompile Include="$(IntDir)moc_qthostinterface.cpp" />
<ClCompile Include="$(IntDir)moc_settingsdialog.cpp" /> <ClCompile Include="$(IntDir)moc_settingsdialog.cpp" />
<ClCompile Include="$(IntDir)qrc_icons.cpp" /> <ClCompile Include="$(IntDir)qrc_icons.cpp" />
@ -255,7 +258,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
@ -276,7 +279,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
@ -297,7 +300,7 @@
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks> <BasicRuntimeChecks>Default</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
@ -320,7 +323,7 @@
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks> <BasicRuntimeChecks>Default</BasicRuntimeChecks>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
@ -342,7 +345,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
@ -364,7 +367,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x86\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
@ -388,7 +391,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
@ -410,7 +413,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\YBaseLib\Include;$(SolutionDir)dep\glad\Include;$(SolutionDir)dep\imgui\include;$(SolutionDir)src;$(SolutionDir)dep\msvc\qt5-x64\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>

View File

@ -21,11 +21,13 @@
<ClCompile Include="$(IntDir)qrc_icons.cpp" /> <ClCompile Include="$(IntDir)qrc_icons.cpp" />
<ClCompile Include="portsettingswidget.cpp" /> <ClCompile Include="portsettingswidget.cpp" />
<ClCompile Include="$(IntDir)moc_portsettingswidget.cpp" /> <ClCompile Include="$(IntDir)moc_portsettingswidget.cpp" />
<ClCompile Include="qtdisplaywindow.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="qtsettingsinterface.h" /> <ClInclude Include="qtsettingsinterface.h" />
<ClInclude Include="qtutils.h" /> <ClInclude Include="qtutils.h" />
<ClInclude Include="settingwidgetbinder.h" /> <ClInclude Include="settingwidgetbinder.h" />
<ClInclude Include="qtdisplaywindow.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="resources"> <Filter Include="resources">

View File

@ -1,9 +1,11 @@
#include "opengldisplaywindow.h" #include "opengldisplaywindow.h"
#include "YBaseLib/Assert.h" #include "YBaseLib/Assert.h"
#include "YBaseLib/Log.h" #include "YBaseLib/Log.h"
#include "imgui.h"
#include "qthostinterface.h" #include "qthostinterface.h"
#include <QtGui/QKeyEvent> #include <QtGui/QKeyEvent>
#include <array> #include <array>
#include <imgui_impl_opengl3.h>
#include <tuple> #include <tuple>
Log_SetChannel(OpenGLDisplayWindow); Log_SetChannel(OpenGLDisplayWindow);
@ -95,13 +97,18 @@ private:
}; };
OpenGLDisplayWindow::OpenGLDisplayWindow(QtHostInterface* host_interface, QWindow* parent) OpenGLDisplayWindow::OpenGLDisplayWindow(QtHostInterface* host_interface, QWindow* parent)
: QWindow(parent), m_host_interface(host_interface) : QtDisplayWindow(host_interface, parent)
{ {
setSurfaceType(QWindow::OpenGLSurface); setSurfaceType(QWindow::OpenGLSurface);
} }
OpenGLDisplayWindow::~OpenGLDisplayWindow() = default; OpenGLDisplayWindow::~OpenGLDisplayWindow() = default;
HostDisplay* OpenGLDisplayWindow::getHostDisplayInterface()
{
return this;
}
HostDisplay::RenderAPI OpenGLDisplayWindow::GetRenderAPI() const HostDisplay::RenderAPI OpenGLDisplayWindow::GetRenderAPI() const
{ {
return HostDisplay::RenderAPI::OpenGL; return HostDisplay::RenderAPI::OpenGL;
@ -114,7 +121,7 @@ void* OpenGLDisplayWindow::GetRenderDevice() const
void* OpenGLDisplayWindow::GetRenderContext() const void* OpenGLDisplayWindow::GetRenderContext() const
{ {
return m_gl_context; return m_gl_context.get();
} }
void* OpenGLDisplayWindow::GetRenderWindow() const void* OpenGLDisplayWindow::GetRenderWindow() const
@ -178,7 +185,7 @@ void OpenGLDisplayWindow::SetVSync(bool enabled)
GLint current_fbo = 0; GLint current_fbo = 0;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
SetSwapInterval(this, m_gl_context, enabled ? 1 : 0); SetSwapInterval(this, m_gl_context.get(), enabled ? 1 : 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo);
} }
@ -190,15 +197,6 @@ std::tuple<u32, u32> OpenGLDisplayWindow::GetWindowSize() const
void OpenGLDisplayWindow::WindowResized() {} void OpenGLDisplayWindow::WindowResized() {}
void OpenGLDisplayWindow::keyPressEvent(QKeyEvent* event)
{
m_host_interface->handleKeyEvent(event->key(), true);
}
void OpenGLDisplayWindow::keyReleaseEvent(QKeyEvent* event)
{
m_host_interface->handleKeyEvent(event->key(), false);
}
const char* OpenGLDisplayWindow::GetGLSLVersionString() const const char* OpenGLDisplayWindow::GetGLSLVersionString() const
{ {
@ -238,9 +236,9 @@ static void APIENTRY GLDebugCallback(GLenum source, GLenum type, GLuint id, GLen
} }
} }
bool OpenGLDisplayWindow::createGLContext(QThread* worker_thread) bool OpenGLDisplayWindow::createDeviceContext(QThread* worker_thread)
{ {
m_gl_context = new QOpenGLContext(); m_gl_context = std::make_unique<QOpenGLContext>();
// Prefer a desktop OpenGL context where possible. If we can't get this, try OpenGL ES. // Prefer a desktop OpenGL context where possible. If we can't get this, try OpenGL ES.
static constexpr std::array<std::tuple<int, int>, 11> desktop_versions_to_try = { static constexpr std::array<std::tuple<int, int>, 11> desktop_versions_to_try = {
@ -293,16 +291,21 @@ bool OpenGLDisplayWindow::createGLContext(QThread* worker_thread)
if (!m_gl_context->isValid()) if (!m_gl_context->isValid())
{ {
Log_ErrorPrintf("Failed to create any GL context"); Log_ErrorPrintf("Failed to create any GL context");
delete m_gl_context; m_gl_context.reset();
m_gl_context = nullptr;
return false; return false;
} }
if (!m_gl_context->makeCurrent(this)) if (!m_gl_context->makeCurrent(this))
{ {
Log_ErrorPrintf("Failed to make GL context current on UI thread"); Log_ErrorPrintf("Failed to make GL context current on UI thread");
delete m_gl_context; m_gl_context.reset();
m_gl_context = nullptr; return false;
}
if (!QtDisplayWindow::createDeviceContext(worker_thread))
{
m_gl_context->doneCurrent();
m_gl_context.reset();
return false; return false;
} }
@ -311,12 +314,12 @@ bool OpenGLDisplayWindow::createGLContext(QThread* worker_thread)
return true; return true;
} }
bool OpenGLDisplayWindow::initializeGLContext() bool OpenGLDisplayWindow::initializeDeviceContext()
{ {
if (!m_gl_context->makeCurrent(this)) if (!m_gl_context->makeCurrent(this))
return false; return false;
s_thread_gl_context = m_gl_context; s_thread_gl_context = m_gl_context.get();
// Load GLAD. // Load GLAD.
const auto load_result = const auto load_result =
@ -324,6 +327,8 @@ bool OpenGLDisplayWindow::initializeGLContext()
if (!load_result) if (!load_result)
{ {
Log_ErrorPrintf("Failed to load GL functions"); Log_ErrorPrintf("Failed to load GL functions");
s_thread_gl_context = nullptr;
m_gl_context->doneCurrent();
return false; return false;
} }
@ -336,7 +341,7 @@ bool OpenGLDisplayWindow::initializeGLContext()
} }
#endif #endif
if (!CreateImGuiContext() || !CreateGLResources()) if (!QtDisplayWindow::initializeDeviceContext())
{ {
s_thread_gl_context = nullptr; s_thread_gl_context = nullptr;
m_gl_context->doneCurrent(); m_gl_context->doneCurrent();
@ -346,31 +351,37 @@ bool OpenGLDisplayWindow::initializeGLContext()
return true; return true;
} }
void OpenGLDisplayWindow::destroyGLContext() void OpenGLDisplayWindow::destroyDeviceContext()
{ {
Assert(m_gl_context && s_thread_gl_context == m_gl_context); Assert(m_gl_context && s_thread_gl_context == m_gl_context.get());
QtDisplayWindow::destroyDeviceContext();
s_thread_gl_context = nullptr; s_thread_gl_context = nullptr;
if (m_display_vao != 0)
glDeleteVertexArrays(1, &m_display_vao);
if (m_display_linear_sampler != 0)
glDeleteSamplers(1, &m_display_linear_sampler);
if (m_display_nearest_sampler != 0)
glDeleteSamplers(1, &m_display_nearest_sampler);
m_display_program.Destroy();
m_gl_context->doneCurrent(); m_gl_context->doneCurrent();
delete m_gl_context; m_gl_context.reset();
m_gl_context = nullptr;
} }
bool OpenGLDisplayWindow::CreateImGuiContext() bool OpenGLDisplayWindow::createImGuiContext()
{ {
if (!QtDisplayWindow::createImGuiContext())
return false;
if (!ImGui_ImplOpenGL3_Init(GetGLSLVersionString()))
return false;
ImGui_ImplOpenGL3_NewFrame();
return true; return true;
} }
bool OpenGLDisplayWindow::CreateGLResources() void OpenGLDisplayWindow::destroyImGuiContext()
{
ImGui_ImplOpenGL3_Shutdown();
QtDisplayWindow::destroyImGuiContext();
}
bool OpenGLDisplayWindow::createDeviceResources()
{ {
static constexpr char fullscreen_quad_vertex_shader[] = R"( static constexpr char fullscreen_quad_vertex_shader[] = R"(
uniform vec4 u_src_rect; uniform vec4 u_src_rect;
@ -430,6 +441,20 @@ void main()
return true; return true;
} }
void OpenGLDisplayWindow::destroyDeviceResources()
{
QtDisplayWindow::destroyDeviceResources();
if (m_display_vao != 0)
glDeleteVertexArrays(1, &m_display_vao);
if (m_display_linear_sampler != 0)
glDeleteSamplers(1, &m_display_linear_sampler);
if (m_display_nearest_sampler != 0)
glDeleteSamplers(1, &m_display_nearest_sampler);
m_display_program.Destroy();
}
void OpenGLDisplayWindow::Render() void OpenGLDisplayWindow::Render()
{ {
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
@ -437,20 +462,21 @@ void OpenGLDisplayWindow::Render()
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
RenderDisplay(); renderDisplay();
// ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImDrawData* draw_data = ImGui::GetDrawData();
if (draw_data)
ImGui_ImplOpenGL3_RenderDrawData(draw_data);
m_gl_context->makeCurrent(this); m_gl_context->makeCurrent(this);
m_gl_context->swapBuffers(this); m_gl_context->swapBuffers(this);
// ImGui_ImplSDL2_NewFrame(m_window); ImGui_ImplOpenGL3_NewFrame();
// ImGui_ImplOpenGL3_NewFrame();
GL::Program::ResetLastProgram(); GL::Program::ResetLastProgram();
} }
void OpenGLDisplayWindow::RenderDisplay() void OpenGLDisplayWindow::renderDisplay()
{ {
if (!m_display_texture_id) if (!m_display_texture_id)
return; return;
@ -477,3 +503,4 @@ void OpenGLDisplayWindow::RenderDisplay()
glDrawArrays(GL_TRIANGLES, 0, 3); glDrawArrays(GL_TRIANGLES, 0, 3);
glBindSampler(0, 0); glBindSampler(0, 0);
} }

View File

@ -1,17 +1,16 @@
#pragma once #pragma once
#include <glad.h> #include <glad.h>
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
#include "common/gl/program.h" #include "common/gl/program.h"
#include "common/gl/texture.h" #include "common/gl/texture.h"
#include "core/host_display.h" #include "core/host_display.h"
#include <string> #include "qtdisplaywindow.h"
#include <QtGui/QOpenGLContext>
#include <memory> #include <memory>
class QtHostInterface; class QtHostInterface;
class OpenGLDisplayWindow final : public QWindow, public HostDisplay class OpenGLDisplayWindow final : public QtDisplayWindow, public HostDisplay
{ {
Q_OBJECT Q_OBJECT
@ -19,9 +18,11 @@ public:
OpenGLDisplayWindow(QtHostInterface* host_interface, QWindow* parent); OpenGLDisplayWindow(QtHostInterface* host_interface, QWindow* parent);
~OpenGLDisplayWindow(); ~OpenGLDisplayWindow();
bool createGLContext(QThread* worker_thread); HostDisplay* getHostDisplayInterface() override;
bool initializeGLContext();
void destroyGLContext(); bool createDeviceContext(QThread* worker_thread) override;
bool initializeDeviceContext() override;
void destroyDeviceContext() override;
RenderAPI GetRenderAPI() const override; RenderAPI GetRenderAPI() const override;
void* GetRenderDevice() const override; void* GetRenderDevice() const override;
@ -45,23 +46,20 @@ public:
std::tuple<u32, u32> GetWindowSize() const override; std::tuple<u32, u32> GetWindowSize() const override;
void WindowResized() override; void WindowResized() override;
protected: void Render() override;
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
private: private:
const char* GetGLSLVersionString() const; const char* GetGLSLVersionString() const;
std::string GetGLSLVersionHeader() const; std::string GetGLSLVersionHeader() const;
bool CreateImGuiContext(); bool createImGuiContext() override;
bool CreateGLResources(); void destroyImGuiContext() override;
bool createDeviceResources() override;
void destroyDeviceResources() override;
void Render(); void renderDisplay();
void RenderDisplay();
QtHostInterface* m_host_interface; std::unique_ptr<QOpenGLContext> m_gl_context = nullptr;
QOpenGLContext* m_gl_context = nullptr;
GL::Program m_display_program; GL::Program m_display_program;
GLuint m_display_vao = 0; GLuint m_display_vao = 0;

View File

@ -0,0 +1,65 @@
#include "qtdisplaywindow.h"
#include "imgui.h"
#include "qthostinterface.h"
#include <QtGui/QKeyEvent>
QtDisplayWindow::QtDisplayWindow(QtHostInterface* host_interface, QWindow* parent)
: QWindow(parent), m_host_interface(host_interface)
{
}
QtDisplayWindow::~QtDisplayWindow() = default;
HostDisplay* QtDisplayWindow::getHostDisplayInterface()
{
return nullptr;
}
bool QtDisplayWindow::createDeviceContext(QThread* worker_thread)
{
return true;
}
bool QtDisplayWindow::initializeDeviceContext()
{
if (!createImGuiContext() || !createDeviceResources())
return false;
return true;
}
void QtDisplayWindow::destroyDeviceContext()
{
destroyImGuiContext();
destroyDeviceResources();
}
bool QtDisplayWindow::createImGuiContext()
{
ImGui::CreateContext();
return true;
}
void QtDisplayWindow::destroyImGuiContext()
{
ImGui::DestroyContext();
}
bool QtDisplayWindow::createDeviceResources()
{
return true;
}
void QtDisplayWindow::destroyDeviceResources() {}
void QtDisplayWindow::Render() {}
void QtDisplayWindow::keyPressEvent(QKeyEvent* event)
{
m_host_interface->handleKeyEvent(event->key(), true);
}
void QtDisplayWindow::keyReleaseEvent(QKeyEvent* event)
{
m_host_interface->handleKeyEvent(event->key(), false);
}

View File

@ -0,0 +1,36 @@
#pragma once
#include <QtGui/QWindow>
class QKeyEvent;
class HostDisplay;
class QtHostInterface;
class QtDisplayWindow : public QWindow
{
Q_OBJECT
public:
QtDisplayWindow(QtHostInterface* host_interface, QWindow* parent);
virtual ~QtDisplayWindow();
virtual HostDisplay* getHostDisplayInterface();
virtual bool createDeviceContext(QThread* worker_thread);
virtual bool initializeDeviceContext();
virtual void destroyDeviceContext();
virtual void Render();
protected:
virtual bool createImGuiContext();
virtual void destroyImGuiContext();
virtual bool createDeviceResources();
virtual void destroyDeviceResources();
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
QtHostInterface* m_host_interface;
};

View File

@ -24,7 +24,7 @@ QtHostInterface::QtHostInterface(QObject* parent)
QtHostInterface::~QtHostInterface() QtHostInterface::~QtHostInterface()
{ {
Assert(!m_opengl_display_window); Assert(!m_display_window);
stopThread(); stopThread();
} }
@ -129,24 +129,24 @@ void QtHostInterface::refreshGameList(bool invalidate_cache /*= false*/)
QWidget* QtHostInterface::createDisplayWidget(QWidget* parent) QWidget* QtHostInterface::createDisplayWidget(QWidget* parent)
{ {
m_opengl_display_window = new OpenGLDisplayWindow(this, nullptr); m_display_window = new OpenGLDisplayWindow(this, nullptr);
m_display.release(); m_display.release();
m_display = std::unique_ptr<HostDisplay>(static_cast<HostDisplay*>(m_opengl_display_window)); m_display = std::unique_ptr<HostDisplay>(m_display_window->getHostDisplayInterface());
return QWidget::createWindowContainer(m_opengl_display_window, parent); return QWidget::createWindowContainer(m_display_window, parent);
} }
void QtHostInterface::destroyDisplayWidget() void QtHostInterface::destroyDisplayWidget()
{ {
m_display.release(); m_display.release();
delete m_opengl_display_window; delete m_display_window;
m_opengl_display_window = nullptr; m_display_window = nullptr;
} }
void QtHostInterface::bootSystem(QString initial_filename, QString initial_save_state_filename) void QtHostInterface::bootSystem(QString initial_filename, QString initial_save_state_filename)
{ {
emit emulationStarting(); emit emulationStarting();
if (!m_opengl_display_window->createGLContext(m_worker_thread)) if (!m_display_window->createDeviceContext(m_worker_thread))
{ {
emit emulationStopped(); emit emulationStopped();
return; return;
@ -252,7 +252,7 @@ void QtHostInterface::powerOffSystem()
} }
m_system.reset(); m_system.reset();
m_opengl_display_window->destroyGLContext(); m_display_window->destroyDeviceContext();
emit emulationStopped(); emit emulationStopped();
} }
@ -290,7 +290,7 @@ void QtHostInterface::changeDisc(QString new_disc_filename) {}
void QtHostInterface::doBootSystem(QString initial_filename, QString initial_save_state_filename) void QtHostInterface::doBootSystem(QString initial_filename, QString initial_save_state_filename)
{ {
if (!m_opengl_display_window->initializeGLContext()) if (!m_display_window->initializeDeviceContext())
{ {
emit emulationStopped(); emit emulationStopped();
return; return;
@ -305,7 +305,7 @@ void QtHostInterface::doBootSystem(QString initial_filename, QString initial_sav
!BootSystem(initial_filename_str.empty() ? nullptr : initial_filename_str.c_str(), !BootSystem(initial_filename_str.empty() ? nullptr : initial_filename_str.c_str(),
initial_save_state_filename_str.empty() ? nullptr : initial_save_state_filename_str.c_str())) initial_save_state_filename_str.empty() ? nullptr : initial_save_state_filename_str.c_str()))
{ {
m_opengl_display_window->destroyGLContext(); m_display_window->destroyDeviceContext();
emit emulationStopped(); emit emulationStopped();
return; return;
} }

View File

@ -92,7 +92,7 @@ private:
std::unique_ptr<GameList> m_game_list; std::unique_ptr<GameList> m_game_list;
OpenGLDisplayWindow* m_opengl_display_window = nullptr; QtDisplayWindow* m_display_window = nullptr;
QThread* m_original_thread = nullptr; QThread* m_original_thread = nullptr;
Thread* m_worker_thread = nullptr; Thread* m_worker_thread = nullptr;