diff options
| author | crueter <crueter@eden-emu.dev> | 2026-05-20 04:49:16 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-05-20 04:49:16 +0200 |
| commit | feb8c5f88eae046c1b76f46e4fa103a844fb0f23 (patch) | |
| tree | 70f71937a8930c1a5b562f69047e35491d6156b4 /src/qt_common/render/context.h | |
| parent | 300a646a34b6729879e3fb71d53e625a09683bb2 (diff) | |
[desktop] More qt_common reorganization (#3916)
Ported from QML branch.
Main "big" change is that EmuThread is now a shared state in QtCommon,
not individually managed/passed around by GRenderWindow and MainWindow.
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3916
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Diffstat (limited to 'src/qt_common/render/context.h')
| -rw-r--r-- | src/qt_common/render/context.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/qt_common/render/context.h b/src/qt_common/render/context.h new file mode 100644 index 0000000000..a0ecade9c8 --- /dev/null +++ b/src/qt_common/render/context.h @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <QSurface> +#include "common/logging.h" +#include "common/settings.h" +#include "core/frontend/graphics_context.h" + +#ifdef HAS_OPENGL +#include <QOffscreenSurface> +#include <QOpenGLContext> +#endif + +#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 { + 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 {}; |
