summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-02-18 03:29:12 +0100
committerbunnei <bunneidev@gmail.com>2020-02-26 03:23:01 +0100
commite25297536f975db307f7117b3060e9919c44be52 (patch)
tree80e2f2b7e577fe3b16521b0f6f28e38a352b97b0 /src
parentfrontend: qt: bootmanager: OpenGL: Implement separate presentation thread. (diff)
downloadyuzu-e25297536f975db307f7117b3060e9919c44be52.tar
yuzu-e25297536f975db307f7117b3060e9919c44be52.tar.gz
yuzu-e25297536f975db307f7117b3060e9919c44be52.tar.bz2
yuzu-e25297536f975db307f7117b3060e9919c44be52.tar.lz
yuzu-e25297536f975db307f7117b3060e9919c44be52.tar.xz
yuzu-e25297536f975db307f7117b3060e9919c44be52.tar.zst
yuzu-e25297536f975db307f7117b3060e9919c44be52.zip
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp15
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.h8
-rw-r--r--src/yuzu/bootmanager.cpp205
-rw-r--r--src/yuzu/bootmanager.h26
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp4
5 files changed, 145 insertions, 113 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index d5032b432..ddc62bc97 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -106,8 +106,14 @@ RendererVulkan::~RendererVulkan() {
}
void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
+ render_window.PollEvents();
+
+ if (!framebuffer) {
+ return;
+ }
+
const auto& layout = render_window.GetFramebufferLayout();
- if (framebuffer && layout.width > 0 && layout.height > 0 && render_window.IsShown()) {
+ if (layout.width > 0 && layout.height > 0 && render_window.IsShown()) {
const VAddr framebuffer_addr = framebuffer->address + framebuffer->offset;
const bool use_accelerated =
rasterizer->AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
@@ -128,13 +134,16 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
blit_screen->Recreate();
}
- render_window.SwapBuffers();
rasterizer->TickFrame();
}
render_window.PollEvents();
}
+void RendererVulkan::TryPresent(int /*timeout_ms*/) {
+ // TODO (bunnei): ImplementMe
+}
+
bool RendererVulkan::Init() {
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr{};
render_window.RetrieveVulkanHandlers(&vkGetInstanceProcAddr, &instance, &surface);
@@ -262,4 +271,4 @@ void RendererVulkan::Report() const {
telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions);
}
-} // namespace Vulkan \ No newline at end of file
+} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h
index a472c5dc9..f513397f0 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.h
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.h
@@ -36,14 +36,10 @@ public:
explicit RendererVulkan(Core::Frontend::EmuWindow& window, Core::System& system);
~RendererVulkan() override;
- /// Swap buffers (render frame)
- void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
-
- /// Initialize the renderer
bool Init() override;
-
- /// Shutdown the renderer
void ShutDown() override;
+ void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
+ void TryPresent(int timeout_ms) override;
private:
std::optional<vk::DebugUtilsMessengerEXT> CreateDebugCallback(
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 99e0ac61e..704c5ecdd 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -147,88 +147,129 @@ private:
QOffscreenSurface* surface;
};
-OpenGLWindow::OpenGLWindow(QWindow* parent, QWidget* event_handler, QOpenGLContext* shared_context)
- : QWindow(parent), event_handler(event_handler),
- context(new QOpenGLContext(shared_context->parent())) {
+class ChildRenderWindow : public QWindow {
+public:
+ ChildRenderWindow(QWindow* parent, QWidget* event_handler)
+ : QWindow{parent}, event_handler{event_handler} {}
+
+ virtual ~ChildRenderWindow() = default;
+
+ virtual void Present() = 0;
+
+protected:
+ bool event(QEvent* event) override {
+ switch (event->type()) {
+ case QEvent::UpdateRequest:
+ Present();
+ return true;
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ case QEvent::FocusAboutToChange:
+ case QEvent::Enter:
+ case QEvent::Leave:
+ case QEvent::Wheel:
+ case QEvent::TabletMove:
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::InputMethodQuery:
+ case QEvent::TouchCancel:
+ return QCoreApplication::sendEvent(event_handler, event);
+ case QEvent::Drop:
+ GetMainWindow()->DropAction(static_cast<QDropEvent*>(event));
+ return true;
+ case QEvent::DragResponse:
+ case QEvent::DragEnter:
+ case QEvent::DragLeave:
+ case QEvent::DragMove:
+ GetMainWindow()->AcceptDropEvent(static_cast<QDropEvent*>(event));
+ return true;
+ default:
+ return QWindow::event(event);
+ }
+ }
- // disable vsync for any shared contexts
- auto format = shared_context->format();
- format.setSwapInterval(Settings::values.use_vsync ? 1 : 0);
- this->setFormat(format);
+ void exposeEvent(QExposeEvent* event) override {
+ QWindow::requestUpdate();
+ QWindow::exposeEvent(event);
+ }
- context->setShareContext(shared_context);
- context->setScreen(this->screen());
- context->setFormat(format);
- context->create();
+private:
+ QWidget* event_handler{};
+};
- setSurfaceType(QWindow::OpenGLSurface);
+class OpenGLWindow final : public ChildRenderWindow {
+public:
+ OpenGLWindow(QWindow* parent, QWidget* event_handler, QOpenGLContext* shared_context)
+ : ChildRenderWindow{parent, event_handler},
+ context(new QOpenGLContext(shared_context->parent())) {
- // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground,
- // WA_DontShowOnScreen, WA_DeleteOnClose
-}
+ // disable vsync for any shared contexts
+ auto format = shared_context->format();
+ format.setSwapInterval(Settings::values.use_vsync ? 1 : 0);
+ this->setFormat(format);
-OpenGLWindow::~OpenGLWindow() {
- context->doneCurrent();
-}
+ context->setShareContext(shared_context);
+ context->setScreen(this->screen());
+ context->setFormat(format);
+ context->create();
-void OpenGLWindow::Present() {
- if (!isExposed())
- return;
+ setSurfaceType(QWindow::OpenGLSurface);
- context->makeCurrent(this);
- Core::System::GetInstance().Renderer().TryPresent(100);
- context->swapBuffers(this);
- auto f = context->versionFunctions<QOpenGLFunctions_4_3_Core>();
- f->glFinish();
- QWindow::requestUpdate();
-}
+ // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground,
+ // WA_DontShowOnScreen, WA_DeleteOnClose
+ }
-bool OpenGLWindow::event(QEvent* event) {
- switch (event->type()) {
- case QEvent::UpdateRequest:
- Present();
- return true;
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- case QEvent::FocusAboutToChange:
- case QEvent::Enter:
- case QEvent::Leave:
- case QEvent::Wheel:
- case QEvent::TabletMove:
- case QEvent::TabletPress:
- case QEvent::TabletRelease:
- case QEvent::TabletEnterProximity:
- case QEvent::TabletLeaveProximity:
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- case QEvent::InputMethodQuery:
- case QEvent::TouchCancel:
- return QCoreApplication::sendEvent(event_handler, event);
- case QEvent::Drop:
- GetMainWindow()->DropAction(static_cast<QDropEvent*>(event));
- return true;
- case QEvent::DragResponse:
- case QEvent::DragEnter:
- case QEvent::DragLeave:
- case QEvent::DragMove:
- GetMainWindow()->AcceptDropEvent(static_cast<QDropEvent*>(event));
- return true;
- default:
- return QWindow::event(event);
+ ~OpenGLWindow() override {
+ context->doneCurrent();
}
-}
-void OpenGLWindow::exposeEvent(QExposeEvent* event) {
- QWindow::requestUpdate();
- QWindow::exposeEvent(event);
-}
+ void Present() override {
+ if (!isExposed()) {
+ return;
+ }
+
+ context->makeCurrent(this);
+ Core::System::GetInstance().Renderer().TryPresent(100);
+ context->swapBuffers(this);
+ auto f = context->versionFunctions<QOpenGLFunctions_4_3_Core>();
+ f->glFinish();
+ QWindow::requestUpdate();
+ }
+
+private:
+ QOpenGLContext* context{};
+};
+
+#ifdef HAS_VULKAN
+class VulkanWindow final : public ChildRenderWindow {
+public:
+ VulkanWindow(QWindow* parent, QWidget* event_handler, QVulkanInstance* instance)
+ : ChildRenderWindow{parent, event_handler} {
+ setSurfaceType(QSurface::SurfaceType::VulkanSurface);
+ setVulkanInstance(instance);
+ }
+
+ ~VulkanWindow() override = default;
+
+ void Present() override {
+ // TODO(bunnei): ImplementMe
+ }
+
+private:
+ QWidget* event_handler{};
+};
+#endif
GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread)
: QWidget(parent_), emu_thread(emu_thread) {
@@ -251,11 +292,15 @@ GRenderWindow::~GRenderWindow() {
}
void GRenderWindow::MakeCurrent() {
- core_context->MakeCurrent();
+ if (core_context) {
+ core_context->MakeCurrent();
+ }
}
void GRenderWindow::DoneCurrent() {
- core_context->DoneCurrent();
+ if (core_context) {
+ core_context->DoneCurrent();
+ }
}
void GRenderWindow::PollEvents() {
@@ -274,7 +319,7 @@ void GRenderWindow::RetrieveVulkanHandlers(void* get_instance_proc_addr, void* i
#ifdef HAS_VULKAN
const auto instance_proc_addr = vk_instance->getInstanceProcAddr("vkGetInstanceProcAddr");
const VkInstance instance_copy = vk_instance->vkInstance();
- const VkSurfaceKHR surface_copy = vk_instance->surfaceForWindow(child);
+ const VkSurfaceKHR surface_copy = vk_instance->surfaceForWindow(child_window);
std::memcpy(get_instance_proc_addr, &instance_proc_addr, sizeof(instance_proc_addr));
std::memcpy(instance, &instance_copy, sizeof(instance_copy));
@@ -535,7 +580,6 @@ bool GRenderWindow::InitializeOpenGL() {
layout()->addWidget(child_widget);
core_context = CreateSharedContext();
- resize(Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height);
return true;
}
@@ -565,7 +609,14 @@ bool GRenderWindow::InitializeVulkan() {
return false;
}
- child = new GVKWidgetInternal(this, vk_instance.get());
+ GMainWindow* parent = GetMainWindow();
+ QWindow* parent_win_handle = parent ? parent->windowHandle() : nullptr;
+ child_window = new VulkanWindow(parent_win_handle, this, vk_instance.get());
+ child_window->create();
+ child_widget = createWindowContainer(child_window, this);
+ child_widget->resize(Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height);
+ layout()->addWidget(child_widget);
+
return true;
#else
QMessageBox::critical(this, tr("Vulkan not available!"),
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 37bc4f043..6710a6e7f 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -27,14 +27,6 @@ class QOpenGLContext;
class QVulkanInstance;
#endif
-class GWidgetInternal;
-class GGLWidgetInternal;
-class GVKWidgetInternal;
-class GMainWindow;
-class GRenderWindow;
-class QSurface;
-class QOpenGLContext;
-
namespace VideoCore {
enum class LoadCallbackStage;
}
@@ -123,24 +115,6 @@ signals:
void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total);
};
-class OpenGLWindow : public QWindow {
- Q_OBJECT
-public:
- explicit OpenGLWindow(QWindow* parent, QWidget* event_handler, QOpenGLContext* shared_context);
-
- ~OpenGLWindow();
-
- void Present();
-
-protected:
- bool event(QEvent* event) override;
- void exposeEvent(QExposeEvent* event) override;
-
-private:
- QOpenGLContext* context;
- QWidget* event_handler;
-};
-
class GRenderWindow : public QWidget, public Core::Frontend::EmuWindow {
Q_OBJECT
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
index f5f6675b5..abcc58165 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp
@@ -160,4 +160,6 @@ bool EmuWindow_SDL2_VK::UseStandardLayers(PFN_vkGetInstanceProcAddr vkGetInstanc
}) != layers.end();
}
-void EmuWindow_SDL2_VK::Present() {}
+void EmuWindow_SDL2_VK::Present() {
+ // TODO (bunnei): ImplementMe
+}