| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // 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 "common/common_types.h"
- #include "common/polyfill_thread.h"
- #include "common/thread.h"
- #include "core/hle/result.h"
- #include "core/hle/service/kernel_helpers.h"
- #include "core/hle/service/nvnflinger/hwc_layer.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 FbShareBufferManager;
- class HardwareComposer;
- class HosBinderDriverServer;
- class Nvnflinger final {
- public:
- explicit Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_);
- ~Nvnflinger();
- void ShutdownLayers();
- /// 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,
- LayerBlending blending = LayerBlending::None);
- /// Opens a layer on all displays for the given layer ID.
- bool OpenLayer(u64 layer_id);
- /// Closes a layer on all displays for the given layer ID.
- bool CloseLayer(u64 layer_id);
- /// Makes a layer visible on all displays for the given layer ID.
- void SetLayerVisibility(u64 layer_id, bool visible);
- /// Destroys the given layer ID.
- void DestroyLayer(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]] Result FindVsyncEvent(Kernel::KReadableEvent** out_vsync_event, 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;
- FbShareBufferManager& GetSystemBufferManager();
- private:
- struct Layer {
- std::unique_ptr<android::BufferQueueCore> core;
- std::unique_ptr<android::BufferQueueProducer> producer;
- };
- friend class FbShareBufferManager;
- 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);
- /// Creates a layer with the specified layer ID in the desired display.
- void CreateLayerAtId(VI::Display& display, u64 layer_id, LayerBlending blending);
- 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;
- f32 compose_speed_scale = 1.0f;
- bool is_abandoned = false;
- /// Event that handles screen composition.
- std::shared_ptr<Core::Timing::EventType> multi_composition_event;
- std::shared_ptr<Core::Timing::EventType> single_composition_event;
- std::unique_ptr<FbShareBufferManager> system_buffer_manager;
- std::shared_ptr<std::mutex> guard;
- Core::System& system;
- Common::Event vsync_signal;
- std::jthread vsync_thread;
- KernelHelpers::ServiceContext service_context;
- HosBinderDriverServer& hos_binder_driver_server;
- };
- void LoopProcess(Core::System& system);
- } // namespace Service::Nvnflinger
|