From: Simon Glass <sjg@chromium.org> Update sandbox_sdl_sync() to accept an optional damage rectangle and update only the damaged region. This should reduce the amount of work performed by the driver when only a small part of the display needs to be updated. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <sjg@chromium.org> --- arch/sandbox/cpu/sdl.c | 46 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c index fa431010b11..f4038c2431a 100644 --- a/arch/sandbox/cpu/sdl.c +++ b/arch/sandbox/cpu/sdl.c @@ -6,6 +6,7 @@ #include <errno.h> #include <mouse.h> #include <unistd.h> +#include <video_defs.h> #include <stdbool.h> #include <sysreset.h> #include <linux/input.h> @@ -232,17 +233,46 @@ int sandbox_sdl_init_display(int width, int height, int log2_bpp, return 0; } -static int copy_to_texture(void *lcd_base) +static int copy_to_texture(void *lcd_base, const struct video_bbox *damage) { char *dest; int pitch, x, y; int src_pitch; void *pixels; char *src; + SDL_Rect rect, *rectp = NULL; int ret; + int x0, y0, x1, y1; + + /* Set up damage region if provided */ + if (damage && damage->x1 > damage->x0 && damage->y1 > damage->y0) { + rect.x = damage->x0; + rect.y = damage->y0; + rect.w = damage->x1 - damage->x0; + rect.h = damage->y1 - damage->y0; + rectp = ▭ + x0 = damage->x0; + y0 = damage->y0; + x1 = damage->x1; + y1 = damage->y1; + } else { + x0 = 0; + y0 = 0; + x1 = sdl.width; + y1 = sdl.height; + } if (sdl.src_depth == sdl.depth) { - SDL_UpdateTexture(sdl.texture, NULL, lcd_base, sdl.pitch); + if (rectp) { + /* Update only the damaged region */ + src_pitch = sdl.width * sdl.src_depth / 8; + src = lcd_base + y0 * src_pitch + + x0 * sdl.src_depth / 8; + SDL_UpdateTexture(sdl.texture, rectp, src, src_pitch); + } else { + SDL_UpdateTexture(sdl.texture, NULL, lcd_base, + sdl.pitch); + } return 0; } @@ -255,7 +285,7 @@ static int copy_to_texture(void *lcd_base) return -EINVAL; } - ret = SDL_LockTexture(sdl.texture, NULL, &pixels, &pitch); + ret = SDL_LockTexture(sdl.texture, rectp, &pixels, &pitch); if (ret) { printf("SDL lock %d: %s\n", ret, SDL_GetError()); return ret; @@ -263,12 +293,12 @@ static int copy_to_texture(void *lcd_base) /* Copy the pixels one by one */ src_pitch = sdl.width * sdl.src_depth / 8; - for (y = 0; y < sdl.height; y++) { + for (y = y0; y < y1; y++) { char val; - dest = pixels + y * pitch; - src = lcd_base + src_pitch * y; - for (x = 0; x < sdl.width; x++, dest += 4) { + dest = pixels + (y - y0) * pitch; + src = lcd_base + src_pitch * y + x0; + for (x = x0; x < x1; x++, dest += 4) { val = *src++; dest[0] = val; dest[1] = val; @@ -289,7 +319,7 @@ int sandbox_sdl_sync(void *lcd_base) if (!sdl.texture) return 0; SDL_RenderClear(sdl.renderer); - ret = copy_to_texture(lcd_base); + ret = copy_to_texture(lcd_base, NULL); if (ret) { printf("copy_to_texture: %d: %s\n", ret, SDL_GetError()); return -EIO; -- 2.43.0