service: vi: Implement CloseLayer.
- Needed for Undertale.
This commit is contained in:
		@@ -88,6 +88,12 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
 | 
			
		||||
    return layer_id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NVFlinger::CloseLayer(u64 layer_id) {
 | 
			
		||||
    for (auto& display : displays) {
 | 
			
		||||
        display.CloseLayer(layer_id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const {
 | 
			
		||||
    const auto* const layer = FindLayer(display_id, layer_id);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -54,6 +54,9 @@ public:
 | 
			
		||||
    /// If an invalid display ID is specified, then an empty optional is returned.
 | 
			
		||||
    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.
 | 
			
		||||
 
 | 
			
		||||
@@ -24,11 +24,11 @@ Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{
 | 
			
		||||
Display::~Display() = default;
 | 
			
		||||
 | 
			
		||||
Layer& Display::GetLayer(std::size_t index) {
 | 
			
		||||
    return layers.at(index);
 | 
			
		||||
    return *layers.at(index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Layer& Display::GetLayer(std::size_t index) const {
 | 
			
		||||
    return layers.at(index);
 | 
			
		||||
    return *layers.at(index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Kernel::ReadableEvent> Display::GetVSyncEvent() const {
 | 
			
		||||
@@ -43,29 +43,38 @@ void Display::CreateLayer(u64 id, NVFlinger::BufferQueue& buffer_queue) {
 | 
			
		||||
    // TODO(Subv): Support more than 1 layer.
 | 
			
		||||
    ASSERT_MSG(layers.empty(), "Only one layer is supported per display at the moment");
 | 
			
		||||
 | 
			
		||||
    layers.emplace_back(id, buffer_queue);
 | 
			
		||||
    layers.emplace_back(std::make_shared<Layer>(id, buffer_queue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Display::CloseLayer(u64 id) {
 | 
			
		||||
    layers.erase(
 | 
			
		||||
        std::remove_if(layers.begin(), layers.end(),
 | 
			
		||||
                       [id](const std::shared_ptr<Layer>& layer) { return layer->GetID() == id; }),
 | 
			
		||||
        layers.end());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Layer* Display::FindLayer(u64 id) {
 | 
			
		||||
    const auto itr = std::find_if(layers.begin(), layers.end(),
 | 
			
		||||
                                  [id](const VI::Layer& layer) { return layer.GetID() == id; });
 | 
			
		||||
    const auto itr =
 | 
			
		||||
        std::find_if(layers.begin(), layers.end(),
 | 
			
		||||
                     [id](const std::shared_ptr<Layer>& layer) { return layer->GetID() == id; });
 | 
			
		||||
 | 
			
		||||
    if (itr == layers.end()) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return &*itr;
 | 
			
		||||
    return itr->get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Layer* Display::FindLayer(u64 id) const {
 | 
			
		||||
    const auto itr = std::find_if(layers.begin(), layers.end(),
 | 
			
		||||
                                  [id](const VI::Layer& layer) { return layer.GetID() == id; });
 | 
			
		||||
    const auto itr =
 | 
			
		||||
        std::find_if(layers.begin(), layers.end(),
 | 
			
		||||
                     [id](const std::shared_ptr<Layer>& layer) { return layer->GetID() == id; });
 | 
			
		||||
 | 
			
		||||
    if (itr == layers.end()) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return &*itr;
 | 
			
		||||
    return itr->get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Service::VI
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@@ -69,6 +70,12 @@ public:
 | 
			
		||||
    ///
 | 
			
		||||
    void CreateLayer(u64 id, NVFlinger::BufferQueue& buffer_queue);
 | 
			
		||||
 | 
			
		||||
    /// Closes and removes a layer from this display with the given ID.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @param id           The ID assigned to the layer to close.
 | 
			
		||||
    ///
 | 
			
		||||
    void CloseLayer(u64 id);
 | 
			
		||||
 | 
			
		||||
    /// Attempts to find a layer with the given ID.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @param id The layer ID.
 | 
			
		||||
@@ -91,7 +98,7 @@ private:
 | 
			
		||||
    u64 id;
 | 
			
		||||
    std::string name;
 | 
			
		||||
 | 
			
		||||
    std::vector<Layer> layers;
 | 
			
		||||
    std::vector<std::shared_ptr<Layer>> layers;
 | 
			
		||||
    Kernel::EventPair vsync_event;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1066,6 +1066,18 @@ private:
 | 
			
		||||
        rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void CloseLayer(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        IPC::RequestParser rp{ctx};
 | 
			
		||||
        const auto layer_id{rp.Pop<u64>()};
 | 
			
		||||
 | 
			
		||||
        LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}", layer_id);
 | 
			
		||||
 | 
			
		||||
        nv_flinger->CloseLayer(layer_id);
 | 
			
		||||
 | 
			
		||||
        IPC::ResponseBuilder rb{ctx, 2};
 | 
			
		||||
        rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void CreateStrayLayer(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
        IPC::RequestParser rp{ctx};
 | 
			
		||||
        const u32 flags = rp.Pop<u32>();
 | 
			
		||||
@@ -1178,7 +1190,7 @@ IApplicationDisplayService::IApplicationDisplayService(
 | 
			
		||||
        {1101, &IApplicationDisplayService::SetDisplayEnabled, "SetDisplayEnabled"},
 | 
			
		||||
        {1102, &IApplicationDisplayService::GetDisplayResolution, "GetDisplayResolution"},
 | 
			
		||||
        {2020, &IApplicationDisplayService::OpenLayer, "OpenLayer"},
 | 
			
		||||
        {2021, nullptr, "CloseLayer"},
 | 
			
		||||
        {2021, &IApplicationDisplayService::CloseLayer, "CloseLayer"},
 | 
			
		||||
        {2030, &IApplicationDisplayService::CreateStrayLayer, "CreateStrayLayer"},
 | 
			
		||||
        {2031, &IApplicationDisplayService::DestroyStrayLayer, "DestroyStrayLayer"},
 | 
			
		||||
        {2101, &IApplicationDisplayService::SetLayerScalingMode, "SetLayerScalingMode"},
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user