From 282adfc70b5d7d958d564bfda0227bb3fbd8d110 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 24 Mar 2020 20:58:49 -0600 Subject: Frontend/GPU: Refactor context management Changes the GraphicsContext to be managed by the GPU core. This eliminates the need for the frontends to fool around with tricky MakeCurrent/DoneCurrent calls that are dependent on the settings (such as async gpu option). This also refactors out the need to use QWidget::fromWindowContainer as that caused issues with focus and input handling. Now we use a regular QWidget and just access the native windowHandle() directly. Another change is removing the debug tool setting in FrameMailbox. Instead of trying to block the frontend until a new frame is ready, the core will now take over presentation and draw directly to the window if the renderer detects that its hooked by NSight or RenderDoc Lastly, since it was in the way, I removed ScopeAcquireWindowContext and replaced it with a simple subclass in GraphicsContext that achieves the same result --- src/core/CMakeLists.txt | 2 -- src/core/core.cpp | 20 +++---------- src/core/frontend/emu_window.h | 44 ++++++++++++++++++----------- src/core/frontend/scope_acquire_context.cpp | 18 ------------ src/core/frontend/scope_acquire_context.h | 23 --------------- 5 files changed, 32 insertions(+), 75 deletions(-) delete mode 100644 src/core/frontend/scope_acquire_context.cpp delete mode 100644 src/core/frontend/scope_acquire_context.h (limited to 'src/core') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b31a0328c..29a267957 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -131,8 +131,6 @@ add_library(core STATIC frontend/framebuffer_layout.cpp frontend/framebuffer_layout.h frontend/input.h - frontend/scope_acquire_context.cpp - frontend/scope_acquire_context.h gdbstub/gdbstub.cpp gdbstub/gdbstub.h hardware_interrupt_manager.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 218508126..6cc4a0812 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -24,7 +24,6 @@ #include "core/file_sys/sdmc_factory.h" #include "core/file_sys/vfs_concat.h" #include "core/file_sys/vfs_real.h" -#include "core/frontend/scope_acquire_context.h" #include "core/gdbstub/gdbstub.h" #include "core/hardware_interrupt_manager.h" #include "core/hle/kernel/client_port.h" @@ -168,13 +167,9 @@ struct System::Impl { Service::Init(service_manager, system); GDBStub::Init(); - renderer = VideoCore::CreateRenderer(emu_window, system); - if (!renderer->Init()) { - return ResultStatus::ErrorVideoCore; - } interrupt_manager = std::make_unique(system); - gpu_core = VideoCore::CreateGPU(system); - renderer->Rasterizer().SetupDirtyFlags(); + gpu_core = VideoCore::CreateGPU(emu_window, system); + gpu_core->Renderer().Rasterizer().SetupDirtyFlags(); is_powered_on = true; exit_lock = false; @@ -186,7 +181,6 @@ struct System::Impl { ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath) { - Core::Frontend::ScopeAcquireContext acquire_context{emu_window}; app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath)); if (!app_loader) { @@ -216,10 +210,6 @@ struct System::Impl { AddGlueRegistrationForProcess(*app_loader, *main_process); kernel.MakeCurrentProcess(main_process.get()); - // Main process has been loaded and been made current. - // Begin GPU and CPU execution. - gpu_core->Start(); - // Initialize cheat engine if (cheat_engine) { cheat_engine->Initialize(); @@ -277,7 +267,6 @@ struct System::Impl { } // Shutdown emulation session - renderer.reset(); GDBStub::Shutdown(); Service::Shutdown(); service_manager.reset(); @@ -353,7 +342,6 @@ struct System::Impl { Service::FileSystem::FileSystemController fs_controller; /// AppLoader used to load the current executing application std::unique_ptr app_loader; - std::unique_ptr renderer; std::unique_ptr gpu_core; std::unique_ptr interrupt_manager; Memory::Memory memory; @@ -536,11 +524,11 @@ const Core::Hardware::InterruptManager& System::InterruptManager() const { } VideoCore::RendererBase& System::Renderer() { - return *impl->renderer; + return impl->gpu_core->Renderer(); } const VideoCore::RendererBase& System::Renderer() const { - return *impl->renderer; + return impl->gpu_core->Renderer(); } Kernel::KernelCore& System::Kernel() { diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 5eb87fb63..bb283d844 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -13,19 +13,39 @@ namespace Core::Frontend { /** - * Represents a graphics context that can be used for background computation or drawing. If the - * graphics backend doesn't require the context, then the implementation of these methods can be - * stubs + * Represents a drawing context that supports graphics operations. */ class GraphicsContext { public: virtual ~GraphicsContext(); + /// Inform the driver to swap the front/back buffers and present the current image + virtual void SwapBuffers() {} + /// Makes the graphics context current for the caller thread - virtual void MakeCurrent() = 0; + virtual void MakeCurrent() {} /// Releases (dunno if this is the "right" word) the context from the caller thread - virtual void DoneCurrent() = 0; + virtual void DoneCurrent() {} + + class Scoped { + public: + Scoped(GraphicsContext& context_) : context(context_) { + context.MakeCurrent(); + } + ~Scoped() { + context.DoneCurrent(); + } + + private: + GraphicsContext& context; + }; + + /// Calls MakeCurrent on the context and calls DoneCurrent when the scope for the returned value + /// ends + Scoped Acquire() { + return Scoped{*this}; + } }; /** @@ -46,7 +66,7 @@ public: * - DO NOT TREAT THIS CLASS AS A GUI TOOLKIT ABSTRACTION LAYER. That's not what it is. Please * re-read the upper points again and think about it if you don't see this. */ -class EmuWindow : public GraphicsContext { +class EmuWindow { public: /// Data structure to store emuwindow configuration struct WindowConfig { @@ -60,17 +80,9 @@ public: virtual void PollEvents() = 0; /** - * Returns a GraphicsContext that the frontend provides that is shared with the emu window. This - * context can be used from other threads for background graphics computation. If the frontend - * is using a graphics backend that doesn't need anything specific to run on a different thread, - * then it can use a stubbed implemenation for GraphicsContext. - * - * If the return value is null, then the core should assume that the frontend cannot provide a - * Shared Context + * Returns a GraphicsContext that the frontend provides to be used for rendering. */ - virtual std::unique_ptr CreateSharedContext() const { - return nullptr; - } + virtual std::unique_ptr CreateSharedContext() const = 0; /// Returns if window is shown (not minimized) virtual bool IsShown() const = 0; diff --git a/src/core/frontend/scope_acquire_context.cpp b/src/core/frontend/scope_acquire_context.cpp deleted file mode 100644 index 878c3157c..000000000 --- a/src/core/frontend/scope_acquire_context.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "core/frontend/emu_window.h" -#include "core/frontend/scope_acquire_context.h" - -namespace Core::Frontend { - -ScopeAcquireContext::ScopeAcquireContext(Core::Frontend::GraphicsContext& context) - : context{context} { - context.MakeCurrent(); -} -ScopeAcquireContext::~ScopeAcquireContext() { - context.DoneCurrent(); -} - -} // namespace Core::Frontend diff --git a/src/core/frontend/scope_acquire_context.h b/src/core/frontend/scope_acquire_context.h deleted file mode 100644 index 7a65c0623..000000000 --- a/src/core/frontend/scope_acquire_context.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2019 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_types.h" - -namespace Core::Frontend { - -class GraphicsContext; - -/// Helper class to acquire/release window context within a given scope -class ScopeAcquireContext : NonCopyable { -public: - explicit ScopeAcquireContext(Core::Frontend::GraphicsContext& context); - ~ScopeAcquireContext(); - -private: - Core::Frontend::GraphicsContext& context; -}; - -} // namespace Core::Frontend -- cgit v1.2.3 From cf9c94d4017120b618194a720942ef4e5c8289bd Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 24 Mar 2020 22:57:36 -0600 Subject: Address review and fix broken yuzu-tester build --- src/core/core.cpp | 4 +++- src/core/frontend/emu_window.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/core.cpp b/src/core/core.cpp index 6cc4a0812..26a580cb7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -169,6 +169,9 @@ struct System::Impl { interrupt_manager = std::make_unique(system); gpu_core = VideoCore::CreateGPU(emu_window, system); + if (!gpu_core) { + return ResultStatus::ErrorVideoCore; + } gpu_core->Renderer().Rasterizer().SetupDirtyFlags(); is_powered_on = true; @@ -181,7 +184,6 @@ struct System::Impl { ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath) { - app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath)); if (!app_loader) { LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index bb283d844..72294d4d8 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -30,7 +30,7 @@ public: class Scoped { public: - Scoped(GraphicsContext& context_) : context(context_) { + explicit Scoped(GraphicsContext& context_) : context(context_) { context.MakeCurrent(); } ~Scoped() { -- cgit v1.2.3