From 14877b8f3539c6bd2adf66f81cfb2cd052862b73 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 17 Feb 2020 15:53:21 -0500 Subject: frontend: qt: bootmanager: OpenGL: Implement separate presentation thread. --- src/yuzu/bootmanager.h | 72 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 22 deletions(-) (limited to 'src/yuzu/bootmanager.h') diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 71a2fa321..37bc4f043 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "common/thread.h" #include "core/core.h" @@ -42,7 +43,7 @@ class EmuThread final : public QThread { Q_OBJECT public: - explicit EmuThread(GRenderWindow* render_window); + explicit EmuThread(Core::Frontend::GraphicsContext& context); ~EmuThread() override; /** @@ -96,7 +97,7 @@ private: std::mutex running_mutex; std::condition_variable running_cv; - GRenderWindow* render_window; + Core::Frontend::GraphicsContext& core_context; signals: /** @@ -122,15 +123,32 @@ 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 public: - GRenderWindow(GMainWindow* parent, EmuThread* emu_thread); + GRenderWindow(QWidget* parent, EmuThread* emu_thread); ~GRenderWindow() override; - // EmuWindow implementation - void SwapBuffers() override; + // EmuWindow implementation. void MakeCurrent() override; void DoneCurrent() override; void PollEvents() override; @@ -139,30 +157,36 @@ public: void* surface) const override; std::unique_ptr CreateSharedContext() const override; - void ForwardKeyPressEvent(QKeyEvent* event); - void ForwardKeyReleaseEvent(QKeyEvent* event); - void BackupGeometry(); void RestoreGeometry(); void restoreGeometry(const QByteArray& geometry); // overridden QByteArray saveGeometry(); // overridden - qreal GetWindowPixelRatio() const; - std::pair ScaleTouch(QPointF pos) const; + qreal windowPixelRatio() const; void closeEvent(QCloseEvent* event) override; + + void resizeEvent(QResizeEvent* event) override; + + void keyPressEvent(QKeyEvent* event) override; + void keyReleaseEvent(QKeyEvent* event) override; + + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + bool event(QEvent* event) override; - void focusOutEvent(QFocusEvent* event) override; - void OnClientAreaResized(u32 width, u32 height); + void focusOutEvent(QFocusEvent* event) override; bool InitRenderTarget(); + /// Destroy the previous run's child_widget which should also destroy the child_window + void ReleaseRenderTarget(); + void CaptureScreenshot(u32 res_scale, const QString& screenshot_path); public slots: - void moveContext(); // overridden - void OnEmulationStarting(EmuThread* emu_thread); void OnEmulationStopping(); void OnFramebufferSizeChanged(); @@ -173,6 +197,7 @@ signals: void FirstFrameDisplayed(); private: + std::pair ScaleTouch(QPointF pos) const; void TouchBeginEvent(const QTouchEvent* event); void TouchUpdateEvent(const QTouchEvent* event); void TouchEndEvent(); @@ -184,15 +209,9 @@ private: bool LoadOpenGL(); QStringList GetUnsupportedGLExtensions() const; - QWidget* container = nullptr; - GWidgetInternal* child = nullptr; - EmuThread* emu_thread; - // Context that backs the GGLWidgetInternal (and will be used by core to render) - std::unique_ptr context; - // Context that will be shared between all newly created contexts. This should never be made - // current - std::unique_ptr shared_context; + + std::unique_ptr core_context; #ifdef HAS_VULKAN std::unique_ptr vk_instance; @@ -202,6 +221,15 @@ private: QImage screenshot_image; QByteArray geometry; + + /// Native window handle that backs this presentation widget + QWindow* child_window = nullptr; + + /// In order to embed the window into GRenderWindow, you need to use createWindowContainer to + /// put the child_window into a widget then add it to the layout. This child_widget can be + /// parented to GRenderWindow and use Qt's lifetime system + QWidget* child_widget = nullptr; + bool first_frame = false; protected: -- cgit v1.2.3 From e25297536f975db307f7117b3060e9919c44be52 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 17 Feb 2020 21:29:12 -0500 Subject: frontend: qt: bootmanager: Vulkan: Restore support for VK backend. --- src/yuzu/bootmanager.h | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'src/yuzu/bootmanager.h') 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 -- cgit v1.2.3 From c6f78a4a6d8746b84b2891e536286d9d6a63015e Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 21 Feb 2020 12:40:23 -0500 Subject: frontend: qt: bootmanager: Acquire a shared context in main emu thread. --- src/yuzu/bootmanager.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/yuzu/bootmanager.h') diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 6710a6e7f..79b030304 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -17,6 +17,7 @@ #include "core/core.h" #include "core/frontend/emu_window.h" +class GRenderWindow; class QKeyEvent; class QScreen; class QTouchEvent; @@ -35,7 +36,7 @@ class EmuThread final : public QThread { Q_OBJECT public: - explicit EmuThread(Core::Frontend::GraphicsContext& context); + explicit EmuThread(GRenderWindow& window); ~EmuThread() override; /** @@ -89,7 +90,11 @@ private: std::mutex running_mutex; std::condition_variable running_cv; - Core::Frontend::GraphicsContext& core_context; + /// Only used in asynchronous GPU mode + std::unique_ptr shared_context; + + /// This is shared_context in asynchronous GPU mode, core_context in synchronous GPU mode + Core::Frontend::GraphicsContext& context; signals: /** -- cgit v1.2.3