[Concept,12/14] expo: Add a way to calculate the bbox of dirty objects

Message ID 20251006165452.1675349-13-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>

When rendering an expo we should normally only need to draw the objects
which are marked dirty. Add a way to calculate the bounding box of
these.

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

 boot/scene.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
  

Patch

diff --git a/boot/scene.c b/boot/scene.c
index 242f21bbacf..332d11fc751 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -895,12 +895,53 @@  int scene_render_deps(struct scene *scn, uint id)
 	return 0;
 }
 
+/**
+ * scene_get_dirty_bbox() - Get bounding box of all dirty objects in a scene
+ *
+ * @scn: Scene to scan
+ * @bbox: Returns bounding box of all dirty objects
+ * Return: 0 if dirty objects found, -ENOENT if no dirty objects
+ */
+static int scene_get_dirty_bbox(struct scene *scn, struct vid_bbox *bbox)
+{
+	struct scene_obj *obj;
+	bool found_dirty = false;
+
+	list_for_each_entry(obj, &scn->obj_head, sibling) {
+		if (obj->flags & SCENEOF_DIRTY) {
+			if (!found_dirty) {
+				/* First dirty object - initialize bbox */
+				*bbox = obj->bbox;
+				found_dirty = true;
+			} else {
+				/* Expand bbox to include this object */
+				if (obj->bbox.x0 < bbox->x0)
+					bbox->x0 = obj->bbox.x0;
+				if (obj->bbox.y0 < bbox->y0)
+					bbox->y0 = obj->bbox.y0;
+				if (obj->bbox.x1 > bbox->x1)
+					bbox->x1 = obj->bbox.x1;
+				if (obj->bbox.y1 > bbox->y1)
+					bbox->y1 = obj->bbox.y1;
+			}
+		}
+	}
+
+	return found_dirty ? 0 : -ENOENT;
+}
+
 int scene_render(struct scene *scn)
 {
 	struct expo *exp = scn->expo;
 	struct scene_obj *obj;
+	struct vid_bbox dirty_bbox;
 	int ret;
 
+	/* Get bounding box of dirty objects and add to expo damage */
+	ret = scene_get_dirty_bbox(scn, &dirty_bbox);
+	if (!ret)
+		expo_damage_add(exp, &dirty_bbox);
+
 	list_for_each_entry(obj, &scn->obj_head, sibling) {
 		if (!(obj->flags & SCENEOF_HIDE)) {
 			ret = scene_obj_render(obj, exp->text_mode);