[Concept,13/14] expo: Add selective rendering for dirty objects in scene

Message ID 20251006165452.1675349-14-sjg@u-boot.org
State New
Headers
Series expo: Continue development of expo with mouse |

Commit Message

Simon Glass Oct. 6, 2025, 4:54 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

Support rendering only the dirty objects in a scene.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 boot/expo.c           |  2 +-
 boot/scene.c          | 27 +++++++++++++++++++++++++--
 boot/scene_internal.h |  3 ++-
 3 files changed, 28 insertions(+), 4 deletions(-)
  

Patch

diff --git a/boot/expo.c b/boot/expo.c
index 5cbe06b1c28..8423a304eb0 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -320,7 +320,7 @@  int expo_render(struct expo *exp)
 		if (!scn)
 			return log_msg_ret("scn", -ENOENT);
 
-		ret = scene_render(scn);
+		ret = scene_render(scn, false);
 		if (ret)
 			return log_msg_ret("ren", ret);
 	}
diff --git a/boot/scene.c b/boot/scene.c
index 332d11fc751..ec0c5899bca 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -930,7 +930,21 @@  static int scene_get_dirty_bbox(struct scene *scn, struct vid_bbox *bbox)
 	return found_dirty ? 0 : -ENOENT;
 }
 
-int scene_render(struct scene *scn)
+/**
+ * bbox_intersects() - Check if two bounding boxes intersect
+ *
+ * @bbox1: First bounding box
+ * @bbox2: Second bounding box
+ * Return: true if bounding boxes intersect, false otherwise
+ */
+static bool bbox_intersects(const struct vid_bbox *bbox1,
+			    const struct vid_bbox *bbox2)
+{
+	return !(bbox1->x1 <= bbox2->x0 || bbox2->x1 <= bbox1->x0 ||
+		 bbox1->y1 <= bbox2->y0 || bbox2->y1 <= bbox1->y0);
+}
+
+int scene_render(struct scene *scn, bool dirty_only)
 {
 	struct expo *exp = scn->expo;
 	struct scene_obj *obj;
@@ -943,7 +957,16 @@  int scene_render(struct scene *scn)
 		expo_damage_add(exp, &dirty_bbox);
 
 	list_for_each_entry(obj, &scn->obj_head, sibling) {
-		if (!(obj->flags & SCENEOF_HIDE)) {
+		bool render = true;
+
+		if (obj->flags & SCENEOF_HIDE)
+			continue;
+
+		/* render objects that intersect with dirty bbox */
+		if (dirty_only && !ret)
+			render = bbox_intersects(&obj->bbox, &dirty_bbox);
+
+		if (render) {
 			ret = scene_obj_render(obj, exp->text_mode);
 			if (ret && ret != -ENOTSUPP)
 				return log_msg_ret("ren", ret);
diff --git a/boot/scene_internal.h b/boot/scene_internal.h
index 0bc6f45cdcb..00696979f7d 100644
--- a/boot/scene_internal.h
+++ b/boot/scene_internal.h
@@ -237,9 +237,10 @@  void scene_destroy(struct scene *scn);
  * This is called from expo_render()
  *
  * @scn: Scene to render
+ * @dirty_only: If true, only render objects that intersect with dirty areas
  * Returns: 0 if OK, -ve on error
  */
-int scene_render(struct scene *scn);
+int scene_render(struct scene *scn, bool dirty_only);
 
 /**
  * scene_send_key() - set a keypress to a scene