diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nvnflinger/nvnflinger.cpp | 42 | ||||
| -rw-r--r-- | src/core/hle/service/nvnflinger/nvnflinger.h | 11 | ||||
| -rw-r--r-- | src/core/hle/service/vi/display/vi_display.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/service/vi/display/vi_display.h | 15 | ||||
| -rw-r--r-- | src/core/hle/service/vi/layer/vi_layer.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/vi/layer/vi_layer.h | 13 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 3 |
8 files changed, 74 insertions, 42 deletions
diff --git a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp index 75bf31e32..2fef6cc1a 100644 --- a/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp +++ b/src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp | |||
| @@ -204,8 +204,9 @@ Result FbShareBufferManager::Initialize(u64* out_buffer_id, u64* out_layer_id, u | |||
| 204 | // Record the display id. | 204 | // Record the display id. |
| 205 | m_display_id = display_id; | 205 | m_display_id = display_id; |
| 206 | 206 | ||
| 207 | // Create a layer for the display. | 207 | // Create and open a layer for the display. |
| 208 | m_layer_id = m_flinger.CreateLayer(m_display_id).value(); | 208 | m_layer_id = m_flinger.CreateLayer(m_display_id).value(); |
| 209 | m_flinger.OpenLayer(m_layer_id); | ||
| 209 | 210 | ||
| 210 | // Set up the buffer. | 211 | // Set up the buffer. |
| 211 | m_buffer_id = m_next_buffer_id++; | 212 | m_buffer_id = m_next_buffer_id++; |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp index 0745434c5..6352b09a9 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.cpp +++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp | |||
| @@ -176,17 +176,37 @@ void Nvnflinger::CreateLayerAtId(VI::Display& display, u64 layer_id) { | |||
| 176 | display.CreateLayer(layer_id, buffer_id, nvdrv->container); | 176 | display.CreateLayer(layer_id, buffer_id, nvdrv->container); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | void Nvnflinger::OpenLayer(u64 layer_id) { | ||
| 180 | const auto lock_guard = Lock(); | ||
| 181 | |||
| 182 | for (auto& display : displays) { | ||
| 183 | if (auto* layer = display.FindLayer(layer_id); layer) { | ||
| 184 | layer->Open(); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 179 | void Nvnflinger::CloseLayer(u64 layer_id) { | 189 | void Nvnflinger::CloseLayer(u64 layer_id) { |
| 180 | const auto lock_guard = Lock(); | 190 | const auto lock_guard = Lock(); |
| 181 | 191 | ||
| 182 | for (auto& display : displays) { | 192 | for (auto& display : displays) { |
| 183 | display.CloseLayer(layer_id); | 193 | if (auto* layer = display.FindLayer(layer_id); layer) { |
| 194 | layer->Close(); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | void Nvnflinger::DestroyLayer(u64 layer_id) { | ||
| 200 | const auto lock_guard = Lock(); | ||
| 201 | |||
| 202 | for (auto& display : displays) { | ||
| 203 | display.DestroyLayer(layer_id); | ||
| 184 | } | 204 | } |
| 185 | } | 205 | } |
| 186 | 206 | ||
| 187 | std::optional<u32> Nvnflinger::FindBufferQueueId(u64 display_id, u64 layer_id) { | 207 | std::optional<u32> Nvnflinger::FindBufferQueueId(u64 display_id, u64 layer_id) { |
| 188 | const auto lock_guard = Lock(); | 208 | const auto lock_guard = Lock(); |
| 189 | const auto* const layer = FindOrCreateLayer(display_id, layer_id); | 209 | const auto* const layer = FindLayer(display_id, layer_id); |
| 190 | 210 | ||
| 191 | if (layer == nullptr) { | 211 | if (layer == nullptr) { |
| 192 | return std::nullopt; | 212 | return std::nullopt; |
| @@ -240,24 +260,6 @@ VI::Layer* Nvnflinger::FindLayer(u64 display_id, u64 layer_id) { | |||
| 240 | return display->FindLayer(layer_id); | 260 | return display->FindLayer(layer_id); |
| 241 | } | 261 | } |
| 242 | 262 | ||
| 243 | VI::Layer* Nvnflinger::FindOrCreateLayer(u64 display_id, u64 layer_id) { | ||
| 244 | auto* const display = FindDisplay(display_id); | ||
| 245 | |||
| 246 | if (display == nullptr) { | ||
| 247 | return nullptr; | ||
| 248 | } | ||
| 249 | |||
| 250 | auto* layer = display->FindLayer(layer_id); | ||
| 251 | |||
| 252 | if (layer == nullptr) { | ||
| 253 | LOG_DEBUG(Service_Nvnflinger, "Layer at id {} not found. Trying to create it.", layer_id); | ||
| 254 | CreateLayerAtId(*display, layer_id); | ||
| 255 | return display->FindLayer(layer_id); | ||
| 256 | } | ||
| 257 | |||
| 258 | return layer; | ||
| 259 | } | ||
| 260 | |||
| 261 | void Nvnflinger::Compose() { | 263 | void Nvnflinger::Compose() { |
| 262 | for (auto& display : displays) { | 264 | for (auto& display : displays) { |
| 263 | // Trigger vsync for this display at the end of drawing | 265 | // Trigger vsync for this display at the end of drawing |
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h index f5d73acdb..871285764 100644 --- a/src/core/hle/service/nvnflinger/nvnflinger.h +++ b/src/core/hle/service/nvnflinger/nvnflinger.h | |||
| @@ -73,9 +73,15 @@ public: | |||
| 73 | /// If an invalid display ID is specified, then an empty optional is returned. | 73 | /// If an invalid display ID is specified, then an empty optional is returned. |
| 74 | [[nodiscard]] std::optional<u64> CreateLayer(u64 display_id); | 74 | [[nodiscard]] std::optional<u64> CreateLayer(u64 display_id); |
| 75 | 75 | ||
| 76 | /// Opens a layer on all displays for the given layer ID. | ||
| 77 | void OpenLayer(u64 layer_id); | ||
| 78 | |||
| 76 | /// Closes a layer on all displays for the given layer ID. | 79 | /// Closes a layer on all displays for the given layer ID. |
| 77 | void CloseLayer(u64 layer_id); | 80 | void CloseLayer(u64 layer_id); |
| 78 | 81 | ||
| 82 | /// Destroys the given layer ID. | ||
| 83 | void DestroyLayer(u64 layer_id); | ||
| 84 | |||
| 79 | /// Finds the buffer queue ID of the specified layer in the specified display. | 85 | /// Finds the buffer queue ID of the specified layer in the specified display. |
| 80 | /// | 86 | /// |
| 81 | /// If an invalid display ID or layer ID is provided, then an empty optional is returned. | 87 | /// If an invalid display ID or layer ID is provided, then an empty optional is returned. |
| @@ -117,11 +123,6 @@ private: | |||
| 117 | /// Finds the layer identified by the specified ID in the desired display. | 123 | /// Finds the layer identified by the specified ID in the desired display. |
| 118 | [[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id); | 124 | [[nodiscard]] VI::Layer* FindLayer(u64 display_id, u64 layer_id); |
| 119 | 125 | ||
| 120 | /// Finds the layer identified by the specified ID in the desired display, | ||
| 121 | /// or creates the layer if it is not found. | ||
| 122 | /// To be used when the system expects the specified ID to already exist. | ||
| 123 | [[nodiscard]] VI::Layer* FindOrCreateLayer(u64 display_id, u64 layer_id); | ||
| 124 | |||
| 125 | /// Creates a layer with the specified layer ID in the desired display. | 126 | /// Creates a layer with the specified layer ID in the desired display. |
| 126 | void CreateLayerAtId(VI::Display& display, u64 layer_id); | 127 | void CreateLayerAtId(VI::Display& display, u64 layer_id); |
| 127 | 128 | ||
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index d30f49877..71ce9be50 100644 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp | |||
| @@ -51,11 +51,24 @@ Display::~Display() { | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | Layer& Display::GetLayer(std::size_t index) { | 53 | Layer& Display::GetLayer(std::size_t index) { |
| 54 | return *layers.at(index); | 54 | size_t i = 0; |
| 55 | for (auto& layer : layers) { | ||
| 56 | if (!layer->IsOpen()) { | ||
| 57 | continue; | ||
| 58 | } | ||
| 59 | |||
| 60 | if (i == index) { | ||
| 61 | return *layer; | ||
| 62 | } | ||
| 63 | |||
| 64 | i++; | ||
| 65 | } | ||
| 66 | |||
| 67 | UNREACHABLE(); | ||
| 55 | } | 68 | } |
| 56 | 69 | ||
| 57 | const Layer& Display::GetLayer(std::size_t index) const { | 70 | size_t Display::GetNumLayers() const { |
| 58 | return *layers.at(index); | 71 | return std::ranges::count_if(layers, [](auto& l) { return l->IsOpen(); }); |
| 59 | } | 72 | } |
| 60 | 73 | ||
| 61 | Result Display::GetVSyncEvent(Kernel::KReadableEvent** out_vsync_event) { | 74 | Result Display::GetVSyncEvent(Kernel::KReadableEvent** out_vsync_event) { |
| @@ -92,7 +105,11 @@ void Display::CreateLayer(u64 layer_id, u32 binder_id, | |||
| 92 | hos_binder_driver_server.RegisterProducer(std::move(producer)); | 105 | hos_binder_driver_server.RegisterProducer(std::move(producer)); |
| 93 | } | 106 | } |
| 94 | 107 | ||
| 95 | void Display::CloseLayer(u64 layer_id) { | 108 | void Display::DestroyLayer(u64 layer_id) { |
| 109 | if (auto* layer = this->FindLayer(layer_id); layer != nullptr) { | ||
| 110 | layer->GetConsumer().Abandon(); | ||
| 111 | } | ||
| 112 | |||
| 96 | std::erase_if(layers, | 113 | std::erase_if(layers, |
| 97 | [layer_id](const auto& layer) { return layer->GetLayerId() == layer_id; }); | 114 | [layer_id](const auto& layer) { return layer->GetLayerId() == layer_id; }); |
| 98 | } | 115 | } |
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h index 101cbce20..1d9360b96 100644 --- a/src/core/hle/service/vi/display/vi_display.h +++ b/src/core/hle/service/vi/display/vi_display.h | |||
| @@ -66,18 +66,13 @@ public: | |||
| 66 | 66 | ||
| 67 | /// Whether or not this display has any layers added to it. | 67 | /// Whether or not this display has any layers added to it. |
| 68 | bool HasLayers() const { | 68 | bool HasLayers() const { |
| 69 | return !layers.empty(); | 69 | return GetNumLayers() > 0; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | /// Gets a layer for this display based off an index. | 72 | /// Gets a layer for this display based off an index. |
| 73 | Layer& GetLayer(std::size_t index); | 73 | Layer& GetLayer(std::size_t index); |
| 74 | 74 | ||
| 75 | /// Gets a layer for this display based off an index. | 75 | std::size_t GetNumLayers() const; |
| 76 | const Layer& GetLayer(std::size_t index) const; | ||
| 77 | |||
| 78 | std::size_t GetNumLayers() const { | ||
| 79 | return layers.size(); | ||
| 80 | } | ||
| 81 | 76 | ||
| 82 | /** | 77 | /** |
| 83 | * Gets the internal vsync event. | 78 | * Gets the internal vsync event. |
| @@ -100,11 +95,11 @@ public: | |||
| 100 | /// | 95 | /// |
| 101 | void CreateLayer(u64 layer_id, u32 binder_id, Service::Nvidia::NvCore::Container& core); | 96 | void CreateLayer(u64 layer_id, u32 binder_id, Service::Nvidia::NvCore::Container& core); |
| 102 | 97 | ||
| 103 | /// Closes and removes a layer from this display with the given ID. | 98 | /// Removes a layer from this display with the given ID. |
| 104 | /// | 99 | /// |
| 105 | /// @param layer_id The ID assigned to the layer to close. | 100 | /// @param layer_id The ID assigned to the layer to destroy. |
| 106 | /// | 101 | /// |
| 107 | void CloseLayer(u64 layer_id); | 102 | void DestroyLayer(u64 layer_id); |
| 108 | 103 | ||
| 109 | /// Resets the display for a new connection. | 104 | /// Resets the display for a new connection. |
| 110 | void Reset() { | 105 | void Reset() { |
diff --git a/src/core/hle/service/vi/layer/vi_layer.cpp b/src/core/hle/service/vi/layer/vi_layer.cpp index 9ae2e0e44..04e52a23b 100644 --- a/src/core/hle/service/vi/layer/vi_layer.cpp +++ b/src/core/hle/service/vi/layer/vi_layer.cpp | |||
| @@ -8,8 +8,8 @@ namespace Service::VI { | |||
| 8 | Layer::Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_, | 8 | Layer::Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_, |
| 9 | android::BufferQueueProducer& binder_, | 9 | android::BufferQueueProducer& binder_, |
| 10 | std::shared_ptr<android::BufferItemConsumer>&& consumer_) | 10 | std::shared_ptr<android::BufferItemConsumer>&& consumer_) |
| 11 | : layer_id{layer_id_}, binder_id{binder_id_}, core{core_}, binder{binder_}, consumer{std::move( | 11 | : layer_id{layer_id_}, binder_id{binder_id_}, core{core_}, binder{binder_}, |
| 12 | consumer_)} {} | 12 | consumer{std::move(consumer_)}, open{false} {} |
| 13 | 13 | ||
| 14 | Layer::~Layer() = default; | 14 | Layer::~Layer() = default; |
| 15 | 15 | ||
diff --git a/src/core/hle/service/vi/layer/vi_layer.h b/src/core/hle/service/vi/layer/vi_layer.h index 8cf1b5275..295005e23 100644 --- a/src/core/hle/service/vi/layer/vi_layer.h +++ b/src/core/hle/service/vi/layer/vi_layer.h | |||
| @@ -71,12 +71,25 @@ public: | |||
| 71 | return core; | 71 | return core; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | bool IsOpen() const { | ||
| 75 | return open; | ||
| 76 | } | ||
| 77 | |||
| 78 | void Close() { | ||
| 79 | open = false; | ||
| 80 | } | ||
| 81 | |||
| 82 | void Open() { | ||
| 83 | open = true; | ||
| 84 | } | ||
| 85 | |||
| 74 | private: | 86 | private: |
| 75 | const u64 layer_id; | 87 | const u64 layer_id; |
| 76 | const u32 binder_id; | 88 | const u32 binder_id; |
| 77 | android::BufferQueueCore& core; | 89 | android::BufferQueueCore& core; |
| 78 | android::BufferQueueProducer& binder; | 90 | android::BufferQueueProducer& binder; |
| 79 | std::shared_ptr<android::BufferItemConsumer> consumer; | 91 | std::shared_ptr<android::BufferItemConsumer> consumer; |
| 92 | bool open; | ||
| 80 | }; | 93 | }; |
| 81 | 94 | ||
| 82 | } // namespace Service::VI | 95 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index b1bfb9898..9ab8788e3 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -719,6 +719,8 @@ private: | |||
| 719 | return; | 719 | return; |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | nv_flinger.OpenLayer(layer_id); | ||
| 723 | |||
| 722 | android::OutputParcel parcel; | 724 | android::OutputParcel parcel; |
| 723 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); | 725 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); |
| 724 | 726 | ||
| @@ -783,6 +785,7 @@ private: | |||
| 783 | const u64 layer_id = rp.Pop<u64>(); | 785 | const u64 layer_id = rp.Pop<u64>(); |
| 784 | 786 | ||
| 785 | LOG_WARNING(Service_VI, "(STUBBED) called. layer_id=0x{:016X}", layer_id); | 787 | LOG_WARNING(Service_VI, "(STUBBED) called. layer_id=0x{:016X}", layer_id); |
| 788 | nv_flinger.DestroyLayer(layer_id); | ||
| 786 | 789 | ||
| 787 | IPC::ResponseBuilder rb{ctx, 2}; | 790 | IPC::ResponseBuilder rb{ctx, 2}; |
| 788 | rb.Push(ResultSuccess); | 791 | rb.Push(ResultSuccess); |