This patch optimizes SDL updates by keeping track of which parts of the guest screen have been written since last update and calling SDL_BlitSurface() and SDL_UpdateRect() for only changed parts of the screen. Cc: Cyrill Gorcunov <gorcunov@xxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxx> Cc: John Floren <john@xxxxxxxxxxx> Cc: Sasha Levin <levinsasha928@xxxxxxxxx> Signed-off-by: Pekka Enberg <penberg@xxxxxxxxxx> --- tools/kvm/ui/sdl.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 57 insertions(+), 3 deletions(-) diff --git a/tools/kvm/ui/sdl.c b/tools/kvm/ui/sdl.c index bc69ed9..f175a60 100644 --- a/tools/kvm/ui/sdl.c +++ b/tools/kvm/ui/sdl.c @@ -6,11 +6,51 @@ #include <SDL/SDL.h> #include <pthread.h> +#include <linux/kernel.h> + #define FRAME_RATE 25 +static u64 min_x; +static u64 min_y; +static u64 max_x; +static u64 max_y; + +static void sdl__finish(void) +{ + max_x = 0; + max_y = 0; + min_x = ULLONG_MAX; + min_y = ULLONG_MAX; +} + +static inline bool sdl__need_update(void) +{ + return min_x < max_x && min_y < max_y; +} + static void sdl__write(struct framebuffer *fb, u64 addr, u8 *data, u32 len) { - memcpy(&fb->mem[addr - fb->mem_addr], data, len); + u64 x, y; + u64 pos; + + pos = addr - fb->mem_addr; + + x = (pos / 4) % fb->width; + y = ((pos / 4) - x) / fb->width; + + if (x < min_x) + min_x = x; + + if (y < min_y) + min_y = y; + + if (x > max_x) + max_x = x; + + if (y > max_y) + max_y = y; + + memcpy(&fb->mem[pos], data, len); } static void *sdl__thread(void *p) @@ -40,9 +80,23 @@ static void *sdl__thread(void *p) if (!screen) die("Unable to set SDL video mode"); + sdl__finish(); + for (;;) { - SDL_BlitSurface(guest_screen, NULL, screen, NULL); - SDL_UpdateRect(screen, 0, 0, 0, 0); + if (sdl__need_update()) { + SDL_Rect rect = { + .x = min_x, + .y = min_y, + .w = max_x - min_x, + .h = max_y - min_y, + }; + + SDL_BlitSurface(guest_screen, &rect, screen, &rect); + SDL_UpdateRect(screen, rect.x, rect.y, rect.w, rect.h); + } + + sdl__finish(); + while (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_QUIT: -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html