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:
Lioncash 2019-02-19 17:00:03 -05:00
parent 4bce08d497
commit 8d5d369b54
7 changed files with 123 additions and 57 deletions

View File

@ -400,6 +400,10 @@ add_library(core STATIC
hle/service/time/time.h
hle/service/usb/usb.cpp
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.h
hle/service/vi/vi_m.cpp

View File

@ -14,11 +14,12 @@
#include "core/core_timing_util.h"
#include "core/hle/kernel/kernel.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/nvdrv.h"
#include "core/hle/service/nvflinger/buffer_queue.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 "video_core/renderer_base.h"
@ -27,7 +28,9 @@ namespace Service::NVFlinger {
constexpr std::size_t SCREEN_REFRESH_RATE = 60;
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
composition_event =
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");
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()) {
return {};
}
@ -106,9 +109,10 @@ std::shared_ptr<BufferQueue> NVFlinger::FindBufferQueue(u32 id) const {
return *itr;
}
Display* NVFlinger::FindDisplay(u64 display_id) {
const auto itr = std::find_if(displays.begin(), displays.end(),
[&](const Display& display) { return display.id == display_id; });
VI::Display* NVFlinger::FindDisplay(u64 display_id) {
const auto itr =
std::find_if(displays.begin(), displays.end(),
[&](const VI::Display& display) { return display.id == display_id; });
if (itr == displays.end()) {
return nullptr;
@ -117,9 +121,10 @@ Display* NVFlinger::FindDisplay(u64 display_id) {
return &*itr;
}
const Display* NVFlinger::FindDisplay(u64 display_id) const {
const auto itr = std::find_if(displays.begin(), displays.end(),
[&](const Display& display) { return display.id == display_id; });
const VI::Display* NVFlinger::FindDisplay(u64 display_id) const {
const auto itr =
std::find_if(displays.begin(), displays.end(),
[&](const VI::Display& display) { return display.id == display_id; });
if (itr == displays.end()) {
return nullptr;
@ -128,7 +133,7 @@ const Display* NVFlinger::FindDisplay(u64 display_id) const {
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);
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 Layer& layer) { return layer.id == layer_id; });
[&](const VI::Layer& layer) { return layer.id == layer_id; });
if (itr == display->layers.end()) {
return nullptr;
@ -145,7 +150,7 @@ Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
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);
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 Layer& layer) { return layer.id == layer_id; });
[&](const VI::Layer& layer) { return layer.id == layer_id; });
if (itr == display->layers.end()) {
return nullptr;
@ -174,7 +179,7 @@ void NVFlinger::Compose() {
// TODO(Subv): Support more than 1 layer.
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;
// 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

View File

@ -4,7 +4,6 @@
#pragma once
#include <array>
#include <memory>
#include <optional>
#include <string>
@ -26,31 +25,17 @@ class WritableEvent;
namespace Service::Nvidia {
class Module;
}
} // namespace Service::Nvidia
namespace Service::VI {
struct Display;
struct Layer;
} // namespace Service::VI
namespace Service::NVFlinger {
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 {
public:
explicit NVFlinger(Core::Timing::CoreTiming& core_timing);
@ -88,26 +73,20 @@ public:
private:
/// 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.
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.
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.
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::array<Display, 5> displays{{
{0, "Default"},
{1, "External"},
{2, "Edid"},
{3, "Internal"},
{4, "Null"},
}};
std::vector<VI::Display> displays;
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.

View 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

View 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

View 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

View 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