From 82bfdeccd9cf17aa581ff49a356ef4a8bd45860b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=98yvind=20Kol=C3=A5s?= <pippin@gimp.org>
Date: Fri, 15 Sep 2023 19:00:41 +0200
Subject: [PATCH] py,st3m-ui: hold overlays mutex for shorter intervals

For fps overlay only show every 5th frame, for the regular overlay
first collect list of active overlays, and only if there is overlays
active get and flush the overlay ctx.

Also clearing a smaller rectangle with default overlays - the fps code
which does a lot less work is more reliable for use with mpremote.
---
 python_payload/st3m/ui/elements/overlays.py | 88 +++++++++++++--------
 1 file changed, 54 insertions(+), 34 deletions(-)

diff --git a/python_payload/st3m/ui/elements/overlays.py b/python_payload/st3m/ui/elements/overlays.py
index 82d8e8b493..d582e8736d 100644
--- a/python_payload/st3m/ui/elements/overlays.py
+++ b/python_payload/st3m/ui/elements/overlays.py
@@ -66,6 +66,8 @@ class Compositor(Responder):
             OverlayKind.Debug: True,
             OverlayKind.Toast: True,
         }
+        self._last_fps_string = ""
+        self._frame_skip = 0
 
     def _enabled_overlays(self) -> List[Responder]:
         res: List[Responder] = []
@@ -93,41 +95,59 @@ class Compositor(Responder):
         self.main.draw(ctx)
         if (sys_display.get_mode() & sys_display.osd) == 0:
             return
-        octx = sys_display.ctx(sys_display.osd)
         if settings.onoff_show_fps.value:
-            _clip_x0 = 0
-            _clip_y1 = 0
-            _clip_x1 = 240
-            _clip_y1 = 24
-            octx.save()
-            octx.rgba(0, 0, 0, 0.5)
-            octx.compositing_mode = octx.COPY
-            octx.rectangle(
-                _clip_x0 - 120,
-                _clip_y0 - 120,
-                _clip_x1 - _clip_x0 + 1,
-                _clip_y1 - _clip_y0 + 1,
-            ).fill()
-            octx.restore()
-            octx.gray(1)
-            octx.font_size = 18
-            octx.font = "Bold"
-            octx.move_to(0, -103)
-            octx.text_align = octx.CENTER
-            octx.text("{0:.1f}".format(sys_display.fps()))
+            fps_string = "{0:.1f}".format(sys_display.fps())
+            if fps_string != self._last_fps_string and self._frame_skip <= 0:
+                octx = sys_display.ctx(sys_display.osd)
+                self._last_fps_string = fps_string
+                _clip_x0 = 0
+                _clip_y1 = 0
+                _clip_x1 = 240
+                _clip_y1 = 24
+                octx.save()
+                octx.rgba(0, 0, 0, 0.5)
+                octx.compositing_mode = octx.COPY
+                octx.rectangle(
+                    _clip_x0 - 120,
+                    _clip_y0 - 120,
+                    _clip_x1 - _clip_x0 + 1,
+                    _clip_y1 - _clip_y0 + 2,
+                ).fill()
+                octx.restore()
+                octx.gray(1)
+                octx.font_size = 18
+                octx.font = "Bold"
+                octx.move_to(0, -103)
+                octx.text_align = octx.CENTER
+                octx.text(fps_string)
+                self._frame_skip = 5
+                sys_display.update(octx)
+                sys_display.overlay_clip(_clip_x0, _clip_y0, _clip_x1, _clip_y1)
+            else:
+                self._frame_skip -= 1
         else:
-            _clip_x0 = 80
-            _clip_y0 = 0
-            _clip_x1 = 160
-            _clip_y1 = 0
-            octx.save()
-            octx.compositing_mode = octx.CLEAR
-            octx.rectangle(-120, -120, 240, 240).fill()
-            octx.restore()
-            for overlay in self._enabled_overlays():
-                overlay.draw(octx)
-        sys_display.overlay_clip(_clip_x0, _clip_y0, _clip_x1, _clip_y1)
-        sys_display.update(octx)
+            if self._frame_skip <= 0:
+                overlays = self._enabled_overlays()
+                _clip_x0 = 80
+                _clip_y0 = 0
+                _clip_x1 = 160
+                _clip_y1 = 0
+
+                octx = sys_display.ctx(sys_display.osd)
+                octx.save()
+                octx.compositing_mode = octx.CLEAR
+                if len(overlays) == 1:
+                    octx.rectangle(-50, -120, 100, 150).fill()
+                else:
+                    octx.rectangle(-120, -120, 240, 240).fill()
+                octx.restore()
+                for overlay in overlays:
+                    overlay.draw(octx)
+                sys_display.update(octx)
+                sys_display.overlay_clip(_clip_x0, _clip_y0, _clip_x1, _clip_y1)
+                self._frame_skip = 2
+            else:
+                self._frame_skip -= 1
 
     def add_overlay(self, ov: Overlay) -> None:
         """
@@ -316,7 +336,7 @@ class OverlayVolume(Overlay):
 
         if self._showing is None:
             return
-        self._showing -= delta_ms
+        self._showing -= delta_ms / 2
         if self._showing < 0:
             self._showing = None
 
-- 
GitLab