static int vnc_update_stats(VncDisplay *vd, struct timeval * tv) { int width = pixman_image_get_width(vd->guest.fb); int height = pixman_image_get_height(vd->guest.fb); int x, y; struct timeval res; int has_dirty = 0; for (y = 0; y < height; y += VNC_STAT_RECT) { for (x = 0; x < width; x += VNC_STAT_RECT) { VncRectStat *rect = vnc_stat_rect(vd, x, y); rect->updated = false; } } qemu_timersub(tv, &VNC_REFRESH_STATS, &res); if (timercmp(&vd->guest.last_freq_check, &res, >)) { return has_dirty; } vd->guest.last_freq_check = *tv; for (y = 0; y < height; y += VNC_STAT_RECT) { for (x = 0; x < width; x += VNC_STAT_RECT) { VncRectStat *rect= vnc_stat_rect(vd, x, y); int count = ARRAY_SIZE(rect->times); struct timeval min, max; if (!timerisset(&rect->times[count - 1])) { continue ; } max = rect->times[(rect->idx + count - 1) % count]; qemu_timersub(tv, &max, &res); if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) { rect->freq = 0; has_dirty += vnc_refresh_lossy_rect(vd, x, y); memset(rect->times, 0, sizeof (rect->times)); continue ; } min = rect->times[rect->idx]; max = rect->times[(rect->idx + count - 1) % count]; qemu_timersub(&max, &min, &res); rect->freq = res.tv_sec + res.tv_usec / 1000000.; rect->freq /= count; rect->freq = 1. / rect->freq; } } return has_dirty; }