[host] initial changes to implement frame rate control

This commit is contained in:
Geoffrey McRae 2022-11-07 19:46:18 +11:00
parent f0cb9d1167
commit 3ec632dd3c
3 changed files with 29 additions and 4 deletions

View File

@ -28,7 +28,7 @@
#include "types.h" #include "types.h"
#define KVMFR_MAGIC "KVMFR---" #define KVMFR_MAGIC "KVMFR---"
#define KVMFR_VERSION 19 #define KVMFR_VERSION 20
#define KVMFR_MAX_DAMAGE_RECTS 64 #define KVMFR_MAX_DAMAGE_RECTS 64
@ -56,7 +56,8 @@ typedef uint32_t KVMFRFeatureFlags;
enum enum
{ {
KVMFR_MESSAGE_SETCURSORPOS KVMFR_MESSAGE_SETCURSORPOS,
KVMFR_MESSAGE_FRAME_TIME
}; };
typedef uint32_t KVMFRMessageType; typedef uint32_t KVMFRMessageType;
@ -137,6 +138,8 @@ typedef struct KVMFRFrame
{ {
uint32_t formatVer; // the frame format version number uint32_t formatVer; // the frame format version number
uint32_t frameSerial; // the unique frame 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 FrameType type; // the frame data type
uint32_t screenWidth; // the client's screen width uint32_t screenWidth; // the client's screen width
uint32_t screenHeight; // the client's screen height uint32_t screenHeight; // the client's screen height
@ -155,14 +158,28 @@ KVMFRFrame;
typedef struct KVMFRMessage typedef struct KVMFRMessage
{ {
KVMFRMessageType type; KVMFRMessageType type;
uint32_t clientID;
} }
KVMFRMessage; KVMFRMessage;
typedef struct KVMFRSetCursorPos typedef struct KVMFRMessage_SetCursorPos
{ {
KVMFRMessage msg; KVMFRMessage msg;
int32_t x, y; int32_t x, y;
} }
KVMFRSetCursorPos; 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 #endif

View File

@ -96,6 +96,7 @@ struct app
unsigned int frameIndex; unsigned int frameIndex;
bool frameValid; bool frameValid;
uint32_t frameSerial; uint32_t frameSerial;
uint64_t frameTimeUs;
CaptureInterface * iface; CaptureInterface * iface;
@ -268,6 +269,7 @@ static bool sendFrame(void)
} }
fi->formatVer = frame.formatVer; fi->formatVer = frame.formatVer;
fi->frameTimeUs = app.frameTimeUs;
fi->frameSerial = app.frameSerial++; fi->frameSerial = app.frameSerial++;
fi->screenWidth = frame.screenWidth; fi->screenWidth = frame.screenWidth;
fi->screenHeight = frame.screenHeight; fi->screenHeight = frame.screenHeight;
@ -295,6 +297,11 @@ static bool sendFrame(void)
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)fi) + fi->offset); FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)fi) + fi->offset);
framebuffer_prepare(fb); 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! */ /* we post and then get the frame, this is intentional! */
if ((status = lgmpHostQueuePost(app.frameQueue, 0, if ((status = lgmpHostQueuePost(app.frameQueue, 0,
app.frameMemory[app.frameIndex])) != LGMP_OK) app.frameMemory[app.frameIndex])) != LGMP_OK)
@ -911,6 +918,7 @@ int app_main(int argc, char * argv[])
else else
previousFrameTime = now; previousFrameTime = now;
app.frameTimeUs = microtime();
switch(iface->capture()) switch(iface->capture())
{ {
case CAPTURE_RESULT_OK: case CAPTURE_RESULT_OK:

@ -1 +1 @@
Subproject commit 66ac3bae0b4136f0a4e817b3d0892db4dc153759 Subproject commit 18a96cd95ed71fae782d306a5a0dd231c800ea44