@@ -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;
@@ -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;
@@ -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 */
@@ -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));