From 8fbe3e74540c398bfb0165c3323ce49c2a7f47f6 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Tue, 1 Sep 2026 20:58:25 +1000 Subject: [PATCH] [repos] lgprotocol: import shared protocol definitions Add LGProtocol as a pinned submodule and consume its KVMFR protocol definitions throughout the client, host, IDD, OBS, and profiler. Keep Looking Glass framebuffer helpers local while removing duplicated protocol headers and migrating users to KVMFR-scoped types. --- .gitmodules | 3 + client/displayservers/Wayland/clipboard.c | 2 +- client/displayservers/Wayland/wayland.h | 2 +- client/displayservers/X11/clipboard.c | 2 +- client/include/interface/renderer.h | 8 +- client/include/interface/transport.h | 56 +-- client/renderers/EGL/cursor.c | 6 +- client/renderers/EGL/cursor.h | 2 +- client/renderers/EGL/damage.h | 2 +- client/renderers/EGL/desktop.c | 5 +- client/renderers/EGL/desktop.h | 4 +- client/renderers/EGL/desktop_rects.c | 13 +- client/renderers/EGL/desktop_rects.h | 12 +- client/renderers/EGL/egl.c | 34 +- client/renderers/EGL/hdr_overlay.c | 8 +- client/renderers/EGL/texture.c | 6 +- client/renderers/EGL/texture.h | 12 +- client/renderers/EGL/texture_buffer.c | 22 +- client/renderers/EGL/texture_buffer.h | 8 +- client/renderers/EGL/texture_framebuffer.c | 16 +- client/renderers/OpenGL/opengl.c | 32 +- client/src/clipboard_files.c | 2 +- client/src/main.c | 8 +- client/src/render_queue.c | 50 +- client/src/render_queue.h | 2 +- client/tests/CMakeLists.txt | 4 + client/tests/clipboard_files_test.c | 2 +- client/tests/desktop_rects_test.c | 14 +- client/tests/frame_timing_test.c | 2 +- client/tests/lgmp_clipboard_test.c | 4 +- client/tests/lgmp_frame_test.c | 9 +- client/tests/lgmp_input_test.c | 4 +- client/tests/lgmp_transport_test.c | 11 +- client/tests/render_queue_test.c | 48 +- client/tests/render_test.cpp | 8 +- client/tests/x11_clipboard_test.c | 2 +- client/transports/LGMP/clipboard.c | 4 +- client/transports/LGMP/input.c | 4 +- client/transports/LGMP/lgmp.c | 22 +- client/transports/Test/test.c | 32 +- cmake/CheckSubmodule.cmake | 1 + common/CMakeLists.txt | 19 +- common/include/common/KVMFR.h | 370 --------------- common/include/common/KVMFRClipboard.h | 438 ------------------ common/include/common/KVMFRInput.h | 246 ---------- common/include/common/KVMFRRecovery.h | 263 ----------- common/include/common/KVMFRStream.h | 68 --- common/include/common/LGMPConfig.h | 39 -- common/include/common/framebuffer.h | 40 +- common/include/common/rects.h | 17 +- common/include/common/types.h | 61 +-- common/src/KVMFR.c | 2 +- common/src/framebuffer.c | 108 ++--- common/src/rects.c | 46 +- host/CMakeLists.txt | 2 +- host/include/interface/capture.h | 34 +- host/include/interface/platform.h | 2 +- host/platform/Linux/capture/XCB/src/xcb.c | 10 +- .../Linux/capture/pipewire/src/pipewire.c | 10 +- host/platform/Windows/capture/D12/d12.c | 45 +- .../Windows/capture/DXGI/src/backend.h | 8 +- .../platform/Windows/capture/DXGI/src/d3d11.c | 4 +- host/platform/Windows/capture/DXGI/src/dxgi.c | 47 +- .../Windows/capture/NVFBC/src/nvfbc.c | 22 +- host/src/app.c | 32 +- idd/LGCommon/ClipboardRing.h | 2 +- idd/LGCommon/InputPipeProtocol.h | 2 +- idd/LGCommon/LGCommon.vcxproj | 2 +- idd/LGIdd/LGIdd.vcxproj | 8 +- idd/LGIdd/postprocess/D12FrameFormat.cpp | 4 +- idd/LGIdd/postprocess/D12FrameFormat.h | 6 +- .../effect/CColorTransformEffect.cpp | 4 +- idd/LGIdd/postprocess/effect/CRGB24Effect.cpp | 2 +- idd/LGIdd/transport/CFrameHub.h | 144 +++--- idd/LGIdd/transport/IClipboardSource.h | 2 +- idd/LGIdd/transport/lgmp/CIVSHMEM.h | 2 +- .../transport/lgmp/CLGMPClipboardFiles.h | 2 +- .../transport/lgmp/CLGMPClipboardTransport.h | 4 +- idd/LGIdd/transport/lgmp/CLGMPControl.h | 2 +- .../transport/lgmp/CLGMPFrameTransport.h | 16 +- idd/LGIdd/transport/lgmp/CLGMPHost.cpp | 2 +- .../transport/lgmp/CLGMPInputTransport.cpp | 4 +- .../transport/lgmp/CLGMPInputTransport.h | 4 +- idd/LGIdd/transport/lgmp/CLGMPTransport.cpp | 4 +- idd/LGIdd/transport/lgmp/CRecovery.cpp | 4 +- idd/LGIddHelper/CClipboardFiles.h | 2 +- idd/LGIddHelper/LGIddHelper.vcxproj | 8 +- idd/LGInput/LGInput.vcxproj | 2 +- obs/CMakeLists.txt | 2 +- obs/frame_scheduler.c | 2 +- obs/lg.c | 17 +- profile/client/CMakeLists.txt | 2 +- profile/client/src/main.c | 4 +- repos/LGProtocol | 1 + 94 files changed, 619 insertions(+), 2062 deletions(-) delete mode 100644 common/include/common/KVMFR.h delete mode 100644 common/include/common/KVMFRClipboard.h delete mode 100644 common/include/common/KVMFRInput.h delete mode 100644 common/include/common/KVMFRRecovery.h delete mode 100644 common/include/common/KVMFRStream.h delete mode 100644 common/include/common/LGMPConfig.h create mode 160000 repos/LGProtocol diff --git a/.gitmodules b/.gitmodules index c1a7557e..9a0f58b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "repos/cimplot"] path = repos/gui/cimplot url = https://github.com/cimgui/cimplot.git +[submodule "repos/LGProtocol"] + path = repos/LGProtocol + url = https://github.com/gnif/LGProtocol.git diff --git a/client/displayservers/Wayland/clipboard.c b/client/displayservers/Wayland/clipboard.c index 4ef16bd0..ed184699 100644 --- a/client/displayservers/Wayland/clipboard.c +++ b/client/displayservers/Wayland/clipboard.c @@ -33,7 +33,7 @@ #include "core/clipboard_files.h" #include "common/countedbuffer.h" #include "common/debug.h" -#include "common/KVMFRClipboard.h" +#include struct DataOffer { bool isSelfCopy; diff --git a/client/displayservers/Wayland/wayland.h b/client/displayservers/Wayland/wayland.h index ff6b47ea..d5609a87 100644 --- a/client/displayservers/Wayland/wayland.h +++ b/client/displayservers/Wayland/wayland.h @@ -35,7 +35,7 @@ #include "app.h" #include "egl_dynprocs.h" -#include "common/KVMFRClipboard.h" +#include #include "common/locking.h" #include "common/ringbuffer.h" #include "interface/displayserver.h" diff --git a/client/displayservers/X11/clipboard.c b/client/displayservers/X11/clipboard.c index b39b12d3..e1ca07ac 100644 --- a/client/displayservers/X11/clipboard.c +++ b/client/displayservers/X11/clipboard.c @@ -32,7 +32,7 @@ #include "core/clipboard_files.h" #include "common/array.h" #include "common/debug.h" -#include "common/KVMFRClipboard.h" +#include #include "common/locking.h" struct X11ClipboardRead diff --git a/client/include/interface/renderer.h b/client/include/interface/renderer.h index 11c73f7e..b6148073 100644 --- a/client/include/interface/renderer.h +++ b/client/include/interface/renderer.h @@ -75,7 +75,7 @@ LG_RendererRotate; typedef struct LG_RendererFormat { - FrameType type; // frame type + KVMFRFrameType type; // frame type bool hdr; // if the frame is HDR or not bool hdrPQ; // if the HDR content is PQ mapped bool hdrMetadata; // if the HDR static metadata is valid @@ -286,7 +286,7 @@ typedef struct LG_RendererOps /* optional display calibration update for hardware cursor composition * Context: cursorThread */ void (*onMouseColorTransform)(LG_Renderer * renderer, - const LGColorTransform * transform); + const KVMFRColorTransform * transform); /* updates the cursor-specific SDR white level reported by IddCx * Context: cursorThread */ @@ -307,8 +307,8 @@ typedef struct LG_RendererOps * when that update is consumed. A non-NULL releaseFn transfers ownership to * the renderer on success and must be called exactly once when the imported * frame can no longer be sampled. Context: frameThread */ - bool (*onFrame)(LG_Renderer * renderer, const FrameBuffer * frame, int dmaFD, - const FrameDamageRect * damage, int damageCount, + bool (*onFrame)(LG_Renderer * renderer, const KVMFRFrameBuffer * frame, + int dmaFD, const KVMFRFrameDamageRect * damage, int damageCount, LG_RendererFrameToken frameToken, LG_FrameReleaseFn releaseFn, void * releaseOpaque, uint64_t releaseHandle); diff --git a/client/include/interface/transport.h b/client/include/interface/transport.h index e1d04a78..78f451b3 100644 --- a/client/include/interface/transport.h +++ b/client/include/interface/transport.h @@ -202,17 +202,17 @@ LG_TransportFrameTiming; typedef struct LG_TransportFrameFormat { - uint32_t version; - FrameType type; - uint32_t screenWidth; - uint32_t screenHeight; - uint32_t dataWidth; - uint32_t dataHeight; - uint32_t frameWidth; - uint32_t frameHeight; - FrameRotation rotation; - uint32_t stride; - uint32_t pitch; + uint32_t version; + KVMFRFrameType type; + uint32_t screenWidth; + uint32_t screenHeight; + uint32_t dataWidth; + uint32_t dataHeight; + uint32_t frameWidth; + uint32_t frameHeight; + KVMFRFrameRotation rotation; + uint32_t stride; + uint32_t pitch; bool hdr; bool hdrPQ; @@ -340,10 +340,10 @@ typedef struct LG_TransportFrame // Backend-owned immutable metadata, valid until releaseFrame. const LG_TransportFrameFormat * format; - const FrameBuffer * framebuffer; - int dmaFD; - const FrameDamageRect * damageRects; - uint32_t damageRectsCount; + const KVMFRFrameBuffer * framebuffer; + int dmaFD; + const KVMFRFrameDamageRect * damageRects; + uint32_t damageRectsCount; /* A transport may keep the frame payload alive asynchronously after * onFrame returns. The callback is idempotent and releases that ownership. */ @@ -369,19 +369,19 @@ typedef struct LG_TransportPointer /* When setStatusListener is present, matches LG_VideoComponentStatus::epoch * for the pointer endpoint which returned this payload; otherwise may be 0. */ - uint64_t epoch; - LG_TransportPointerFlags flags; - int16_t x; - int16_t y; - CursorType type; - int16_t hx; - int16_t hy; - uint32_t width; - uint32_t height; - uint32_t pitch; - uint32_t sdrWhiteLevel; - const uint8_t * shape; - const LGColorTransform * colorTransform; + uint64_t epoch; + LG_TransportPointerFlags flags; + int16_t x; + int16_t y; + KVMFRCursorType type; + int16_t hx; + int16_t hy; + uint32_t width; + uint32_t height; + uint32_t pitch; + uint32_t sdrWhiteLevel; + const uint8_t * shape; + const KVMFRColorTransform * colorTransform; } LG_TransportPointer; diff --git a/client/renderers/EGL/cursor.c b/client/renderers/EGL/cursor.c index 8669be3f..43ff8b44 100644 --- a/client/renderers/EGL/cursor.c +++ b/client/renderers/EGL/cursor.c @@ -104,8 +104,8 @@ struct EGL_Cursor _Atomic(float) mapHDRContentPeak; bool colorTransformUpdate; - LGColorTransform pendingColorTransform; - LGColorTransform activeColorTransform; + KVMFRColorTransform pendingColorTransform; + KVMFRColorTransform activeColorTransform; GLuint colorLUT; struct CursorTex norm; @@ -344,7 +344,7 @@ bool egl_cursorSetShape(EGL_Cursor * cursor, const LG_RendererCursor type, } void egl_cursorSetColorTransform(EGL_Cursor * cursor, - const LGColorTransform * transform) + const KVMFRColorTransform * transform) { LG_LOCK(cursor->lock); cursor->pendingColorTransform = *transform; diff --git a/client/renderers/EGL/cursor.h b/client/renderers/EGL/cursor.h index 4b194b1d..cf89fbe9 100644 --- a/client/renderers/EGL/cursor.h +++ b/client/renderers/EGL/cursor.h @@ -44,7 +44,7 @@ bool egl_cursorSetShape( const uint8_t * data); void egl_cursorSetColorTransform(EGL_Cursor * cursor, - const LGColorTransform * transform); + const KVMFRColorTransform * transform); void egl_cursorSetSize(EGL_Cursor * cursor, const float x, const float y); diff --git a/client/renderers/EGL/damage.h b/client/renderers/EGL/damage.h index 4cd02d9a..e6a0d52d 100644 --- a/client/renderers/EGL/damage.h +++ b/client/renderers/EGL/damage.h @@ -29,7 +29,7 @@ struct DesktopDamage { LG_RendererFrameToken frameToken; int count; - FrameDamageRect rects[LG_MAX_FRAME_DAMAGE_RECTS]; + KVMFRFrameDamageRect rects[LG_MAX_FRAME_DAMAGE_RECTS]; }; typedef struct EGL_Damage EGL_Damage; diff --git a/client/renderers/EGL/desktop.c b/client/renderers/EGL/desktop.c index 92d73f07..ef859c86 100644 --- a/client/renderers/EGL/desktop.c +++ b/client/renderers/EGL/desktop.c @@ -380,9 +380,10 @@ bool egl_desktopSetup(EGL_Desktop * desktop, const LG_RendererFormat format) return true; } -bool egl_desktopUpdate(EGL_Desktop * desktop, const FrameBuffer * frame, +bool egl_desktopUpdate(EGL_Desktop * desktop, + const KVMFRFrameBuffer * frame, LG_RendererFrameToken frameToken, int dmaFd, - const FrameDamageRect * damageRects, int damageRectsCount, + const KVMFRFrameDamageRect * damageRects, int damageRectsCount, uint64_t * waitTimeNs, LG_FrameReleaseFn releaseFn, void * releaseOpaque, uint64_t releaseHandle) { diff --git a/client/renderers/EGL/desktop.h b/client/renderers/EGL/desktop.h index a0aa48d3..8d021f8a 100644 --- a/client/renderers/EGL/desktop.h +++ b/client/renderers/EGL/desktop.h @@ -48,9 +48,9 @@ void egl_desktopSetNativeHDR(EGL_Desktop * desktop, bool nativeHDR, void egl_desktopGetHDRMapping(EGL_Desktop * desktop, bool * enabled, float * gain, float * contentPeak); bool egl_desktopSetup (EGL_Desktop * desktop, const LG_RendererFormat format); -bool egl_desktopUpdate(EGL_Desktop * desktop, const FrameBuffer * frame, +bool egl_desktopUpdate(EGL_Desktop * desktop, const KVMFRFrameBuffer * frame, LG_RendererFrameToken frameToken, int dmaFd, - const FrameDamageRect * damageRects, int damageRectsCount, + const KVMFRFrameDamageRect * damageRects, int damageRectsCount, uint64_t * waitTimeNs, LG_FrameReleaseFn releaseFn, void * releaseOpaque, uint64_t releaseHandle); void egl_desktopRestart(EGL_Desktop * desktop); diff --git a/client/renderers/EGL/desktop_rects.c b/client/renderers/EGL/desktop_rects.c index 37cfea76..091ffa1d 100644 --- a/client/renderers/EGL/desktop_rects.c +++ b/client/renderers/EGL/desktop_rects.c @@ -95,7 +95,8 @@ void egl_desktopRectsFree(EGL_DesktopRects ** rects_) *rects_ = NULL; } -inline static void rectToVertices(GLfloat * vertex, const FrameDamageRect * rect) +inline static void rectToVertices(GLfloat * vertex, + const KVMFRFrameDamageRect * rect) { vertex[0] = rect->x; vertex[1] = rect->y; @@ -108,7 +109,7 @@ inline static void rectToVertices(GLfloat * vertex, const FrameDamageRect * rect } void egl_desktopRectsUpdate(EGL_DesktopRects * rects, - const FrameDamageRect * data, int count, int width, int height) + const KVMFRFrameDamageRect * data, int count, int width, int height) { if (count == 0) { @@ -120,7 +121,7 @@ void egl_desktopRectsUpdate(EGL_DesktopRects * rects, GLfloat vertices[vertexCount]; if (count < 0) { - FrameDamageRect full = { + KVMFRFrameDamageRect full = { .x = 0, .y = 0, .width = width, .height = height, }; rects->count = 1; @@ -237,7 +238,8 @@ inline static void matrixMultiply(const double matrix[6], double * nx, double * *ny = matrix[1] * x + matrix[3] * y + matrix[5]; } -struct Rect egl_desktopToScreen(const double matrix[6], const struct FrameDamageRect * rect) +struct Rect egl_desktopToScreen(const double matrix[6], + const struct KVMFRFrameDamageRect * rect) { double x1, y1, x2, y2; matrixMultiply(matrix, &x1, &y1, rect->x, rect->y); @@ -270,7 +272,8 @@ void egl_screenToDesktopMatrix(double matrix[6], int frameWidth, int frameHeight matrix[5] = (inverted[1] * inverted[4] - inverted[0] * inverted[5]) / det; } -bool egl_screenToDesktop(struct FrameDamageRect * output, const double matrix[6], +bool egl_screenToDesktop(struct KVMFRFrameDamageRect * output, + const double matrix[6], const struct Rect * rect, int width, int height) { double x1, y1, x2, y2; diff --git a/client/renderers/EGL/desktop_rects.h b/client/renderers/EGL/desktop_rects.h index 41724585..898c4c22 100644 --- a/client/renderers/EGL/desktop_rects.h +++ b/client/renderers/EGL/desktop_rects.h @@ -26,8 +26,8 @@ struct DamageRects { - int count; - FrameDamageRect rects[]; + int count; + KVMFRFrameDamageRect rects[]; }; typedef struct EGL_DesktopRects EGL_DesktopRects; @@ -40,14 +40,16 @@ void egl_desktopRectsMatrix(float matrix[6], int width, int height, float transl void egl_desktopToScreenMatrix(double matrix[6], int frameWidth, int frameHeight, double translateX, double translateY, double scaleX, double scaleY, LG_RendererRotate rotate, double windowWidth, double windowHeight); -struct Rect egl_desktopToScreen(const double matrix[6], const struct FrameDamageRect * rect); +struct Rect egl_desktopToScreen(const double matrix[6], + const struct KVMFRFrameDamageRect * rect); void egl_screenToDesktopMatrix(double matrix[6], int frameWidth, int frameHeight, double translateX, double translateY, double scaleX, double scaleY, LG_RendererRotate rotate, double windowWidth, double windowHeight); -bool egl_screenToDesktop(struct FrameDamageRect * output, const double matrix[6], +bool egl_screenToDesktop(struct KVMFRFrameDamageRect * output, + const double matrix[6], const struct Rect * rect, int width, int height); void egl_desktopRectsUpdate(EGL_DesktopRects * rects, - const FrameDamageRect * data, int count, int width, int height); + const KVMFRFrameDamageRect * data, int count, int width, int height); void egl_desktopRectsRender(EGL_DesktopRects * rects); diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index def18098..9afd1dc2 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -453,7 +453,7 @@ static void egl_addSwSurfaceDamage( if (right <= x || bottom <= y) return; - const FrameDamageRect rect = { + const KVMFRFrameDamageRect rect = { .x = (uint32_t)x, .y = (uint32_t)y, .width = (uint32_t)(right - x), @@ -697,7 +697,7 @@ static bool egl_onMouseShape(LG_Renderer * renderer, const LG_RendererCursor cur } static void egl_onMouseColorTransform(LG_Renderer * renderer, - const LGColorTransform * transform) + const KVMFRColorTransform * transform) { struct Inst * this = UPCAST(struct Inst, renderer); egl_cursorSetColorTransform(this->cursor, transform); @@ -832,8 +832,9 @@ static bool egl_onFrameFormat(LG_Renderer * renderer, const LG_RendererFormat fo return egl_desktopSetup(this->desktop, format); } -static bool egl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, - int dmaFd, const FrameDamageRect * damageRects, int damageRectsCount, +static bool egl_onFrame(LG_Renderer * renderer, + const KVMFRFrameBuffer * frame, int dmaFd, + const KVMFRFrameDamageRect * damageRects, int damageRectsCount, LG_RendererFrameToken frameToken, LG_FrameReleaseFn releaseFn, void * releaseOpaque, uint64_t releaseHandle) { @@ -853,8 +854,9 @@ static bool egl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, const uint64_t elapsed = nanotime() - start; - /* Producer Copy already covers the interval before FrameBuffer::wp becomes - * ready. Exclude that overlapping wait from the client Import stage. */ + /* Producer Copy already covers the interval before KVMFRFrameBuffer::wp + * becomes ready. Exclude that overlapping wait from the client Import + * stage. */ app_setFrameImportTiming( elapsed > waitTimeNs ? elapsed - waitTimeNs : 0, waitTimeNs); @@ -873,7 +875,7 @@ static bool egl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, else { memcpy(damage->rects + damage->count, damageRects, - damageRectsCount * sizeof(FrameDamageRect)); + damageRectsCount * sizeof(KVMFRFrameDamageRect)); damage->count += damageRectsCount; } damage->frameToken = frameToken; @@ -1327,8 +1329,8 @@ inline static EGLint egl_bufferAge(struct Inst * this) return result; } -static FrameDamageRect egl_expandDesktopDamage( - const struct Inst * this, const FrameDamageRect * rect) +static KVMFRFrameDamageRect egl_expandDesktopDamage( + const struct Inst * this, const KVMFRFrameDamageRect * rect) { int width, height; egl_getDesktopSize(this, &width, &height); @@ -1342,7 +1344,7 @@ static FrameDamageRect egl_expandDesktopDamage( const uint32_t bottom = (uint32_t)min((uint64_t)height, (uint64_t)rect->y + rect->height + DESKTOP_DAMAGE_MARGIN); - return (FrameDamageRect) { + return (KVMFRFrameDamageRect) { .x = x, .y = y, .width = right > x ? right - x : 0, @@ -1381,10 +1383,10 @@ static int egl_mergeSurfaceDamage(struct Rect * damage, int count) if (count <= 1) return count; - FrameDamageRect rects[count]; + KVMFRFrameDamageRect rects[count]; for (int i = 0; i < count; ++i) { - rects[i] = (FrameDamageRect) { + rects[i] = (KVMFRFrameDamageRect) { .x = damage[i].x, .y = damage[i].y, .width = damage[i].w, @@ -1422,7 +1424,7 @@ static void egl_requeueDesktopDamage( else { memcpy(pending->rects + pending->count, damage->rects, - damage->count * sizeof(FrameDamageRect)); + damage->count * sizeof(KVMFRFrameDamageRect)); pending->count += damage->count; } @@ -1505,7 +1507,7 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate, struct DamageRects * accumulated = (struct DamageRects *)alloca( sizeof(struct DamageRects) + - MAX_ACCUMULATED_DAMAGE * sizeof(struct FrameDamageRect) + MAX_ACCUMULATED_DAMAGE * sizeof(struct KVMFRFrameDamageRect) ); accumulated->count = 0; @@ -1533,7 +1535,7 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate, for (int j = 0; j < damage->count; ++j) { - const FrameDamageRect rect = + const KVMFRFrameDamageRect rect = egl_expandDesktopDamage(this, damage->rects + j); if (rect.width && rect.height) accumulated->rects[accumulated->count++] = rect; @@ -1732,7 +1734,7 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate, for (int i = 0; i < desktopDamage->count; ++i) { - const FrameDamageRect rect = + const KVMFRFrameDamageRect rect = egl_expandDesktopDamage(this, desktopDamage->rects + i); if (rect.width && rect.height) damage[damageIdx++] = egl_desktopToScreen(matrix, &rect); diff --git a/client/renderers/EGL/hdr_overlay.c b/client/renderers/EGL/hdr_overlay.c index bfbcb7d0..3a47b112 100644 --- a/client/renderers/EGL/hdr_overlay.c +++ b/client/renderers/EGL/hdr_overlay.c @@ -140,7 +140,7 @@ void egl_hdrOverlaySetState(EGL_HDROverlay * this, bool active, bool pq, } static int convertDamage(EGL_HDROverlay * this, const struct Rect * damage, - int damageCount, FrameDamageRect * output) + int damageCount, KVMFRFrameDamageRect * output) { int count = 0; for (int i = 0; i < damageCount; ++i) @@ -152,7 +152,7 @@ static int convertDamage(EGL_HDROverlay * this, const struct Rect * damage, if (x2 <= x1 || y2 <= y1) continue; - output[count++] = (FrameDamageRect) + output[count++] = (KVMFRFrameDamageRect) { .x = x1, .y = this->height - y2, @@ -185,7 +185,7 @@ bool egl_hdrOverlayBegin(EGL_HDROverlay * this, } else { - FrameDamageRect rects[damageCount]; + KVMFRFrameDamageRect rects[damageCount]; const int count = convertDamage(this, damage, damageCount, rects); egl_stateScissor(true); @@ -227,7 +227,7 @@ void egl_hdrOverlayEnd(EGL_HDROverlay * this, } else { - FrameDamageRect rects[damageCount]; + KVMFRFrameDamageRect rects[damageCount]; const int count = convertDamage(this, damage, damageCount, rects); egl_stateScissor(true); diff --git a/client/renderers/EGL/texture.c b/client/renderers/EGL/texture.c index 35a0575e..7ed6a3ce 100644 --- a/client/renderers/EGL/texture.c +++ b/client/renderers/EGL/texture.c @@ -160,8 +160,8 @@ bool egl_textureUpdateRect(EGL_Texture * this, } bool egl_textureUpdateFromFrame(EGL_Texture * this, - const FrameBuffer * frame, LG_RendererFrameToken frameToken, - const FrameDamageRect * damageRects, int damageRectsCount, + const KVMFRFrameBuffer * frame, LG_RendererFrameToken frameToken, + const KVMFRFrameDamageRect * damageRects, int damageRectsCount, uint64_t * waitTimeNs) { const struct EGL_TexUpdate update = @@ -184,7 +184,7 @@ bool egl_textureUpdateFromFrame(EGL_Texture * this, } bool egl_textureUpdateFromDMA(EGL_Texture * this, - const FrameBuffer * frame, LG_RendererFrameToken frameToken, + const KVMFRFrameBuffer * frame, LG_RendererFrameToken frameToken, const int dmaFd, uint64_t * waitTimeNs, LG_FrameReleaseFn releaseFn, void * releaseOpaque, uint64_t releaseHandle) { diff --git a/client/renderers/EGL/texture.h b/client/renderers/EGL/texture.h index 1666fced..cace4c0c 100644 --- a/client/renderers/EGL/texture.h +++ b/client/renderers/EGL/texture.h @@ -67,9 +67,9 @@ typedef struct EGL_TexUpdate /* EGL_TEXTYPE_FRAMEBUFFER */ struct { - const FrameBuffer * frame; - const FrameDamageRect * rects; - int rectCount; + const KVMFRFrameBuffer * frame; + const KVMFRFrameDamageRect * rects; + int rectCount; }; /* EGL_TEXTYPE_DMABUF */ @@ -141,12 +141,12 @@ bool egl_textureUpdateRect(EGL_Texture * texture, const uint8_t * buffer, bool topDown); bool egl_textureUpdateFromFrame(EGL_Texture * texture, - const FrameBuffer * frame, LG_RendererFrameToken frameToken, - const FrameDamageRect * damageRects, int damageRectsCount, + const KVMFRFrameBuffer * frame, LG_RendererFrameToken frameToken, + const KVMFRFrameDamageRect * damageRects, int damageRectsCount, uint64_t * waitTimeNs); bool egl_textureUpdateFromDMA(EGL_Texture * texture, - const FrameBuffer * frame, LG_RendererFrameToken frameToken, + const KVMFRFrameBuffer * frame, LG_RendererFrameToken frameToken, const int dmaFd, uint64_t * waitTimeNs, LG_FrameReleaseFn releaseFn, void * releaseOpaque, uint64_t releaseHandle); diff --git a/client/renderers/EGL/texture_buffer.c b/client/renderers/EGL/texture_buffer.c index e86ca6ae..cf242226 100644 --- a/client/renderers/EGL/texture_buffer.c +++ b/client/renderers/EGL/texture_buffer.c @@ -31,20 +31,20 @@ extern const EGL_TextureOps EGL_TextureBufferStream; // internal functions -static uint64_t egl_texBufferDamageArea(const FrameDamageRect * rect) +static uint64_t egl_texBufferDamageArea(const KVMFRFrameDamageRect * rect) { return (uint64_t)rect->width * rect->height; } -static FrameDamageRect egl_texBufferDamageUnion( - const FrameDamageRect * a, const FrameDamageRect * b) +static KVMFRFrameDamageRect egl_texBufferDamageUnion( + const KVMFRFrameDamageRect * a, const KVMFRFrameDamageRect * b) { const uint32_t left = min(a->x, b->x); const uint32_t top = min(a->y, b->y); const uint32_t right = max(a->x + a->width, b->x + b->width); const uint32_t bottom = max(a->y + a->height, b->y + b->height); - return (FrameDamageRect) + return (KVMFRFrameDamageRect) { .x = left, .y = top, @@ -53,8 +53,8 @@ static FrameDamageRect egl_texBufferDamageUnion( }; } -static bool egl_texBufferDamageTouches(const FrameDamageRect * a, - const FrameDamageRect * b) +static bool egl_texBufferDamageTouches(const KVMFRFrameDamageRect * a, + const KVMFRFrameDamageRect * b) { return a->x <= b->x + b->width && b->x <= a->x + a->width && a->y <= b->y + b->height && b->y <= a->y + a->height; @@ -78,7 +78,7 @@ static void egl_texBufferDamageAdd(TextureBuffer * this, int index, return; } - FrameDamageRect rect = + KVMFRFrameDamageRect rect = { .x = update->x, .y = update->y, @@ -108,9 +108,9 @@ static void egl_texBufferDamageAdd(TextureBuffer * this, int index, uint64_t bestCost = UINT64_MAX; for (int i = 0; i < damage->count; ++i) { - const FrameDamageRect merged = + const KVMFRFrameDamageRect merged = egl_texBufferDamageUnion(&rect, &damage->rects[i]); - const uint64_t cost = egl_texBufferDamageArea(&merged) - + const uint64_t cost = egl_texBufferDamageArea(&merged) - egl_texBufferDamageArea(&damage->rects[i]); if (cost < bestCost) { @@ -479,8 +479,8 @@ EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture, else for (int i = 0; i < damage->count; ++i) { - const FrameDamageRect * rect = &damage->rects[i]; - const uintptr_t offset = + const KVMFRFrameDamageRect * rect = &damage->rects[i]; + const uintptr_t offset = (uintptr_t)rect->y * texture->format.pitch + (uintptr_t)rect->x * texture->format.bpp; glTexSubImage2D(GL_TEXTURE_2D, diff --git a/client/renderers/EGL/texture_buffer.h b/client/renderers/EGL/texture_buffer.h index 789994b6..23240b46 100644 --- a/client/renderers/EGL/texture_buffer.h +++ b/client/renderers/EGL/texture_buffer.h @@ -22,7 +22,7 @@ #include "texture.h" #include "texture_util.h" -#include "common/LGMPConfig.h" +#include #include "common/locking.h" #define EGL_TEX_BUFFER_MAX LGMP_Q_FRAME_BUFFER_LEN @@ -30,9 +30,9 @@ typedef struct EGL_TexBufferDamage { - bool full; - int count; - FrameDamageRect rects[EGL_TEX_BUFFER_DAMAGE_MAX]; + bool full; + int count; + KVMFRFrameDamageRect rects[EGL_TEX_BUFFER_DAMAGE_MAX]; } EGL_TexBufferDamage; diff --git a/client/renderers/EGL/texture_framebuffer.c b/client/renderers/EGL/texture_framebuffer.c index 811e91c9..6e812fdb 100644 --- a/client/renderers/EGL/texture_framebuffer.c +++ b/client/renderers/EGL/texture_framebuffer.c @@ -26,8 +26,8 @@ struct TexDamage { - int count; - FrameDamageRect rects[LG_MAX_FRAME_DAMAGE_RECTS]; + int count; + KVMFRFrameDamageRect rects[LG_MAX_FRAME_DAMAGE_RECTS]; }; typedef struct TexFB @@ -108,17 +108,17 @@ static bool egl_texFBUpdate(EGL_Texture * texture, const EGL_TexUpdate * update) else { memcpy(damage->rects + damage->count, update->rects, - update->rectCount * sizeof(FrameDamageRect)); + update->rectCount * sizeof(KVMFRFrameDamageRect)); damage->count += update->rectCount; if (texture->format.pixFmt == EGL_PF_BGR_32) { - FrameDamageRect scaledDamageRects[damage->count]; + KVMFRFrameDamageRect scaledDamageRects[damage->count]; for (int i = 0; i < damage->count; i++) { - FrameDamageRect rect = damage->rects[i]; - int originalX = rect.x; - int scaledX = originalX * 3 / 4; + KVMFRFrameDamageRect rect = damage->rects[i]; + int originalX = rect.x; + int scaledX = originalX * 3 / 4; rect.x = scaledX; rect.width = (((originalX + rect.width) * 3 + 3) / 4) - scaledX; scaledDamageRects[i] = rect; @@ -175,7 +175,7 @@ static bool egl_texFBUpdate(EGL_Texture * texture, const EGL_TexUpdate * update) damage->count + update->rectCount <= LG_MAX_FRAME_DAMAGE_RECTS) { memcpy(damage->rects + damage->count, update->rects, - update->rectCount * sizeof(FrameDamageRect)); + update->rectCount * sizeof(KVMFRFrameDamageRect)); damage->count += update->rectCount; } else diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index cab24ceb..e75652b9 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -124,17 +124,17 @@ struct Inst float uiScale; _Atomic(bool) frameUpdate; - LG_Lock formatLock; - LG_RendererFormat format; - GLuint intFormat; - GLuint vboFormat; - GLuint dataFormat; - size_t texSize; - size_t texPos; - bool texUploadError; - float scaleX, scaleY; - const FrameBuffer * frame; - LG_RendererFrameToken pendingFrameToken; + LG_Lock formatLock; + LG_RendererFormat format; + GLuint intFormat; + GLuint vboFormat; + GLuint dataFormat; + size_t texSize; + size_t texPos; + bool texUploadError; + float scaleX, scaleY; + const KVMFRFrameBuffer * frame; + LG_RendererFrameToken pendingFrameToken; struct OpenGL_FrameRelease frameRelease; uint64_t drawStart; @@ -482,8 +482,8 @@ bool opengl_onFrameFormat(LG_Renderer * renderer, const LG_RendererFormat format return true; } -bool opengl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, int dmaFd, - const FrameDamageRect * damage, int damageCount, +bool opengl_onFrame(LG_Renderer * renderer, const KVMFRFrameBuffer * frame, + int dmaFd, const KVMFRFrameDamageRect * damage, int damageCount, LG_RendererFrameToken frameToken, LG_FrameReleaseFn releaseFn, void * releaseOpaque, uint64_t releaseHandle) { @@ -1383,9 +1383,9 @@ static bool drawFrame(struct Inst * this, LG_UNLOCK(this->frameLock); return true; } - const FrameBuffer * frame = this->frame; - const LG_RendererFrameToken pendingFrameToken = this->pendingFrameToken; - const struct OpenGL_FrameRelease release = + const KVMFRFrameBuffer * frame = this->frame; + const LG_RendererFrameToken pendingFrameToken = this->pendingFrameToken; + const struct OpenGL_FrameRelease release = takePendingFrameLocked(this); LG_LOCK(this->formatLock); diff --git a/client/src/clipboard_files.c b/client/src/clipboard_files.c index 941b2135..06a5d25d 100644 --- a/client/src/clipboard_files.c +++ b/client/src/clipboard_files.c @@ -23,7 +23,7 @@ #include "core/clipboard_files.h" #include "core/clipboard.h" -#include "common/KVMFRClipboard.h" +#include #include "common/debug.h" #include "common/event.h" #include "common/locking.h" diff --git a/client/src/main.c b/client/src/main.c index fd6d590d..c50382d6 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -167,8 +167,8 @@ static struct } l_testCapture; -static atomic_uint_least64_t l_testFrameSerial; -static _Atomic(FrameType) l_testFrameType; +static atomic_uint_least64_t l_testFrameSerial; +static _Atomic(KVMFRFrameType) l_testFrameType; #endif static void lgInit(void) @@ -697,7 +697,7 @@ static void preSwapCallback(void * udata) return; } - const FrameType sourceType = + const KVMFRFrameType sourceType = atomic_load_explicit(&l_testFrameType, memory_order_acquire); const LG_TestCaptureHeader header = { .magic = LG_TEST_CAPTURE_MAGIC, @@ -1605,7 +1605,7 @@ int main_frameThread(void * unused) (damageCount && !frame.damageRects); for (uint32_t i = 0; !invalidDamage && i < damageCount; ++i) { - const FrameDamageRect * rect = &frame.damageRects[i]; + const KVMFRFrameDamageRect * rect = &frame.damageRects[i]; invalidDamage = !rect->width || !rect->height || rect->x > format->frameWidth || rect->y > format->dataHeight || diff --git a/client/src/render_queue.c b/client/src/render_queue.c index 40db2a54..5d1a1fee 100644 --- a/client/src/render_queue.c +++ b/client/src/render_queue.c @@ -97,7 +97,7 @@ typedef struct RenderCommand struct { - LGColorTransform * data; + KVMFRColorTransform * data; } cursorColorTransform; @@ -144,9 +144,9 @@ typedef struct RenderQueueSwSurface int pitch; uint8_t * data; - bool damageFull; - int damageCount; - FrameDamageRect damage[LG_MAX_FRAME_DAMAGE_RECTS]; + bool damageFull; + int damageCount; + KVMFRFrameDamageRect damage[LG_MAX_FRAME_DAMAGE_RECTS]; bool updateQueued; RenderCommand updateCommand; @@ -218,9 +218,9 @@ typedef struct RenderQueueCursor int pitch; uint8_t * data; - uint64_t colorGeneration; - bool colorValid; - LGColorTransform colorTransform; + uint64_t colorGeneration; + bool colorValid; + KVMFRColorTransform colorTransform; uint64_t whiteGeneration; bool whiteValid; @@ -237,9 +237,9 @@ typedef struct RenderQueueFormat } RenderQueueFormat; -static RenderQueueCursor l_cursor[RENDER_QUEUE_SOURCE_COUNT]; -static RenderQueueFormat l_format[RENDER_QUEUE_SOURCE_COUNT]; -static const LGColorTransform l_identityColorTransform; +static RenderQueueCursor l_cursor[RENDER_QUEUE_SOURCE_COUNT]; +static RenderQueueFormat l_format[RENDER_QUEUE_SOURCE_COUNT]; +static const KVMFRColorTransform l_identityColorTransform; static bool sourceValid(RenderQueueSource source) { @@ -289,20 +289,20 @@ static bool commandValid(const RenderCommand * cmd) return generationValid(cmd->source, cmd->generation) && cursorCurrent; } -static uint64_t swSurfaceDamageArea(const FrameDamageRect * rect) +static uint64_t swSurfaceDamageArea(const KVMFRFrameDamageRect * rect) { return (uint64_t)rect->width * rect->height; } -static FrameDamageRect swSurfaceDamageUnion( - const FrameDamageRect * a, const FrameDamageRect * b) +static KVMFRFrameDamageRect swSurfaceDamageUnion( + const KVMFRFrameDamageRect * a, const KVMFRFrameDamageRect * b) { const uint32_t left = min(a->x, b->x); const uint32_t top = min(a->y, b->y); const uint32_t right = max(a->x + a->width, b->x + b->width); const uint32_t bottom = max(a->y + a->height, b->y + b->height); - return (FrameDamageRect) + return (KVMFRFrameDamageRect) { .x = left, .y = top, @@ -312,7 +312,7 @@ static FrameDamageRect swSurfaceDamageUnion( } static bool swSurfaceDamageTouches( - const FrameDamageRect * a, const FrameDamageRect * b) + const KVMFRFrameDamageRect * a, const KVMFRFrameDamageRect * b) { return a->x <= b->x + b->width && b->x <= a->x + a->width && a->y <= b->y + b->height && b->y <= a->y + a->height; @@ -330,7 +330,7 @@ static bool swSurfaceDamagePending(const RenderQueueSwSurface * surface) } static void swSurfaceDamageAdd(RenderQueueSwSurface * surface, - const FrameDamageRect * damage) + const KVMFRFrameDamageRect * damage) { if (surface->damageFull) return; @@ -344,7 +344,7 @@ static void swSurfaceDamageAdd(RenderQueueSwSurface * surface, return; } - FrameDamageRect rect = *damage; + KVMFRFrameDamageRect rect = *damage; for (;;) { for (int i = 0; i < surface->damageCount;) @@ -367,9 +367,9 @@ static void swSurfaceDamageAdd(RenderQueueSwSurface * surface, uint64_t bestCost = UINT64_MAX; for (int i = 0; i < surface->damageCount; ++i) { - const FrameDamageRect merged = + const KVMFRFrameDamageRect merged = swSurfaceDamageUnion(&rect, &surface->damage[i]); - const uint64_t cost = swSurfaceDamageArea(&merged) - + const uint64_t cost = swSurfaceDamageArea(&merged) - swSurfaceDamageArea(&surface->damage[i]); if (cost < bestCost) { @@ -940,7 +940,7 @@ void renderQueue_sourceSwSurfaceDrawFill(RenderQueueSource source, row += surface->pitch; } - const FrameDamageRect damage = + const KVMFRFrameDamageRect damage = { .x = (uint32_t)x, .y = (uint32_t)y, @@ -1016,7 +1016,7 @@ void renderQueue_sourceSwSurfaceDrawBitmap(RenderQueueSource source, dst += surface->pitch; } - const FrameDamageRect damage = + const KVMFRFrameDamageRect damage = { .x = (uint32_t)x, .y = (uint32_t)y, @@ -1093,7 +1093,7 @@ void renderQueue_sourceCursorImage(RenderQueueSource source, } void renderQueue_sourceCursorColorTransform(RenderQueueSource source, - uint64_t generation, const LGColorTransform * transform) + uint64_t generation, const KVMFRColorTransform * transform) { if (!generationValid(source, generation) || !transform) return; @@ -1102,7 +1102,7 @@ void renderQueue_sourceCursorColorTransform(RenderQueueSource source, if (!cmd) return; - LGColorTransform * copy = malloc(sizeof(*copy)); + KVMFRColorTransform * copy = malloc(sizeof(*copy)); if (!copy) { free(cmd); @@ -1176,8 +1176,8 @@ static void uploadSwSurfaceDamage(RenderQueueSource source, else for (int i = 0; i < surface->damageCount; ++i) { - const FrameDamageRect * damage = &surface->damage[i]; - uint8_t * data = surface->data + + const KVMFRFrameDamageRect * damage = &surface->damage[i]; + uint8_t * data = surface->data + (size_t)damage->y * surface->pitch + (size_t)damage->x * 4; RENDERER(swSurfaceDrawBitmap, damage->x, damage->y, damage->width, damage->height, diff --git a/client/src/render_queue.h b/client/src/render_queue.h index fd919811..e0bf528e 100644 --- a/client/src/render_queue.h +++ b/client/src/render_queue.h @@ -88,7 +88,7 @@ void renderQueue_sourceCursorImage(RenderQueueSource source, int width, int height, int pitch, const void * data); void renderQueue_sourceCursorColorTransform(RenderQueueSource source, - uint64_t generation, const LGColorTransform * transform); + uint64_t generation, const KVMFRColorTransform * transform); void renderQueue_sourceCursorWhiteLevel(RenderQueueSource source, uint64_t generation, uint32_t sdrWhiteLevel); diff --git a/client/tests/CMakeLists.txt b/client/tests/CMakeLists.txt index 9f2a6a21..f20a268e 100644 --- a/client/tests/CMakeLists.txt +++ b/client/tests/CMakeLists.txt @@ -959,6 +959,10 @@ target_include_directories(render-tests PRIVATE "${PROJECT_TOP}/common/include" ) +target_link_libraries(render-tests + LGProtocol::LGProtocol +) + if(TARGET GTest::gtest_main) target_link_libraries(render-tests GTest::gtest_main) else() diff --git a/client/tests/clipboard_files_test.c b/client/tests/clipboard_files_test.c index 88125e17..7a1fa3d7 100644 --- a/client/tests/clipboard_files_test.c +++ b/client/tests/clipboard_files_test.c @@ -23,7 +23,7 @@ #include "test.h" #include "common/debug.h" -#include "common/KVMFRClipboard.h" +#include #include #include diff --git a/client/tests/desktop_rects_test.c b/client/tests/desktop_rects_test.c index eefd8479..3957df66 100644 --- a/client/tests/desktop_rects_test.c +++ b/client/tests/desktop_rects_test.c @@ -46,14 +46,14 @@ static void testRotations(void) { .x = 140, .y = 10, .w = 40, .h = 20 }, { .x = 20, .y = 10, .w = 40, .h = 20 }, }; - const FrameDamageRect damage = + const KVMFRFrameDamageRect damage = { .x = 10, .y = 5, .width = 20, .height = 10, }; - const FrameDamageRect full = + const KVMFRFrameDamageRect full = { .width = 100, .height = 50, @@ -79,7 +79,7 @@ static void testFractional(void) double matrix[6]; egl_desktopToScreenMatrix(matrix, 3, 2, 0.0, 0.0, 1.0, 1.0, LG_ROTATE_0, 10.0, 7.0); - const FrameDamageRect damage = + const KVMFRFrameDamageRect damage = { .x = 1, .width = 1, @@ -90,7 +90,7 @@ static void testFractional(void) egl_desktopToScreenMatrix(matrix, 100, 50, 0.1, -0.2, 0.5, 0.75, LG_ROTATE_0, 10.0, 7.0); - const FrameDamageRect full = + const KVMFRFrameDamageRect full = { .width = 100, .height = 50, @@ -101,7 +101,7 @@ static void testFractional(void) static void testRoundTrip(void) { - const FrameDamageRect damage = + const KVMFRFrameDamageRect damage = { .x = 10, .y = 5, @@ -119,7 +119,7 @@ static void testRoundTrip(void) (LG_RendererRotate)i, 200.0, 100.0); const struct Rect screen = egl_desktopToScreen(forward, &damage); - FrameDamageRect result; + KVMFRFrameDamageRect result; CHECK(egl_screenToDesktop(&result, inverse, &screen, 100, 50)); CHECK(result.x <= damage.x); CHECK(result.y <= damage.y); @@ -141,7 +141,7 @@ static void testClipping(void) .w = 10, .h = 10, }; - FrameDamageRect result; + KVMFRFrameDamageRect result; CHECK(!egl_screenToDesktop(&result, matrix, &outside, 100, 50)); const struct Rect edge = diff --git a/client/tests/frame_timing_test.c b/client/tests/frame_timing_test.c index 59d77ef5..ea24d62e 100644 --- a/client/tests/frame_timing_test.c +++ b/client/tests/frame_timing_test.c @@ -126,7 +126,7 @@ void renderQueue_sourceCursorImage(RenderQueueSource source, } void renderQueue_sourceCursorColorTransform(RenderQueueSource source, - uint64_t generation, const LGColorTransform * transform) + uint64_t generation, const KVMFRColorTransform * transform) { (void)source; (void)generation; diff --git a/client/tests/lgmp_clipboard_test.c b/client/tests/lgmp_clipboard_test.c index ea62af87..44f08ead 100644 --- a/client/tests/lgmp_clipboard_test.c +++ b/client/tests/lgmp_clipboard_test.c @@ -20,8 +20,8 @@ #include "clipboard.h" -#include "common/KVMFRClipboard.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/debug.h" #include diff --git a/client/tests/lgmp_frame_test.c b/client/tests/lgmp_frame_test.c index 6a4c65ee..98630379 100644 --- a/client/tests/lgmp_frame_test.c +++ b/client/tests/lgmp_frame_test.c @@ -20,8 +20,8 @@ #include "interface/transport.h" -#include "common/KVMFR.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/debug.h" #include "common/option.h" @@ -110,7 +110,7 @@ static bool allocMemory(TestState * state, uint32_t size, uint32_t alignment, static bool newFrame(TestState * state, uint32_t serial, TestFrame * result) { - const uint32_t size = sizeof(KVMFRFrame) + sizeof(FrameBuffer) + + const uint32_t size = sizeof(KVMFRFrame) + sizeof(KVMFRFrameBuffer) + TEST_FRAME_DATA; void * pointer; CHECK(allocMemory(state, size, _Alignof(KVMFRFrame), @@ -132,7 +132,8 @@ static bool newFrame(TestState * state, uint32_t serial, TestFrame * result) result->wire->offset = sizeof(KVMFRFrame); result->wire->sdrWhiteLevel = KVMFR_SDR_WHITE_LEVEL_DEFAULT; - FrameBuffer * framebuffer = (FrameBuffer *)((uint8_t *)result->wire + + KVMFRFrameBuffer * framebuffer = + (KVMFRFrameBuffer *)((uint8_t *)result->wire + result->wire->offset); atomic_store(&framebuffer->wp, TEST_FRAME_DATA); return true; diff --git a/client/tests/lgmp_input_test.c b/client/tests/lgmp_input_test.c index dca92d87..f6ce04c9 100644 --- a/client/tests/lgmp_input_test.c +++ b/client/tests/lgmp_input_test.c @@ -20,8 +20,8 @@ #include "../transports/LGMP/input.h" -#include "common/KVMFRInput.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/debug.h" #include diff --git a/client/tests/lgmp_transport_test.c b/client/tests/lgmp_transport_test.c index b1939a08..f3741b3e 100644 --- a/client/tests/lgmp_transport_test.c +++ b/client/tests/lgmp_transport_test.c @@ -20,9 +20,9 @@ #include "interface/transport.h" -#include "common/KVMFR.h" -#include "common/KVMFRRecovery.h" -#include "common/LGMPConfig.h" +#include +#include +#include #include "common/debug.h" #include "common/option.h" @@ -380,7 +380,7 @@ int main(void) .subTimeout = TEST_TIMEOUT, }; const uint32_t frameSize = - sizeof(KVMFRFrame) + sizeof(FrameBuffer) + sizeof(uint32_t); + sizeof(KVMFRFrame) + sizeof(KVMFRFrameBuffer) + sizeof(uint32_t); CHECK(lgmpHostMemAllocAligned(host, frameSize, _Alignof(KVMFRFrame), &frameMemory) == LGMP_OK); KVMFRFrame * wireFrame = lgmpHostMemPtr(frameMemory); @@ -404,7 +404,8 @@ int main(void) wireFrame->readyTime = 400; wireFrame->timingSerial = wireFrame->frameSerial; wireFrame->timingValid = 1; - FrameBuffer * framebuffer = (FrameBuffer *)((uint8_t *)wireFrame + + KVMFRFrameBuffer * framebuffer = + (KVMFRFrameBuffer *)((uint8_t *)wireFrame + wireFrame->offset); atomic_store(&framebuffer->wp, sizeof(uint32_t)); CHECK(lgmpHostMemAlloc(host, sizeof(KVMFRFrame) - 1, diff --git a/client/tests/render_queue_test.c b/client/tests/render_queue_test.c index 72cf544e..8e714b54 100644 --- a/client/tests/render_queue_test.c +++ b/client/tests/render_queue_test.c @@ -73,26 +73,26 @@ struct Fake uint8_t bitmap[64]; size_t bitmapSize; - unsigned int shapeCount; - LG_RendererCursor shapeType; - int shapeWidth; - int shapeHeight; - int shapePitch; - uint8_t shape[64]; - size_t shapeSize; - unsigned int cursorCount; - bool cursorVisible; - int cursorX; - int cursorY; - int cursorHX; - int cursorHY; - unsigned int colorCount; - LGColorTransformFlags colorFlags; - float colorScalar; - float colorMatrix; - float colorLut; - unsigned int whiteCount; - uint32_t whiteLevel; + unsigned int shapeCount; + LG_RendererCursor shapeType; + int shapeWidth; + int shapeHeight; + int shapePitch; + uint8_t shape[64]; + size_t shapeSize; + unsigned int cursorCount; + bool cursorVisible; + int cursorX; + int cursorY; + int cursorHX; + int cursorHY; + unsigned int colorCount; + KVMFRColorTransformFlags colorFlags; + float colorScalar; + float colorMatrix; + float colorLut; + unsigned int whiteCount; + uint32_t whiteLevel; unsigned int hdrCount; LG_RendererFormat hdr[8]; @@ -200,7 +200,7 @@ static bool mouseEvent(LG_Renderer * renderer, bool visible, } static void mouseColor(LG_Renderer * renderer, - const LGColorTransform * color) + const KVMFRColorTransform * color) { (void)renderer; ++f.colorCount; @@ -436,7 +436,7 @@ static void testPayload(void) 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, }; - LGColorTransform color = + KVMFRColorTransform color = { .flags = LG_COLOR_TRANSFORM_MATRIX | LG_COLOR_TRANSFORM_LUT, .matrix[0][0] = 2.0f, @@ -540,7 +540,7 @@ static void testCache(void) const uint64_t generation = renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY); const uint8_t shape[] = { 1, 2, 3, 4 }; - LGColorTransform color = + KVMFRColorTransform color = { .flags = LG_COLOR_TRANSFORM_MATRIX, .matrix[0][0] = 1.5f, @@ -637,7 +637,7 @@ static void testCursorReplacement(void) const uint64_t generation = renderQueue_sourceBegin(RENDER_QUEUE_SOURCE_PRIMARY); const uint8_t shape[] = { 1, 2, 3, 4 }; - LGColorTransform color = + KVMFRColorTransform color = { .flags = LG_COLOR_TRANSFORM_LUT, .scalar = 2.0f, diff --git a/client/tests/render_test.cpp b/client/tests/render_test.cpp index 35a48984..5fb069ee 100644 --- a/client/tests/render_test.cpp +++ b/client/tests/render_test.cpp @@ -57,10 +57,10 @@ constexpr unsigned kFrameSerial = 4; struct FormatCase { - const char * name; - FrameType type; - bool hdr; - bool pq; + const char * name; + KVMFRFrameType type; + bool hdr; + bool pq; }; struct DamageCase diff --git a/client/tests/x11_clipboard_test.c b/client/tests/x11_clipboard_test.c index 61c38c6b..2e7a1619 100644 --- a/client/tests/x11_clipboard_test.c +++ b/client/tests/x11_clipboard_test.c @@ -26,7 +26,7 @@ #include "core/clipboard_files.h" #include "common/debug.h" -#include "common/KVMFRClipboard.h" +#include #include #include diff --git a/client/transports/LGMP/clipboard.c b/client/transports/LGMP/clipboard.c index 2f87c8a6..41619e60 100644 --- a/client/transports/LGMP/clipboard.c +++ b/client/transports/LGMP/clipboard.c @@ -20,8 +20,8 @@ #include "clipboard.h" -#include "common/KVMFRClipboard.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/debug.h" #include "common/event.h" #include "common/locking.h" diff --git a/client/transports/LGMP/input.c b/client/transports/LGMP/input.c index 580889c3..bb7822e6 100644 --- a/client/transports/LGMP/input.c +++ b/client/transports/LGMP/input.c @@ -22,8 +22,8 @@ #include "kb.h" -#include "common/KVMFRInput.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/debug.h" #include "common/event.h" #include "common/locking.h" diff --git a/client/transports/LGMP/lgmp.c b/client/transports/LGMP/lgmp.c index 79659da0..82b9e450 100644 --- a/client/transports/LGMP/lgmp.c +++ b/client/transports/LGMP/lgmp.c @@ -23,9 +23,9 @@ #include "clipboard.h" #include "input.h" -#include "common/KVMFR.h" -#include "common/KVMFRRecovery.h" -#include "common/LGMPConfig.h" +#include +#include +#include #include "common/debug.h" #include "common/event.h" #include "common/ivshmem.h" @@ -1808,10 +1808,11 @@ static bool lgmp_validateFrameMessage(LG_Transport * this, const size_t messageSize = message->message.size; if (frame->offset < sizeof(KVMFRFrame) || - frame->offset > messageSize - sizeof(FrameBuffer) || - frameDataSize > messageSize - frame->offset - sizeof(FrameBuffer) || + frame->offset > messageSize - sizeof(KVMFRFrameBuffer) || + frameDataSize > messageSize - frame->offset - + sizeof(KVMFRFrameBuffer) || (uintptr_t)((const uint8_t *)message->message.mem + frame->offset) % - _Alignof(FrameBuffer)) + _Alignof(KVMFRFrameBuffer)) { DEBUG_ERROR("LGMP frame payload contains invalid dimensions or offsets"); return false; @@ -1876,10 +1877,10 @@ static int lgmp_getDMA(struct LG_Transport * this, const size_t position = address - base; if (position > this->lgmpSize || frameOffset > this->lgmpSize - position || - sizeof(FrameBuffer) > this->lgmpSize - position - frameOffset) + sizeof(KVMFRFrameBuffer) > this->lgmpSize - position - frameOffset) return -1; - const size_t offset = position + frameOffset + sizeof(FrameBuffer); + const size_t offset = position + frameOffset + sizeof(KVMFRFrameBuffer); if (dataSize > this->lgmpSize - offset) return -1; @@ -2082,7 +2083,7 @@ static LG_TransportStatus lgmp_nextFrameLocked(LG_Transport * this, memcpy(&lease->format, format, sizeof(lease->format)); result->format = &lease->format; - result->framebuffer = (const FrameBuffer *) + result->framebuffer = (const KVMFRFrameBuffer *) ((const uint8_t *)selected->sharedFrame + frame->offset); result->dmaFD = -1; if (useDMA) @@ -2214,7 +2215,8 @@ static void lgmp_getFrameTiming(LG_Transport * this, timing->prepareTime = lease->prepareTime; } - /* The producer writes these immediately after publishing FrameBuffer::wp. + /* The producer writes these immediately after publishing + * KVMFRFrameBuffer::wp. * nextFrame can observe the header earlier, so briefly observe the * publication tail after onFrame consumes the framebuffer without sleeping * the frame-acquisition thread. */ diff --git a/client/transports/Test/test.c b/client/transports/Test/test.c index cdf0b8d0..38396cf9 100644 --- a/client/transports/Test/test.c +++ b/client/transports/Test/test.c @@ -47,11 +47,11 @@ enum TestDamageMode struct TestFormat { - const char * name; - FrameType type; - unsigned bytesPerPixel; - bool hdr; - bool hdrPQ; + const char * name; + KVMFRFrameType type; + unsigned bytesPerPixel; + bool hdr; + bool hdrPQ; }; static const struct TestFormat testFormats[] = @@ -66,7 +66,7 @@ static const struct TestFormat testFormats[] = struct TestBuffer { - FrameBuffer * framebuffer; + KVMFRFrameBuffer * framebuffer; }; struct LG_Transport @@ -89,7 +89,7 @@ struct LG_Transport uint64_t framePrepareTime; unsigned bufferIndex; struct TestBuffer buffers[TEST_BUFFER_COUNT]; - FrameDamageRect damage[LG_TRANSPORT_MAX_DAMAGE_RECTS]; + KVMFRFrameDamageRect damage[LG_TRANSPORT_MAX_DAMAGE_RECTS]; LG_TransportFrameFormat format; uint16_t pqLUT[TEST_PQ_LUT_SIZE + 1]; }; @@ -348,7 +348,7 @@ static bool test_create(LG_Transport ** result) stride < 0 || (stride && stride < width) || bufferStride > UINT32_MAX / maxBytesPerPixel || frameRate < 1 || frameRate > 1000000000 || frameCount < 0 || - bufferStride > (SIZE_MAX - sizeof(FrameBuffer)) / + bufferStride > (SIZE_MAX - sizeof(KVMFRFrameBuffer)) / maxBytesPerPixel / (size_t)height) { DEBUG_ERROR( @@ -373,7 +373,8 @@ static bool test_create(LG_Transport ** result) bufferStride * this->height * maxBytesPerPixel; for (unsigned i = 0; i < TEST_BUFFER_COUNT; ++i) { - this->buffers[i].framebuffer = malloc(sizeof(FrameBuffer) + dataSize); + this->buffers[i].framebuffer = + malloc(sizeof(KVMFRFrameBuffer) + dataSize); if (!this->buffers[i].framebuffer) { for (unsigned j = 0; j < i; ++j) @@ -515,7 +516,8 @@ static void test_getColor(const struct LG_Transport * this, *b = color; } -static void test_generateFrame(struct LG_Transport * this, FrameBuffer * fb) +static void test_generateFrame(struct LG_Transport * this, + KVMFRFrameBuffer * fb) { uint8_t * data = framebuffer_get_data(fb); if (this->stride) @@ -653,13 +655,13 @@ static LG_TransportStatus test_nextFrame(LG_Transport * this, bool useDMA, this->width - boxSize : 1; const unsigned rangeY = this->height > boxSize ? this->height - boxSize : 1; - this->damage[0] = (FrameDamageRect) { + this->damage[0] = (KVMFRFrameDamageRect) { .x = ((this->serial - 1) * 7) % rangeX, .y = ((this->serial - 1) * 5) % rangeY, .width = boxSize, .height = boxSize, }; - this->damage[1] = (FrameDamageRect) { + this->damage[1] = (KVMFRFrameDamageRect) { .x = (this->serial * 7) % rangeX, .y = (this->serial * 5) % rangeY, .width = boxSize, @@ -680,12 +682,12 @@ static LG_TransportStatus test_nextFrame(LG_Transport * this, bool useDMA, case TEST_DAMAGE_MAX: for (unsigned i = 2; i < ARRAY_LENGTH(this->damage); ++i) - this->damage[i] = (FrameDamageRect) {0}; + this->damage[i] = (KVMFRFrameDamageRect) {0}; frame->damageRectsCount = ARRAY_LENGTH(this->damage); break; case TEST_DAMAGE_INVALID: - this->damage[0] = (FrameDamageRect) { + this->damage[0] = (KVMFRFrameDamageRect) { .x = this->width, .y = 0, .width = 1, .height = 1 }; frame->damageRectsCount = 1; @@ -697,7 +699,7 @@ static LG_TransportStatus test_nextFrame(LG_Transport * this, bool useDMA, break; case TEST_DAMAGE_ZERO: - this->damage[2] = (FrameDamageRect) {0}; + this->damage[2] = (KVMFRFrameDamageRect) {0}; frame->damageRectsCount = 3; break; diff --git a/cmake/CheckSubmodule.cmake b/cmake/CheckSubmodule.cmake index a3c6ea7e..7a741848 100644 --- a/cmake/CheckSubmodule.cmake +++ b/cmake/CheckSubmodule.cmake @@ -2,6 +2,7 @@ if (EXISTS "${PROJECT_TOP}/.git" AND ( (NOT EXISTS "${PROJECT_TOP}/repos/gui/cimgui/.git") OR (NOT EXISTS "${PROJECT_TOP}/repos/gui/cimplot/.git") OR (NOT EXISTS "${PROJECT_TOP}/repos/LGMP/.git") OR + (NOT EXISTS "${PROJECT_TOP}/repos/LGProtocol/.git") OR (NOT EXISTS "${PROJECT_TOP}/repos/PureSpice/.git") OR (NOT EXISTS "${PROJECT_TOP}/repos/gui/cimgui/imgui/.git") OR (NOT EXISTS "${PROJECT_TOP}/repos/gui/cimplot/implot/.git") OR diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a2795a17..d2077195 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -15,6 +15,19 @@ if (CMAKE_C_COMPILER_ID STREQUAL "Clang") ) endif() +function(_lg_common_add_protocol) + # Function scope preserves the parent BUILD_TESTING setting while disabling + # LGProtocol's standalone tests in the nested build. + set(BUILD_TESTING OFF) + add_subdirectory( + "${CMAKE_CURRENT_SOURCE_DIR}/../repos/LGProtocol" + "${CMAKE_CURRENT_BINARY_DIR}/LGProtocol" + EXCLUDE_FROM_ALL + ) +endfunction() + +_lg_common_add_protocol() + add_subdirectory(src/platform) set(COMMON_SOURCES @@ -35,7 +48,11 @@ set(COMMON_SOURCES ) add_library(lg_common STATIC ${COMMON_SOURCES}) -target_link_libraries(lg_common lg_common_platform) +target_link_libraries(lg_common + PUBLIC + lg_common_platform + LGProtocol::LGProtocol +) if(ENABLE_BACKTRACE) target_compile_definitions(lg_common PUBLIC -DENABLE_BACKTRACE) diff --git a/common/include/common/KVMFR.h b/common/include/common/KVMFR.h deleted file mode 100644 index df8229e1..00000000 --- a/common/include/common/KVMFR.h +++ /dev/null @@ -1,370 +0,0 @@ -/** - * Looking Glass - * Copyright © 2017-2026 The Looking Glass Authors - * https://looking-glass.io - * - * 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 - */ - -#ifndef _H_LG_COMMON_KVMFR_ -#define _H_LG_COMMON_KVMFR_ - -#pragma once - -#include -#include -#include -#include "types.h" -#include "LGMPConfig.h" -#include "KVMFRClipboard.h" -#include "KVMFRInput.h" - -#define KVMFR_MAGIC "KVMFR---" -#define KVMFR_VERSION 34 - -// Fallback used by producers that cannot report the source display's SDR -// white level. IDD frames override this with IDDCX_METADATA2::SdrWhiteLevel. -#define KVMFR_SDR_WHITE_LEVEL_DEFAULT LG_SDR_WHITE_LEVEL_DEFAULT - -#define KVMFR_MAX_DAMAGE_RECTS LG_MAX_FRAME_DAMAGE_RECTS - -#ifdef _MSC_VER - // don't warn on zero length arrays -#pragma warning(push) -#pragma warning(disable: 4200) -#endif - -enum -{ - CURSOR_FLAG_POSITION = 0x1, - CURSOR_FLAG_VISIBLE = 0x2, - CURSOR_FLAG_SHAPE = 0x4, - CURSOR_FLAG_COLOR_TRANSFORM = 0x8, - // CURSOR_FLAG_VISIBLE contains a new visibility state. This distinguishes - // an invisible cursor update from messages carrying unrelated cursor data. - CURSOR_FLAG_VISIBLE_VALID = 0x10 -}; - -typedef uint32_t KVMFRCursorFlags; - -enum -{ - KVMFR_FEATURE_SETCURSORPOS = 0x1, - KVMFR_FEATURE_WINDOWSIZE = 0x2, - KVMFR_FEATURE_FRAME_SCHEDULE = 0x4, - KVMFR_FEATURE_INPUT = 0x8, - KVMFR_FEATURE_CLIPBOARD = 0x10 -}; - -typedef uint32_t KVMFRFeatureFlags; - -enum -{ - KVMFR_MESSAGE_SETCURSORPOS, - KVMFR_MESSAGE_WINDOWSIZE, - KVMFR_MESSAGE_FRAME_SCHEDULE -}; - -typedef uint32_t KVMFRMessageType; - -typedef struct KVMFR -{ - char magic[8]; - uint32_t version; - char hostver[32]; - KVMFRFeatureFlags features; - //KVMFRRecords start here if there are any -} -KVMFR; - -typedef struct KVMFRRecord -{ - uint8_t type; - uint32_t size; - uint8_t data[]; -} -KVMFRRecord; - -enum -{ - KVMFR_RECORD_VMINFO = 1, - KVMFR_RECORD_OSINFO -}; - -typedef enum -{ - KVMFR_OS_LINUX, - KVMFR_OS_BSD, - KVMFR_OS_OSX, - KVMFR_OS_WINDOWS, - KVMFR_OS_OTHER -} -KVMFROS; - -typedef struct KVMFRRecord_VMInfo -{ - uint8_t uuid [16]; // the guest's UUID - char capture[32]; // the capture device in use - uint8_t cpus; // number of CPUs - uint8_t cores; // number of CPU cores - uint8_t sockets; // number of CPU sockets - char model[]; -} -KVMFRRecord_VMInfo; - -typedef struct KVMFRRecord_OSInfo -{ - uint8_t os; // KVMFR_OS_* - char name[]; // friendly name -} -KVMFRRecord_OSInfo; - -typedef struct KVMFRCursor -{ - int16_t x, y; // cursor x & y position - CursorType type; // shape buffer data type - int8_t hx, hy; // shape hotspot x & y - uint32_t width; // width of the shape - uint32_t height; // height of the shape - uint32_t pitch; // row length in bytes of the shape - uint32_t sdrWhiteLevel; // cursor white level in nits for HDR composition -} -KVMFRCursor; - -enum -{ - KVMFR_COLOR_TRANSFORM_MATRIX = LG_COLOR_TRANSFORM_MATRIX, - KVMFR_COLOR_TRANSFORM_LUT = LG_COLOR_TRANSFORM_LUT, -}; - -typedef LGColorTransformFlags KVMFRColorTransformFlags; - -// Optional payload appended to KVMFRCursor when -// CURSOR_FLAG_COLOR_TRANSFORM is present. The matrix is an XYZ-to-XYZ -// adjustment; the LUT is applied after encoding to the active wire transfer -// function. Four LUT components keep the payload directly uploadable as an -// RGBA32F texture, with alpha reserved and set to 1.0. -typedef LGColorTransform KVMFRColorTransform; - -enum -{ - FRAME_FLAG_BLOCK_SCREENSAVER = 0x1 , - FRAME_FLAG_REQUEST_ACTIVATION = 0x2 , - FRAME_FLAG_TRUNCATED = 0x4 , // ivshmem was too small for the frame - FRAME_FLAG_HDR = 0x8 , // RGBA10 may not be HDR - FRAME_FLAG_HDR_PQ = 0x10, // HDR PQ has been applied to the frame - FRAME_FLAG_HDR_METADATA = 0x20 // HDR static metadata fields are valid -}; - -typedef uint32_t KVMFRFrameFlags; - -enum -{ - KVMFR_FRAME_TIMING_PHASE_VALID = 0x1 -}; - -typedef uint32_t KVMFRFrameTimingFlags; - -typedef struct KVMFRFrame -{ - /* - * Keep the fields consumed for every frame in the first cache line. The - * timing and HDR metadata below are diagnostic/conditional, while the large - * damage rectangle array is deliberately last. - */ - uint32_t formatVer; // the frame format version number - uint32_t frameSerial; // the unique frame number - FrameType type; // the frame data type - uint32_t screenWidth; // the client's screen width - uint32_t screenHeight; // the client's screen height - uint32_t dataWidth; // the packed frame width - uint32_t dataHeight; // the packed frame height - uint32_t frameWidth; // the unpacked frame width - uint32_t frameHeight; // the unpacked frame height - FrameRotation rotation; // the frame rotation - uint32_t stride; // the row stride (zero if compressed data) - uint32_t pitch; // the row pitch (stride in bytes or the compressed frame size) - uint32_t offset; // offset from the start of this header to the FrameBuffer header - KVMFRFrameFlags flags; // bit field combination of FRAME_FLAG_* - uint32_t damageRectsCount; // the number of damage rectangles (zero for full-frame damage) - - // White level in nits for SDR content composited into an HDR frame, such as - // the hardware cursor. Valid for all frames; SDR modes normally report 80. - uint32_t sdrWhiteLevel; - - /* - * Producer stage durations in nanoseconds. These are durations rather than - * absolute timestamps because the producer runs in a VM whose monotonic - * clock has a different epoch from the client. Durations can safely be - * combined with the client's local render duration for an end-to-end - * processing time. - */ - uint64_t captureTime; - uint64_t postProcessTime; - uint64_t copyTime; - // Non-copy preparation and publication time, excluding cadence hold time. - uint64_t readyTime; - // Time a prepared frame waited for its cadence publication target. - uint64_t holdTime; - // Time remaining until the cadence deadline when the frame was published. - uint64_t readyLeadTime; - - // Published after the timing fields and matched against frameSerial by the - // client. timingValid is written last by the producer. - uint32_t timingSerial; - uint32_t timingValid; - - KVMFRFrameTimingFlags timingFlags; - - // Keep the conditional HDR block and damage rectangles on separate cache - // lines from the producer timing fields. - uint8_t timingReserved[4]; - - // HDR static metadata (valid when FRAME_FLAG_HDR_METADATA is set) - // Display color primaries in 0.00002 units (SMPTE ST 2086 format) - uint16_t hdrDisplayPrimary[3][2]; // Rx,Ry, Gx,Gy, Bx,By - uint16_t hdrWhitePoint[2]; // Wx, Wy - // Mastering display luminances follow SMPTE ST 2086 units: the maximum is - // in whole cd/m², the minimum in 0.0001 cd/m². (Note: the DXGI docs - // describe MaxMasteringLuminance as 0.0001 cd/m², but IddCx/ST 2086 provide - // it in whole cd/m².) - uint32_t hdrMaxDisplayLuminance; // Max mastering display luminance (cd/m²) - uint32_t hdrMinDisplayLuminance; // Min mastering display luminance (0.0001 cd/m²) - uint32_t hdrMaxContentLightLevel; // MaxCLL (cd/m²) - uint32_t hdrMaxFrameAverageLightLevel; // MaxFALL (cd/m²) - - // Producer cadence identity. Phase feedback is permitted only when the - // matching frame has KVMFR_FRAME_TIMING_PHASE_VALID set. - uint32_t scheduleGeneration; - uint32_t scheduleEpoch; - uint32_t scheduleDeadlineSerial; - - uint8_t hdrReserved[20]; - - FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS]; -} -KVMFRFrame; - -#if defined(__cplusplus) -static_assert(offsetof(KVMFRFrame, captureTime) == 64, - "KVMFRFrame hot fields must fit in one cache line"); -static_assert(offsetof(KVMFRFrame, holdTime) == 96, - "KVMFRFrame hold timing layout changed"); -static_assert(offsetof(KVMFRFrame, readyLeadTime) == 104, - "KVMFRFrame ready lead timing layout changed"); -static_assert(offsetof(KVMFRFrame, timingSerial) == 112, - "KVMFRFrame timing publication layout changed"); -static_assert(offsetof(KVMFRFrame, timingFlags) == 120, - "KVMFRFrame timing flags layout changed"); -static_assert(offsetof(KVMFRFrame, scheduleDeadlineSerial) == 168, - "KVMFRFrame schedule identity layout changed"); -static_assert(offsetof(KVMFRFrame, hdrDisplayPrimary) == 128, - "KVMFRFrame HDR metadata must be cache-line aligned"); -static_assert(offsetof(KVMFRFrame, damageRects) == 192, - "KVMFRFrame damage rectangles must be cache-line aligned"); -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(offsetof(KVMFRFrame, captureTime) == 64, - "KVMFRFrame hot fields must fit in one cache line"); -_Static_assert(offsetof(KVMFRFrame, holdTime) == 96, - "KVMFRFrame hold timing layout changed"); -_Static_assert(offsetof(KVMFRFrame, readyLeadTime) == 104, - "KVMFRFrame ready lead timing layout changed"); -_Static_assert(offsetof(KVMFRFrame, timingSerial) == 112, - "KVMFRFrame timing publication layout changed"); -_Static_assert(offsetof(KVMFRFrame, timingFlags) == 120, - "KVMFRFrame timing flags layout changed"); -_Static_assert(offsetof(KVMFRFrame, scheduleDeadlineSerial) == 168, - "KVMFRFrame schedule identity layout changed"); -_Static_assert(offsetof(KVMFRFrame, hdrDisplayPrimary) == 128, - "KVMFRFrame HDR metadata must be cache-line aligned"); -_Static_assert(offsetof(KVMFRFrame, damageRects) == 192, - "KVMFRFrame damage rectangles must be cache-line aligned"); -#endif - -typedef struct KVMFRMessage -{ - KVMFRMessageType type; -} -KVMFRMessage; - -typedef struct KVMFRSetCursorPos -{ - KVMFRMessage msg; - int32_t x, y; -} -KVMFRSetCursorPos; - -typedef struct KVMFRWindowSize -{ - KVMFRMessage msg; - uint32_t w, h; -} -KVMFRWindowSize; - -enum -{ - KVMFR_FRAME_SCHEDULE_ACTIVE = 0x1, - KVMFR_FRAME_SCHEDULE_RELEASE = 0x2, - KVMFR_FRAME_SCHEDULE_RESET = 0x4, - KVMFR_FRAME_SCHEDULE_IMMEDIATE = 0x8 -}; - -typedef uint32_t KVMFRFrameScheduleFlags; - -/* - * Client presentation scheduling is expressed entirely as durations. Client - * and producer monotonic clocks have unrelated epochs and must never be - * compared directly. - */ -typedef struct KVMFRFrameSchedule -{ - KVMFRMessage msg; - uint32_t clientID; - uint32_t generation; - KVMFRFrameScheduleFlags flags; - uint64_t period; // requested presentation period (ns) - uint64_t targetSlack; // desired ready-to-render lead (ns) - // Positive when the frame arrived early, negative when it arrived late. - int64_t phaseError; // ready-to-render phase error (ns) - uint32_t feedbackFrameSerial; - uint32_t feedbackScheduleEpoch; - // Identifies the exact producer deadline paired with feedbackFrameSerial. - uint32_t feedbackDeadlineSerial; - uint32_t lease; // lease duration (ms) - uint8_t reserved[8]; -} -KVMFRFrameSchedule; - -#if defined(__cplusplus) -static_assert(offsetof(KVMFRFrameSchedule, feedbackDeadlineSerial) == 48, - "KVMFR frame schedule feedback identity layout changed"); -static_assert(offsetof(KVMFRFrameSchedule, lease) == 52, - "KVMFR frame schedule lease layout changed"); -static_assert(sizeof(KVMFRFrameSchedule) == 64, - "KVMFR frame schedule must fit in one LGMP control message"); -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(offsetof(KVMFRFrameSchedule, feedbackDeadlineSerial) == 48, - "KVMFR frame schedule feedback identity layout changed"); -_Static_assert(offsetof(KVMFRFrameSchedule, lease) == 52, - "KVMFR frame schedule lease layout changed"); -_Static_assert(sizeof(KVMFRFrameSchedule) == 64, - "KVMFR frame schedule must fit in one LGMP control message"); -#endif - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif diff --git a/common/include/common/KVMFRClipboard.h b/common/include/common/KVMFRClipboard.h deleted file mode 100644 index 8e8158ad..00000000 --- a/common/include/common/KVMFRClipboard.h +++ /dev/null @@ -1,438 +0,0 @@ -/** - * Looking Glass - * Copyright © 2017-2026 The Looking Glass Authors - * https://looking-glass.io - * - * 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 - */ - -#ifndef _H_LG_COMMON_KVMFR_CLIPBOARD_ -#define _H_LG_COMMON_KVMFR_CLIPBOARD_ - -#pragma once - -#include "KVMFRStream.h" - -#include -#include - -#define KVMFR_CLIPBOARD_VERSION 4U -#define KVMFR_CLIPBOARD_STREAM_VERSION 1U - -/* Physical stream geometry. Keep these independent from the maximum logical - * request and representation sizes below: one response may span several - * stream slots. The generic names are also used by the Helper/IDD clipboard - * ring, which intentionally has the same geometry. */ -#define KVMFR_CLIPBOARD_STREAM_SLOT_COUNT 4U -#define KVMFR_CLIPBOARD_STREAM_SLOT_BYTES (256U * 1024U) -#define KVMFR_CLIPBOARD_STREAM_WINDOW_BYTES \ - (KVMFR_CLIPBOARD_STREAM_SLOT_COUNT * \ - KVMFR_CLIPBOARD_STREAM_SLOT_BYTES) -#define KVMFR_CLIPBOARD_SLOT_COUNT \ - KVMFR_CLIPBOARD_STREAM_SLOT_COUNT -#define KVMFR_CLIPBOARD_DATA_BYTES \ - KVMFR_CLIPBOARD_STREAM_SLOT_BYTES -/* Keep text and image chunks within the core X11 request limit. File data can - * use the full slot without passing through XChangeProperty. */ -#define KVMFR_CLIPBOARD_REPRESENTATION_BYTES (64U * 1024U) -#define KVMFR_CLIPBOARD_SIZE_UNKNOWN UINT64_MAX -/* Logical request size. A READ response may require multiple physical - * stream records and must not be constrained to a single slot. */ -#define KVMFR_CLIPBOARD_FILE_READ_BYTES (1024U * 1024U) -#define KVMFR_CLIPBOARD_FILE_ROOT_NODE UINT64_C(0) -#define KVMFR_CLIPBOARD_FILE_MAX_ACQUISITIONS 8U -#define KVMFR_CLIPBOARD_FILE_MAX_REQUESTS 32U - -/* Transfer IDs are selected by the side which sends REQUEST. Keeping the - * namespaces disjoint makes a simultaneous transfer in each direction - * unambiguous when CANCEL and DATA cross in flight. */ -#define KVMFR_CLIPBOARD_TRANSFER_HELPER (UINT64_C(1) << 63) - -static inline int kvmfrClipboardTransferFromHelper(uint64_t transfer) -{ - return (transfer & KVMFR_CLIPBOARD_TRANSFER_HELPER) != 0; -} - -static inline int kvmfrClipboardTransferFromClient(uint64_t transfer) -{ - return transfer != 0 && !kvmfrClipboardTransferFromHelper(transfer); -} - -enum -{ - KVMFR_CLIPBOARD_FORMAT_NONE = 0, - KVMFR_CLIPBOARD_FORMAT_TEXT = 1, - KVMFR_CLIPBOARD_FORMAT_PNG = 2, - KVMFR_CLIPBOARD_FORMAT_BMP = 3, - KVMFR_CLIPBOARD_FORMAT_TIFF = 4, - KVMFR_CLIPBOARD_FORMAT_JPEG = 5, - KVMFR_CLIPBOARD_FORMAT_FILES = 6 -}; - -typedef uint32_t KVMFRClipboardFormat; - -enum -{ - KVMFR_CLIPBOARD_FORMAT_MASK_TEXT = 1U << 0, - KVMFR_CLIPBOARD_FORMAT_MASK_PNG = 1U << 1, - KVMFR_CLIPBOARD_FORMAT_MASK_BMP = 1U << 2, - KVMFR_CLIPBOARD_FORMAT_MASK_TIFF = 1U << 3, - KVMFR_CLIPBOARD_FORMAT_MASK_JPEG = 1U << 4, - KVMFR_CLIPBOARD_FORMAT_MASK_FILES = 1U << 5, - KVMFR_CLIPBOARD_FORMAT_MASK_ALL = - KVMFR_CLIPBOARD_FORMAT_MASK_TEXT | - KVMFR_CLIPBOARD_FORMAT_MASK_PNG | - KVMFR_CLIPBOARD_FORMAT_MASK_BMP | - KVMFR_CLIPBOARD_FORMAT_MASK_TIFF | - KVMFR_CLIPBOARD_FORMAT_MASK_JPEG | - KVMFR_CLIPBOARD_FORMAT_MASK_FILES, -}; - -typedef uint32_t KVMFRClipboardFormatFlags; - -static inline int kvmfrClipboardFormatValid(KVMFRClipboardFormat format) -{ - return format >= KVMFR_CLIPBOARD_FORMAT_TEXT && - format <= KVMFR_CLIPBOARD_FORMAT_FILES; -} - -static inline int kvmfrClipboardRepresentationFormatValid( - KVMFRClipboardFormat format) -{ - return format >= KVMFR_CLIPBOARD_FORMAT_TEXT && - format <= KVMFR_CLIPBOARD_FORMAT_JPEG; -} - -static inline KVMFRClipboardFormatFlags kvmfrClipboardFormatFlag( - KVMFRClipboardFormat format) -{ - return kvmfrClipboardFormatValid(format) ? - (KVMFRClipboardFormatFlags)(1U << (format - 1U)) : 0U; -} - -enum -{ - KVMFR_CLIPBOARD_MESSAGE_CLAIM = 1, - KVMFR_CLIPBOARD_MESSAGE_RELEASE = 2, - KVMFR_CLIPBOARD_MESSAGE_KEEPALIVE = 3, - KVMFR_CLIPBOARD_MESSAGE_OFFER = 4, - KVMFR_CLIPBOARD_MESSAGE_CLEAR = 5, - KVMFR_CLIPBOARD_MESSAGE_REQUEST = 6, - KVMFR_CLIPBOARD_MESSAGE_DATA = 7, - KVMFR_CLIPBOARD_MESSAGE_CANCEL = 8, - KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE = 9, - KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRED = 10, - KVMFR_CLIPBOARD_MESSAGE_FILE_RELEASE = 11, - KVMFR_CLIPBOARD_MESSAGE_FILE_REQUEST = 12, - KVMFR_CLIPBOARD_MESSAGE_FILE_DATA = 13, - KVMFR_CLIPBOARD_MESSAGE_FILE_CANCEL = 14 -}; - -typedef uint32_t KVMFRClipboardMessageType; - -enum -{ - KVMFR_CLIPBOARD_FLAG_BEGIN = 1U << 0, - KVMFR_CLIPBOARD_FLAG_END = 1U << 1 -}; - -typedef uint32_t KVMFRClipboardFlags; - -/* - * Bidirectional control record. Client-to-host records must fit LGMP's - * 64-byte client message area. Host-to-client records use a small payload - * pool and the same layout. DATA and FILE_DATA records are carried only by - * the duplex streams advertised in KVMFRClipboardStatus; all other records - * use the clipboard queue. CLAIM flags are reserved and must be zero. - */ -typedef struct KVMFRClipboardMessage -{ - uint32_t version; - KVMFRClipboardMessageType type; - uint32_t generation; - uint32_t sequence; - uint64_t clipboardGeneration; - uint64_t transfer; - uint64_t offset; - uint64_t size; - KVMFRClipboardFormat format; - uint32_t flags; - uint32_t token; - uint32_t length; -} -KVMFRClipboardMessage; - -enum -{ - KVMFR_CLIPBOARD_FILE_OP_LIST = 1, - KVMFR_CLIPBOARD_FILE_OP_READ = 2 -}; - -typedef uint32_t KVMFRClipboardFileOperation; - -enum -{ - KVMFR_CLIPBOARD_FILE_TYPE_REGULAR = 1, - KVMFR_CLIPBOARD_FILE_TYPE_DIRECTORY = 2 -}; - -typedef uint32_t KVMFRClipboardFileType; - -enum -{ - KVMFR_CLIPBOARD_FILE_ERROR_NONE = 0, - KVMFR_CLIPBOARD_FILE_ERROR_NOT_FOUND = 1, - KVMFR_CLIPBOARD_FILE_ERROR_ACCESS = 2, - KVMFR_CLIPBOARD_FILE_ERROR_NOT_DIRECTORY = 3, - KVMFR_CLIPBOARD_FILE_ERROR_IS_DIRECTORY = 4, - KVMFR_CLIPBOARD_FILE_ERROR_IO = 5, - KVMFR_CLIPBOARD_FILE_ERROR_INVALID = 6, - KVMFR_CLIPBOARD_FILE_ERROR_NO_MEMORY = 7, - KVMFR_CLIPBOARD_FILE_ERROR_NO_SPACE = 8, - KVMFR_CLIPBOARD_FILE_ERROR_DISCONNECTED = 9, - KVMFR_CLIPBOARD_FILE_ERROR_CANCELLED = 10, - KVMFR_CLIPBOARD_FILE_ERROR_NOT_SUPPORTED = 11, - KVMFR_CLIPBOARD_FILE_ERROR_STALE = 12 -}; - -typedef uint32_t KVMFRClipboardFileError; - -static inline int kvmfrClipboardFileErrorValid( - KVMFRClipboardFileError error) -{ - return error <= KVMFR_CLIPBOARD_FILE_ERROR_STALE; -} - -/* - * A LIST response is a stream of these headers, each immediately followed by - * nameLength bytes of an unescaped UTF-8 path component and then zero padding - * to the next eight-byte boundary. Node zero is the dataset's synthetic root - * and is never returned as an entry. Times are nanoseconds since the Unix - * epoch. A zero creation time means the source cannot report it. - */ -typedef struct KVMFRClipboardFileEntry -{ - uint64_t node; - uint64_t size; - uint64_t createdNs; - uint64_t modifiedNs; - KVMFRClipboardFileType type; - uint32_t nameLength; -} -KVMFRClipboardFileEntry; - -#define KVMFR_CLIPBOARD_FILE_ENTRY_ALIGN 8U -#define KVMFR_CLIPBOARD_FILE_ENTRY_BYTES(nameLength) \ - ((uint64_t)(sizeof(KVMFRClipboardFileEntry) + (uint64_t)(nameLength) + \ - (KVMFR_CLIPBOARD_FILE_ENTRY_ALIGN - 1U)) & \ - ~(uint64_t)(KVMFR_CLIPBOARD_FILE_ENTRY_ALIGN - 1U)) - -/* File message field use: - * - * FILE_ACQUIRE / FILE_ACQUIRED / FILE_RELEASE: - * clipboardGeneration identifies the immutable dataset and transfer is the - * acquisition ID selected by the requester. format is FILES. ACQUIRED token - * is a KVMFRClipboardFileError; all other fields are zero. - * - * FILE_REQUEST: - * clipboardGeneration identifies the acquired dataset, transfer is a unique - * request ID, size is the opaque node ID, token is LIST or READ, and format - * is FILES. LIST requires offset and flags to be zero. READ uses offset as - * the file offset and flags as the requested byte count (at most - * KVMFR_CLIPBOARD_FILE_READ_BYTES). length is always zero because REQUEST - * has no attached payload. - * - * FILE_DATA: - * clipboardGeneration, transfer, format and token echo FILE_REQUEST. offset - * is relative to this response (not the source file), sequence starts at - * zero, and size follows DATA's BEGIN/END total-size rules. Chunks for - * different request IDs may be interleaved. - * - * FILE_CANCEL: - * clipboardGeneration and transfer identify an acquisition or request, - * format is FILES, and token is a non-zero KVMFRClipboardFileError. - */ - -static inline int kvmfrClipboardFileOperationValid( - KVMFRClipboardFileOperation operation) -{ - return operation == KVMFR_CLIPBOARD_FILE_OP_LIST || - operation == KVMFR_CLIPBOARD_FILE_OP_READ; -} - -static inline int kvmfrClipboardFileTransferValid(uint64_t transfer) -{ - return transfer != 0; -} - -static inline int kvmfrClipboardFileMessageType( - KVMFRClipboardMessageType type) -{ - return type >= KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE && - type <= KVMFR_CLIPBOARD_MESSAGE_FILE_CANCEL; -} - -static inline int kvmfrClipboardFileMessageValid( - const KVMFRClipboardMessage * message) -{ - if (!message || message->version != KVMFR_CLIPBOARD_VERSION || - !message->clipboardGeneration || - !kvmfrClipboardFileTransferValid(message->transfer) || - message->format != KVMFR_CLIPBOARD_FORMAT_FILES || - message->length > KVMFR_CLIPBOARD_DATA_BYTES) - return 0; - - switch (message->type) - { - case KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRE: - case KVMFR_CLIPBOARD_MESSAGE_FILE_RELEASE: - return !message->sequence && !message->offset && !message->size && - !message->flags && !message->token && !message->length; - - case KVMFR_CLIPBOARD_MESSAGE_FILE_ACQUIRED: - return !message->sequence && !message->offset && !message->size && - !message->flags && - kvmfrClipboardFileErrorValid(message->token) && !message->length; - - case KVMFR_CLIPBOARD_MESSAGE_FILE_REQUEST: - if (message->sequence || - !kvmfrClipboardFileOperationValid(message->token) || - message->length || - (message->token == KVMFR_CLIPBOARD_FILE_OP_READ && - !message->size)) - return 0; - if (message->token == KVMFR_CLIPBOARD_FILE_OP_LIST) - return !message->offset && !message->flags; - return message->flags && - message->flags <= KVMFR_CLIPBOARD_FILE_READ_BYTES && - message->offset <= UINT64_MAX - message->flags; - - case KVMFR_CLIPBOARD_MESSAGE_FILE_DATA: - { - if (!kvmfrClipboardFileOperationValid(message->token) || - (message->flags & ~(KVMFR_CLIPBOARD_FLAG_BEGIN | - KVMFR_CLIPBOARD_FLAG_END)) || - (!message->length && - !(message->flags & KVMFR_CLIPBOARD_FLAG_END)) || - message->offset > UINT64_MAX - message->length) - return 0; - const uint64_t end = message->offset + message->length; - if (message->flags & KVMFR_CLIPBOARD_FLAG_END) - return message->size == end; - if (!(message->flags & KVMFR_CLIPBOARD_FLAG_BEGIN)) - return message->size == KVMFR_CLIPBOARD_SIZE_UNKNOWN; - return message->size == KVMFR_CLIPBOARD_SIZE_UNKNOWN || - message->size >= end; - } - - case KVMFR_CLIPBOARD_MESSAGE_FILE_CANCEL: - return !message->sequence && !message->offset && !message->size && - !message->flags && message->token && - kvmfrClipboardFileErrorValid(message->token) && !message->length; - - default: - return 0; - } -} - -/* Type-specific fields: - * CLAIM: token is the endpoint generation from the latest status. - * OFFER: token is KVMFRClipboardFormatFlags. - * REQUEST: format and transfer identify the requested representation. - * DATA: size is an optional total hint on BEGIN and authoritative on END; - * offset/length describe this record's borrowed payload. - * CANCEL: token is a KVMFRClipboardCancelReason-compatible reason. */ - -enum -{ - KVMFR_CLIPBOARD_STATUS_AVAILABLE = 1U << 0, - KVMFR_CLIPBOARD_STATUS_HAS_OWNER = 1U << 1 -}; - -typedef uint32_t KVMFRClipboardStatusFlags; - -/* The duplex stream descriptors are always valid. Their slot size includes - * KVMFRClipboardSlotHeader as well as slotBytes of payload. */ -typedef struct KVMFRClipboardStatus -{ - uint32_t version; - KVMFRClipboardStatusFlags flags; - uint32_t generation; - uint32_t ownerClientID; - uint32_t ownerGeneration; - uint32_t lease; - KVMFRClipboardFormatFlags formats; - uint32_t slotBytes; - uint32_t streamVersion; - uint32_t streamSlotCount; - uint32_t reserved[6]; - KVMFRStreamDescriptor hostToClient; - KVMFRStreamDescriptor clientToHost; -} -KVMFRClipboardStatus; - -/* The data immediately following this header is length bytes long. */ -typedef KVMFRClipboardMessage KVMFRClipboardSlotHeader; - -#define KVMFR_CLIPBOARD_STREAM_RECORD_BYTES \ - (sizeof(KVMFRClipboardSlotHeader) + KVMFR_CLIPBOARD_STREAM_SLOT_BYTES) - -enum -{ - KVMFR_CLIPBOARD_QUEUE_STATUS = 1, - KVMFR_CLIPBOARD_QUEUE_MESSAGE = 2 -}; - -typedef uint32_t KVMFRClipboardQueueType; - -#define KVMFR_CLIPBOARD_QUEUE_UDATA(type, serial) \ - ((((uint64_t)(type)) << 32) | (uint32_t)(serial)) -#define KVMFR_CLIPBOARD_QUEUE_TYPE(udata) \ - ((KVMFRClipboardQueueType)((uint64_t)(udata) >> 32)) -#define KVMFR_CLIPBOARD_QUEUE_SERIAL(udata) ((uint32_t)(udata)) - -#if defined(__cplusplus) -static_assert(sizeof(KVMFRClipboardMessage) == 64, - "KVMFR clipboard control message layout changed"); -static_assert(sizeof(KVMFRClipboardFileEntry) == 40, - "KVMFR clipboard file entry layout changed"); -static_assert(offsetof(KVMFRClipboardStatus, streamVersion) == 32, - "KVMFR clipboard stream status layout changed"); -static_assert(offsetof(KVMFRClipboardStatus, hostToClient) == 64, - "KVMFR clipboard stream discovery layout changed"); -static_assert(sizeof(KVMFRClipboardStatus) == 128, - "KVMFR clipboard status layout changed"); -static_assert(sizeof(KVMFRClipboardSlotHeader) == 64, - "KVMFR clipboard slot header layout changed"); -static_assert(sizeof(KVMFRClipboardMessage) <= 64, - "KVMFR clipboard message must fit one LGMP control message"); -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(sizeof(KVMFRClipboardMessage) == 64, - "KVMFR clipboard control message layout changed"); -_Static_assert(sizeof(KVMFRClipboardFileEntry) == 40, - "KVMFR clipboard file entry layout changed"); -_Static_assert(offsetof(KVMFRClipboardStatus, streamVersion) == 32, - "KVMFR clipboard stream status layout changed"); -_Static_assert(offsetof(KVMFRClipboardStatus, hostToClient) == 64, - "KVMFR clipboard stream discovery layout changed"); -_Static_assert(sizeof(KVMFRClipboardStatus) == 128, - "KVMFR clipboard status layout changed"); -_Static_assert(sizeof(KVMFRClipboardSlotHeader) == 64, - "KVMFR clipboard slot header layout changed"); -_Static_assert(sizeof(KVMFRClipboardMessage) <= 64, - "KVMFR clipboard message must fit one LGMP control message"); -#endif - -#endif diff --git a/common/include/common/KVMFRInput.h b/common/include/common/KVMFRInput.h deleted file mode 100644 index 0947a4c9..00000000 --- a/common/include/common/KVMFRInput.h +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Looking Glass - * Copyright © 2017-2026 The Looking Glass Authors - * https://looking-glass.io - * - * 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 - */ - -#ifndef _H_LG_COMMON_KVMFR_INPUT_ -#define _H_LG_COMMON_KVMFR_INPUT_ - -#pragma once - -#include "KVMFRStream.h" - -#include -#include - -#define KVMFR_INPUT_VERSION 3 -#define KVMFR_INPUT_KEYBOARD_LEDS_VERSION 3 -#define KVMFR_INPUT_STREAM_VERSION 1 -#define KVMFR_INPUT_STREAM_ENDPOINT_COUNT 8 -#define KVMFR_INPUT_STREAM_SLOT_COUNT 128 -#define KVMFR_INPUT_STREAM_SLOT_SIZE 64 -#define KVMFR_INPUT_MOUSE_BUTTON_COUNT 32 -#define KVMFR_INPUT_MOUSE_ABSOLUTE_MAX 32767 -#define KVMFR_INPUT_KEYBOARD_KEY_COUNT 6 -#define KVMFR_INPUT_KEYBOARD_USAGE_MAX 0xe7 - -typedef uint32_t KVMFRInputMouseButtons; - -/* - * Bits 0..31 correspond to USB HID mouse button usages 1..32. Wheel motion - * is carried separately and must not be represented as a button. - */ -typedef struct KVMFRInputMouseRelative -{ - KVMFRInputMouseButtons buttons; - int32_t deltaX; - int32_t deltaY; - int32_t wheel; -} -KVMFRInputMouseRelative; - -typedef struct KVMFRInputMouseAbsolute -{ - KVMFRInputMouseButtons buttons; - uint16_t x; - uint16_t y; - int32_t wheel; - uint32_t reserved; -} -KVMFRInputMouseAbsolute; - -typedef struct KVMFRInputKeyboard -{ - uint8_t modifiers; - uint8_t keys[KVMFR_INPUT_KEYBOARD_KEY_COUNT]; - uint8_t reserved[9]; -} -KVMFRInputKeyboard; - -typedef union KVMFRInputPayload -{ - KVMFRInputMouseRelative mouseRelative; - KVMFRInputMouseAbsolute mouseAbsolute; - KVMFRInputKeyboard keyboard; - uint8_t reserved[16]; -} -KVMFRInputPayload; - -enum -{ - KVMFR_INPUT_MESSAGE_CLAIM = 1, - KVMFR_INPUT_MESSAGE_RELEASE = 2, - KVMFR_INPUT_MESSAGE_KEEPALIVE = 3, - KVMFR_INPUT_MESSAGE_RESET = 4, - KVMFR_INPUT_MESSAGE_MOUSE_RELATIVE = 5, - KVMFR_INPUT_MESSAGE_MOUSE_ABSOLUTE = 6, - KVMFR_INPUT_MESSAGE_KEYBOARD = 7 -}; - -typedef uint32_t KVMFRInputMessageType; - -/* - * Input messages are carried by the client's ordered stream endpoint. CLAIM - * is sequence one, reports, KEEPALIVE and RESET increment the sequence, and - * RELEASE is the final record. - */ -typedef struct KVMFRInputMessage -{ - KVMFRInputMessageType type; - // Non-zero client input activation generation. - uint32_t generation; - // Non-zero ordered sequence within generation, beginning at one. - uint32_t sequence; - // Must be zero. - uint32_t reserved; - KVMFRInputPayload payload; -} -KVMFRInputMessage; - -enum -{ - KVMFR_INPUT_CAP_MOUSE_RELATIVE = 0x1, - KVMFR_INPUT_CAP_MOUSE_ABSOLUTE = 0x2, - KVMFR_INPUT_CAP_KEYBOARD = 0x4 -}; - -typedef uint32_t KVMFRInputCapabilityFlags; - -enum -{ - KVMFR_INPUT_KEYBOARD_LED_NUM_LOCK = 0x1, - KVMFR_INPUT_KEYBOARD_LED_CAPS_LOCK = 0x2, - KVMFR_INPUT_KEYBOARD_LED_SCROLL_LOCK = 0x4, - KVMFR_INPUT_KEYBOARD_LED_COMPOSE = 0x8, - KVMFR_INPUT_KEYBOARD_LED_KANA = 0x10, -}; - -typedef uint8_t KVMFRInputKeyboardLEDFlags; - -enum -{ - KVMFR_INPUT_STATUS_AVAILABLE = 0x1, - KVMFR_INPUT_STATUS_HAS_OWNER = 0x2, - KVMFR_INPUT_STATUS_KEYBOARD_LEDS_VALID = 0x4, -}; - -typedef uint32_t KVMFRInputStatusFlags; - -enum -{ - KVMFR_INPUT_STREAM_ENDPOINT_AVAILABLE = 0x1, - KVMFR_INPUT_STREAM_ENDPOINT_BOUND = 0x2, -}; - -typedef uint32_t KVMFRInputStreamEndpointFlags; - -/* - * A bound endpoint is usable only by boundClientID for bindingGeneration. The - * host changes bindingGeneration before reusing an endpoint so stale writers - * can never be accepted as a new client. - */ -typedef struct KVMFRInputStreamEndpoint -{ - KVMFRStreamDescriptor stream; - uint32_t boundClientID; - uint32_t bindingGeneration; - KVMFRInputStreamEndpointFlags flags; - uint32_t reserved; -} -KVMFRInputStreamEndpoint; - -/* - * Published through the LGMP input queue for status and stream discovery. - * KVMFRInputMessage records are carried only by the bound stream endpoint. - */ -typedef struct KVMFRInputStatus -{ - uint32_t version; - KVMFRInputCapabilityFlags capabilities; - KVMFRInputStatusFlags flags; - uint32_t generation; - uint32_t ownerClientID; - uint32_t ownerGeneration; - // Input ownership lease duration in milliseconds. - uint32_t lease; - uint32_t maxButtons; - uint32_t streamVersion; - uint32_t streamEndpointCount; - uint32_t streamGeneration; - // USB HID keyboard LED bits; valid only when the status flag is set. - uint8_t keyboardLEDs; - uint8_t statusReserved[3]; - uint32_t streamReserved[4]; - KVMFRInputStreamEndpoint streamEndpoint[ - KVMFR_INPUT_STREAM_ENDPOINT_COUNT]; -} -KVMFRInputStatus; - -#if defined(__cplusplus) -static_assert(sizeof(KVMFRInputMouseRelative) == 16, - "KVMFR relative mouse input layout changed"); -static_assert(sizeof(KVMFRInputMouseAbsolute) == 16, - "KVMFR absolute mouse input layout changed"); -static_assert(sizeof(KVMFRInputKeyboard) == 16, - "KVMFR keyboard input layout changed"); -static_assert(sizeof(KVMFRInputPayload) == 16, - "KVMFR input payload layout changed"); -static_assert(offsetof(KVMFRInputMessage, payload) == 16, - "KVMFR input message header layout changed"); -static_assert(sizeof(KVMFRInputMessage) == 32, - "KVMFR input message layout changed"); -static_assert(sizeof(KVMFRInputStreamEndpoint) == 48, - "KVMFR input stream endpoint layout changed"); -static_assert(offsetof(KVMFRInputStatus, streamVersion) == 32, - "KVMFR input status stream layout changed"); -static_assert(offsetof(KVMFRInputStatus, keyboardLEDs) == 44, - "KVMFR input status keyboard LED layout changed"); -static_assert(offsetof(KVMFRInputStatus, streamEndpoint) == 64, - "KVMFR input stream discovery layout changed"); -static_assert(sizeof(KVMFRInputStatus) == 448, - "KVMFR input status layout changed"); -static_assert(sizeof(KVMFRInputMessage) <= KVMFR_INPUT_STREAM_SLOT_SIZE, - "KVMFR input message must fit in one stream record"); -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(sizeof(KVMFRInputMouseRelative) == 16, - "KVMFR relative mouse input layout changed"); -_Static_assert(sizeof(KVMFRInputMouseAbsolute) == 16, - "KVMFR absolute mouse input layout changed"); -_Static_assert(sizeof(KVMFRInputKeyboard) == 16, - "KVMFR keyboard input layout changed"); -_Static_assert(sizeof(KVMFRInputPayload) == 16, - "KVMFR input payload layout changed"); -_Static_assert(offsetof(KVMFRInputMessage, payload) == 16, - "KVMFR input message header layout changed"); -_Static_assert(sizeof(KVMFRInputMessage) == 32, - "KVMFR input message layout changed"); -_Static_assert(sizeof(KVMFRInputStreamEndpoint) == 48, - "KVMFR input stream endpoint layout changed"); -_Static_assert(offsetof(KVMFRInputStatus, streamVersion) == 32, - "KVMFR input status stream layout changed"); -_Static_assert(offsetof(KVMFRInputStatus, keyboardLEDs) == 44, - "KVMFR input status keyboard LED layout changed"); -_Static_assert(offsetof(KVMFRInputStatus, streamEndpoint) == 64, - "KVMFR input stream discovery layout changed"); -_Static_assert(sizeof(KVMFRInputStatus) == 448, - "KVMFR input status layout changed"); -_Static_assert(sizeof(KVMFRInputMessage) <= KVMFR_INPUT_STREAM_SLOT_SIZE, - "KVMFR input message must fit in one stream record"); -#endif - -#endif diff --git a/common/include/common/KVMFRRecovery.h b/common/include/common/KVMFRRecovery.h deleted file mode 100644 index bbfac983..00000000 --- a/common/include/common/KVMFRRecovery.h +++ /dev/null @@ -1,263 +0,0 @@ -/** - * Looking Glass - * Copyright © 2017-2026 The Looking Glass Authors - * https://looking-glass.io - * - * 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 - */ - -#ifndef _H_LG_COMMON_KVMFR_RECOVERY_ -#define _H_LG_COMMON_KVMFR_RECOVERY_ - -#pragma once - -#include -#include - -#define KVMFR_R_MAGIC "KVMFRRCV" -#define KVMFR_R_VERSION 1U -#define KVMFR_R_READY 1U - -#define KVMFR_R_REGION_SIZE 65536U -#define KVMFR_R_LINE_SIZE 64U -#define KVMFR_R_HEARTBEAT_MS 250U -#define KVMFR_R_REQ_SLOTS 16U - -enum -{ - KVMFR_R_CAP_DISPLAY = 0x1U -}; - -enum -{ - KVMFR_R_REQ_WRITING = 0x1U, - KVMFR_R_REQ_FIRST = 0x2U -}; - -enum -{ - KVMFR_R_REQ_NONE = 0, - KVMFR_R_REQ_NORMAL = 1, - KVMFR_R_REQ_RECOVERY = 2 -}; - -enum -{ - KVMFR_R_STATE_UNKNOWN = 0, - KVMFR_R_STATE_NORMAL = 1, - KVMFR_R_STATE_SWITCHING = 2, - KVMFR_R_STATE_ACTIVE = 3, - KVMFR_R_STATE_FAILED = 4 -}; - -enum -{ - KVMFR_R_ERR_NONE = 0, - KVMFR_R_ERR_UNSUPPORTED = 1, - KVMFR_R_ERR_HELPER_UNAVAILABLE = 2, - KVMFR_R_ERR_TOPOLOGY_FAILED = 3, - KVMFR_R_ERR_NO_FALLBACK_DISPLAY = 4, - KVMFR_R_ERR_BUSY = 5, - KVMFR_R_ERR_CAPACITY = 6 -}; - -/* - * The recovery region is outside LGMP and remains stable across LGMP and - * KVMFR protocol changes. Header, information, and status lines are - * producer-owned. Request lines are client-owned except that the producer - * atomically clears a completed slot's serial. Shared fields are plain - * fixed-width values; synchronization is supplied externally rather than - * embedded in the wire layout. - */ -typedef struct KVMFRRHeader -{ - char magic[8]; - uint16_t abiVersion; - uint16_t structSize; - uint32_t capabilities; - uint32_t lgmpVersion; - uint32_t kvmfrVersion; - uint64_t session; - uint8_t uuid[16]; - uint32_t heartbeat; - uint32_t reserved[2]; - uint32_t ready; -} -KVMFRRHeader; - -/* - * Initialized by the IDD before publishing KVMFRRHeader::ready with - * release ordering. Clients acquire ready before reading either producer - * line. The heartbeat is an independently published 32-bit counter. The - * version string is NUL-terminated. - */ -typedef struct KVMFRRInfo -{ - char version[48]; - uint8_t reserved[16]; -} -KVMFRRInfo; - -/* - * Written by clients. Ticket is an even monotonic counter used to allocate a - * unique request serial. Zero is skipped when it wraps. - */ -typedef struct KVMFRRReqHead -{ - uint32_t ticket; - uint8_t reserved[60]; -} -KVMFRRReqHead; - -/* - * Written by clients. A writer claims an empty slot by changing serial from - * zero to its odd ticket, writes the payload, then release-publishes the even - * ticket. The IDD ignores odd slots and atomically clears completed even - * slots. An interrupted writer only consumes its own slot and cannot block or - * corrupt another writer. Session rejects requests from an old producer - * instance. - */ -typedef struct KVMFRRRequest -{ - uint32_t serial; - uint32_t request; - uint64_t session; - uint8_t reserved[48]; -} -KVMFRRRequest; - -/* - * Written only by the IDD. Serial is an independent publication generation: - * the IDD makes it odd before changing the payload, then publishes the next - * nonzero even value with release ordering. Clients use it to take a coherent - * snapshot. AckSerial identifies the request being acknowledged and does not - * provide publication ordering because it remains unchanged as a request - * moves through states. - */ -typedef struct KVMFRRStatus -{ - uint32_t ackSerial; - uint32_t ackRequest; - uint32_t state; - uint32_t error; - uint64_t session; - uint32_t serial; - uint8_t reserved[36]; -} -KVMFRRStatus; - -typedef struct KVMFRR -{ - KVMFRRHeader header; - KVMFRRInfo info; - KVMFRRReqHead req; - KVMFRRRequest requests[KVMFR_R_REQ_SLOTS]; - KVMFRRStatus status; -} -KVMFRR; - -#if defined(__cplusplus) -static_assert(KVMFR_R_REGION_SIZE % KVMFR_R_LINE_SIZE == 0, - "KVMFR recovery region must contain whole cache lines"); -static_assert(sizeof(KVMFRRHeader) == KVMFR_R_LINE_SIZE, - "KVMFR recovery header must occupy one cache line"); -static_assert(offsetof(KVMFRRHeader, lgmpVersion) == 16, - "KVMFR recovery protocol version layout changed"); -static_assert(offsetof(KVMFRRHeader, session) == 24, - "KVMFR recovery session layout changed"); -static_assert(offsetof(KVMFRRHeader, uuid) == 32, - "KVMFR recovery UUID layout changed"); -static_assert(offsetof(KVMFRRHeader, heartbeat) == 48, - "KVMFR recovery heartbeat layout changed"); -static_assert(offsetof(KVMFRRHeader, ready) == 60, - "KVMFR recovery publication layout changed"); -static_assert(sizeof(KVMFRRInfo) == KVMFR_R_LINE_SIZE, - "KVMFR recovery producer information must occupy one cache line"); -static_assert(sizeof(KVMFRRReqHead) == KVMFR_R_LINE_SIZE, - "KVMFR recovery request header must occupy one cache line"); -static_assert(sizeof(KVMFRRRequest) == KVMFR_R_LINE_SIZE, - "KVMFR recovery request must occupy one cache line"); -static_assert(offsetof(KVMFRRRequest, session) == 8, - "KVMFR recovery request session layout changed"); -static_assert(offsetof(KVMFRRRequest, request) == 4, - "KVMFR recovery request publication layout changed"); -static_assert(sizeof(KVMFRRStatus) == KVMFR_R_LINE_SIZE, - "KVMFR recovery status must occupy one cache line"); -static_assert(offsetof(KVMFRRStatus, session) == 16, - "KVMFR recovery status session layout changed"); -static_assert(offsetof(KVMFRRStatus, serial) == 24, - "KVMFR recovery status publication layout changed"); -static_assert(offsetof(KVMFRR, info) == KVMFR_R_LINE_SIZE, - "KVMFR recovery producer information must be cache-line aligned"); -static_assert(offsetof(KVMFRR, req) == KVMFR_R_LINE_SIZE * 2, - "KVMFR recovery request header must be cache-line aligned"); -static_assert(offsetof(KVMFRR, requests) == KVMFR_R_LINE_SIZE * 3, - "KVMFR recovery request must be cache-line aligned"); -static_assert(offsetof(KVMFRR, status) == - KVMFR_R_LINE_SIZE * (3 + KVMFR_R_REQ_SLOTS), - "KVMFR recovery status must be cache-line aligned"); -static_assert(sizeof(KVMFRR) == - KVMFR_R_LINE_SIZE * (4 + KVMFR_R_REQ_SLOTS), - "KVMFR recovery layout changed"); -static_assert(sizeof(KVMFRR) <= KVMFR_R_REGION_SIZE, - "KVMFR recovery data must fit in its reserved region"); -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(KVMFR_R_REGION_SIZE % KVMFR_R_LINE_SIZE == 0, - "KVMFR recovery region must contain whole cache lines"); -_Static_assert(sizeof(KVMFRRHeader) == KVMFR_R_LINE_SIZE, - "KVMFR recovery header must occupy one cache line"); -_Static_assert(offsetof(KVMFRRHeader, lgmpVersion) == 16, - "KVMFR recovery protocol version layout changed"); -_Static_assert(offsetof(KVMFRRHeader, session) == 24, - "KVMFR recovery session layout changed"); -_Static_assert(offsetof(KVMFRRHeader, uuid) == 32, - "KVMFR recovery UUID layout changed"); -_Static_assert(offsetof(KVMFRRHeader, heartbeat) == 48, - "KVMFR recovery heartbeat layout changed"); -_Static_assert(offsetof(KVMFRRHeader, ready) == 60, - "KVMFR recovery publication layout changed"); -_Static_assert(sizeof(KVMFRRInfo) == KVMFR_R_LINE_SIZE, - "KVMFR recovery producer information must occupy one cache line"); -_Static_assert(sizeof(KVMFRRReqHead) == KVMFR_R_LINE_SIZE, - "KVMFR recovery request header must occupy one cache line"); -_Static_assert(sizeof(KVMFRRRequest) == KVMFR_R_LINE_SIZE, - "KVMFR recovery request must occupy one cache line"); -_Static_assert(offsetof(KVMFRRRequest, session) == 8, - "KVMFR recovery request session layout changed"); -_Static_assert(offsetof(KVMFRRRequest, request) == 4, - "KVMFR recovery request publication layout changed"); -_Static_assert(sizeof(KVMFRRStatus) == KVMFR_R_LINE_SIZE, - "KVMFR recovery status must occupy one cache line"); -_Static_assert(offsetof(KVMFRRStatus, session) == 16, - "KVMFR recovery status session layout changed"); -_Static_assert(offsetof(KVMFRRStatus, serial) == 24, - "KVMFR recovery status publication layout changed"); -_Static_assert(offsetof(KVMFRR, info) == KVMFR_R_LINE_SIZE, - "KVMFR recovery producer information must be cache-line aligned"); -_Static_assert(offsetof(KVMFRR, req) == KVMFR_R_LINE_SIZE * 2, - "KVMFR recovery request header must be cache-line aligned"); -_Static_assert(offsetof(KVMFRR, requests) == KVMFR_R_LINE_SIZE * 3, - "KVMFR recovery request must be cache-line aligned"); -_Static_assert(offsetof(KVMFRR, status) == - KVMFR_R_LINE_SIZE * (3 + KVMFR_R_REQ_SLOTS), - "KVMFR recovery status must be cache-line aligned"); -_Static_assert(sizeof(KVMFRR) == - KVMFR_R_LINE_SIZE * (4 + KVMFR_R_REQ_SLOTS), - "KVMFR recovery layout changed"); -_Static_assert(sizeof(KVMFRR) <= KVMFR_R_REGION_SIZE, - "KVMFR recovery data must fit in its reserved region"); -#endif - -#endif diff --git a/common/include/common/KVMFRStream.h b/common/include/common/KVMFRStream.h deleted file mode 100644 index 36598f59..00000000 --- a/common/include/common/KVMFRStream.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Looking Glass - * Copyright © 2017-2026 The Looking Glass Authors - * https://looking-glass.io - * - * 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 - */ - -#ifndef _H_LG_COMMON_KVMFR_STREAM_ -#define _H_LG_COMMON_KVMFR_STREAM_ - -#pragma once - -#include -#include - -/* - * Transport-neutral wire copy of an exported LGMP stream descriptor. Keep - * common protocol headers independent of LGMP; the LGMP transports convert - * this structure field by field at their integration boundary. - */ -typedef struct KVMFRStreamDescriptor -{ - uint32_t magic; - uint16_t version; - uint16_t size; - uint32_t offset; - uint32_t regionSize; - uint32_t direction; - uint32_t policy; - uint32_t slotCount; - uint32_t slotSize; -} -KVMFRStreamDescriptor; - -#if defined(__cplusplus) -static_assert(offsetof(KVMFRStreamDescriptor, magic) == 0, - "KVMFR stream descriptor magic layout changed"); -static_assert(offsetof(KVMFRStreamDescriptor, offset) == 8, - "KVMFR stream descriptor offset layout changed"); -static_assert(offsetof(KVMFRStreamDescriptor, slotSize) == 28, - "KVMFR stream descriptor geometry layout changed"); -static_assert(sizeof(KVMFRStreamDescriptor) == 32, - "KVMFR stream descriptor layout changed"); -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(offsetof(KVMFRStreamDescriptor, magic) == 0, - "KVMFR stream descriptor magic layout changed"); -_Static_assert(offsetof(KVMFRStreamDescriptor, offset) == 8, - "KVMFR stream descriptor offset layout changed"); -_Static_assert(offsetof(KVMFRStreamDescriptor, slotSize) == 28, - "KVMFR stream descriptor geometry layout changed"); -_Static_assert(sizeof(KVMFRStreamDescriptor) == 32, - "KVMFR stream descriptor layout changed"); -#endif - -#endif diff --git a/common/include/common/LGMPConfig.h b/common/include/common/LGMPConfig.h deleted file mode 100644 index 6a74a11e..00000000 --- a/common/include/common/LGMPConfig.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Looking Glass - * Copyright © 2017-2026 The Looking Glass Authors - * https://looking-glass.io - * - * 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 - */ - -#ifndef _H_LG_COMMON_LGMP_CONFIG_ -#define _H_LG_COMMON_LGMP_CONFIG_ - -#define LGMP_Q_POINTER 1 -#define LGMP_Q_FRAME 2 -// Base ID for LGMP_Q_FRAME_LEN independent owner-delivery queues. -#define LGMP_Q_FRAME_OWNER 3 -#define LGMP_Q_INPUT 5 -#define LGMP_Q_CLIPBOARD 6 - -// Two delivery lanes plus a spare buffer let the timing owner continue to -// alternate buffers while a secondary client holds the shared delivery. -#define LGMP_Q_FRAME_LEN 2 -#define LGMP_Q_FRAME_BUFFER_LEN 3 -#define LGMP_Q_POINTER_LEN 32 -#define LGMP_Q_INPUT_LEN 4 -#define LGMP_Q_CLIPBOARD_LEN 32 - -#endif diff --git a/common/include/common/framebuffer.h b/common/include/common/framebuffer.h index 9f3844f6..0d0ea420 100644 --- a/common/include/common/framebuffer.h +++ b/common/include/common/framebuffer.h @@ -24,86 +24,80 @@ #include #include #include -#include + +#include #define FB_CHUNK_SIZE 1048576 // 1MB #define FB_SPIN_LIMIT 10000 // 10ms -#define FB_WP_TYPE atomic_uint_least32_t -#define FB_WP_SIZE sizeof(FB_WP_TYPE) - -typedef struct stFrameBuffer -{ - FB_WP_TYPE wp; - uint8_t data[0]; -} FrameBuffer; typedef bool (*FrameBufferReadFn)(void * opaque, const void * src, size_t size); /** * Wait for the framebuffer to fill to the specified size */ -bool framebuffer_wait(const FrameBuffer * frame, size_t size); +bool framebuffer_wait(const KVMFRFrameBuffer * frame, size_t size); /** * Wait for the framebuffer to fill to the specified size and accumulate the * nanoseconds spent waiting for the producer in `waitTimeNs`. */ -bool framebuffer_wait_timed(const FrameBuffer * frame, size_t size, +bool framebuffer_wait_timed(const KVMFRFrameBuffer * frame, size_t size, uint64_t * waitTimeNs); /** * Read `size` bytes from the KVMFRFrame into the dst buffer */ -bool framebuffer_read_linear(const FrameBuffer * frame, void * restrict dst, - size_t size); +bool framebuffer_read_linear(const KVMFRFrameBuffer * frame, + void * restrict dst, size_t size); /** * Read data from the KVMFRFrame into the dst buffer */ -bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t dstpitch, - size_t height, size_t width, size_t bpp, size_t pitch); +bool framebuffer_read(const KVMFRFrameBuffer * frame, void * dst, + size_t dstpitch, size_t height, size_t width, size_t bpp, size_t pitch); /** * Read data from the KVMFRFrame and accumulate the nanoseconds spent waiting * for the producer in `waitTimeNs`. */ -bool framebuffer_read_timed(const FrameBuffer * frame, void * dst, +bool framebuffer_read_timed(const KVMFRFrameBuffer * frame, void * dst, size_t dstpitch, size_t height, size_t width, size_t bpp, size_t pitch, uint64_t * waitTimeNs); /** * Read data from the KVMFRFrame using a callback */ -bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width, - size_t bpp, size_t pitch, FrameBufferReadFn fn, void * opaque); +bool framebuffer_read_fn(const KVMFRFrameBuffer * frame, size_t height, + size_t width, size_t bpp, size_t pitch, FrameBufferReadFn fn, + void * opaque); /** * Prepare the framebuffer for writing */ -void framebuffer_prepare(FrameBuffer * frame); +void framebuffer_prepare(KVMFRFrameBuffer * frame); /** * Write data from the src buffer into the KVMFRFrame */ -extern bool (*framebuffer_write)(FrameBuffer * frame, +extern bool (*framebuffer_write)(KVMFRFrameBuffer * frame, const void * restrict src, size_t size); /** * Gets the underlying data buffer of the framebuffer. * For custom read routines only. */ -const uint8_t * framebuffer_get_buffer(const FrameBuffer * frame); +const uint8_t * framebuffer_get_buffer(const KVMFRFrameBuffer * frame); /** * Gets the underlying data buffer of the framebuffer. * For custom write routines only. */ -uint8_t * framebuffer_get_data(FrameBuffer * frame); +uint8_t * framebuffer_get_data(KVMFRFrameBuffer * frame); /** * Sets the write pointer of the framebuffer. * For custom write routines only. */ -void framebuffer_set_write_ptr(FrameBuffer * frame, size_t size); +void framebuffer_set_write_ptr(KVMFRFrameBuffer * frame, size_t size); #endif diff --git a/common/include/common/rects.h b/common/include/common/rects.h index 4988572d..f77f7761 100644 --- a/common/include/common/rects.h +++ b/common/include/common/rects.h @@ -33,21 +33,22 @@ extern void (*rectCopyUnaligned)( void rectScaleOutward(struct Rect * rect, double scale); -bool rectsBufferToFramebuffer(const FrameDamageRect * rects, int count, int bpp, - FrameBuffer * frame, int dstPitch, int height, +bool rectsBufferToFramebuffer(const KVMFRFrameDamageRect * rects, int count, + int bpp, KVMFRFrameBuffer * frame, int dstPitch, int height, const uint8_t * src, int srcPitch); -bool rectsFramebufferToBuffer(const FrameDamageRect * rects, int count, int bpp, +bool rectsFramebufferToBuffer(const KVMFRFrameDamageRect * rects, int count, + int bpp, uint8_t * dst, int dstPitch, int height, - const FrameBuffer * frame, int srcPitch); + const KVMFRFrameBuffer * frame, int srcPitch); /* As above, accumulating producer wait time in nanoseconds. */ -bool rectsFramebufferToBufferTimed(const FrameDamageRect * rects, +bool rectsFramebufferToBufferTimed(const KVMFRFrameDamageRect * rects, int count, int bpp, uint8_t * dst, int dstPitch, int height, - const FrameBuffer * frame, int srcPitch, uint64_t * waitTimeNs); + const KVMFRFrameBuffer * frame, int srcPitch, uint64_t * waitTimeNs); -int rectsMergeOverlapping(FrameDamageRect * rects, int count); -int rectsRejectContained(FrameDamageRect * rects, int count); +int rectsMergeOverlapping(KVMFRFrameDamageRect * rects, int count); +int rectsRejectContained(KVMFRFrameDamageRect * rects, int count); #endif diff --git a/common/include/common/types.h b/common/include/common/types.h index 7c063640..d3f4f9ca 100644 --- a/common/include/common/types.h +++ b/common/include/common/types.h @@ -23,6 +23,8 @@ #include +#include + typedef void (*LG_FrameReleaseFn)(void * opaque, uint64_t handle); struct Point @@ -50,67 +52,8 @@ struct Border int left, top, right, bottom; }; -typedef enum FrameType -{ - FRAME_TYPE_INVALID , - FRAME_TYPE_BGRA , // BGRA interleaved: B,G,R,A 32bpp - FRAME_TYPE_RGBA , // RGBA interleaved: R,G,B,A 32bpp - FRAME_TYPE_RGBA10 , // RGBA interleaved: R,G,B,A 10,10,10,2 bpp - FRAME_TYPE_RGBA16F , // RGBA interleaved: R,G,B,A 16,16,16,16 bpp float - FRAME_TYPE_BGR_32 , // BGR 24-bpp in 32bpp - FRAME_TYPE_RGB_24 , // RGB 24-bpp - FRAME_TYPE_MAX , // sentinel value -} -FrameType; - -typedef enum FrameRotation -{ - FRAME_ROT_0, - FRAME_ROT_90, - FRAME_ROT_180, - FRAME_ROT_270 -} -FrameRotation; - -typedef struct FrameDamageRect -{ - uint32_t x; - uint32_t y; - uint32_t width; - uint32_t height; -} -FrameDamageRect; - extern const char * FrameTypeStr[FRAME_TYPE_MAX]; -typedef enum CursorType -{ - CURSOR_TYPE_COLOR , - CURSOR_TYPE_MONOCHROME , - CURSOR_TYPE_MASKED_COLOR -} -CursorType; - -enum -{ - LG_COLOR_TRANSFORM_MATRIX = 0x1, - LG_COLOR_TRANSFORM_LUT = 0x2, -}; - -typedef uint32_t LGColorTransformFlags; - -#define LG_SDR_WHITE_LEVEL_DEFAULT 203 -#define LG_MAX_FRAME_DAMAGE_RECTS 64 - -typedef struct LGColorTransform -{ - LGColorTransformFlags flags; - float matrix[3][4]; - float scalar; - float lut[4096][4]; -} -LGColorTransform; - typedef struct StringPair { const char * name; diff --git a/common/src/KVMFR.c b/common/src/KVMFR.c index 85017cf5..1660c78c 100644 --- a/common/src/KVMFR.c +++ b/common/src/KVMFR.c @@ -18,7 +18,7 @@ * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "common/KVMFR.h" +#include const char * FrameTypeStr[FRAME_TYPE_MAX] = { diff --git a/common/src/framebuffer.c b/common/src/framebuffer.c index 3245d4db..58383d5e 100644 --- a/common/src/framebuffer.c +++ b/common/src/framebuffer.c @@ -43,7 +43,7 @@ static bool framebuffer_size_mul(size_t a, size_t b, size_t * result) return true; } -bool framebuffer_wait_timed(const FrameBuffer * frame, size_t size, +bool framebuffer_wait_timed(const KVMFRFrameBuffer * frame, size_t size, uint64_t * waitTimeNs) { if (size > UINT_LEAST32_MAX) @@ -75,27 +75,27 @@ bool framebuffer_wait_timed(const FrameBuffer * frame, size_t size, return true; } -bool framebuffer_wait(const FrameBuffer * frame, size_t size) +bool framebuffer_wait(const KVMFRFrameBuffer * frame, size_t size) { return framebuffer_wait_timed(frame, size, NULL); } -static bool framebuffer_read_linear_timed(const FrameBuffer * frame, +static bool framebuffer_read_linear_timed(const KVMFRFrameBuffer * frame, void * restrict dst, size_t size, uint64_t * waitTimeNs) { if (size > UINT_LEAST32_MAX) return false; #ifdef FB_PROFILE - static RunningAvg ra = NULL; - static int raCount = 0; - const uint64_t ts = microtime(); + static RunningAvg ra = NULL; + static int raCount = 0; + const uint64_t ts = microtime(); if (!ra) ra = runningavg_new(100); #endif - uint8_t * restrict d = (uint8_t*)dst; - size_t rp = 0; + uint8_t * restrict d = (uint8_t*)dst; + size_t rp = 0; // copy in large 1MB chunks if the pitches match while(size) @@ -119,13 +119,14 @@ static bool framebuffer_read_linear_timed(const FrameBuffer * frame, return true; } -bool framebuffer_read_linear(const FrameBuffer * frame, void * restrict dst, - size_t size) +bool framebuffer_read_linear(const KVMFRFrameBuffer * frame, + void * restrict dst, size_t size) { return framebuffer_read_linear_timed(frame, dst, size, NULL); } -bool framebuffer_read_timed(const FrameBuffer * frame, void * restrict dst, +bool framebuffer_read_timed(const KVMFRFrameBuffer * frame, + void * restrict dst, size_t dstpitch, size_t height, size_t width, size_t bpp, size_t pitch, uint64_t * waitTimeNs) { @@ -147,15 +148,15 @@ bool framebuffer_read_timed(const FrameBuffer * frame, void * restrict dst, frame, dst, sourceSize, waitTimeNs); #ifdef FB_PROFILE - static RunningAvg ra = NULL; - static int raCount = 0; - const uint64_t ts = microtime(); + static RunningAvg ra = NULL; + static int raCount = 0; + const uint64_t ts = microtime(); if (!ra) ra = runningavg_new(100); #endif - uint8_t * restrict d = (uint8_t*)dst; - size_t rp = 0; + uint8_t * restrict d = (uint8_t*)dst; + size_t rp = 0; // copy per line to match the pitch of the destination buffer for(size_t y = 0; y < height; ++y) @@ -177,15 +178,16 @@ bool framebuffer_read_timed(const FrameBuffer * frame, void * restrict dst, return true; } -bool framebuffer_read(const FrameBuffer * frame, void * restrict dst, +bool framebuffer_read(const KVMFRFrameBuffer * frame, void * restrict dst, size_t dstpitch, size_t height, size_t width, size_t bpp, size_t pitch) { return framebuffer_read_timed(frame, dst, dstpitch, height, width, bpp, pitch, NULL); } -bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width, - size_t bpp, size_t pitch, FrameBufferReadFn fn, void * opaque) +bool framebuffer_read_fn(const KVMFRFrameBuffer * frame, size_t height, + size_t width, size_t bpp, size_t pitch, FrameBufferReadFn fn, + void * opaque) { size_t linewidth; size_t sourceSize; @@ -200,15 +202,15 @@ bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width, return true; #ifdef FB_PROFILE - static RunningAvg ra = NULL; - static int raCount = 0; - const uint64_t ts = microtime(); + static RunningAvg ra = NULL; + static int raCount = 0; + const uint64_t ts = microtime(); if (!ra) ra = runningavg_new(100); #endif - size_t rp = 0; - size_t y = 0; + size_t rp = 0; + size_t y = 0; while(y < height) { @@ -234,37 +236,37 @@ bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width, /** * Prepare the framebuffer for writing */ -void framebuffer_prepare(FrameBuffer * frame) +void framebuffer_prepare(KVMFRFrameBuffer * frame) { atomic_store_explicit(&frame->wp, 0, memory_order_release); } -static bool framebuffer_write_sse4_1(FrameBuffer * frame, +static bool framebuffer_write_sse4_1(KVMFRFrameBuffer * frame, const void * restrict src, size_t size) { #ifdef FB_PROFILE - static RunningAvg ra = NULL; - static int raCount = 0; - const uint64_t ts = microtime(); + static RunningAvg ra = NULL; + static int raCount = 0; + const uint64_t ts = microtime(); if (!ra) ra = runningavg_new(100); #endif - __m128i * restrict s = (__m128i *)src; - __m128i * restrict d = (__m128i *)frame->data; - size_t wp = 0; + __m128i * restrict s = (__m128i *)src; + __m128i * restrict d = (__m128i *)frame->data; + size_t wp = 0; _mm_mfence(); /* copy in chunks */ while(size > 63) { - __m128i *_d = (__m128i *)d; - __m128i *_s = (__m128i *)s; - __m128i v1 = _mm_stream_load_si128(_s + 0); - __m128i v2 = _mm_stream_load_si128(_s + 1); - __m128i v3 = _mm_stream_load_si128(_s + 2); - __m128i v4 = _mm_stream_load_si128(_s + 3); + __m128i * _d = (__m128i *)d; + __m128i * _s = (__m128i *)s; + __m128i v1 = _mm_stream_load_si128(_s + 0); + __m128i v2 = _mm_stream_load_si128(_s + 1); + __m128i v3 = _mm_stream_load_si128(_s + 2); + __m128i v4 = _mm_stream_load_si128(_s + 3); _mm_store_si128(_d + 0, v1); _mm_store_si128(_d + 1, v2); @@ -303,20 +305,20 @@ static bool framebuffer_write_sse4_1(FrameBuffer * frame, #pragma GCC push_options #pragma GCC target ("avx2") #endif -bool framebuffer_write_avx2(FrameBuffer * frame, +bool framebuffer_write_avx2(KVMFRFrameBuffer * frame, const void * restrict src, size_t size) { #ifdef FB_PROFILE - static RunningAvg ra = NULL; - static int raCount = 0; - const uint64_t ts = microtime(); - if (!ra) - ra = runningavg_new(100); + static RunningAvg ra = NULL; + static int raCount = 0; + const uint64_t ts = microtime(); + if (!ra) + ra = runningavg_new(100); #endif - __m256i *restrict s = (__m256i *)src; - __m256i *restrict d = (__m256i *)frame->data; - size_t wp = 0; + __m256i * restrict s = (__m256i *)src; + __m256i * restrict d = (__m256i *)frame->data; + size_t wp = 0; _mm_mfence(); @@ -381,7 +383,7 @@ bool framebuffer_write_avx2(FrameBuffer * frame, #pragma GCC pop_options #endif -static bool _framebuffer_write(FrameBuffer * frame, +static bool _framebuffer_write(KVMFRFrameBuffer * frame, const void * restrict src, size_t size) { if (cpuInfo_getFeatures()->avx2) @@ -392,20 +394,20 @@ static bool _framebuffer_write(FrameBuffer * frame, return framebuffer_write(frame, src, size); } -bool (*framebuffer_write)(FrameBuffer * frame, - const void * restrict src, size_t size) = &_framebuffer_write; +bool (*framebuffer_write)(KVMFRFrameBuffer * frame, + const void * restrict src, size_t size) = &_framebuffer_write; -const uint8_t * framebuffer_get_buffer(const FrameBuffer * frame) +const uint8_t * framebuffer_get_buffer(const KVMFRFrameBuffer * frame) { return frame->data; } -uint8_t * framebuffer_get_data(FrameBuffer * frame) +uint8_t * framebuffer_get_data(KVMFRFrameBuffer * frame) { return frame->data; } -void framebuffer_set_write_ptr(FrameBuffer * frame, size_t size) +void framebuffer_set_write_ptr(KVMFRFrameBuffer * frame, size_t size) { atomic_store_explicit(&frame->wp, size, memory_order_release); } diff --git a/common/src/rects.c b/common/src/rects.c index c47d3f64..7f7ff95b 100644 --- a/common/src/rects.c +++ b/common/src/rects.c @@ -52,8 +52,8 @@ void rectScaleOutward(struct Rect * rect, double scale) rect->h = bottom - top; } -inline static bool rectIntersects(const FrameDamageRect * r1, - const FrameDamageRect * r2) +inline static bool rectIntersects(const KVMFRFrameDamageRect * r1, + const KVMFRFrameDamageRect * r2) { return !( r1->x > r2->x + r2->width || @@ -62,8 +62,8 @@ inline static bool rectIntersects(const FrameDamageRect * r1, r2->y > r1->y + r1->height); } -inline static bool rectContains(const FrameDamageRect * r1, - const FrameDamageRect * r2) +inline static bool rectContains(const KVMFRFrameDamageRect * r1, + const KVMFRFrameDamageRect * r2) { return !( r2->x < r1->x || @@ -72,7 +72,7 @@ inline static bool rectContains(const FrameDamageRect * r1, r2->y + r2->height > r1->y + r1->height); } -inline static int removeRects(FrameDamageRect * rects, int count, +inline static int removeRects(KVMFRFrameDamageRect * rects, int count, bool removed[]) { int o = 0; @@ -99,7 +99,7 @@ static int cornerCompare(const void * a_, const void * b_) return 0; } -static bool rectsBufferCopy(const FrameDamageRect * rects, +static bool rectsBufferCopy(const KVMFRFrameDamageRect * rects, int count, int bpp, uint8_t * dst, int dstStride, int height, const uint8_t * src, int srcStride, void * opaque, @@ -117,9 +117,9 @@ static bool rectsBufferCopy(const FrameDamageRect * rects, for (int i = 0; i < count; ++i) { - const FrameDamageRect * rect = rects + i; - const uint64_t right = (uint64_t)rect->x + rect->width; - const uint64_t bottom = (uint64_t)rect->y + rect->height; + const KVMFRFrameDamageRect * rect = rects + i; + const uint64_t right = (uint64_t)rect->x + rect->width; + const uint64_t bottom = (uint64_t)rect->y + rect->height; if (!rect->width || !rect->height || bottom > (uint32_t)height || right > (uint32_t)dstStride / (uint32_t)bpp || right > (uint32_t)srcStride / (uint32_t)bpp) @@ -133,7 +133,7 @@ static bool rectsBufferCopy(const FrameDamageRect * rects, for (int i = 0; i < count; ++i) { - const FrameDamageRect * rect = rects + i; + const KVMFRFrameDamageRect * rect = rects + i; corners[4 * i + 0] = (struct Corner) { .x = rect->x, .y = rect->y, .delta = 1 }; @@ -233,8 +233,8 @@ static bool rectsBufferCopy(const FrameDamageRect * rects, struct ToFramebufferData { - FrameBuffer * frame; - int pitch; + KVMFRFrameBuffer * frame; + int pitch; }; static void fbRowFinish(int y, void * opaque) @@ -244,9 +244,9 @@ static void fbRowFinish(int y, void * opaque) data->frame, (size_t)y * (size_t)data->pitch); } -bool rectsBufferToFramebuffer(const FrameDamageRect * rects, +bool rectsBufferToFramebuffer(const KVMFRFrameDamageRect * rects, int count, int bpp, - FrameBuffer * frame, int dstPitch, int height, + KVMFRFrameBuffer * frame, int dstPitch, int height, const uint8_t * src, int srcPitch) { if (!rects || !frame || count <= 0) @@ -271,9 +271,9 @@ bool rectsBufferToFramebuffer(const FrameDamageRect * rects, struct FromFramebufferData { - const FrameBuffer * frame; - int pitch; - uint64_t * waitTimeNs; + const KVMFRFrameBuffer * frame; + int pitch; + uint64_t * waitTimeNs; }; static bool fbRowStart(int y, void * opaque) @@ -283,10 +283,10 @@ static bool fbRowStart(int y, void * opaque) data->frame, (size_t)y * (size_t)data->pitch, data->waitTimeNs); } -bool rectsFramebufferToBufferTimed(const FrameDamageRect * rects, +bool rectsFramebufferToBufferTimed(const KVMFRFrameDamageRect * rects, int count, int bpp, uint8_t * dst, int dstPitch, int height, - const FrameBuffer * frame, int srcPitch, uint64_t * waitTimeNs) + const KVMFRFrameBuffer * frame, int srcPitch, uint64_t * waitTimeNs) { if (!rects || !frame || count <= 0) return false; @@ -310,16 +310,16 @@ bool rectsFramebufferToBufferTimed(const FrameDamageRect * rects, return true; } -bool rectsFramebufferToBuffer(const FrameDamageRect * rects, +bool rectsFramebufferToBuffer(const KVMFRFrameDamageRect * rects, int count, int bpp, uint8_t * dst, int dstPitch, int height, - const FrameBuffer * frame, int srcPitch) + const KVMFRFrameBuffer * frame, int srcPitch) { return rectsFramebufferToBufferTimed(rects, count, bpp, dst, dstPitch, height, frame, srcPitch, NULL); } -int rectsMergeOverlapping(FrameDamageRect * rects, int count) +int rectsMergeOverlapping(KVMFRFrameDamageRect * rects, int count) { if (count == 0) return 0; @@ -362,7 +362,7 @@ int rectsMergeOverlapping(FrameDamageRect * rects, int count) return removeRects(rects, count, removed); } -int rectsRejectContained(FrameDamageRect * rects, int count) +int rectsRejectContained(KVMFRFrameDamageRect * rects, int count) { bool removed[count]; memset(removed, 0, sizeof(removed)); diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index a27e7092..498d9c0f 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(looking-glass-host C) +project(looking-glass-host C CXX) get_filename_component(PROJECT_TOP "${PROJECT_SOURCE_DIR}/.." ABSOLUTE) diff --git a/host/include/interface/capture.h b/host/include/interface/capture.h index 845438d5..a91636ac 100644 --- a/host/include/interface/capture.h +++ b/host/include/interface/capture.h @@ -22,13 +22,9 @@ #include #include -#include "common/KVMFR.h" +#include -#ifdef __cplusplus -/* using common/framebuffer.h breaks compatibillity with C++ due to it's usage - * of stdatomic.h, so we need to forward declare the structure here */ -typedef struct stFrameBuffer FrameBuffer; -#else +#ifndef __cplusplus #include "common/framebuffer.h" #endif @@ -95,8 +91,8 @@ typedef struct CaptureFrame uint32_t hdrMaxFrameAverageLightLevel; uint32_t sdrWhiteLevel; - uint32_t damageRectsCount; - FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS]; + uint32_t damageRectsCount; + KVMFRFrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS]; // Producer-local durations. Absolute timestamps must not cross KVMFR as the // client and producer use different monotonic clock domains. @@ -148,18 +144,18 @@ typedef struct CaptureInterface void (*free )(void); CaptureResult (*capture )( - unsigned frameBufferIndex, - FrameBuffer * frame); + unsigned frameBufferIndex, + KVMFRFrameBuffer * frame); CaptureResult (*waitFrame )( - unsigned frameBufferIndex, - CaptureFrame * frame, - /* Capacity of FrameBuffer::data, excluding the message and header. */ - const size_t maxFrameSize); - CaptureResult (*getFrame )( unsigned frameBufferIndex, - FrameBuffer * frame, - /* Capacity of FrameBuffer::data, excluding the message and header. */ - const size_t maxFrameSize, - CaptureFrame * captureFrame); + CaptureFrame * frame, + /* Capacity of KVMFRFrameBuffer::data, excluding message and header. */ + const size_t maxFrameSize); + CaptureResult (*getFrame )( + unsigned frameBufferIndex, + KVMFRFrameBuffer * frame, + /* Capacity of KVMFRFrameBuffer::data, excluding message and header. */ + const size_t maxFrameSize, + CaptureFrame * captureFrame); } CaptureInterface; diff --git a/host/include/interface/platform.h b/host/include/interface/platform.h index 1b3ee732..4ebb5602 100644 --- a/host/include/interface/platform.h +++ b/host/include/interface/platform.h @@ -21,7 +21,7 @@ #pragma once #include -#include "common/KVMFR.h" +#include // exit code for user opted to exit looking-glass-host #define LG_HOST_EXIT_USER 0x10 diff --git a/host/platform/Linux/capture/XCB/src/xcb.c b/host/platform/Linux/capture/XCB/src/xcb.c index c5e94408..b245246c 100644 --- a/host/platform/Linux/capture/XCB/src/xcb.c +++ b/host/platform/Linux/capture/XCB/src/xcb.c @@ -247,7 +247,7 @@ static void xcb_free(void) static CaptureResult xcb_capture( unsigned frameBufferIndex, - FrameBuffer * frame) + KVMFRFrameBuffer * frame) { DEBUG_ASSERT(this); DEBUG_ASSERT(this->initialized); @@ -299,10 +299,10 @@ static CaptureResult xcb_waitFrame( } static CaptureResult xcb_getFrame( - unsigned frameBufferIndex, - FrameBuffer * frame, - const size_t maxFrameSize, - CaptureFrame * captureFrame) + unsigned frameBufferIndex, + KVMFRFrameBuffer * frame, + const size_t maxFrameSize, + CaptureFrame * captureFrame) { (void)captureFrame; DEBUG_ASSERT(this); diff --git a/host/platform/Linux/capture/pipewire/src/pipewire.c b/host/platform/Linux/capture/pipewire/src/pipewire.c index ee87da12..6509609a 100644 --- a/host/platform/Linux/capture/pipewire/src/pipewire.c +++ b/host/platform/Linux/capture/pipewire/src/pipewire.c @@ -406,7 +406,7 @@ static void pipewire_free(void) static CaptureResult pipewire_capture( unsigned frameBufferIndex, - FrameBuffer * frame) + KVMFRFrameBuffer * frame) { int result; @@ -463,10 +463,10 @@ static CaptureResult pipewire_waitFrame( } static CaptureResult pipewire_getFrame( - unsigned frameBufferIndex, - FrameBuffer * frame, - const size_t maxFrameSize, - CaptureFrame * captureFrame) + unsigned frameBufferIndex, + KVMFRFrameBuffer * frame, + const size_t maxFrameSize, + CaptureFrame * captureFrame) { (void)captureFrame; if (this->stop || !this->frameData) diff --git a/host/platform/Windows/capture/D12/d12.c b/host/platform/Windows/capture/D12/d12.c index fd462bdd..7cc4e7e3 100644 --- a/host/platform/Windows/capture/D12/d12.c +++ b/host/platform/Windows/capture/D12/d12.c @@ -104,13 +104,13 @@ struct D12Interface struct { // the size of the frame buffer - unsigned size; + unsigned size; // the frame buffer it itself - FrameBuffer * frameBuffer; + KVMFRFrameBuffer * frameBuffer; // the resource backed by the framebuffer - ID3D12Resource ** resource; + ID3D12Resource ** resource; // the mapped resource if indirectCopy is in use - void * map; + void * map; } frameBuffers[0]; }; @@ -184,10 +184,10 @@ static bool d12_enumerateDevices( static bool d12_heapTest(ID3D12Device3 * device, ID3D12Heap * heap); static ID3D12Resource * d12_frameBufferToResource( - unsigned frameBufferIndex, - FrameBuffer * frameBuffer, - unsigned size, - void ** map); + unsigned frameBufferIndex, + KVMFRFrameBuffer * frameBuffer, + unsigned size, + void ** map); static bool d12_copyTimingInit( ID3D12Device3 * device, ID3D12CommandQueue * queue); @@ -778,7 +778,7 @@ static void d12_free(void) } static CaptureResult d12_capture( - unsigned frameBufferIndex, FrameBuffer * frameBuffer) + unsigned frameBufferIndex, KVMFRFrameBuffer * frameBuffer) { DEBUG_TRACE("d12_backendCapture"); return d12_backendCapture(this->backend, frameBufferIndex); @@ -958,11 +958,11 @@ static CaptureResult d12_waitFrame(unsigned frameBufferIndex, { // create a clean list of rects - FrameDamageRect allRects[D12_MAX_DIRTY_RECTS]; - unsigned count = 0; + KVMFRFrameDamageRect allRects[D12_MAX_DIRTY_RECTS]; + unsigned count = 0; for(const RECT * rect = desc.dirtyRects; rect < desc.dirtyRects + desc.nbDirtyRects; ++rect) - allRects[count++] = (FrameDamageRect){ + allRects[count++] = (KVMFRFrameDamageRect){ .x = rect->left, .y = rect->top, .width = (rect->right - rect->left), @@ -993,10 +993,10 @@ exit: } static CaptureResult d12_getFrame( - unsigned frameBufferIndex, - FrameBuffer * frameBuffer, - const size_t maxFrameSize, - CaptureFrame * captureFrame) + unsigned frameBufferIndex, + KVMFRFrameBuffer * frameBuffer, + const size_t maxFrameSize, + CaptureFrame * captureFrame) { const uint64_t postProcessStart = nanotime(); captureFrame->postProcessTime = 0; @@ -1006,8 +1006,8 @@ static CaptureResult d12_getFrame( CaptureResult result = CAPTURE_RESULT_ERROR; comRef_scopePush(3); - D12FrameDesc desc; - FrameDamageRect allRects[D12_MAX_DIRTY_RECTS * 2]; + D12FrameDesc desc; + KVMFRFrameDamageRect allRects[D12_MAX_DIRTY_RECTS * 2]; comRef_defineLocal(ID3D12Resource, src); DEBUG_TRACE("d12_backendFetch"); @@ -1142,7 +1142,7 @@ static CaptureResult d12_getFrame( * be redrawn by the client, such as under the cursor */ for(const RECT * rect = this->dirtyRects; rect < this->dirtyRects + this->nbDirtyRects; ++rect) - allRects[rectCount++] = (FrameDamageRect){ + allRects[rectCount++] = (KVMFRFrameDamageRect){ .x = rect->left, .y = rect->top, .width = rect->right - rect->left, @@ -1152,7 +1152,7 @@ static CaptureResult d12_getFrame( /* add the new dirtyRects to the array */ for(const RECT * rect = desc.dirtyRects; rect < desc.dirtyRects + desc.nbDirtyRects; ++rect) - allRects[rectCount++] = (FrameDamageRect){ + allRects[rectCount++] = (KVMFRFrameDamageRect){ .x = rect->left, .y = rect->top, .width = rect->right - rect->left, @@ -1163,7 +1163,8 @@ static CaptureResult d12_getFrame( rectCount = rectsMergeOverlapping(allRects, rectCount); /* copy all the rects */ - for(FrameDamageRect * rect = allRects; rect < allRects + rectCount; ++rect) + for(KVMFRFrameDamageRect * rect = allRects; + rect < allRects + rectCount; ++rect) { D3D12_BOX box = { @@ -1476,7 +1477,7 @@ exit: } static ID3D12Resource * d12_frameBufferToResource(unsigned frameBufferIndex, - FrameBuffer * frameBuffer, unsigned size, void ** map) + KVMFRFrameBuffer * frameBuffer, unsigned size, void ** map) { ID3D12Resource * result = NULL; comRef_scopePush(10); diff --git a/host/platform/Windows/capture/DXGI/src/backend.h b/host/platform/Windows/capture/DXGI/src/backend.h index 7d89f033..8fff21e7 100644 --- a/host/platform/Windows/capture/DXGI/src/backend.h +++ b/host/platform/Windows/capture/DXGI/src/backend.h @@ -57,14 +57,14 @@ struct DXGICopyBackend bool (*preCopy)(ID3D11Texture2D * src, unsigned textureIndex, unsigned frameBufferIndex, - FrameBuffer * frameBuffer); + KVMFRFrameBuffer * frameBuffer); // called to copy the full frame bool (*copyFull)(ID3D11Texture2D * src, unsigned textureIndex); // called for each damage rect that needs to be copied bool (*copyRect)(ID3D11Texture2D * src, unsigned textureIndex, - FrameDamageRect * rect); + KVMFRFrameDamageRect * rect); // called just after the copy has finished bool (*postCopy)(ID3D11Texture2D * src, unsigned textureIndex); @@ -72,8 +72,8 @@ struct DXGICopyBackend // maps the copied frame into memory CaptureResult (*mapTexture)(unsigned textureIndex, void ** map); - // [optional] backend specific write into the FrameBuffer - CaptureResult (*writeFrame)(int textureIndex, FrameBuffer * frame); + // [optional] backend specific write into the KVMFRFrameBuffer + CaptureResult (*writeFrame)(int textureIndex, KVMFRFrameBuffer * frame); // unmaps the copied frame from memory void (*unmapTexture)(unsigned textureIndex); diff --git a/host/platform/Windows/capture/DXGI/src/d3d11.c b/host/platform/Windows/capture/DXGI/src/d3d11.c index 5a7f4fdc..465839bc 100644 --- a/host/platform/Windows/capture/DXGI/src/d3d11.c +++ b/host/platform/Windows/capture/DXGI/src/d3d11.c @@ -147,7 +147,7 @@ static bool d3d11_preCopy( ID3D11Texture2D * src, unsigned textureIndex, unsigned frameBufferIndex, - FrameBuffer * frameBuffer) + KVMFRFrameBuffer * frameBuffer) { dxgi_contextLock(); this->texture[textureIndex].copyTime = microtime(); @@ -166,7 +166,7 @@ static bool d3d11_copyFull(ID3D11Texture2D * src, unsigned textureIndex) static bool d3d11_copyRect(ID3D11Texture2D * src, unsigned textureIndex, - FrameDamageRect * rect) + KVMFRFrameDamageRect * rect) { ID3D11Texture2D * dst = *this->texture[textureIndex].tex; diff --git a/host/platform/Windows/capture/DXGI/src/dxgi.c b/host/platform/Windows/capture/DXGI/src/dxgi.c index 17da1e05..533d21c6 100644 --- a/host/platform/Windows/capture/DXGI/src/dxgi.c +++ b/host/platform/Windows/capture/DXGI/src/dxgi.c @@ -29,8 +29,8 @@ #include "common/event.h" #include "common/rects.h" #include "common/runningavg.h" -#include "common/KVMFR.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/vector.h" #include @@ -90,9 +90,9 @@ typedef struct Texture volatile enum TextureState state; void * map; uint32_t damageRectsCount; - FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS]; + KVMFRFrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS]; int texDamageCount; - FrameDamageRect texDamageRects[KVMFR_MAX_DAMAGE_RECTS]; + KVMFRFrameDamageRect texDamageRects[KVMFR_MAX_DAMAGE_RECTS]; // post processing Vector pp; @@ -101,8 +101,8 @@ Texture; typedef struct FrameDamage { - int count; - FrameDamageRect rects[KVMFR_MAX_DAMAGE_RECTS]; + int count; + KVMFRFrameDamageRect rects[KVMFR_MAX_DAMAGE_RECTS]; } FrameDamage; @@ -1022,9 +1022,9 @@ static CaptureResult dxgi_hResultToCaptureResult(const HRESULT status) } } -static void rectToFrameDamageRect(RECT * src, FrameDamageRect * dst) +static void rectToFrameDamageRect(RECT * src, KVMFRFrameDamageRect * dst) { - *dst = (FrameDamageRect) + *dst = (KVMFRFrameDamageRect) { .x = floor((double)src->left * this->scaleX), .y = floor((double)src->top * this->scaleY), @@ -1068,7 +1068,7 @@ static void computeFrameDamage(Texture * tex) const int moveRectsCount = moveRectsBufferSizeRequired / sizeof(*moveRects); - FrameDamageRect * texDamageRect = tex->damageRects; + KVMFRFrameDamageRect * texDamageRect = tex->damageRects; for (RECT *dirtyRect = dirtyRects; dirtyRect < dirtyRects + dirtyRectsCount; dirtyRect++) @@ -1085,7 +1085,7 @@ static void computeFrameDamage(Texture * tex) moveRect->SourcePoint.y == moveRect->DestinationRect.top) continue; - *texDamageRect++ = (FrameDamageRect) + *texDamageRect++ = (KVMFRFrameDamageRect) { .x = floor((double)moveRect->SourcePoint.x * this->scaleX), .y = floor((double)moveRect->SourcePoint.y * this->scaleY), @@ -1110,14 +1110,14 @@ static void computeTexDamage(Texture * tex) else { memcpy(tex->texDamageRects + tex->texDamageCount, tex->damageRects, - tex->damageRectsCount * sizeof(FrameDamageRect)); + tex->damageRectsCount * sizeof(KVMFRFrameDamageRect)); tex->texDamageCount += tex->damageRectsCount; tex->texDamageCount = rectsMergeOverlapping(tex->texDamageRects, tex->texDamageCount); } } static CaptureResult dxgi_capture(unsigned frameBufferIndex, - FrameBuffer * frameBuffer) + KVMFRFrameBuffer * frameBuffer) { DEBUG_ASSERT(this); DEBUG_ASSERT(this->initialized); @@ -1317,7 +1317,7 @@ static CaptureResult dxgi_capture(unsigned frameBufferIndex, { for (int i = 0; i < tex->texDamageCount; ++i) { - FrameDamageRect rect = tex->texDamageRects[i]; + KVMFRFrameDamageRect rect = tex->texDamageRects[i]; // correct the damage rect for BGR packed data if (this->outputFormat == CAPTURE_FMT_BGR_32) @@ -1505,10 +1505,10 @@ static CaptureResult dxgi_waitFrame(unsigned frameBufferIndex, } static CaptureResult dxgi_getFrame( - unsigned frameBufferIndex, - FrameBuffer * frame, - const size_t maxFrameSize, - CaptureFrame * captureFrame) + unsigned frameBufferIndex, + KVMFRFrameBuffer * frame, + const size_t maxFrameSize, + CaptureFrame * captureFrame) { (void)captureFrame; DEBUG_ASSERT(this); @@ -1550,12 +1550,13 @@ static CaptureResult dxgi_getFrame( if (this->outputFormat == CAPTURE_FMT_BGR_32) { - FrameDamageRect scaledDamageRects[damage->count]; - for (int i = 0; i < ARRAYSIZE(scaledDamageRects); i++) { - FrameDamageRect rect = damage->rects[i]; - int originalX = rect.x; - int scaledX = originalX * 3 / 4; - rect.x = scaledX; + KVMFRFrameDamageRect scaledDamageRects[damage->count]; + for (int i = 0; i < ARRAYSIZE(scaledDamageRects); i++) + { + KVMFRFrameDamageRect rect = damage->rects[i]; + int originalX = rect.x; + int scaledX = originalX * 3 / 4; + rect.x = scaledX; rect.width = (((originalX + rect.width) * 3 + 3) / 4) - scaledX; scaledDamageRects[i] = rect; diff --git a/host/platform/Windows/capture/NVFBC/src/nvfbc.c b/host/platform/Windows/capture/NVFBC/src/nvfbc.c index b6a74ba4..813f8570 100644 --- a/host/platform/Windows/capture/NVFBC/src/nvfbc.c +++ b/host/platform/Windows/capture/NVFBC/src/nvfbc.c @@ -30,8 +30,8 @@ #include "common/event.h" #include "common/rects.h" #include "common/thread.h" -#include "common/KVMFR.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/vector.h" #include #include @@ -456,7 +456,7 @@ static void nvfbc_free(void) } static CaptureResult nvfbc_capture(unsigned frameBufferIndex, - FrameBuffer * frameBuffer) + KVMFRFrameBuffer * frameBuffer) { // this is a bit of a hack as it causes this thread to block until the next // present keeping us locked with the refresh rate of the monitor being @@ -644,10 +644,10 @@ static void updateDamageRects(CaptureFrame * frame) int y1 = ds[c].y1 << this->diffShift; int x2 = min((ds[c].x2 + 1) << this->diffShift, this->grabWidth); int y2 = min((ds[c].y2 + 1) << this->diffShift, this->grabHeight); - frame->damageRects[rectId++] = (FrameDamageRect) { - .x = x1, - .y = y1, - .width = x2 - x1, + frame->damageRects[rectId++] = (KVMFRFrameDamageRect) { + .x = x1, + .y = y1, + .width = x2 - x1, .height = y2 - y1, }; } @@ -719,10 +719,10 @@ static CaptureResult nvfbc_waitFrame(unsigned frameBufferIndex, } static CaptureResult nvfbc_getFrame( - unsigned frameBufferIndex, - FrameBuffer * frame, - const size_t maxFrameSize, - CaptureFrame * captureFrame) + unsigned frameBufferIndex, + KVMFRFrameBuffer * frame, + const size_t maxFrameSize, + CaptureFrame * captureFrame) { (void)captureFrame; const unsigned int h = DIFF_MAP_DIM(this->grabHeight, this->diffShift); diff --git a/host/src/app.c b/host/src/app.c index 9f17c366..641435a5 100644 --- a/host/src/app.c +++ b/host/src/app.c @@ -25,8 +25,8 @@ #include "common/debug.h" #include "common/option.h" #include "common/locking.h" -#include "common/KVMFR.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/crash.h" #include "common/thread.h" #include "common/ivshmem.h" @@ -97,13 +97,13 @@ struct app unsigned int pointerIndex; unsigned int pointerShapeIndex; - unsigned alignSize; - size_t frameMemorySize; - size_t maxFrameSize; - PLGMPHostQueue frameQueue; - PLGMPMemory frameMemory[LGMP_Q_FRAME_LEN]; - KVMFRFrame * frame [LGMP_Q_FRAME_LEN]; - FrameBuffer * frameBuffer[LGMP_Q_FRAME_LEN]; + unsigned alignSize; + size_t frameMemorySize; + size_t maxFrameSize; + PLGMPHostQueue frameQueue; + PLGMPMemory frameMemory[LGMP_Q_FRAME_LEN]; + KVMFRFrame * frame [LGMP_Q_FRAME_LEN]; + KVMFRFrameBuffer * frameBuffer[LGMP_Q_FRAME_LEN]; unsigned int captureIndex; unsigned int readIndex; @@ -435,7 +435,7 @@ static bool sendFrame(CaptureResult result, bool * restart) } fi->damageRectsCount = frame.damageRectsCount; memcpy(fi->damageRects, frame.damageRects, - frame.damageRectsCount * sizeof(FrameDamageRect)); + frame.damageRectsCount * sizeof(KVMFRFrameDamageRect)); app.frameValid = true; @@ -879,7 +879,8 @@ static bool lgmpSetup(struct IVSHMEM * shmDev) const size_t frameMemoryAvail = lgmpHostMemAvail(app.lgmp); if (!app.alignSize || - (size_t)app.alignSize < sizeof(KVMFRFrame) + sizeof(FrameBuffer) || + (size_t)app.alignSize < + sizeof(KVMFRFrame) + sizeof(KVMFRFrameBuffer) || (app.alignSize & (app.alignSize - 1)) || frameMemoryAvail <= app.alignSize - 1) { @@ -888,8 +889,8 @@ static bool lgmpSetup(struct IVSHMEM * shmDev) } /* Reserve the worst-case alignment padding once, then round each message - * down so all frame allocations are guaranteed to fit. The FrameBuffer data - * begins one alignment unit into each message. */ + * down so all frame allocations are guaranteed to fit. The KVMFRFrameBuffer + * data begins one alignment unit into each message. */ app.frameMemorySize = (frameMemoryAvail - (app.alignSize - 1)) / LGMP_Q_FRAME_LEN; app.frameMemorySize &= ~((size_t)app.alignSize - 1); @@ -918,9 +919,10 @@ static bool lgmpSetup(struct IVSHMEM * shmDev) /* put the framebuffer on the border of the next page, this is to allow for aligned DMA transfers by the receiver */ - const unsigned alignOffset = app.alignSize - sizeof(FrameBuffer); + const unsigned alignOffset = app.alignSize - sizeof(KVMFRFrameBuffer); app.frame[i]->offset = alignOffset; - app.frameBuffer[i] = (FrameBuffer *)(((uint8_t*)app.frame[i]) + alignOffset); + app.frameBuffer[i] = + (KVMFRFrameBuffer *)(((uint8_t *)app.frame[i]) + alignOffset); } atomic_store(&app.sdrWhiteLevel, diff --git a/idd/LGCommon/ClipboardRing.h b/idd/LGCommon/ClipboardRing.h index 63820161..a9c9a5f5 100644 --- a/idd/LGCommon/ClipboardRing.h +++ b/idd/LGCommon/ClipboardRing.h @@ -20,7 +20,7 @@ #pragma once -#include "common/KVMFRClipboard.h" +#include #include #include diff --git a/idd/LGCommon/InputPipeProtocol.h b/idd/LGCommon/InputPipeProtocol.h index 0aba2bdd..2cea47f3 100644 --- a/idd/LGCommon/InputPipeProtocol.h +++ b/idd/LGCommon/InputPipeProtocol.h @@ -20,7 +20,7 @@ #pragma once -#include "common/KVMFRInput.h" +#include #include #include diff --git a/idd/LGCommon/LGCommon.vcxproj b/idd/LGCommon/LGCommon.vcxproj index 047d020b..233d07bb 100644 --- a/idd/LGCommon/LGCommon.vcxproj +++ b/idd/LGCommon/LGCommon.vcxproj @@ -61,7 +61,7 @@ MultiThreaded UMDF_USING_NTSTATUS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions) /EHsc /D_ATL_NO_WIN_SUPPORT %(AdditionalOptions) - $(ProjectDir);$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(SolutionDir)..\repos\LGProtocol\include;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) diff --git a/idd/LGIdd/LGIdd.vcxproj b/idd/LGIdd/LGIdd.vcxproj index 01d80236..ab9cd486 100644 --- a/idd/LGIdd/LGIdd.vcxproj +++ b/idd/LGIdd/LGIdd.vcxproj @@ -291,7 +291,7 @@ true trace.h /EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions) - $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\repos\LGProtocol\include;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) %(AdditionalDependencies);OneCoreUAP.lib;avrt.lib;bcrypt.lib;d3d12.lib;d3dcompiler.lib @@ -306,7 +306,7 @@ true trace.h /EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions) - $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\repos\LGProtocol\include;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) %(AdditionalDependencies);OneCoreUAP.lib;avrt.lib;bcrypt.lib;d3d12.lib;d3dcompiler.lib @@ -321,7 +321,7 @@ true trace.h /EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions) - $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\repos\LGProtocol\include;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) %(AdditionalDependencies);OneCoreUAP.lib;avrt.lib;bcrypt.lib;d3d12.lib;d3dcompiler.lib @@ -336,7 +336,7 @@ true trace.h /EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions) - $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) + $(ProjectDir);$(SolutionDir)LGCommon;$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\repos\LGProtocol\include;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories) %(AdditionalDependencies);OneCoreUAP.lib;avrt.lib;bcrypt.lib;d3d12.lib;d3dcompiler.lib diff --git a/idd/LGIdd/postprocess/D12FrameFormat.cpp b/idd/LGIdd/postprocess/D12FrameFormat.cpp index 28695242..4f5811b1 100644 --- a/idd/LGIdd/postprocess/D12FrameFormat.cpp +++ b/idd/LGIdd/postprocess/D12FrameFormat.cpp @@ -87,12 +87,12 @@ DXGI_FORMAT D12::Dxgi(FramePixel pixel) return DXGI_FORMAT_UNKNOWN; } -FrameType D12::Type(FramePixel pixel) +KVMFRFrameType D12::Type(FramePixel pixel) { return Type(Dxgi(pixel)); } -FrameType D12::Type(DXGI_FORMAT format) +KVMFRFrameType D12::Type(DXGI_FORMAT format) { switch (format) { diff --git a/idd/LGIdd/postprocess/D12FrameFormat.h b/idd/LGIdd/postprocess/D12FrameFormat.h index 4e7c2303..5f15dbac 100644 --- a/idd/LGIdd/postprocess/D12FrameFormat.h +++ b/idd/LGIdd/postprocess/D12FrameFormat.h @@ -48,7 +48,7 @@ struct D12FrameFormat unsigned pitch = 0; unsigned width = 0; unsigned height = 0; - FrameType format = FRAME_TYPE_INVALID; + KVMFRFrameType format = FRAME_TYPE_INVALID; bool hdr = false; bool hdrPQ = false; bool hdrMetadata = false; @@ -88,8 +88,8 @@ namespace D12 }; DXGI_FORMAT Dxgi(FramePixel pixel); - FrameType Type(DXGI_FORMAT format); - FrameType Type(FramePixel pixel); + KVMFRFrameType Type(DXGI_FORMAT format); + KVMFRFrameType Type(FramePixel pixel); bool Profile(const D12FrameFormat& format, FrameStorage storage, FrameProfile& profile); diff --git a/idd/LGIdd/postprocess/effect/CColorTransformEffect.cpp b/idd/LGIdd/postprocess/effect/CColorTransformEffect.cpp index 3aa47b42..084c634e 100644 --- a/idd/LGIdd/postprocess/effect/CColorTransformEffect.cpp +++ b/idd/LGIdd/postprocess/effect/CColorTransformEffect.cpp @@ -191,8 +191,8 @@ PostProcessStatus CColorTransformEffect::Set( if (!matrixEnabled && !lutEnabled) return PostProcessStatus::BYPASS_EFFECT; - DXGI_FORMAT dstFormat; - FrameType frameType; + DXGI_FORMAT dstFormat; + KVMFRFrameType frameType; switch (src.desc.Format) { case DXGI_FORMAT_B8G8R8A8_UNORM: diff --git a/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp b/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp index cc51286f..90804bc2 100644 --- a/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp +++ b/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp @@ -56,7 +56,7 @@ struct CRGB24Effect::State DXGI_FORMAT resourceFormat = DXGI_FORMAT_UNKNOWN; unsigned width = 0; unsigned height = 0; - FrameType format = FRAME_TYPE_INVALID; + KVMFRFrameType format = FRAME_TYPE_INVALID; bool hdr = false; bool hdrPQ = false; std::shared_ptr colorTransform; diff --git a/idd/LGIdd/transport/CFrameHub.h b/idd/LGIdd/transport/CFrameHub.h index 70781153..41fa9364 100644 --- a/idd/LGIdd/transport/CFrameHub.h +++ b/idd/LGIdd/transport/CFrameHub.h @@ -49,86 +49,86 @@ private: bool valid = false; bool busy = false; - FrameToken token = {}; - CFrameScheduler::Schedule schedule = {}; - uint64_t content = 0; - uint64_t captureTime = 0; + FrameToken token = {}; + CFrameScheduler::Schedule schedule = {}; + uint64_t content = 0; + uint64_t captureTime = 0; uint64_t postProcessTime = 0; - uint64_t copyTime = 0; - uint64_t readyTime = 0; - uint64_t holdTime = 0; - uint64_t filledAt = 0; - uint64_t workStart = 0; - unsigned pitch = 0; - unsigned width = 0; - unsigned height = 0; - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - FrameType frameType = FRAME_TYPE_INVALID; - Phase phase = IDLE; - FrameDone pendingResult = FrameDone::FAILED; - uint64_t pendingReadyAt = 0; - bool timingValid = false; - bool resultPending = false; - bool callActive = false; + uint64_t copyTime = 0; + uint64_t readyTime = 0; + uint64_t holdTime = 0; + uint64_t filledAt = 0; + uint64_t workStart = 0; + unsigned pitch = 0; + unsigned width = 0; + unsigned height = 0; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + KVMFRFrameType frameType = FRAME_TYPE_INVALID; + Phase phase = IDLE; + FrameDone pendingResult = FrameDone::FAILED; + uint64_t pendingReadyAt = 0; + bool timingValid = false; + bool resultPending = false; + bool callActive = false; bool cancelRequested = false; }; - CSRWLock callLock; - CSRWLock laneLock; - IFrameSink * target = nullptr; - HANDLE drained = nullptr; - std::atomic outstanding = 0; - std::atomic_bool active = false; - std::atomic backend = 0; - std::atomic epoch = 0; - bool reserved = false; - bool primary = false; - bool needsFullCopy = true; - uint64_t lastContent = 0; - uint64_t lastTerminalContent = 0; - uint64_t blockedContent = 0; - size_t blockedFrameSize = 0; - bool blockedAllocation = false; - unsigned pitch = 0; - unsigned width = 0; - unsigned height = 0; - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - FrameType frameType = FRAME_TYPE_INVALID; - ResourceLane lanes[FRAME_SINK_BUFFERS] = {}; + CSRWLock callLock; + CSRWLock laneLock; + IFrameSink * target = nullptr; + HANDLE drained = nullptr; + std::atomic outstanding = 0; + std::atomic_bool active = false; + std::atomic backend = 0; + std::atomic epoch = 0; + bool reserved = false; + bool primary = false; + bool needsFullCopy = true; + uint64_t lastContent = 0; + uint64_t lastTerminalContent = 0; + uint64_t blockedContent = 0; + size_t blockedFrameSize = 0; + bool blockedAllocation = false; + unsigned pitch = 0; + unsigned width = 0; + unsigned height = 0; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + KVMFRFrameType frameType = FRAME_TYPE_INVALID; + ResourceLane lanes[FRAME_SINK_BUFFERS] = {}; }; struct BatchTarget { - Sink * sink = nullptr; - BackendId backend = 0; - uint32_t epoch = 0; - unsigned localSlot = 0; - unsigned resourceLane = 0; - CFrameScheduler::Schedule schedule = {}; - CFrameScheduler::Schedule deliverySchedule = {}; - uint64_t content = 0; - unsigned pitch = 0; - unsigned width = 0; - unsigned height = 0; - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - FrameType frameType = FRAME_TYPE_INVALID; - bool periodic = false; - bool published = false; - bool delivered = false; - bool submitted = false; - bool committed = false; - bool completionPending = false; - bool completionSucceeded = false; - bool releasePending = false; - uint64_t captureTime = 0; - uint64_t postProcessTime = 0; - uint64_t copyTime = 0; - uint64_t readyTime = 0; - uint64_t holdTime = 0; - uint64_t filledAt = 0; - uint64_t workStart = 0; - bool timingValid = false; - bool active = false; + Sink * sink = nullptr; + BackendId backend = 0; + uint32_t epoch = 0; + unsigned localSlot = 0; + unsigned resourceLane = 0; + CFrameScheduler::Schedule schedule = {}; + CFrameScheduler::Schedule deliverySchedule = {}; + uint64_t content = 0; + unsigned pitch = 0; + unsigned width = 0; + unsigned height = 0; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + KVMFRFrameType frameType = FRAME_TYPE_INVALID; + bool periodic = false; + bool published = false; + bool delivered = false; + bool submitted = false; + bool committed = false; + bool completionPending = false; + bool completionSucceeded = false; + bool releasePending = false; + uint64_t captureTime = 0; + uint64_t postProcessTime = 0; + uint64_t copyTime = 0; + uint64_t readyTime = 0; + uint64_t holdTime = 0; + uint64_t filledAt = 0; + uint64_t workStart = 0; + bool timingValid = false; + bool active = false; }; struct Batch diff --git a/idd/LGIdd/transport/IClipboardSource.h b/idd/LGIdd/transport/IClipboardSource.h index 7175f11b..533b58c1 100644 --- a/idd/LGIdd/transport/IClipboardSource.h +++ b/idd/LGIdd/transport/IClipboardSource.h @@ -21,7 +21,7 @@ #pragma once #include "CClipboardChannel.h" -#include "common/KVMFRClipboard.h" +#include #include diff --git a/idd/LGIdd/transport/lgmp/CIVSHMEM.h b/idd/LGIdd/transport/lgmp/CIVSHMEM.h index 95a46623..f42c928a 100644 --- a/idd/LGIdd/transport/lgmp/CIVSHMEM.h +++ b/idd/LGIdd/transport/lgmp/CIVSHMEM.h @@ -24,7 +24,7 @@ #include #include -#include "common/KVMFRRecovery.h" +#include class CIVSHMEM { diff --git a/idd/LGIdd/transport/lgmp/CLGMPClipboardFiles.h b/idd/LGIdd/transport/lgmp/CLGMPClipboardFiles.h index 41f4bb51..6ac38241 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPClipboardFiles.h +++ b/idd/LGIdd/transport/lgmp/CLGMPClipboardFiles.h @@ -20,7 +20,7 @@ #pragma once -#include "common/KVMFRClipboard.h" +#include #include diff --git a/idd/LGIdd/transport/lgmp/CLGMPClipboardTransport.h b/idd/LGIdd/transport/lgmp/CLGMPClipboardTransport.h index 347ddf9a..16515478 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPClipboardTransport.h +++ b/idd/LGIdd/transport/lgmp/CLGMPClipboardTransport.h @@ -24,8 +24,8 @@ #include "transport/IClipboardSource.h" #include "transport/lgmp/CLGMPClipboardFiles.h" -#include "common/KVMFRClipboard.h" -#include "common/LGMPConfig.h" +#include +#include #include diff --git a/idd/LGIdd/transport/lgmp/CLGMPControl.h b/idd/LGIdd/transport/lgmp/CLGMPControl.h index aec71511..d96a0c1b 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPControl.h +++ b/idd/LGIdd/transport/lgmp/CLGMPControl.h @@ -25,7 +25,7 @@ #include "transport/lgmp/CLGMPHost.h" #include "transport/IControlSink.h" -#include "common/KVMFR.h" +#include #include #include diff --git a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h index 7d7b7518..5f3dcf60 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h +++ b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h @@ -30,7 +30,7 @@ extern "C" { #include "lgmp/host.h" } -#include "common/KVMFR.h" +#include #include "capture/CFrameScheduler.h" #include "capture/FramePipeline.h" #include "transport/FrameCaps.h" @@ -117,13 +117,13 @@ private: KVMFRFrame * m_frame [LGMP_Q_FRAME_BUFFER_LEN] = {}; LGMPBuffer * m_frameBuffer[LGMP_Q_FRAME_BUFFER_LEN] = {}; - unsigned m_width = 0; - unsigned m_height = 0; - unsigned m_frameWidth = 0; - unsigned m_frameHeight = 0; - unsigned m_pitch = 0; - DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN; - FrameType m_frameType = FRAME_TYPE_INVALID; + unsigned m_width = 0; + unsigned m_height = 0; + unsigned m_frameWidth = 0; + unsigned m_frameHeight = 0; + unsigned m_pitch = 0; + DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN; + KVMFRFrameType m_frameType = FRAME_TYPE_INVALID; // Previous HDR metadata used to detect changes for formatVer bumps. uint16_t m_lastHDRDisplayPrimary[3][2] = {}; diff --git a/idd/LGIdd/transport/lgmp/CLGMPHost.cpp b/idd/LGIdd/transport/lgmp/CLGMPHost.cpp index 92027368..e4f7e971 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPHost.cpp +++ b/idd/LGIdd/transport/lgmp/CLGMPHost.cpp @@ -25,7 +25,7 @@ #include "CDebug.h" #include "VersionInfo.h" -#include "common/KVMFR.h" +#include #include #include diff --git a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp index ce106ed9..fb4f78fa 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp +++ b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp @@ -31,8 +31,8 @@ #include "CSRWLock.h" #include "Seq.h" -#include "common/KVMFRInput.h" -#include "common/LGMPConfig.h" +#include +#include #include #include diff --git a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h index 2ad2113b..5ccb7526 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h +++ b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h @@ -23,8 +23,8 @@ #include "Atomic.h" #include "CSRWLock.h" #include "transport/IInputSource.h" -#include "common/KVMFRInput.h" -#include "common/LGMPConfig.h" +#include +#include #include diff --git a/idd/LGIdd/transport/lgmp/CLGMPTransport.cpp b/idd/LGIdd/transport/lgmp/CLGMPTransport.cpp index cef0e070..00accb3f 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPTransport.cpp +++ b/idd/LGIdd/transport/lgmp/CLGMPTransport.cpp @@ -22,8 +22,8 @@ #include "Atomic.h" #include "CDebug.h" -#include "common/KVMFR.h" -#include "common/KVMFRRecovery.h" +#include +#include static bool TranslateFrameScheduleFlags( uint32_t source, uint32_t& destination) diff --git a/idd/LGIdd/transport/lgmp/CRecovery.cpp b/idd/LGIdd/transport/lgmp/CRecovery.cpp index e9f14fde..79efcf89 100644 --- a/idd/LGIdd/transport/lgmp/CRecovery.cpp +++ b/idd/LGIdd/transport/lgmp/CRecovery.cpp @@ -26,8 +26,8 @@ #include "CDebug.h" #include "VersionInfo.h" -#include "common/KVMFR.h" -#include "common/KVMFRRecovery.h" +#include +#include #include diff --git a/idd/LGIddHelper/CClipboardFiles.h b/idd/LGIddHelper/CClipboardFiles.h index 4dea7fbb..5df2226e 100644 --- a/idd/LGIddHelper/CClipboardFiles.h +++ b/idd/LGIddHelper/CClipboardFiles.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/idd/LGIddHelper/LGIddHelper.vcxproj b/idd/LGIddHelper/LGIddHelper.vcxproj index d97f3a5e..976cf06b 100644 --- a/idd/LGIddHelper/LGIddHelper.vcxproj +++ b/idd/LGIddHelper/LGIddHelper.vcxproj @@ -77,7 +77,7 @@ true WIN32;_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) true - $(SolutionDir)LGCommon;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) + $(SolutionDir)LGCommon;$(SolutionDir)..\repos\LGProtocol\include;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) stdcpp17 @@ -103,7 +103,7 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd true WIN32;NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) true - $(SolutionDir)LGCommon;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) + $(SolutionDir)LGCommon;$(SolutionDir)..\repos\LGProtocol\include;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) stdcpp17 @@ -131,7 +131,7 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd true stdcpp17 Default - $(SolutionDir)LGCommon;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) + $(SolutionDir)LGCommon;$(SolutionDir)..\repos\LGProtocol\include;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) Windows @@ -159,7 +159,7 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd true stdcpp17 Default - $(SolutionDir)LGCommon;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) + $(SolutionDir)LGCommon;$(SolutionDir)..\repos\LGProtocol\include;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories) Windows diff --git a/idd/LGInput/LGInput.vcxproj b/idd/LGInput/LGInput.vcxproj index d9c98222..7635b0c4 100644 --- a/idd/LGInput/LGInput.vcxproj +++ b/idd/LGInput/LGInput.vcxproj @@ -81,7 +81,7 @@ true Trace.h /EHsc /D_ATL_NO_WIN_SUPPORT %(AdditionalOptions) - $(ProjectDir)..\LGCommon;$(ProjectDir)..\LGIdd;$(ProjectDir)..\..\common\include;$(DDK_INC_PATH);%(AdditionalIncludeDirectories) + $(ProjectDir)..\LGCommon;$(ProjectDir)..\LGIdd;$(ProjectDir)..\..\repos\LGProtocol\include;$(ProjectDir)..\..\common\include;$(DDK_INC_PATH);%(AdditionalIncludeDirectories) %(AdditionalDependencies);OneCoreUAP.lib diff --git a/obs/CMakeLists.txt b/obs/CMakeLists.txt index 02c0e9d8..c52ddb81 100644 --- a/obs/CMakeLists.txt +++ b/obs/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(looking-glass-obs C) +project(looking-glass-obs C CXX) get_filename_component(PROJECT_TOP "${PROJECT_SOURCE_DIR}/.." ABSOLUTE) list(APPEND CMAKE_MODULE_PATH "${PROJECT_TOP}/cmake/" "${PROJECT_SOURCE_DIR}/cmake/") diff --git a/obs/frame_scheduler.c b/obs/frame_scheduler.c index 59a295b6..c541c3f3 100644 --- a/obs/frame_scheduler.c +++ b/obs/frame_scheduler.c @@ -20,7 +20,7 @@ #include "frame_scheduler.h" -#include +#include #include diff --git a/obs/lg.c b/obs/lg.c index 1a291047..7050e6dd 100644 --- a/obs/lg.c +++ b/obs/lg.c @@ -29,8 +29,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -97,7 +97,7 @@ typedef struct bool unpack; uint32_t drmFormat; struct vec2 screenScale; - FrameType type; + KVMFRFrameType type; int bpp; struct IVSHMEM shmDev; PLGMPClient lgmp; @@ -709,8 +709,8 @@ static void * frameThread(void * data) (const KVMFRFrame *)frameMessage.msg.mem; if (frameMessage.owner) { - const FrameBuffer * fb = - (const FrameBuffer *)((const uint8_t *)frame + frame->offset); + const KVMFRFrameBuffer * fb = + (const KVMFRFrameBuffer *)((const uint8_t *)frame + frame->offset); if (framebuffer_wait( fb, (size_t)frame->dataHeight * frame->pitch)) { @@ -1024,7 +1024,8 @@ static DMAFrameInfo * dmabufOpenDMAFrameInfo(LGPlugin * this, LGMPMessage * msg, if (fi->fd == -1) { const uintptr_t pos = (uintptr_t) msg->mem - (uintptr_t) this->shmDev.mem; - const uintptr_t offset = (uintptr_t) frame->offset + sizeof(FrameBuffer); + const uintptr_t offset = + (uintptr_t)frame->offset + sizeof(KVMFRFrameBuffer); fi->dataSize = dataSize; fi->fd = ivshmemGetDMABuf(&this->shmDev, pos + offset, dataSize); @@ -1599,8 +1600,8 @@ static void lgVideoTick(void * data, float seconds) return; } - const FrameBuffer * fb = - (const FrameBuffer *)((const uint8_t *)frame + frame->offset); + const KVMFRFrameBuffer * fb = + (const KVMFRFrameBuffer *)((const uint8_t *)frame + frame->offset); bool frameComplete = false; if (frameMessage.owner) { diff --git a/profile/client/CMakeLists.txt b/profile/client/CMakeLists.txt index 9ae4d9e6..bdabfbb0 100644 --- a/profile/client/CMakeLists.txt +++ b/profile/client/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(profiler-client C) +project(profiler-client C CXX) get_filename_component(PROJECT_TOP "${PROJECT_SOURCE_DIR}/../.." ABSOLUTE) list(APPEND CMAKE_MODULE_PATH "${PROJECT_TOP}/cmake/" "${PROJECT_SOURCE_DIR}/cmake/") diff --git a/profile/client/src/main.c b/profile/client/src/main.c index dfcf5f01..0cd7ee39 100644 --- a/profile/client/src/main.c +++ b/profile/client/src/main.c @@ -21,8 +21,8 @@ #include "common/debug.h" #include "common/option.h" #include "common/crash.h" -#include "common/KVMFR.h" -#include "common/LGMPConfig.h" +#include +#include #include "common/locking.h" #include "common/stringutils.h" #include "common/ivshmem.h" diff --git a/repos/LGProtocol b/repos/LGProtocol new file mode 160000 index 00000000..62b52724 --- /dev/null +++ b/repos/LGProtocol @@ -0,0 +1 @@ +Subproject commit 62b52724b63b6e179b8fb7e0c7c03e9a8b4e1636