diff options
author | Morph <39850852+Morph1984@users.noreply.github.com> | 2023-03-04 04:51:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-04 04:51:17 +0100 |
commit | ce8f4da63834be0179d98a7720dee47d65f3ec06 (patch) | |
tree | a9a9303a532d374db9ae8255e5f3f2487e370f84 /src/core/hle/service/nvnflinger/nvnflinger.h | |
parent | Merge pull request #9855 from liamwhite/kern-16-support (diff) | |
parent | nvnflinger: fix name (diff) | |
download | yuzu-ce8f4da63834be0179d98a7720dee47d65f3ec06.tar yuzu-ce8f4da63834be0179d98a7720dee47d65f3ec06.tar.gz yuzu-ce8f4da63834be0179d98a7720dee47d65f3ec06.tar.bz2 yuzu-ce8f4da63834be0179d98a7720dee47d65f3ec06.tar.lz yuzu-ce8f4da63834be0179d98a7720dee47d65f3ec06.tar.xz yuzu-ce8f4da63834be0179d98a7720dee47d65f3ec06.tar.zst yuzu-ce8f4da63834be0179d98a7720dee47d65f3ec06.zip |
Diffstat (limited to 'src/core/hle/service/nvnflinger/nvnflinger.h')
-rw-r--r-- | src/core/hle/service/nvnflinger/nvnflinger.h | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h new file mode 100644 index 000000000..a043cceb2 --- /dev/null +++ b/src/core/hle/service/nvnflinger/nvnflinger.h @@ -0,0 +1,155 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <list> +#include <memory> +#include <mutex> +#include <optional> +#include <thread> +#include <vector> + +#include "common/common_types.h" +#include "common/polyfill_thread.h" +#include "core/hle/result.h" +#include "core/hle/service/kernel_helpers.h" + +namespace Common { +class Event; +} // namespace Common + +namespace Core::Timing { +class CoreTiming; +struct EventType; +} // namespace Core::Timing + +namespace Kernel { +class KReadableEvent; +} // namespace Kernel + +namespace Service::Nvidia { +class Module; +} // namespace Service::Nvidia + +namespace Service::VI { +class Display; +class Layer; +} // namespace Service::VI + +namespace Service::android { +class BufferQueueCore; +class BufferQueueProducer; +} // namespace Service::android + +namespace Service::Nvnflinger { + +class Nvnflinger final { +public: + explicit Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_); + ~Nvnflinger(); + + void ShutdownLayers(); + + /// Sets the NVDrv module instance to use to send buffers to the GPU. + void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance); + + /// Opens the specified display and returns the ID. + /// + /// If an invalid display name is provided, then an empty optional is returned. + [[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name); + + /// Closes the specified display by its ID. + /// + /// Returns false if an invalid display ID is provided. + [[nodiscard]] bool CloseDisplay(u64 display_id); + + /// Creates a layer on the specified display and returns the layer ID. + /// + /// If an invalid display ID is specified, then an empty optional is returned. + [[nodiscard]] std::optional<u64> CreateLayer(u64 display_id); + + /// Closes a layer on all displays for the given layer ID. + void CloseLayer(u64 layer_id); + + /// Finds the buffer queue ID of the specified layer in the specified display. + /// + /// If an invalid display ID or layer ID is provided, then an empty optional is returned. + [[nodiscard]] std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id); + + /// Gets the vsync event for the specified display. + /// + /// If an invalid display ID is provided, then VI::ResultNotFound is returned. + /// If the vsync event has already been retrieved, then VI::ResultPermissionDenied is returned. + [[nodiscard]] ResultVal<Kernel::KReadableEvent*> FindVsyncEvent(u64 display_id); + + /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when + /// finished. + void Compose(); + + [[nodiscard]] s64 GetNextTicks() const; + +private: + struct Layer { + std::unique_ptr<android::BufferQueueCore> core; + std::unique_ptr<android::BufferQueueProducer> producer; + }; + +private: + [[nodiscard]] std::unique_lock<std::mutex> Lock() const { + return std::unique_lock{*guard}; + } + + /// Finds the display identified by the specified ID. + [[nodiscard]] VI::Display* FindDisplay(u64 display_id); + + /// Finds the display identified by the specified ID. + [[nodiscard]] const VI::Display* FindDisplay(u64 display_id) const; + + /// Finds the layer identified by the specified ID in the desired display. + [[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id); + + /// Finds the layer identified by the specified ID in the desired display. + [[nodiscard]] const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const; + + /// Finds the layer identified by the specified ID in the desired display, + /// or creates the layer if it is not found. + /// To be used when the system expects the specified ID to already exist. + [[nodiscard]] VI::Layer* FindOrCreateLayer(u64 display_id, u64 layer_id); + + /// Creates a layer with the specified layer ID in the desired display. + void CreateLayerAtId(VI::Display& display, u64 layer_id); + + void SplitVSync(std::stop_token stop_token); + + std::shared_ptr<Nvidia::Module> nvdrv; + s32 disp_fd; + + std::list<VI::Display> displays; + + /// Id to use for the next layer that is created, this counter is shared among all displays. + u64 next_layer_id = 1; + /// Id to use for the next buffer queue that is created, this counter is shared among all + /// layers. + u32 next_buffer_queue_id = 1; + + s32 swap_interval = 1; + + /// Event that handles screen composition. + std::shared_ptr<Core::Timing::EventType> multi_composition_event; + std::shared_ptr<Core::Timing::EventType> single_composition_event; + + std::shared_ptr<std::mutex> guard; + + Core::System& system; + + std::atomic<bool> vsync_signal; + + std::jthread vsync_thread; + + KernelHelpers::ServiceContext service_context; + + HosBinderDriverServer& hos_binder_driver_server; +}; + +} // namespace Service::Nvnflinger |