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(-)
@@ -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;