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