]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
video: Use VIDEO_DAMAGE for VIDEO_COPY
authorAlexander Graf <agraf@csgraf.de>
Thu, 9 Jun 2022 22:59:21 +0000 (00:59 +0200)
committerSimon Glass <sjg@chromium.org>
Thu, 1 May 2025 10:32:45 +0000 (04:32 -0600)
CONFIG_VIDEO_COPY implemented a range-based copying mechanism: If we
print a single character, it will always copy the full range of bytes
from the top left corner of the character to the lower right onto the
uncached frame buffer. This includes pretty much the full line contents
of the printed character.

Since we now have proper damage tracking, let's make use of that to reduce
the amount of data we need to copy. With this patch applied, we will only
copy the tiny rectangle surrounding characters when we print them,
speeding up the video console.

After this, changes to the main frame buffer are not immediately copied
to the copy frame buffer, but postponed until the next video device
sync. So issue an explicit sync before inspecting the copy frame buffer
contents for the video tests.

Signed-off-by: Alexander Graf <agraf@csgraf.de>
[Alper: Rebase for fontdata->height/w, fill_part(), fix memmove(dev),
        drop from defconfig, use damage.xstart/yend, use IS_ENABLED(),
        call video_sync() before copy_fb check, update video_copy test]
Co-developed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Link: https://lore.kernel.org/u-boot/20230821135111.3558478-12-alpernebiyasak@gmail.com/
configs/sandbox_defconfig
drivers/video/Kconfig
drivers/video/console_normal.c
drivers/video/console_rotate.c
drivers/video/console_truetype.c
drivers/video/vidconsole-uclass.c
drivers/video/video-uclass.c
drivers/video/video_bmp.c
include/video.h
include/video_console.h
test/dm/video.c

index f41021a384b972b3b50857dfbae72c4cf906d0f2..c4b1b8114d69aea5df29fc6f959b03dd1ca30b59 100644 (file)
@@ -329,7 +329,6 @@ CONFIG_USB_ETH_CDC=y
 CONFIG_VIDEO=y
 CONFIG_VIDEO_FONT_SUN12X22=y
 CONFIG_VIDEO_COPY=y
-CONFIG_VIDEO_DAMAGE=y
 CONFIG_VIDEO_BRIDGE=y
 CONFIG_VIDEO_BRIDGE_LVDS_CODEC=y
 CONFIG_CONSOLE_ROTATION=y
index bc9c7c1d223fbef8066b0fbe52aae5d18bf81259..4e5a3dcb41df6d493babe30ddb76bb8cc376cb55 100644 (file)
@@ -89,11 +89,14 @@ config VIDEO_PCI_DEFAULT_FB_SIZE
 
 config VIDEO_COPY
        bool "Enable copying the frame buffer to a hardware copy"
+       select VIDEO_DAMAGE
        help
          On some machines (e.g. x86), reading from the frame buffer is very
          slow because it is uncached. To improve performance, this feature
          allows the frame buffer to be kept in cached memory (allocated by
          U-Boot) and then copied to the hardware frame-buffer as needed.
+         It uses the VIDEO_DAMAGE feature to keep track of regions to copy
+         and will only copy actually touched regions.
 
          To use this, your video driver must set @copy_base in
          struct video_uc_plat.
@@ -111,6 +114,8 @@ config VIDEO_DAMAGE
          regions of the frame buffer that were modified before, speeding up
          screen refreshes significantly.
 
+         It is also used by VIDEO_COPY to identify which regions changed.
+
 config BACKLIGHT_PWM
        bool "Generic PWM based Backlight Driver"
        depends on BACKLIGHT && DM_PWM
index 51ac8cc78e9daa56cb363f9f66f168bd81c55dbd..07db613ac53c957cfdfff0c9fb857b4aab4d0f21 100644 (file)
@@ -35,10 +35,6 @@ static int console_set_row(struct udevice *dev, uint row, int clr)
                fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
        end = dst;
 
-       ret = vidconsole_sync_copy(dev, line, end);
-       if (ret)
-               return ret;
-
        video_damage(dev->parent,
                     0,
                     fontdata->height * row,
@@ -57,14 +53,11 @@ static int console_move_rows(struct udevice *dev, uint rowdst,
        void *dst;
        void *src;
        int size;
-       int ret;
 
        dst = vid_priv->fb + rowdst * fontdata->height * vid_priv->line_length;
        src = vid_priv->fb + rowsrc * fontdata->height * vid_priv->line_length;
        size = fontdata->height * vid_priv->line_length * count;
-       ret = vidconsole_memmove(dev, dst, src, size);
-       if (ret)
-               return ret;
+       memmove(dst, src, size);
 
        video_damage(dev->parent,
                     0,
@@ -109,10 +102,6 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
                     fontdata->width,
                     fontdata->height);
 
-       ret = vidconsole_sync_copy(dev, start, line);
-       if (ret)
-               return ret;
-
        return VID_TO_POS(fontdata->width);
 }
 
index f11dc3a0b075934a9866b2c328098c8730956970..886b25dcfafccba22074f4761cf582ec4b906c66 100644 (file)
@@ -21,7 +21,6 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
        int pbytes = VNBYTES(vid_priv->bpix);
        void *start, *dst, *line;
        int i, j;
-       int ret;
 
        start = vid_priv->fb + vid_priv->line_length -
                (row + 1) * fontdata->height * pbytes;
@@ -32,9 +31,6 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
                        fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
                line += vid_priv->line_length;
        }
-       ret = vidconsole_sync_copy(dev, start, line);
-       if (ret)
-               return ret;
 
        video_damage(dev->parent,
                     vid_priv->xsize - ((row + 1) * fontdata->height),
@@ -54,7 +50,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
        int pbytes = VNBYTES(vid_priv->bpix);
        void *dst;
        void *src;
-       int j, ret;
+       int j;
 
        dst = vid_priv->fb + vid_priv->line_length -
                (rowdst + count) * fontdata->height * pbytes;
@@ -62,10 +58,7 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
                (rowsrc + count) * fontdata->height * pbytes;
 
        for (j = 0; j < vid_priv->ysize; j++) {
-               ret = vidconsole_memmove(dev, dst, src,
-                                       fontdata->height * pbytes * count);
-               if (ret)
-                       return ret;
+               memmove(dst, src, fontdata->height * pbytes * count);
                src += vid_priv->line_length;
                dst += vid_priv->line_length;
        }
@@ -105,10 +98,6 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp)
                return ret;
 
        /* We draw backwards from 'start, so account for the first line */
-       ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line);
-       if (ret)
-               return ret;
-
        video_damage(dev->parent,
                     vid_priv->xsize - y - fontdata->height,
                     linenum - 1,
@@ -125,7 +114,7 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
        struct video_fontdata *fontdata = priv->fontdata;
        void *start, *line, *dst, *end;
        int pixels = fontdata->height * vid_priv->xsize;
-       int i, ret;
+       int i;
        int pbytes = VNBYTES(vid_priv->bpix);
 
        start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
@@ -135,9 +124,6 @@ static int console_set_row_2(struct udevice *dev, uint row, int clr)
        for (i = 0; i < pixels; i++)
                fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
        end = dst;
-       ret = vidconsole_sync_copy(dev, start, end);
-       if (ret)
-               return ret;
 
        video_damage(dev->parent,
                     0,
@@ -163,8 +149,7 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
                vid_priv->line_length;
        src = end - (rowsrc + count) * fontdata->height *
                vid_priv->line_length;
-       vidconsole_memmove(dev, dst, src,
-                          fontdata->height * vid_priv->line_length * count);
+       memmove(dst, src, fontdata->height * vid_priv->line_length * count);
 
        video_damage(dev->parent,
                     0,
@@ -200,11 +185,6 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp)
        if (ret)
                return ret;
 
-       /* Add 4 bytes to allow for the first pixel writen */
-       ret = vidconsole_sync_copy(dev, start + 4, line);
-       if (ret)
-               return ret;
-
        video_damage(dev->parent,
                     x - fontdata->width + 1,
                     linenum - fontdata->height + 1,
@@ -221,7 +201,7 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
        struct video_fontdata *fontdata = priv->fontdata;
        int pbytes = VNBYTES(vid_priv->bpix);
        void *start, *dst, *line;
-       int i, j, ret;
+       int i, j;
 
        start = vid_priv->fb + row * fontdata->height * pbytes;
        line = start;
@@ -231,9 +211,6 @@ static int console_set_row_3(struct udevice *dev, uint row, int clr)
                        fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
                line += vid_priv->line_length;
        }
-       ret = vidconsole_sync_copy(dev, start, line);
-       if (ret)
-               return ret;
 
        video_damage(dev->parent,
                     row * fontdata->height,
@@ -253,16 +230,13 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
        int pbytes = VNBYTES(vid_priv->bpix);
        void *dst;
        void *src;
-       int j, ret;
+       int j;
 
        dst = vid_priv->fb + rowdst * fontdata->height * pbytes;
        src = vid_priv->fb + rowsrc * fontdata->height * pbytes;
 
        for (j = 0; j < vid_priv->ysize; j++) {
-               ret = vidconsole_memmove(dev, dst, src,
-                                       fontdata->height * pbytes * count);
-               if (ret)
-                       return ret;
+               memmove(dst, src, fontdata->height * pbytes * count);
                src += vid_priv->line_length;
                dst += vid_priv->line_length;
        }
@@ -298,10 +272,6 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp)
        line = start;
 
        ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION);
-       if (ret)
-               return ret;
-       /* Add a line to allow for the first pixels writen */
-       ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line);
        if (ret)
                return ret;
 
index 073ddcfb6950cf202418dc5e187d6acc664f07e3..980baee83cf86d37585f5288d656e419c482128a 100644 (file)
@@ -194,7 +194,6 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
        struct console_tt_priv *priv = dev_get_priv(dev);
        struct console_tt_metrics *met = priv->cur_met;
        void *end, *line;
-       int ret;
 
        line = vid_priv->fb + row * met->font_size * vid_priv->line_length;
        end = line + met->font_size * vid_priv->line_length;
@@ -230,9 +229,6 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr)
        default:
                return -ENOSYS;
        }
-       ret = vidconsole_sync_copy(dev, line, end);
-       if (ret)
-               return ret;
 
        video_damage(dev->parent,
                     0,
@@ -252,14 +248,11 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst,
        struct console_tt_metrics *met = priv->cur_met;
        void *dst;
        void *src;
-       int i, diff, ret;
+       int i, diff;
 
        dst = vid_priv->fb + rowdst * met->font_size * vid_priv->line_length;
        src = vid_priv->fb + rowsrc * met->font_size * vid_priv->line_length;
-       ret = vidconsole_memmove(dev, dst, src, met->font_size *
-                                vid_priv->line_length * count);
-       if (ret)
-               return ret;
+       memmove(dst, src, met->font_size * vid_priv->line_length * count);
 
        /* Scroll up our position history */
        diff = (rowsrc - rowdst) * met->font_size;
@@ -292,7 +285,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
        u8 *bits, *data;
        int advance;
        void *start, *end, *line;
-       int row, ret;
+       int row;
 
        /* First get some basic metrics about this character */
        stbtt_GetCodepointHMetrics(font, cp, &advance, &lsb);
@@ -439,9 +432,6 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
                     width,
                     height);
 
-       ret = vidconsole_sync_copy(dev, start, line);
-       if (ret)
-               return ret;
        free(data);
 
        return width_frac;
@@ -872,7 +862,6 @@ static int truetype_set_cursor_visible(struct udevice *dev, bool visible,
        uint row, width, height, xoff;
        void *start, *line;
        uint out, val;
-       int ret;
 
        if (xpl_phase() <= PHASE_SPL)
                return -ENOSYS;
@@ -962,9 +951,8 @@ static int truetype_set_cursor_visible(struct udevice *dev, bool visible,
 
                line += vid_priv->line_length;
        }
-       ret = vidconsole_sync_copy(dev, start, line);
-       if (ret)
-               return ret;
+
+       video_damage(dev->parent, x, y, width, height);
 
        return video_sync(vid, true);
 }
index ebe96bf0c2f38299f549d6eb2773f1049012d9fc..a1dfd35b7b8dbc4cbbb729a1a29cfe4af8a98ba1 100644 (file)
@@ -761,22 +761,6 @@ UCLASS_DRIVER(vidconsole) = {
        .per_device_auto        = sizeof(struct vidconsole_priv),
 };
 
-#ifdef CONFIG_VIDEO_COPY
-int vidconsole_sync_copy(struct udevice *dev, void *from, void *to)
-{
-       struct udevice *vid = dev_get_parent(dev);
-
-       return video_sync_copy(vid, from, to);
-}
-
-int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
-                      int size)
-{
-       memmove(dst, src, size);
-       return vidconsole_sync_copy(dev, dst, dst + size);
-}
-#endif
-
 int vidconsole_clear_and_reset(struct udevice *dev)
 {
        int ret;
index 8fb3b2296fd76c6b5b05b88fa914bbef85805d9d..0d582e796cdf94eec185c7f2a4cceb39d61f1192 100644 (file)
@@ -171,7 +171,7 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
        struct video_priv *priv = dev_get_uclass_priv(dev);
        void *start, *line;
        int pixels = xend - xstart;
-       int row, i, ret;
+       int row, i;
 
        start = priv->fb + ystart * priv->line_length;
        start += xstart * VNBYTES(priv->bpix);
@@ -210,9 +210,6 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
                }
                line += priv->line_length;
        }
-       ret = video_sync_copy(dev, start, line);
-       if (ret)
-               return ret;
 
        video_damage(dev, xstart, ystart, xend - xstart, yend - ystart);
 
@@ -235,7 +232,6 @@ int video_reserve_from_bloblist(struct video_handoff *ho)
 int video_fill(struct udevice *dev, u32 colour)
 {
        struct video_priv *priv = dev_get_uclass_priv(dev);
-       int ret;
 
        switch (priv->bpix) {
        case VIDEO_BPP16:
@@ -262,9 +258,6 @@ int video_fill(struct udevice *dev, u32 colour)
                memset(priv->fb, colour, priv->fb_size);
                break;
        }
-       ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
-       if (ret)
-               return ret;
 
        video_damage(dev, 0, 0, priv->xsize, priv->ysize);
 
@@ -435,6 +428,27 @@ static void video_flush_dcache(struct udevice *vid, bool use_copy)
 }
 #endif
 
+static void video_flush_copy(struct udevice *vid)
+{
+       struct video_priv *priv = dev_get_uclass_priv(vid);
+
+       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);
+               int y;
+
+               for (y = priv->damage.ystart; y < priv->damage.yend; y++) {
+                       ulong offset = (y * priv->line_length) + lstart;
+                       ulong len = lend - lstart;
+
+                       memcpy(priv->copy_fb + offset, priv->fb + offset, len);
+               }
+       }
+}
+
 /* Flush video activity to the caches */
 int video_sync(struct udevice *vid, bool force)
 {
@@ -442,6 +456,9 @@ int video_sync(struct udevice *vid, bool force)
        struct video_ops *ops = video_get_ops(vid);
        int ret;
 
+       if (IS_ENABLED(CONFIG_VIDEO_COPY))
+               video_flush_copy(vid);
+
        if (ops && ops->video_sync) {
                ret = ops->video_sync(vid);
                if (ret)
@@ -525,69 +542,6 @@ int video_get_ysize(struct udevice *dev)
        return priv->ysize;
 }
 
-#ifdef CONFIG_VIDEO_COPY
-int video_sync_copy(struct udevice *dev, void *from, void *to)
-{
-       struct video_priv *priv = dev_get_uclass_priv(dev);
-
-       if (priv->copy_fb) {
-               long offset, size;
-
-               /* Find the offset of the first byte to copy */
-               if ((ulong)to > (ulong)from) {
-                       size = to - from;
-                       offset = from - priv->fb;
-               } else {
-                       size = from - to;
-                       offset = to - priv->fb;
-               }
-
-               /*
-                * Allow a bit of leeway for valid requests somewhere near the
-                * frame buffer
-                */
-               if (offset < -priv->fb_size || offset > 2 * priv->fb_size) {
-#ifdef DEBUG
-                       char str[120];
-
-                       snprintf(str, sizeof(str),
-                                "[** FAULT sync_copy fb=%p, from=%p, to=%p, offset=%lx]",
-                                priv->fb, from, to, offset);
-                       console_puts_select_stderr(true, str);
-#endif
-                       return -EFAULT;
-               }
-
-               /*
-                * Silently crop the memcpy. This allows callers to avoid doing
-                * this themselves. It is common for the end pointer to go a
-                * few lines after the end of the frame buffer, since most of
-                * the update algorithms terminate a line after their last write
-                */
-               if (offset + size > priv->fb_size) {
-                       size = priv->fb_size - offset;
-               } else if (offset < 0) {
-                       size += offset;
-                       offset = 0;
-               }
-
-               memcpy(priv->copy_fb + offset, priv->fb + offset, size);
-       }
-
-       return 0;
-}
-
-int video_sync_copy_all(struct udevice *dev)
-{
-       struct video_priv *priv = dev_get_uclass_priv(dev);
-
-       video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
-
-       return 0;
-}
-
-#endif
-
 #define SPLASH_DECL(_name) \
        extern u8 __splash_ ## _name ## _begin[]; \
        extern u8 __splash_ ## _name ## _end[]
index 78de95607924799bfba80a8c9d3561a697899375..1f267d45812c35e82a0d65a87eabbb06e656891a 100644 (file)
@@ -267,7 +267,6 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
        enum video_format eformat;
        struct bmp_color_table_entry *palette;
        int hdr_size;
-       int ret;
 
        if (!bmp || !(bmp->header.signature[0] == 'B' &&
            bmp->header.signature[1] == 'M')) {
@@ -461,11 +460,5 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
 
        video_damage(dev, x, y, width, height);
 
-       /* Find the position of the top left of the image in the framebuffer */
-       fb = (uchar *)(priv->fb + y * priv->line_length + x * bpix / 8);
-       ret = video_sync_copy(dev, start, fb);
-       if (ret)
-               return log_ret(ret);
-
        return video_sync(dev, false);
 }
index 7eed112e00c4ac2ee2ba5535c29084c0ba5c7001..2fe2f73a865ba5cbf726d010f4434de811f7feaa 100644 (file)
@@ -355,43 +355,6 @@ void video_set_default_colors(struct udevice *dev, bool invert);
  */
 int video_default_font_height(struct udevice *dev);
 
-#ifdef CONFIG_VIDEO_COPY
-/**
- * vidconsole_sync_copy() - Sync back to the copy framebuffer
- *
- * This ensures that the copy framebuffer has the same data as the framebuffer
- * for a particular region. It should be called after the framebuffer is updated
- *
- * @from and @to can be in either order. The region between them is synced.
- *
- * @dev: Vidconsole device being updated
- * @from: Start/end address within the framebuffer (->fb)
- * @to: Other address within the frame buffer
- * Return: 0 if OK, -EFAULT if the start address is before the start of the
- *     frame buffer start
- */
-int video_sync_copy(struct udevice *dev, void *from, void *to);
-
-/**
- * video_sync_copy_all() - Sync the entire framebuffer to the copy
- *
- * @dev: Vidconsole device being updated
- * Return: 0 (always)
- */
-int video_sync_copy_all(struct udevice *dev);
-#else
-static inline int video_sync_copy(struct udevice *dev, void *from, void *to)
-{
-       return 0;
-}
-
-static inline int video_sync_copy_all(struct udevice *dev)
-{
-       return 0;
-}
-
-#endif
-
 #ifdef CONFIG_VIDEO_DAMAGE
 /**
  * video_damage() - Notify the video subsystem about screen updates.
index 723d2315606d368f9a9d7ed906feb9a2566a4019..13197fa4518a89af6f2497101cfe43df924246fa 100644 (file)
@@ -537,56 +537,4 @@ void vidconsole_list_fonts(struct udevice *dev);
  */
 int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep);
 
-#ifdef CONFIG_VIDEO_COPY
-/**
- * vidconsole_sync_copy() - Sync back to the copy framebuffer
- *
- * This ensures that the copy framebuffer has the same data as the framebuffer
- * for a particular region. It should be called after the framebuffer is updated
- *
- * @from and @to can be in either order. The region between them is synced.
- *
- * @dev: Vidconsole device being updated
- * @from: Start/end address within the framebuffer (->fb)
- * @to: Other address within the frame buffer
- * Return: 0 if OK, -EFAULT if the start address is before the start of the
- *     frame buffer start
- */
-int vidconsole_sync_copy(struct udevice *dev, void *from, void *to);
-
-/**
- * vidconsole_memmove() - Perform a memmove() within the frame buffer
- *
- * This handles a memmove(), e.g. for scrolling. It also updates the copy
- * framebuffer.
- *
- * @dev: Vidconsole device being updated
- * @dst: Destination address within the framebuffer (->fb)
- * @src: Source address within the framebuffer (->fb)
- * @size: Number of bytes to transfer
- * Return: 0 if OK, -EFAULT if the start address is before the start of the
- *     frame buffer start
- */
-int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
-                      int size);
-#else
-
-#include <string.h>
-
-static inline int vidconsole_sync_copy(struct udevice *dev, void *from,
-                                      void *to)
-{
-       return 0;
-}
-
-static inline int vidconsole_memmove(struct udevice *dev, void *dst,
-                                    const void *src, int size)
-{
-       memmove(dst, src, size);
-
-       return 0;
-}
-
-#endif
-
 #endif
index cf81b907969cf31c676738db7dc2db973632f24b..929fc16d0effaabbe3f8f99eb8777c16d19433de 100644 (file)
@@ -105,6 +105,7 @@ static int check_copy_frame_buffer(struct unit_test_state *uts,
        if (!IS_ENABLED(CONFIG_VIDEO_COPY))
                return 0;
 
+       video_sync(dev, false);
        ut_assertf(!memcmp(priv->fb, priv->copy_fb, priv->fb_size),
                   "Copy framebuffer does not match fb");
 
@@ -700,12 +701,22 @@ static int dm_test_video_copy(struct unit_test_state *uts)
 
        /*
         * We should have the full content on the main buffer, but only
-        * the new content should have been copied to the copy buffer.
+        * 'damage' should have been copied to the copy buffer. This consists
+        * of a while rectangle with the Denx logo and four lines of text. The
+        * rest of the display is black.
+        *
+        * An easy way to try this is by changing video_sync() to call
+        * sandbox_sdl_sync(priv->copy_fb) instead of priv->fb then running the
+        * unit test:
+        *
+        *   ./u-boot -Tl
+        *   ut dm dm_test_video_copy
         */
        vidconsole_put_string(con, test_string);
        vidconsole_put_string(con, test_string);
+       video_sync(dev, true);
        ut_asserteq(7589, compress_frame_buffer(uts, dev, false));
-       ut_asserteq(5278, compress_frame_buffer(uts, dev, true));
+       ut_asserteq(7704, compress_frame_buffer(uts, dev, true));
 
        return 0;
 }