From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pekka Enberg Subject: [PATCH] kvm tools, ui: Optimize SDL updates Date: Sat, 4 Jun 2011 00:20:23 +0300 Message-ID: <1307136023-16693-1-git-send-email-penberg@kernel.org> Cc: Pekka Enberg , Cyrill Gorcunov , Ingo Molnar , John Floren , Sasha Levin To: kvm@vger.kernel.org Return-path: Received: from filtteri1.pp.htv.fi ([213.243.153.184]:49118 "EHLO filtteri1.pp.htv.fi" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753823Ab1FCVU0 (ORCPT ); Fri, 3 Jun 2011 17:20:26 -0400 Sender: kvm-owner@vger.kernel.org List-ID: 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 Cc: Ingo Molnar Cc: John Floren Cc: Sasha Levin Signed-off-by: Pekka Enberg --- 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 #include +#include + #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