summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nvflinger
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/nvflinger')
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.cpp7
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp25
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h7
3 files changed, 35 insertions, 4 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
index 77ddbb6ef..41ba44b21 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
@@ -742,6 +742,13 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
return Status::NoError;
}
+ // HACK: We are not Android. Remove handle for items in queue, and clear queue.
+ // Allows synchronous destruction of nvmap handles.
+ for (auto& item : core->queue) {
+ nvmap.FreeHandle(item.graphic_buffer->BufferId(), true);
+ }
+ core->queue.clear();
+
switch (api) {
case NativeWindowApi::Egl:
case NativeWindowApi::Cpu:
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index aa14d2cbc..c3af12c90 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -102,15 +102,19 @@ NVFlinger::~NVFlinger() {
system.CoreTiming().UnscheduleEvent(single_composition_event, {});
}
+ ShutdownLayers();
+
+ if (nvdrv) {
+ nvdrv->Close(disp_fd);
+ }
+}
+
+void NVFlinger::ShutdownLayers() {
for (auto& display : displays) {
for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
display.GetLayer(layer).Core().NotifyShutdown();
}
}
-
- if (nvdrv) {
- nvdrv->Close(disp_fd);
- }
}
void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
@@ -134,6 +138,19 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
return itr->GetID();
}
+bool NVFlinger::CloseDisplay(u64 display_id) {
+ const auto lock_guard = Lock();
+ auto* const display = FindDisplay(display_id);
+
+ if (display == nullptr) {
+ return false;
+ }
+
+ display->Reset();
+
+ return true;
+}
+
std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
const auto lock_guard = Lock();
auto* const display = FindDisplay(display_id);
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 99509bc5b..460bef976 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -48,6 +48,8 @@ public:
explicit NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_);
~NVFlinger();
+ void ShutdownLayers();
+
/// Sets the NVDrv module instance to use to send buffers to the GPU.
void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance);
@@ -56,6 +58,11 @@ public:
/// If an invalid display name is provided, then an empty optional is returned.
[[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name);
+ /// Closes the specified display by its ID.
+ ///
+ /// Returns false if an invalid display ID is provided.
+ [[nodiscard]] bool CloseDisplay(u64 display_id);
+
/// Creates a layer on the specified display and returns the layer ID.
///
/// If an invalid display ID is specified, then an empty optional is returned.