mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-23 00:40:58 +01:00
service/nvflinger: Relocate definitions of Layer and Display to the vi service
These are more closely related to the vi service as opposed to the
intermediary nvflinger.
This also places them in their relevant subfolder, as future changes to
these will likely result in subclassing to represent various displays
and services, as they're done within the service itself on hardware.
The reasoning for prefixing the display and layer source files is to
avoid potential clashing if two files with the same name are compiled
(e.g. if 'display.cpp/.h' or 'layer.cpp/.h' is added to another service
at any point), which MSVC will actually warn against. This prevents that
case from occurring.
This also presently coverts the std::array introduced within
f45c25aaba
back to a std::vector to allow
the forward declaration of the Display type. Forward declaring a type
within a std::vector is allowed since the introduction of N4510
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4510.html) by
Zhihao Yuan.
This commit is contained in:
parent
4bce08d497
commit
8d5d369b54
7 changed files with 123 additions and 57 deletions
|
@ -400,6 +400,10 @@ add_library(core STATIC
|
||||||
hle/service/time/time.h
|
hle/service/time/time.h
|
||||||
hle/service/usb/usb.cpp
|
hle/service/usb/usb.cpp
|
||||||
hle/service/usb/usb.h
|
hle/service/usb/usb.h
|
||||||
|
hle/service/vi/display/vi_display.cpp
|
||||||
|
hle/service/vi/display/vi_display.h
|
||||||
|
hle/service/vi/layer/vi_layer.cpp
|
||||||
|
hle/service/vi/layer/vi_layer.h
|
||||||
hle/service/vi/vi.cpp
|
hle/service/vi/vi.cpp
|
||||||
hle/service/vi/vi.h
|
hle/service/vi/vi.h
|
||||||
hle/service/vi/vi_m.cpp
|
hle/service/vi/vi_m.cpp
|
||||||
|
|
|
@ -14,11 +14,12 @@
|
||||||
#include "core/core_timing_util.h"
|
#include "core/core_timing_util.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/readable_event.h"
|
#include "core/hle/kernel/readable_event.h"
|
||||||
#include "core/hle/kernel/writable_event.h"
|
|
||||||
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
|
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
|
||||||
#include "core/hle/service/nvdrv/nvdrv.h"
|
#include "core/hle/service/nvdrv/nvdrv.h"
|
||||||
#include "core/hle/service/nvflinger/buffer_queue.h"
|
#include "core/hle/service/nvflinger/buffer_queue.h"
|
||||||
#include "core/hle/service/nvflinger/nvflinger.h"
|
#include "core/hle/service/nvflinger/nvflinger.h"
|
||||||
|
#include "core/hle/service/vi/display/vi_display.h"
|
||||||
|
#include "core/hle/service/vi/layer/vi_layer.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
|
||||||
|
@ -27,7 +28,9 @@ namespace Service::NVFlinger {
|
||||||
constexpr std::size_t SCREEN_REFRESH_RATE = 60;
|
constexpr std::size_t SCREEN_REFRESH_RATE = 60;
|
||||||
constexpr u64 frame_ticks = static_cast<u64>(Core::Timing::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE);
|
constexpr u64 frame_ticks = static_cast<u64>(Core::Timing::BASE_CLOCK_RATE / SCREEN_REFRESH_RATE);
|
||||||
|
|
||||||
NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_timing} {
|
NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing)
|
||||||
|
: displays{{0, "Default"}, {1, "External"}, {2, "Edid"}, {3, "Internal"}, {4, "Null"}},
|
||||||
|
core_timing{core_timing} {
|
||||||
// Schedule the screen composition events
|
// Schedule the screen composition events
|
||||||
composition_event =
|
composition_event =
|
||||||
core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) {
|
core_timing.RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) {
|
||||||
|
@ -53,7 +56,7 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
|
||||||
ASSERT(name == "Default");
|
ASSERT(name == "Default");
|
||||||
|
|
||||||
const auto itr = std::find_if(displays.begin(), displays.end(),
|
const auto itr = std::find_if(displays.begin(), displays.end(),
|
||||||
[&](const Display& display) { return display.name == name; });
|
[&](const VI::Display& display) { return display.name == name; });
|
||||||
if (itr == displays.end()) {
|
if (itr == displays.end()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -106,9 +109,10 @@ std::shared_ptr<BufferQueue> NVFlinger::FindBufferQueue(u32 id) const {
|
||||||
return *itr;
|
return *itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Display* NVFlinger::FindDisplay(u64 display_id) {
|
VI::Display* NVFlinger::FindDisplay(u64 display_id) {
|
||||||
const auto itr = std::find_if(displays.begin(), displays.end(),
|
const auto itr =
|
||||||
[&](const Display& display) { return display.id == display_id; });
|
std::find_if(displays.begin(), displays.end(),
|
||||||
|
[&](const VI::Display& display) { return display.id == display_id; });
|
||||||
|
|
||||||
if (itr == displays.end()) {
|
if (itr == displays.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -117,9 +121,10 @@ Display* NVFlinger::FindDisplay(u64 display_id) {
|
||||||
return &*itr;
|
return &*itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Display* NVFlinger::FindDisplay(u64 display_id) const {
|
const VI::Display* NVFlinger::FindDisplay(u64 display_id) const {
|
||||||
const auto itr = std::find_if(displays.begin(), displays.end(),
|
const auto itr =
|
||||||
[&](const Display& display) { return display.id == display_id; });
|
std::find_if(displays.begin(), displays.end(),
|
||||||
|
[&](const VI::Display& display) { return display.id == display_id; });
|
||||||
|
|
||||||
if (itr == displays.end()) {
|
if (itr == displays.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -128,7 +133,7 @@ const Display* NVFlinger::FindDisplay(u64 display_id) const {
|
||||||
return &*itr;
|
return &*itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
|
VI::Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
|
||||||
auto* const display = FindDisplay(display_id);
|
auto* const display = FindDisplay(display_id);
|
||||||
|
|
||||||
if (display == nullptr) {
|
if (display == nullptr) {
|
||||||
|
@ -136,7 +141,7 @@ Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
|
const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
|
||||||
[&](const Layer& layer) { return layer.id == layer_id; });
|
[&](const VI::Layer& layer) { return layer.id == layer_id; });
|
||||||
|
|
||||||
if (itr == display->layers.end()) {
|
if (itr == display->layers.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -145,7 +150,7 @@ Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
|
||||||
return &*itr;
|
return &*itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
|
const VI::Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
|
||||||
const auto* const display = FindDisplay(display_id);
|
const auto* const display = FindDisplay(display_id);
|
||||||
|
|
||||||
if (display == nullptr) {
|
if (display == nullptr) {
|
||||||
|
@ -153,7 +158,7 @@ const Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
|
const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
|
||||||
[&](const Layer& layer) { return layer.id == layer_id; });
|
[&](const VI::Layer& layer) { return layer.id == layer_id; });
|
||||||
|
|
||||||
if (itr == display->layers.end()) {
|
if (itr == display->layers.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -174,7 +179,7 @@ void NVFlinger::Compose() {
|
||||||
// TODO(Subv): Support more than 1 layer.
|
// TODO(Subv): Support more than 1 layer.
|
||||||
ASSERT_MSG(display.layers.size() == 1, "Max 1 layer per display is supported");
|
ASSERT_MSG(display.layers.size() == 1, "Max 1 layer per display is supported");
|
||||||
|
|
||||||
Layer& layer = display.layers[0];
|
VI::Layer& layer = display.layers[0];
|
||||||
auto& buffer_queue = layer.buffer_queue;
|
auto& buffer_queue = layer.buffer_queue;
|
||||||
|
|
||||||
// Search for a queued buffer and acquire it
|
// Search for a queued buffer and acquire it
|
||||||
|
@ -207,15 +212,4 @@ void NVFlinger::Compose() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {}
|
|
||||||
Layer::~Layer() = default;
|
|
||||||
|
|
||||||
Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) {
|
|
||||||
auto& kernel = Core::System::GetInstance().Kernel();
|
|
||||||
vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky,
|
|
||||||
fmt::format("Display VSync Event {}", id));
|
|
||||||
}
|
|
||||||
|
|
||||||
Display::~Display() = default;
|
|
||||||
|
|
||||||
} // namespace Service::NVFlinger
|
} // namespace Service::NVFlinger
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -26,31 +25,17 @@ class WritableEvent;
|
||||||
|
|
||||||
namespace Service::Nvidia {
|
namespace Service::Nvidia {
|
||||||
class Module;
|
class Module;
|
||||||
}
|
} // namespace Service::Nvidia
|
||||||
|
|
||||||
|
namespace Service::VI {
|
||||||
|
struct Display;
|
||||||
|
struct Layer;
|
||||||
|
} // namespace Service::VI
|
||||||
|
|
||||||
namespace Service::NVFlinger {
|
namespace Service::NVFlinger {
|
||||||
|
|
||||||
class BufferQueue;
|
class BufferQueue;
|
||||||
|
|
||||||
struct Layer {
|
|
||||||
Layer(u64 id, std::shared_ptr<BufferQueue> queue);
|
|
||||||
~Layer();
|
|
||||||
|
|
||||||
u64 id;
|
|
||||||
std::shared_ptr<BufferQueue> buffer_queue;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Display {
|
|
||||||
Display(u64 id, std::string name);
|
|
||||||
~Display();
|
|
||||||
|
|
||||||
u64 id;
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
std::vector<Layer> layers;
|
|
||||||
Kernel::EventPair vsync_event;
|
|
||||||
};
|
|
||||||
|
|
||||||
class NVFlinger final {
|
class NVFlinger final {
|
||||||
public:
|
public:
|
||||||
explicit NVFlinger(Core::Timing::CoreTiming& core_timing);
|
explicit NVFlinger(Core::Timing::CoreTiming& core_timing);
|
||||||
|
@ -88,26 +73,20 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Finds the display identified by the specified ID.
|
/// Finds the display identified by the specified ID.
|
||||||
Display* FindDisplay(u64 display_id);
|
VI::Display* FindDisplay(u64 display_id);
|
||||||
|
|
||||||
/// Finds the display identified by the specified ID.
|
/// Finds the display identified by the specified ID.
|
||||||
const Display* FindDisplay(u64 display_id) const;
|
const VI::Display* FindDisplay(u64 display_id) const;
|
||||||
|
|
||||||
/// Finds the layer identified by the specified ID in the desired display.
|
/// Finds the layer identified by the specified ID in the desired display.
|
||||||
Layer* FindLayer(u64 display_id, u64 layer_id);
|
VI::Layer* FindLayer(u64 display_id, u64 layer_id);
|
||||||
|
|
||||||
/// Finds the layer identified by the specified ID in the desired display.
|
/// Finds the layer identified by the specified ID in the desired display.
|
||||||
const Layer* FindLayer(u64 display_id, u64 layer_id) const;
|
const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const;
|
||||||
|
|
||||||
std::shared_ptr<Nvidia::Module> nvdrv;
|
std::shared_ptr<Nvidia::Module> nvdrv;
|
||||||
|
|
||||||
std::array<Display, 5> displays{{
|
std::vector<VI::Display> displays;
|
||||||
{0, "Default"},
|
|
||||||
{1, "External"},
|
|
||||||
{2, "Edid"},
|
|
||||||
{3, "Internal"},
|
|
||||||
{4, "Null"},
|
|
||||||
}};
|
|
||||||
std::vector<std::shared_ptr<BufferQueue>> buffer_queues;
|
std::vector<std::shared_ptr<BufferQueue>> buffer_queues;
|
||||||
|
|
||||||
/// Id to use for the next layer that is created, this counter is shared among all displays.
|
/// Id to use for the next layer that is created, this counter is shared among all displays.
|
||||||
|
|
22
src/core/hle/service/vi/display/vi_display.cpp
Normal file
22
src/core/hle/service/vi/display/vi_display.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/hle/kernel/readable_event.h"
|
||||||
|
#include "core/hle/service/vi/display/vi_display.h"
|
||||||
|
#include "core/hle/service/vi/layer/vi_layer.h"
|
||||||
|
|
||||||
|
namespace Service::VI {
|
||||||
|
|
||||||
|
Display::Display(u64 id, std::string name) : id{id}, name{std::move(name)} {
|
||||||
|
auto& kernel = Core::System::GetInstance().Kernel();
|
||||||
|
vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky,
|
||||||
|
fmt::format("Display VSync Event {}", id));
|
||||||
|
}
|
||||||
|
|
||||||
|
Display::~Display() = default;
|
||||||
|
|
||||||
|
} // namespace Service::VI
|
28
src/core/hle/service/vi/display/vi_display.h
Normal file
28
src/core/hle/service/vi/display/vi_display.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/kernel/writable_event.h"
|
||||||
|
|
||||||
|
namespace Service::VI {
|
||||||
|
|
||||||
|
struct Layer;
|
||||||
|
|
||||||
|
struct Display {
|
||||||
|
Display(u64 id, std::string name);
|
||||||
|
~Display();
|
||||||
|
|
||||||
|
u64 id;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
std::vector<Layer> layers;
|
||||||
|
Kernel::EventPair vsync_event;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::VI
|
14
src/core/hle/service/vi/layer/vi_layer.cpp
Normal file
14
src/core/hle/service/vi/layer/vi_layer.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/hle/service/vi/layer/vi_layer.h"
|
||||||
|
|
||||||
|
namespace Service::VI {
|
||||||
|
|
||||||
|
Layer::Layer(u64 id, std::shared_ptr<NVFlinger::BufferQueue> queue)
|
||||||
|
: id{id}, buffer_queue{std::move(queue)} {}
|
||||||
|
|
||||||
|
Layer::~Layer() = default;
|
||||||
|
|
||||||
|
} // namespace Service::VI
|
25
src/core/hle/service/vi/layer/vi_layer.h
Normal file
25
src/core/hle/service/vi/layer/vi_layer.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Service::NVFlinger {
|
||||||
|
class BufferQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Service::VI {
|
||||||
|
|
||||||
|
struct Layer {
|
||||||
|
Layer(u64 id, std::shared_ptr<NVFlinger::BufferQueue> queue);
|
||||||
|
~Layer();
|
||||||
|
|
||||||
|
u64 id;
|
||||||
|
std::shared_ptr<NVFlinger::BufferQueue> buffer_queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::VI
|
Loading…
Reference in a new issue