On Tue, 24 Jul 2007 19:44:12 +0100
Daniel P. Berrange [EMAIL PROTECTED] wrote:
Using a command line argument to change the refresh rate doesn't seem
like a particularly optional solution. It think it would be better to
have QEMU automatically adapt the refresh rate. eg, it would start
off refreshing SDL at 30ms intervals. If it sees a keyboard or mouse
event, it would increase the refresh rate to 10ms. If, say, 100ms
passes without any further events, then it could decrease it to 30ms
again.
That way everyone would always get the low CPU load, unless they were
actaully interacting with the mouse/keyboard in which case it would
tune itself for interactive response.
Sounds reasonable. Updated patch attached.
--
Jindrich Makovicka
diff -ur kvm-33.orig/qemu/sdl.c kvm-33/qemu/sdl.c
--- kvm-33.orig/qemu/sdl.c 2007-07-23 16:58:51.0 +0200
+++ kvm-33/qemu/sdl.c 2007-07-29 16:27:49.0 +0200
@@ -43,6 +43,8 @@
static SDL_Cursor *sdl_cursor_normal;
static SDL_Cursor *sdl_cursor_hidden;
static int absolute_enabled = 0;
+static int decimate_counter = 0;
+static int idle_counter = 0;
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
{
@@ -311,17 +313,24 @@
vga_hw_update();
}
+#define SDL_IDLE_THRESHOLD 10
+#define SDL_DECIMATE 3
+
static void sdl_refresh(DisplayState *ds)
{
SDL_Event ev1, *ev = ev1;
int mod_state;
+int was_idle = 1;
if (last_vm_running != vm_running) {
last_vm_running = vm_running;
sdl_update_caption();
}
-vga_hw_update();
+if (idle_counter SDL_IDLE_THRESHOLD || decimate_counter == 0)
+ vga_hw_update();
+
+decimate_counter = (decimate_counter + 1) % SDL_DECIMATE;
while (SDL_PollEvent(ev)) {
switch (ev-type) {
@@ -330,6 +339,7 @@
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
+ was_idle = 0;
if (ev-type == SDL_KEYDOWN) {
mod_state = (SDL_GetModState() gui_grab_code) ==
gui_grab_code;
@@ -428,6 +438,7 @@
}
break;
case SDL_MOUSEMOTION:
+ was_idle = 0;
if (gui_grab || kbd_mouse_is_absolute() ||
absolute_enabled) {
sdl_send_mouse_event(0);
@@ -435,6 +446,7 @@
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
+ was_idle = 0;
{
SDL_MouseButtonEvent *bev = ev-button;
if (!gui_grab !kbd_mouse_is_absolute()) {
@@ -467,6 +479,13 @@
break;
}
}
+
+if (was_idle) {
+ if (idle_counter SDL_IDLE_THRESHOLD)
+ idle_counter++;
+} else {
+ idle_counter = 0;
+}
}
static void sdl_cleanup(void)
@@ -504,6 +523,7 @@
ds-dpy_update = sdl_update;
ds-dpy_resize = sdl_resize;
ds-dpy_refresh = sdl_refresh;
+ds-refresh_interval = 10;
sdl_resize(ds, 640, 400);
sdl_update_caption();
diff -ur kvm-33.orig/qemu/vl.c kvm-33/qemu/vl.c
--- kvm-33.orig/qemu/vl.c 2007-07-23 16:58:51.0 +0200
+++ kvm-33/qemu/vl.c 2007-07-29 17:18:24.0 +0200
@@ -110,7 +110,7 @@
#define DEFAULT_RAM_SIZE 128
#endif
/* in ms */
-#define GUI_REFRESH_INTERVAL 30
+#define DEFAULT_GUI_REFRESH_INTERVAL 30
/* Max number of USB devices that can be specified on the commandline. */
#define MAX_USB_CMDLINE 8
@@ -4137,6 +4137,7 @@
ds-dpy_update = dumb_update;
ds-dpy_resize = dumb_resize;
ds-dpy_refresh = dumb_refresh;
+ds-refresh_interval = DEFAULT_GUI_REFRESH_INTERVAL;
}
/***/
@@ -5995,7 +5996,7 @@
void gui_update(void *opaque)
{
display_state.dpy_refresh(display_state);
-qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
+qemu_mod_timer(gui_timer, display_state.refresh_interval + qemu_get_clock(rt_clock));
}
struct vm_change_state_entry {
Only in kvm-33/qemu: vl.c~
diff -ur kvm-33.orig/qemu/vl.h kvm-33/qemu/vl.h
--- kvm-33.orig/qemu/vl.h 2007-07-23 16:58:51.0 +0200
+++ kvm-33/qemu/vl.h 2007-07-29 16:13:15.0 +0200
@@ -907,6 +907,7 @@
int width;
int height;
void *opaque;
+int refresh_interval;
void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
void (*dpy_resize)(struct DisplayState *s, int w, int h);