[Concept,14/22] video: Add a struct video_bbox for damage tracking

Message ID 20251003165525.440173-15-sjg@u-boot.org
State New
Headers
Series video: Enhancements to support a pointer |

Commit Message

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

Replace the anonymous struct in video_priv with struct video_bbox for
the damage field.

Update all references from xstart/ystart/xend/yend to x0/y0/x1/y1 to
match the video_bbox field names. Add local video_bbox pointers in
functions that access damage fields repeatedly to improve readability.

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

 drivers/video/video-uclass.c | 36 +++++++++++++++++++----------------
 include/video.h              | 13 ++-----------
 include/video_defs.h         | 37 ++++++++++++++++++++++++++++++++++++
 test/dm/video.c              | 34 +++++++++++++++++----------------
 4 files changed, 77 insertions(+), 43 deletions(-)
  

Patch

diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
index f5cd1727fce..5c2cb251683 100644
--- a/drivers/video/video-uclass.c
+++ b/drivers/video/video-uclass.c
@@ -411,6 +411,7 @@  void video_set_default_colors(struct udevice *dev, bool invert)
 void video_damage(struct udevice *vid, int x, int y, int width, int height)
 {
 	struct video_priv *priv = dev_get_uclass_priv(vid);
+	struct video_bbox *damage = &priv->damage;
 	int xend = x + width;
 	int yend = y + height;
 
@@ -427,10 +428,10 @@  void video_damage(struct udevice *vid, int x, int y, int width, int height)
 		yend = priv->ysize;
 
 	/* Span a rectangle across all old and new damage */
-	priv->damage.xstart = min(x, priv->damage.xstart);
-	priv->damage.ystart = min(y, priv->damage.ystart);
-	priv->damage.xend = max(xend, priv->damage.xend);
-	priv->damage.yend = max(yend, priv->damage.yend);
+	damage->x0 = min(x, damage->x0);
+	damage->y0 = min(y, damage->y0);
+	damage->x1 = max(xend, damage->x1);
+	damage->y1 = max(yend, damage->y1);
 }
 #endif
 
@@ -457,12 +458,12 @@  static void video_flush_dcache(struct udevice *vid, bool use_copy)
 		return;
 	}
 
-	if (priv->damage.xend && priv->damage.yend) {
-		int lstart = priv->damage.xstart * VNBYTES(priv->bpix);
-		int lend = priv->damage.xend * VNBYTES(priv->bpix);
+	if (priv->damage.x1 && priv->damage.y1) {
+		int lstart = priv->damage.x0 * VNBYTES(priv->bpix);
+		int lend = priv->damage.x1 * VNBYTES(priv->bpix);
 		int y;
 
-		for (y = priv->damage.ystart; y < priv->damage.yend; y++) {
+		for (y = priv->damage.y0; y < priv->damage.y1; y++) {
 			ulong start = fb + (y * priv->line_length) + lstart;
 			ulong end = start + lend - lstart;
 
@@ -477,16 +478,17 @@  static void video_flush_dcache(struct udevice *vid, bool use_copy)
 static void video_flush_copy(struct udevice *vid)
 {
 	struct video_priv *priv = dev_get_uclass_priv(vid);
+	struct video_bbox *damage = &priv->damage;
 
 	if (!priv->copy_fb)
 		return;
 
-	if (priv->damage.xend && priv->damage.yend) {
-		int lstart = priv->damage.xstart * VNBYTES(priv->bpix);
-		int lend = priv->damage.xend * VNBYTES(priv->bpix);
+	if (damage->x1 && damage->y1) {
+		int lstart = damage->x0 * VNBYTES(priv->bpix);
+		int lend = damage->x1 * VNBYTES(priv->bpix);
 		int y;
 
-		for (y = priv->damage.ystart; y < priv->damage.yend; y++) {
+		for (y = damage->y0; y < damage->y1; y++) {
 			ulong offset = (y * priv->line_length) + lstart;
 			ulong len = lend - lstart;
 
@@ -527,10 +529,12 @@  int video_sync(struct udevice *vid, bool force)
 	priv->last_sync = get_timer(0);
 
 	if (IS_ENABLED(CONFIG_VIDEO_DAMAGE)) {
-		priv->damage.xstart = priv->xsize;
-		priv->damage.ystart = priv->ysize;
-		priv->damage.xend = 0;
-		priv->damage.yend = 0;
+		struct video_bbox *damage = &priv->damage;
+
+		damage->x0 = priv->xsize;
+		damage->y0 = priv->ysize;
+		damage->x1 = 0;
+		damage->y1 = 0;
 	}
 
 	return 0;
diff --git a/include/video.h b/include/video.h
index 1ad5868e2f6..92dca60a872 100644
--- a/include/video.h
+++ b/include/video.h
@@ -90,11 +90,7 @@  enum video_format {
  * @fb_size:	Frame buffer size
  * @copy_fb:	Copy of the frame buffer to keep up to date; see struct
  *		video_uc_plat
- * @damage:	A bounding box of framebuffer regions updated since last sync
- * @damage.xstart:	X start position in pixels from the left
- * @damage.ystart:	Y start position in pixels from the top
- * @damage.xend:	X end position in pixels from the left
- * @damage.xend:	Y end position in pixels from the top
+ * @damage:	Bounding box of framebuffer regions updated since last sync
  * @line_length:	Length of each frame buffer line, in bytes. This can be
  *		set by the driver, but if not, the uclass will set it after
  *		probing
@@ -124,12 +120,7 @@  struct video_priv {
 	void *fb;
 	int fb_size;
 	void *copy_fb;
-	struct {
-		int xstart;
-		int ystart;
-		int xend;
-		int yend;
-	} damage;
+	struct video_bbox damage;
 	int line_length;
 	u32 colour_fg;
 	u32 colour_bg;
diff --git a/include/video_defs.h b/include/video_defs.h
index 6bd822dc99e..c17959e3146 100644
--- a/include/video_defs.h
+++ b/include/video_defs.h
@@ -12,4 +12,41 @@ 
 /* Maximum length of an embedded image name */
 #define VIDEO_IMAGE_NAMELEN	16
 
+#ifndef __ASSEMBLY__
+
+#include <stdbool.h>
+
+/**
+ * struct video_bbox - Represents a bounding box for video operations
+ *
+ * The bounding box is only valid if x1 > x0 and y1 > y0. An invalid bounding
+ * box (where x1 <= x0 or y1 <= y0) indicates that there is no area to process.
+ *
+ * @x0: X start position in pixels from the left
+ * @y0: Y start position in pixels from the top
+ * @x1: X end position in pixels from the left
+ * @y1: Y end position in pixels from the top
+ */
+struct video_bbox {
+	int x0;
+	int y0;
+	int x1;
+	int y1;
+};
+
+/**
+ * video_bbox_valid() - Check if a bounding box is valid
+ *
+ * A valid bounding box has x1 > x0 and y1 > y0. An invalid/inverted bounding
+ * box (where x1 <= x0 or y1 <= y0) indicates that there is no area to process.
+ *
+ * @bbox: Bounding box to check
+ * Return: true if valid, false if invalid/inverted
+ */
+static inline bool video_bbox_valid(const struct video_bbox *bbox)
+{
+	return bbox->x1 > bbox->x0 && bbox->y1 > bbox->y0;
+}
+#endif /* __ASSEMBLY__ */
+
 #endif /* __VIDEO_DEFS_H */
diff --git a/test/dm/video.c b/test/dm/video.c
index 3defa184b14..7ada4c75bf7 100644
--- a/test/dm/video.c
+++ b/test/dm/video.c
@@ -903,32 +903,34 @@  static int dm_test_video_damage(struct unit_test_state *uts)
 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
 	priv = dev_get_uclass_priv(dev);
 
+	struct video_bbox *damage = &priv->damage;
+
 	vidconsole_position_cursor(con, 14, 10);
 	vidconsole_put_string(con, test_string_2);
-	ut_asserteq(449, priv->damage.xstart);
-	ut_asserteq(325, priv->damage.ystart);
-	ut_asserteq(661, priv->damage.xend);
-	ut_asserteq(350, priv->damage.yend);
+	ut_asserteq(449, damage->x0);
+	ut_asserteq(325, damage->y0);
+	ut_asserteq(661, damage->x1);
+	ut_asserteq(350, damage->y1);
 
 	vidconsole_position_cursor(con, 7, 5);
 	vidconsole_put_string(con, test_string_1);
-	ut_asserteq(225, priv->damage.xstart);
-	ut_asserteq(164, priv->damage.ystart);
-	ut_asserteq(661, priv->damage.xend);
-	ut_asserteq(350, priv->damage.yend);
+	ut_asserteq(225, damage->x0);
+	ut_asserteq(164, damage->y0);
+	ut_asserteq(661, damage->x1);
+	ut_asserteq(350, damage->y1);
 
 	vidconsole_position_cursor(con, 21, 15);
 	vidconsole_put_string(con, test_string_3);
-	ut_asserteq(225, priv->damage.xstart);
-	ut_asserteq(164, priv->damage.ystart);
-	ut_asserteq(1280, priv->damage.xend);
-	ut_asserteq(510, priv->damage.yend);
+	ut_asserteq(225, damage->x0);
+	ut_asserteq(164, damage->y0);
+	ut_asserteq(1280, damage->x1);
+	ut_asserteq(510, damage->y1);
 
 	video_sync(dev, true);
-	ut_asserteq(priv->xsize, priv->damage.xstart);
-	ut_asserteq(priv->ysize, priv->damage.ystart);
-	ut_asserteq(0, priv->damage.xend);
-	ut_asserteq(0, priv->damage.yend);
+	ut_asserteq(priv->xsize, damage->x0);
+	ut_asserteq(priv->ysize, damage->y0);
+	ut_asserteq(0, damage->x1);
+	ut_asserteq(0, damage->y1);
 
 	ut_asserteq(7335, video_compress_fb(uts, dev, false));
 	ut_assertok(video_check_copy_fb(uts, dev));