2022-04-23 04:59:50 -04:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
2021-11-11 22:15:51 -05:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
2018-01-22 11:54:58 -05:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2021-04-04 03:56:09 -04:00
|
|
|
#include <list>
|
2018-01-22 11:54:58 -05:00
|
|
|
#include <memory>
|
2020-02-27 09:47:02 -05:00
|
|
|
#include <mutex>
|
2019-02-05 16:20:04 -05:00
|
|
|
#include <optional>
|
2020-05-29 15:00:17 -04:00
|
|
|
#include <thread>
|
2020-06-27 10:59:51 -04:00
|
|
|
#include <vector>
|
2018-08-07 08:24:30 -04:00
|
|
|
|
|
|
|
#include "common/common_types.h"
|
2022-09-25 21:20:36 -04:00
|
|
|
#include "core/hle/result.h"
|
2021-08-07 04:05:46 -04:00
|
|
|
#include "core/hle/service/kernel_helpers.h"
|
2018-01-22 11:54:58 -05:00
|
|
|
|
2020-05-29 15:00:17 -04:00
|
|
|
namespace Common {
|
|
|
|
class Event;
|
|
|
|
} // namespace Common
|
|
|
|
|
2019-02-12 12:32:15 -05:00
|
|
|
namespace Core::Timing {
|
2019-02-14 12:42:58 -05:00
|
|
|
class CoreTiming;
|
2018-01-22 11:54:58 -05:00
|
|
|
struct EventType;
|
2019-02-14 12:42:58 -05:00
|
|
|
} // namespace Core::Timing
|
2018-01-22 11:54:58 -05:00
|
|
|
|
2018-11-26 18:34:07 -05:00
|
|
|
namespace Kernel {
|
2021-01-30 01:48:06 -05:00
|
|
|
class KReadableEvent;
|
2018-11-26 18:34:07 -05:00
|
|
|
} // namespace Kernel
|
|
|
|
|
2018-08-07 09:17:09 -04:00
|
|
|
namespace Service::Nvidia {
|
|
|
|
class Module;
|
2019-02-19 17:00:03 -05:00
|
|
|
} // namespace Service::Nvidia
|
|
|
|
|
|
|
|
namespace Service::VI {
|
2019-02-21 10:43:26 -05:00
|
|
|
class Display;
|
2019-02-21 10:56:20 -05:00
|
|
|
class Layer;
|
2019-02-19 17:00:03 -05:00
|
|
|
} // namespace Service::VI
|
2018-08-07 09:17:09 -04:00
|
|
|
|
2022-03-20 00:51:16 -04:00
|
|
|
namespace Service::android {
|
2021-11-11 22:15:51 -05:00
|
|
|
class BufferQueueCore;
|
|
|
|
class BufferQueueProducer;
|
2022-03-20 00:51:16 -04:00
|
|
|
} // namespace Service::android
|
2018-01-22 11:54:58 -05:00
|
|
|
|
2021-11-11 22:15:51 -05:00
|
|
|
namespace Service::NVFlinger {
|
2018-01-22 11:54:58 -05:00
|
|
|
|
|
|
|
class NVFlinger final {
|
|
|
|
public:
|
2021-11-11 22:15:51 -05:00
|
|
|
explicit NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_);
|
2018-01-22 11:54:58 -05:00
|
|
|
~NVFlinger();
|
|
|
|
|
2022-10-23 05:45:45 -04:00
|
|
|
void ShutdownLayers();
|
|
|
|
|
2018-08-07 09:17:09 -04:00
|
|
|
/// Sets the NVDrv module instance to use to send buffers to the GPU.
|
|
|
|
void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance);
|
|
|
|
|
2019-01-29 23:30:22 -05:00
|
|
|
/// Opens the specified display and returns the ID.
|
2019-02-05 16:20:04 -05:00
|
|
|
///
|
|
|
|
/// If an invalid display name is provided, then an empty optional is returned.
|
2020-07-25 18:55:53 -04:00
|
|
|
[[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name);
|
2018-01-22 11:54:58 -05:00
|
|
|
|
2019-01-29 23:30:22 -05:00
|
|
|
/// Creates a layer on the specified display and returns the layer ID.
|
2019-02-05 16:20:04 -05:00
|
|
|
///
|
|
|
|
/// If an invalid display ID is specified, then an empty optional is returned.
|
2020-07-25 18:55:53 -04:00
|
|
|
[[nodiscard]] std::optional<u64> CreateLayer(u64 display_id);
|
2018-01-22 11:54:58 -05:00
|
|
|
|
2020-01-04 00:45:06 -05:00
|
|
|
/// Closes a layer on all displays for the given layer ID.
|
|
|
|
void CloseLayer(u64 layer_id);
|
|
|
|
|
2019-01-29 23:30:22 -05:00
|
|
|
/// Finds the buffer queue ID of the specified layer in the specified display.
|
2019-02-05 16:20:04 -05:00
|
|
|
///
|
|
|
|
/// If an invalid display ID or layer ID is provided, then an empty optional is returned.
|
2021-05-06 11:20:52 -04:00
|
|
|
[[nodiscard]] std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id);
|
2018-01-22 11:54:58 -05:00
|
|
|
|
|
|
|
/// Gets the vsync event for the specified display.
|
2019-02-05 16:20:04 -05:00
|
|
|
///
|
2022-09-25 21:20:36 -04:00
|
|
|
/// 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);
|
2018-01-22 11:54:58 -05:00
|
|
|
|
|
|
|
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
|
|
|
|
/// finished.
|
|
|
|
void Compose();
|
|
|
|
|
2020-07-25 18:55:53 -04:00
|
|
|
[[nodiscard]] s64 GetNextTicks() const;
|
2019-06-04 16:10:07 -04:00
|
|
|
|
2021-11-11 22:15:51 -05:00
|
|
|
private:
|
|
|
|
struct Layer {
|
|
|
|
std::unique_ptr<android::BufferQueueCore> core;
|
|
|
|
std::unique_ptr<android::BufferQueueProducer> producer;
|
|
|
|
};
|
|
|
|
|
2020-12-10 18:32:52 -05:00
|
|
|
private:
|
2020-08-11 11:08:10 -04:00
|
|
|
[[nodiscard]] std::unique_lock<std::mutex> Lock() const {
|
|
|
|
return std::unique_lock{*guard};
|
|
|
|
}
|
2020-02-27 09:47:02 -05:00
|
|
|
|
2020-08-11 11:08:10 -04:00
|
|
|
/// Finds the display identified by the specified ID.
|
|
|
|
[[nodiscard]] VI::Display* FindDisplay(u64 display_id);
|
2018-01-22 11:54:58 -05:00
|
|
|
|
2019-01-30 11:14:05 -05:00
|
|
|
/// Finds the display identified by the specified ID.
|
2020-07-25 18:55:53 -04:00
|
|
|
[[nodiscard]] const VI::Display* FindDisplay(u64 display_id) const;
|
2019-01-30 11:14:05 -05:00
|
|
|
|
2019-01-29 23:30:22 -05:00
|
|
|
/// Finds the layer identified by the specified ID in the desired display.
|
2020-07-25 18:55:53 -04:00
|
|
|
[[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id);
|
2018-01-22 11:54:58 -05:00
|
|
|
|
2019-01-30 11:14:05 -05:00
|
|
|
/// Finds the layer identified by the specified ID in the desired display.
|
2020-07-25 18:55:53 -04:00
|
|
|
[[nodiscard]] const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const;
|
2019-01-30 11:14:05 -05:00
|
|
|
|
2021-05-06 11:20:52 -04:00
|
|
|
/// 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);
|
|
|
|
|
2021-10-02 00:39:57 -04:00
|
|
|
void SplitVSync(std::stop_token stop_token);
|
2020-05-29 15:00:17 -04:00
|
|
|
|
2018-08-07 09:17:09 -04:00
|
|
|
std::shared_ptr<Nvidia::Module> nvdrv;
|
2021-11-04 20:44:11 -04:00
|
|
|
s32 disp_fd;
|
2018-08-07 09:17:09 -04:00
|
|
|
|
2021-04-04 03:56:09 -04:00
|
|
|
std::list<VI::Display> displays;
|
2018-01-22 11:54:58 -05:00
|
|
|
|
|
|
|
/// 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;
|
|
|
|
|
2019-06-04 16:10:07 -04:00
|
|
|
u32 swap_interval = 1;
|
|
|
|
|
2019-02-12 12:32:15 -05:00
|
|
|
/// Event that handles screen composition.
|
2022-07-26 17:04:18 -04:00
|
|
|
std::shared_ptr<Core::Timing::EventType> multi_composition_event;
|
|
|
|
std::shared_ptr<Core::Timing::EventType> single_composition_event;
|
2019-02-14 12:42:58 -05:00
|
|
|
|
2020-02-27 09:47:02 -05:00
|
|
|
std::shared_ptr<std::mutex> guard;
|
|
|
|
|
2019-09-21 05:23:31 -04:00
|
|
|
Core::System& system;
|
2020-05-29 15:00:17 -04:00
|
|
|
|
2022-07-26 17:04:18 -04:00
|
|
|
std::atomic<bool> vsync_signal;
|
|
|
|
|
2021-10-02 00:39:57 -04:00
|
|
|
std::jthread vsync_thread;
|
2021-08-07 04:05:46 -04:00
|
|
|
|
|
|
|
KernelHelpers::ServiceContext service_context;
|
2021-11-11 22:15:51 -05:00
|
|
|
|
|
|
|
HosBinderDriverServer& hos_binder_driver_server;
|
2018-01-22 11:54:58 -05:00
|
|
|
};
|
|
|
|
|
2018-04-19 21:41:44 -04:00
|
|
|
} // namespace Service::NVFlinger
|