diff --git a/client/Makefile b/client/Makefile index 276b0a26..c275e0a7 100644 --- a/client/Makefile +++ b/client/Makefile @@ -13,6 +13,7 @@ BUILD ?= .build BIN ?= bin OBJS = main.o \ + delay.o \ spice/spice.o \ ivshmem/ivshmem.o \ renderers/basic.o \ diff --git a/client/delay.c b/client/delay.c new file mode 100644 index 00000000..9d2de265 --- /dev/null +++ b/client/delay.c @@ -0,0 +1,70 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017 Geoffrey McRae + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "delay.h" + +#include + +#include "debug.h" + +static unsigned int delay_loop_count = 0; + +void delay() +{ + unsigned char j; + for(unsigned int i = 0; i < delay_loop_count; ++i) + { + j = 0; + while(--j) + asm(""); + } +} + +void delay_calibrate() +{ + // initialize the poll limit to a sane value + for(int start = SDL_GetTicks(); SDL_GetTicks() - start < 10; ++delay_loop_count) {} + DEBUG_INFO("Init : %u", delay_loop_count); + + // the following loop must produce 20 concurrent valid results to ensure a valid calculation + int okCount = 0; + while(okCount < 20) + { + // time the final loop and calculate the remaining time + unsigned int ticks = SDL_GetTicks(); + delay(); + int remain = 10 - (SDL_GetTicks() - ticks); + + // if the remaining time is within 2ms, accept it (Linux is not a RTOS) + if (remain > -2 && remain < 2) + { + ++okCount; + continue; + } + + // the delay is out of spec, adjust the limit + okCount = 0; + DEBUG_INFO("Diff : %c%d ms", remain > 0 ? '-' : '+', abs(remain)); + delay_loop_count += ceil(((double)delay_loop_count / 10.0) * remain); + } + + DEBUG_INFO("Final: %u", delay_loop_count); + + // scale the limit for a 1ms delay + delay_loop_count = ceil((double)delay_loop_count / 10.0); +} \ No newline at end of file diff --git a/client/delay.h b/client/delay.h new file mode 100644 index 00000000..e365362c --- /dev/null +++ b/client/delay.h @@ -0,0 +1,22 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017 Geoffrey McRae + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#pragma once + +void delay_calibrate(); +void delay(); \ No newline at end of file diff --git a/client/main.c b/client/main.c index 449c5fa6..6e7a9c04 100644 --- a/client/main.c +++ b/client/main.c @@ -34,6 +34,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include "debug.h" +#include "delay.h" #include "memcpySSE.h" #include "KVMFR.h" #include "ivshmem/ivshmem.h" @@ -641,6 +642,8 @@ int run() state.scaleX = 1.0f; state.scaleY = 1.0f; + delay_calibrate(); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { DEBUG_ERROR("SDL_Init Failed");