The branch main has been updated by aokblast:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=76aa776b5f47ecd0d45336e22795fef98af57d2f

commit 76aa776b5f47ecd0d45336e22795fef98af57d2f
Author:     ShengYi Hung <[email protected]>
AuthorDate: 2026-06-24 14:31:03 +0000
Commit:     ShengYi Hung <[email protected]>
CommitDate: 2026-06-30 19:52:55 +0000

    stand: Fix shadow buffer offset handling
    
    The shadow buffer is addressed relative to `tg_origin`, which includes
    the padding offset, whereas `gfxfb_blt` operates on coordinates without
    that offset. To make `gfx_fb_copy_area` emulate the behavior of
    `gfxfb_blt`, the source coordinates must include the padding offset,
    while the destination coordinates must not. The original implementation
    omitted the offset from the source coordinates; this change corrects
    that.
    
    Additionally, `gfx_fb_cons_display` already applies the padding offset,
    so the redundant adjustment is removed.
    
    PR:             296246
    Reported by:    [email protected]
    Reviewed by:    imp
    Tested by:      [email protected], [email protected],
    [email protected]
    Fixes:          32da2f23ae4d
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D57821
---
 stand/common/gfx_fb.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c
index 7ed0cf6bdb39..8185afccf944 100644
--- a/stand/common/gfx_fb.c
+++ b/stand/common/gfx_fb.c
@@ -1400,26 +1400,32 @@ gfx_fb_copy_area(teken_gfx_t *state, const teken_rect_t 
*s,
        pitch = state->tg_fb.fb_width;
        bytes = width * sizeof (*state->tg_shadow_fb);
 
-       uint32_t dst_x = dx + state->tg_origin.tp_col;
-       uint32_t dst_y = dy + state->tg_origin.tp_row;
+       uint32_t ssx = sx + state->tg_origin.tp_col;
+       uint32_t ssy = sy + state->tg_origin.tp_row;
+       uint32_t dsx = dx + state->tg_origin.tp_col;
+       uint32_t dsy = dy + state->tg_origin.tp_row;
+       uint32_t dst_x = dsx;
+       uint32_t dst_y = dsy;
        uint32_t dst_h = height;
 
        /*
         * To handle overlapping areas, set up reverse copy here.
+        * The origin offset cancels out in the comparison so the
+        * terminal-relative form is equivalent.
         */
        if (dy * pitch + dx > sy * pitch + sx) {
-               sy += height;
-               dy += height;
+               ssy += height;
+               dsy += height;
                step = -step;
        }
 
        while (height-- > 0) {
-               uint32_t *source = &state->tg_shadow_fb[sy * pitch + sx];
-               uint32_t *destination = &state->tg_shadow_fb[dy * pitch + dx];
+               uint32_t *source = &state->tg_shadow_fb[ssy * pitch + ssx];
+               uint32_t *destination = &state->tg_shadow_fb[dsy * pitch + dsx];
 
                bcopy(source, destination, bytes);
-               sy += step;
-               dy += step;
+               ssy += step;
+               dsy += step;
        }
 
        gfx_shadow_mark_dirty(dst_x, dst_y, width, dst_h);
@@ -1618,13 +1624,11 @@ gfx_fb_cons_display(uint32_t x, uint32_t y, uint32_t 
width, uint32_t height,
         */
        if (gfx_state.tg_shadow_fb != NULL) {
                uint32_t pitch = gfx_state.tg_fb.fb_width;
-               uint32_t sy = y - gfx_state.tg_origin.tp_row;
-               uint32_t sx = x - gfx_state.tg_origin.tp_col;
 
                p = data;
                for (uint32_t row = 0; row < height; row++) {
                        buf = (void *)(gfx_state.tg_shadow_fb +
-                           (sy + row) * pitch + sx);
+                           (y + row) * pitch + x);
                        bitmap_cpy(buf, &p[row * width], width);
                }
                gfx_shadow_mark_dirty(x, y, width, height);

Reply via email to