summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/nvnflinger/fb_share_buffer_manager.cpp3
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp42
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.h11
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp25
-rw-r--r--src/core/hle/service/vi/display/vi_display.h15
-rw-r--r--src/core/hle/service/vi/layer/vi_layer.cpp4
-rw-r--r--src/core/hle/service/vi/layer/vi_layer.h13
-rw-r--r--src/core/hle/service/vi/vi.cpp3
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
179void 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
179void Nvnflinger::CloseLayer(u64 layer_id) { 189void 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
199void 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
187std::optional<u32> Nvnflinger::FindBufferQueueId(u64 display_id, u64 layer_id) { 207std::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
243VI::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
261void Nvnflinger::Compose() { 263void 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
53Layer& Display::GetLayer(std::size_t index) { 53Layer& 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
57const Layer& Display::GetLayer(std::size_t index) const { 70size_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
61Result Display::GetVSyncEvent(Kernel::KReadableEvent** out_vsync_event) { 74Result 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
95void Display::CloseLayer(u64 layer_id) { 108void 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 {
8Layer::Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_, 8Layer::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
14Layer::~Layer() = default; 14Layer::~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
74private: 86private:
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);