aboutsummaryrefslogtreecommitdiff
path: root/src/yuzu/bootmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/bootmanager.cpp')
-rw-r--r--src/yuzu/bootmanager.cpp213
1 files changed, 17 insertions, 196 deletions
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index dd55034e4e..074b2360ee 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -6,8 +6,6 @@
#include <cmath>
#include <cstring>
#include <string>
-#include <tuple>
-#include <type_traits>
#ifdef HAS_OPENGL
#include <glad/glad.h>
@@ -45,16 +43,13 @@
#include <QOpenGLContext>
#endif
-#include "common/polyfill_thread.h"
#include "common/scm_rev.h"
#include "common/settings.h"
#include "common/settings_input.h"
-#include "common/thread.h"
#include "core/core.h"
#include "core/cpu_manager.h"
#include "core/frontend/framebuffer_layout.h"
#include "core/frontend/graphics_context.h"
-#include "input_common/drivers/camera.h"
#include "input_common/drivers/keyboard.h"
#include "input_common/drivers/mouse.h"
#include "input_common/drivers/tas_input.h"
@@ -62,189 +57,19 @@
#include "input_common/main.h"
#include "qt_common/qt_common.h"
#include "video_core/gpu.h"
-#include "video_core/rasterizer_interface.h"
#include "video_core/renderer_base.h"
#include "yuzu/bootmanager.h"
#include "yuzu/main_window.h"
+#include "qt_common/render/context.h"
+#include "qt_common/render/emu_thread.h"
+
class QObject;
class QPaintEngine;
class QSurface;
constexpr int default_mouse_constrain_timeout = 10;
-EmuThread::EmuThread(Core::System& system) : m_system{system} {}
-
-EmuThread::~EmuThread() = default;
-
-void EmuThread::run() {
- Common::SetCurrentThreadName("EmuControlThread");
-
- auto& gpu = m_system.GPU();
- auto stop_token = m_stop_source.get_token();
-
- m_system.RegisterHostThread();
-
- // Main process has been loaded. Make the context current to this thread and begin GPU and CPU
- // execution.
- gpu.ObtainContext();
-
- emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
- if (Settings::values.use_disk_shader_cache.GetValue()) {
- m_system.Renderer().ReadRasterizer()->LoadDiskResources(
- m_system.GetApplicationProcessProgramID(), stop_token,
- [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
- emit LoadProgress(stage, value, total);
- });
- }
- emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
-
- gpu.ReleaseContext();
- gpu.Start();
-
- m_system.GetCpuManager().OnGpuReady();
-
- if (m_system.DebuggerEnabled()) {
- m_system.InitializeDebugger();
- }
-
- while (!stop_token.stop_requested()) {
- std::unique_lock lk{m_should_run_mutex};
- if (m_should_run) {
- m_system.Run();
- m_stopped.Reset();
-
- m_should_run_cv.wait(lk, stop_token, [&] { return !m_should_run; });
- } else {
- m_system.Pause();
- m_stopped.Set();
-
- EmulationPaused(lk);
- m_should_run_cv.wait(lk, stop_token, [&] { return m_should_run; });
- EmulationResumed(lk);
- }
- }
-
- // Shutdown the main emulated process
- m_system.DetachDebugger();
- m_system.ShutdownMainProcess();
-}
-
-// Unlock while emitting signals so that the main thread can
-// continue pumping events.
-
-void EmuThread::EmulationPaused(std::unique_lock<std::mutex>& lk) {
- lk.unlock();
- emit DebugModeEntered();
- lk.lock();
-}
-
-void EmuThread::EmulationResumed(std::unique_lock<std::mutex>& lk) {
- lk.unlock();
- emit DebugModeLeft();
- lk.lock();
-}
-
-#ifdef HAS_OPENGL
-class OpenGLSharedContext : public Core::Frontend::GraphicsContext {
-public:
- /// Create the original context that should be shared from
- explicit OpenGLSharedContext(QSurface* surface_) : surface{surface_} {
- QSurfaceFormat format;
- format.setVersion(4, 6);
- format.setProfile(QSurfaceFormat::CompatibilityProfile);
- format.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions);
- if (Settings::values.renderer_debug) {
- format.setOption(QSurfaceFormat::FormatOption::DebugContext);
- }
- // TODO: expose a setting for buffer value (ie default/single/double/triple)
- format.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior);
- format.setSwapInterval(0);
-
- context = std::make_unique<QOpenGLContext>();
- context->setFormat(format);
- if (!context->create()) {
- LOG_ERROR(Frontend, "Unable to create main openGL context");
- }
- }
-
- /// Create the shared contexts for rendering and presentation
- explicit OpenGLSharedContext(QOpenGLContext* share_context, QSurface* main_surface = nullptr) {
-
- // disable vsync for any shared contexts
- auto format = share_context->format();
- const int swap_interval =
- Settings::values.vsync_mode.GetValue() == Settings::VSyncMode::Immediate ? 0 : 1;
-
- format.setSwapInterval(main_surface ? swap_interval : 0);
-
- context = std::make_unique<QOpenGLContext>();
- context->setShareContext(share_context);
- context->setFormat(format);
- if (!context->create()) {
- LOG_ERROR(Frontend, "Unable to create shared openGL context");
- }
-
- if (!main_surface) {
- offscreen_surface = std::make_unique<QOffscreenSurface>(nullptr);
- offscreen_surface->setFormat(format);
- offscreen_surface->create();
- surface = offscreen_surface.get();
- } else {
- surface = main_surface;
- }
- }
-
- ~OpenGLSharedContext() {
- DoneCurrent();
- }
-
- void SwapBuffers() override {
- if (auto window = static_cast<QWindow*>(surface)) {
- if (!window->isExposed()) {
- LOG_DEBUG(Frontend, "SwapBuffers ignored: window not exposed");
- return;
- }
- }
-
- context->swapBuffers(surface);
- }
-
- void MakeCurrent() override {
- // We can't track the current state of the underlying context in this wrapper class because
- // Qt may make the underlying context not current for one reason or another. In particular,
- // the WebBrowser uses GL, so it seems to conflict if we aren't careful.
- // Instead of always just making the context current (which does not have any caching to
- // check if the underlying context is already current) we can check for the current context
- // in the thread local data by calling `currentContext()` and checking if its ours.
- if (QOpenGLContext::currentContext() != context.get()) {
- context->makeCurrent(surface);
- }
- }
-
- void DoneCurrent() override {
- context->doneCurrent();
- }
-
- QOpenGLContext* GetShareContext() {
- return context.get();
- }
-
- const QOpenGLContext* GetShareContext() const {
- return context.get();
- }
-
-private:
- // Avoid using Qt parent system here since we might move the QObjects to new threads
- // As a note, this means we should avoid using slots/signals with the objects too
- std::unique_ptr<QOpenGLContext> context;
- std::unique_ptr<QOffscreenSurface> offscreen_surface{};
- QSurface* surface;
-};
-#endif
-
-class DummyContext : public Core::Frontend::GraphicsContext {};
-
class RenderWidget : public QWidget {
public:
explicit RenderWidget(GRenderWindow* parent) : QWidget(parent) {
@@ -285,11 +110,9 @@ struct NullRenderWidget : public RenderWidget {
explicit NullRenderWidget(GRenderWindow* parent) : RenderWidget(parent) {}
};
-GRenderWindow::GRenderWindow(MainWindow* parent, EmuThread* emu_thread_,
- std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
- Core::System& system_)
- : QWidget(parent), emu_thread(emu_thread_), input_subsystem{std::move(input_subsystem_)},
- system{system_} {
+GRenderWindow::GRenderWindow(MainWindow* parent,
+ std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_)
+ : QWidget(parent), input_subsystem{std::move(input_subsystem_)} {
setWindowTitle(QStringLiteral("Eden %1 | %2-%3")
.arg(QString::fromUtf8(Common::g_build_name),
QString::fromUtf8(Common::g_scm_branch),
@@ -708,10 +531,11 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
}
void GRenderWindow::ConstrainMouse() {
- if (emu_thread == nullptr || !Settings::values.mouse_panning) {
+ if (QtCommon::emu_thread == nullptr || !Settings::values.mouse_panning) {
mouse_constrain_timer.stop();
return;
}
+
if (!this->isActiveWindow()) {
mouse_constrain_timer.stop();
return;
@@ -964,7 +788,7 @@ void GRenderWindow::ReleaseRenderTarget() {
}
void GRenderWindow::CaptureScreenshot(const QString& screenshot_path) {
- auto& renderer = system.Renderer();
+ auto& renderer = QtCommon::system->Renderer();
if (renderer.IsScreenshotPending()) {
LOG_WARNING(Render,
@@ -989,7 +813,12 @@ void GRenderWindow::CaptureScreenshot(const QString& screenshot_path) {
screenshot_image.bits(),
[=, this](bool invert_y) {
const std::string std_screenshot_path = screenshot_path.toStdString();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
+ if (screenshot_image.flipped(invert_y ? Qt::Vertical : (Qt::Orientations)0)
+ .save(screenshot_path)) {
+#else
if (screenshot_image.mirrored(false, invert_y).save(screenshot_path)) {
+#endif
LOG_INFO(Frontend, "Screenshot saved to \"{}\"", std_screenshot_path);
} else {
LOG_ERROR(Frontend, "Failed to save screenshot to \"{}\"", std_screenshot_path);
@@ -1026,7 +855,8 @@ bool GRenderWindow::InitializeOpenGL() {
return true;
#else
- QMessageBox::warning(this, tr("OpenGL not available!"), tr("Eden has not been compiled with OpenGL support."));
+ QMessageBox::warning(this, tr("OpenGL not available!"),
+ tr("Eden has not been compiled with OpenGL support."));
return false;
#endif
}
@@ -1072,8 +902,7 @@ bool GRenderWindow::LoadOpenGL() {
tr("Your GPU may not support one or more required OpenGL extensions. Please ensure you "
"have the latest graphics driver.<br><br>GL Renderer:<br>%1<br><br>Unsupported "
"extensions:<br>%2")
- .arg(renderer)
- .arg(missing_ext.join(QStringLiteral("<br>"))));
+ .arg(renderer, missing_ext.join(QStringLiteral("<br>"))));
// Non fatal
}
return true;
@@ -1101,14 +930,6 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const {
return missing_ext;
}
-void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread_) {
- emu_thread = emu_thread_;
-}
-
-void GRenderWindow::OnEmulationStopping() {
- emu_thread = nullptr;
-}
-
void GRenderWindow::showEvent(QShowEvent* event) {
QWidget::showEvent(event);