From 3ec632dd3c1292ce138274abe58f6a796a322008 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Mon, 7 Nov 2022 19:46:18 +1100 Subject: [PATCH] [host] initial changes to implement frame rate control --- common/include/common/KVMFR.h | 23 ++++++++++++++++++++--- host/src/app.c | 8 ++++++++ repos/LGMP | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/common/include/common/KVMFR.h b/common/include/common/KVMFR.h index c208487e..b6c06b85 100644 --- a/common/include/common/KVMFR.h +++ b/common/include/common/KVMFR.h @@ -28,7 +28,7 @@ #include "types.h" #define KVMFR_MAGIC "KVMFR---" -#define KVMFR_VERSION 19 +#define KVMFR_VERSION 20 #define KVMFR_MAX_DAMAGE_RECTS 64 @@ -56,7 +56,8 @@ typedef uint32_t KVMFRFeatureFlags; enum { - KVMFR_MESSAGE_SETCURSORPOS + KVMFR_MESSAGE_SETCURSORPOS, + KVMFR_MESSAGE_FRAME_TIME }; typedef uint32_t KVMFRMessageType; @@ -137,6 +138,8 @@ typedef struct KVMFRFrame { uint32_t formatVer; // the frame format version number uint32_t frameSerial; // the unique frame number + uint64_t frameTimeUs; // when the capture was started + uint64_t frameElapsedUs; // total time elapsed to capture the frame FrameType type; // the frame data type uint32_t screenWidth; // the client's screen width uint32_t screenHeight; // the client's screen height @@ -155,14 +158,28 @@ KVMFRFrame; typedef struct KVMFRMessage { KVMFRMessageType type; + uint32_t clientID; } KVMFRMessage; -typedef struct KVMFRSetCursorPos +typedef struct KVMFRMessage_SetCursorPos { KVMFRMessage msg; int32_t x, y; } KVMFRSetCursorPos; +typedef struct KVMFRMessage_FrameTime +{ + KVMFRMessage msg; + /* this is the desired time to start the next capture operation where zero is + * immediate. This is only a hint to the host application and may not be + * honored. The value provided should be offset from the latest frame's + * frameTimeUs. When multiple clients are sending this message, the one with + * the lowest value will be used. + */ + uint64_t frameTimeUs; +} +KVMFRMessage_FrameTime; + #endif diff --git a/host/src/app.c b/host/src/app.c index a52fb53e..449a8a09 100644 --- a/host/src/app.c +++ b/host/src/app.c @@ -96,6 +96,7 @@ struct app unsigned int frameIndex; bool frameValid; uint32_t frameSerial; + uint64_t frameTimeUs; CaptureInterface * iface; @@ -268,6 +269,7 @@ static bool sendFrame(void) } fi->formatVer = frame.formatVer; + fi->frameTimeUs = app.frameTimeUs; fi->frameSerial = app.frameSerial++; fi->screenWidth = frame.screenWidth; fi->screenHeight = frame.screenHeight; @@ -295,6 +297,11 @@ static bool sendFrame(void) FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)fi) + fi->offset); framebuffer_prepare(fb); + // calculate the elapsed time as late as possible, note that this does not + // take into account the memory copy time and the client's that care about + // this value will need to take this into account + fi->frameElapsedUs = microtime() - app.frameTimeUs; + /* we post and then get the frame, this is intentional! */ if ((status = lgmpHostQueuePost(app.frameQueue, 0, app.frameMemory[app.frameIndex])) != LGMP_OK) @@ -911,6 +918,7 @@ int app_main(int argc, char * argv[]) else previousFrameTime = now; + app.frameTimeUs = microtime(); switch(iface->capture()) { case CAPTURE_RESULT_OK: diff --git a/repos/LGMP b/repos/LGMP index 66ac3bae..18a96cd9 160000 --- a/repos/LGMP +++ b/repos/LGMP @@ -1 +1 @@ -Subproject commit 66ac3bae0b4136f0a4e817b3d0892db4dc153759 +Subproject commit 18a96cd95ed71fae782d306a5a0dd231c800ea44