summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp16
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.h4
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp11
-rw-r--r--src/core/hle/service/vi/display/vi_display.h3
-rw-r--r--src/core/hle/service/vi/layer/vi_layer.h9
-rw-r--r--src/core/hle/service/vi/vi.cpp14
6 files changed, 42 insertions, 15 deletions
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index 0469110e8..af6591370 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -112,9 +112,7 @@ void Nvnflinger::ShutdownLayers() {
112 { 112 {
113 const auto lock_guard = Lock(); 113 const auto lock_guard = Lock();
114 for (auto& display : displays) { 114 for (auto& display : displays) {
115 for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) { 115 display.Abandon();
116 display.GetLayer(layer).GetConsumer().Abandon();
117 }
118 } 116 }
119 117
120 is_abandoned = true; 118 is_abandoned = true;
@@ -176,24 +174,28 @@ void Nvnflinger::CreateLayerAtId(VI::Display& display, u64 layer_id) {
176 display.CreateLayer(layer_id, buffer_id, nvdrv->container); 174 display.CreateLayer(layer_id, buffer_id, nvdrv->container);
177} 175}
178 176
179void Nvnflinger::OpenLayer(u64 layer_id) { 177bool Nvnflinger::OpenLayer(u64 layer_id) {
180 const auto lock_guard = Lock(); 178 const auto lock_guard = Lock();
181 179
182 for (auto& display : displays) { 180 for (auto& display : displays) {
183 if (auto* layer = display.FindLayer(layer_id); layer) { 181 if (auto* layer = display.FindLayer(layer_id); layer) {
184 layer->Open(); 182 return layer->Open();
185 } 183 }
186 } 184 }
185
186 return false;
187} 187}
188 188
189void Nvnflinger::CloseLayer(u64 layer_id) { 189bool Nvnflinger::CloseLayer(u64 layer_id) {
190 const auto lock_guard = Lock(); 190 const auto lock_guard = Lock();
191 191
192 for (auto& display : displays) { 192 for (auto& display : displays) {
193 if (auto* layer = display.FindLayer(layer_id); layer) { 193 if (auto* layer = display.FindLayer(layer_id); layer) {
194 layer->Close(); 194 return layer->Close();
195 } 195 }
196 } 196 }
197
198 return false;
197} 199}
198 200
199void Nvnflinger::DestroyLayer(u64 layer_id) { 201void Nvnflinger::DestroyLayer(u64 layer_id) {
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.h b/src/core/hle/service/nvnflinger/nvnflinger.h
index 871285764..a60e0ae6b 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.h
+++ b/src/core/hle/service/nvnflinger/nvnflinger.h
@@ -74,10 +74,10 @@ public:
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. 76 /// Opens a layer on all displays for the given layer ID.
77 void OpenLayer(u64 layer_id); 77 bool OpenLayer(u64 layer_id);
78 78
79 /// Closes a layer on all displays for the given layer ID. 79 /// Closes a layer on all displays for the given layer ID.
80 void CloseLayer(u64 layer_id); 80 bool CloseLayer(u64 layer_id);
81 81
82 /// Destroys the given layer ID. 82 /// Destroys the given layer ID.
83 void DestroyLayer(u64 layer_id); 83 void DestroyLayer(u64 layer_id);
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index e2d9cd98a..725311c53 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -91,6 +91,10 @@ void Display::CreateLayer(u64 layer_id, u32 binder_id,
91 layers.emplace_back(std::make_unique<Layer>(layer_id, binder_id, *core, *producer, 91 layers.emplace_back(std::make_unique<Layer>(layer_id, binder_id, *core, *producer,
92 std::move(buffer_item_consumer))); 92 std::move(buffer_item_consumer)));
93 93
94 if (is_abandoned) {
95 this->FindLayer(layer_id)->GetConsumer().Abandon();
96 }
97
94 hos_binder_driver_server.RegisterProducer(std::move(producer)); 98 hos_binder_driver_server.RegisterProducer(std::move(producer));
95} 99}
96 100
@@ -103,6 +107,13 @@ void Display::DestroyLayer(u64 layer_id) {
103 [layer_id](const auto& layer) { return layer->GetLayerId() == layer_id; }); 107 [layer_id](const auto& layer) { return layer->GetLayerId() == layer_id; });
104} 108}
105 109
110void Display::Abandon() {
111 for (auto& layer : layers) {
112 layer->GetConsumer().Abandon();
113 }
114 is_abandoned = true;
115}
116
106Layer* Display::FindLayer(u64 layer_id) { 117Layer* Display::FindLayer(u64 layer_id) {
107 const auto itr = 118 const auto itr =
108 std::find_if(layers.begin(), layers.end(), [layer_id](const std::unique_ptr<Layer>& layer) { 119 std::find_if(layers.begin(), layers.end(), [layer_id](const std::unique_ptr<Layer>& layer) {
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h
index 7e68ee79b..8eb8a5155 100644
--- a/src/core/hle/service/vi/display/vi_display.h
+++ b/src/core/hle/service/vi/display/vi_display.h
@@ -98,6 +98,8 @@ public:
98 layers.clear(); 98 layers.clear();
99 } 99 }
100 100
101 void Abandon();
102
101 /// Attempts to find a layer with the given ID. 103 /// Attempts to find a layer with the given ID.
102 /// 104 ///
103 /// @param layer_id The layer ID. 105 /// @param layer_id The layer ID.
@@ -124,6 +126,7 @@ private:
124 126
125 std::vector<std::unique_ptr<Layer>> layers; 127 std::vector<std::unique_ptr<Layer>> layers;
126 Kernel::KEvent* vsync_event{}; 128 Kernel::KEvent* vsync_event{};
129 bool is_abandoned{};
127}; 130};
128 131
129} // namespace Service::VI 132} // namespace Service::VI
diff --git a/src/core/hle/service/vi/layer/vi_layer.h b/src/core/hle/service/vi/layer/vi_layer.h
index 295005e23..f95e2dc71 100644
--- a/src/core/hle/service/vi/layer/vi_layer.h
+++ b/src/core/hle/service/vi/layer/vi_layer.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include <memory> 6#include <memory>
7#include <utility>
7 8
8#include "common/common_types.h" 9#include "common/common_types.h"
9 10
@@ -75,12 +76,12 @@ public:
75 return open; 76 return open;
76 } 77 }
77 78
78 void Close() { 79 bool Close() {
79 open = false; 80 return std::exchange(open, false);
80 } 81 }
81 82
82 void Open() { 83 bool Open() {
83 open = true; 84 return !std::exchange(open, true);
84 } 85 }
85 86
86private: 87private:
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 39d5be90d..bfcc27ddc 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -719,7 +719,12 @@ private:
719 return; 719 return;
720 } 720 }
721 721
722 nvnflinger.OpenLayer(layer_id); 722 if (!nvnflinger.OpenLayer(layer_id)) {
723 LOG_WARNING(Service_VI, "Tried to open layer which was already open");
724 IPC::ResponseBuilder rb{ctx, 2};
725 rb.Push(ResultOperationFailed);
726 return;
727 }
723 728
724 android::OutputParcel parcel; 729 android::OutputParcel parcel;
725 parcel.WriteInterface(NativeWindow{*buffer_queue_id}); 730 parcel.WriteInterface(NativeWindow{*buffer_queue_id});
@@ -737,7 +742,12 @@ private:
737 742
738 LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}", layer_id); 743 LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}", layer_id);
739 744
740 nvnflinger.CloseLayer(layer_id); 745 if (!nvnflinger.CloseLayer(layer_id)) {
746 LOG_WARNING(Service_VI, "Tried to close layer which was not open");
747 IPC::ResponseBuilder rb{ctx, 2};
748 rb.Push(ResultOperationFailed);
749 return;
750 }
741 751
742 IPC::ResponseBuilder rb{ctx, 2}; 752 IPC::ResponseBuilder rb{ctx, 2};
743 rb.Push(ResultSuccess); 753 rb.Push(ResultSuccess);