git: 76aa776b5f47 - main - stand: Fix shadow buffer offset handling
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 30 Jun 2026 19:53:06 UTC
The branch main has been updated by aokblast:
URL: https://cgit.FreeBSD.org/src/commit/?id=76aa776b5f47ecd0d45336e22795fef98af57d2f
commit 76aa776b5f47ecd0d45336e22795fef98af57d2f
Author: ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2026-06-24 14:31:03 +0000
Commit: ShengYi Hung <aokblast@FreeBSD.org>
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: 2khramtsov@gmail.com
Reviewed by: imp
Tested by: 2khramtsov@gmail.com, junchoon@dec.sakura.ne.jp,
naito.yuichiro_@gmail.com
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);