From 940a71422e18b6305556d0efc2588a90f156ae04 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 18 Feb 2024 11:25:47 -0500
Subject: [PATCH] nvnflinger: check for layers before compose

---
 src/core/hle/service/nvnflinger/display.h           | 4 ++++
 src/core/hle/service/nvnflinger/surface_flinger.cpp | 7 ++++---
 src/core/hle/service/nvnflinger/surface_flinger.h   | 2 +-
 src/core/hle/service/vi/container.cpp               | 5 +++--
 src/core/hle/service/vi/container.h                 | 2 +-
 5 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/core/hle/service/nvnflinger/display.h b/src/core/hle/service/nvnflinger/display.h
index 8a1956fe0..f27cbf144 100644
--- a/src/core/hle/service/nvnflinger/display.h
+++ b/src/core/hle/service/nvnflinger/display.h
@@ -44,6 +44,10 @@ struct Display {
         return nullptr;
     }
 
+    bool HasLayers() {
+        return !stack.layers.empty();
+    }
+
     u64 id;
     LayerStack stack;
 };
diff --git a/src/core/hle/service/nvnflinger/surface_flinger.cpp b/src/core/hle/service/nvnflinger/surface_flinger.cpp
index 0e9714a03..41a705717 100644
--- a/src/core/hle/service/nvnflinger/surface_flinger.cpp
+++ b/src/core/hle/service/nvnflinger/surface_flinger.cpp
@@ -33,16 +33,17 @@ void SurfaceFlinger::RemoveDisplay(u64 display_id) {
     std::erase_if(m_displays, [&](auto& display) { return display.id == display_id; });
 }
 
-void SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
+bool SurfaceFlinger::ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
                                     u64 display_id) {
     auto* const display = this->FindDisplay(display_id);
-    if (!display) {
-        return;
+    if (!display || !display->HasLayers()) {
+        return false;
     }
 
     *out_swap_interval =
         m_composer.ComposeLocked(out_compose_speed_scale, *display,
                                  *nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd));
+    return true;
 }
 
 void SurfaceFlinger::AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id) {
diff --git a/src/core/hle/service/nvnflinger/surface_flinger.h b/src/core/hle/service/nvnflinger/surface_flinger.h
index a2e661430..d8c53fbda 100644
--- a/src/core/hle/service/nvnflinger/surface_flinger.h
+++ b/src/core/hle/service/nvnflinger/surface_flinger.h
@@ -34,7 +34,7 @@ public:
 
     void AddDisplay(u64 display_id);
     void RemoveDisplay(u64 display_id);
-    void ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
+    bool ComposeDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
 
     void AddLayerToDisplayStack(u64 display_id, s32 consumer_binder_id);
     void RemoveLayerFromDisplayStack(u64 display_id, s32 consumer_binder_id);
diff --git a/src/core/hle/service/vi/container.cpp b/src/core/hle/service/vi/container.cpp
index 2d6b9cbfe..310a207f1 100644
--- a/src/core/hle/service/vi/container.cpp
+++ b/src/core/hle/service/vi/container.cpp
@@ -218,10 +218,11 @@ void Container::DestroyBufferQueueLocked(Layer* layer) {
                                           layer->GetProducerBinderId());
 }
 
-void Container::ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
+bool Container::ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale,
                                  u64 display_id) {
     std::scoped_lock lk{m_lock};
-    m_surface_flinger->ComposeDisplay(out_swap_interval, out_compose_speed_scale, display_id);
+    return m_surface_flinger->ComposeDisplay(out_swap_interval, out_compose_speed_scale,
+                                             display_id);
 }
 
 } // namespace Service::VI
diff --git a/src/core/hle/service/vi/container.h b/src/core/hle/service/vi/container.h
index 155c4c629..cd0d2ca86 100644
--- a/src/core/hle/service/vi/container.h
+++ b/src/core/hle/service/vi/container.h
@@ -76,7 +76,7 @@ private:
     void DestroyBufferQueueLocked(Layer* layer);
 
 public:
-    void ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
+    bool ComposeOnDisplay(s32* out_swap_interval, f32* out_compose_speed_scale, u64 display_id);
 
 private:
     std::mutex m_lock{};