[common/client] ivshmem: add portable external frames

This commit is contained in:
Geoffrey McRae
2026-09-12 09:49:24 +10:00
parent 6d367d4ab2
commit 382f35e503
28 changed files with 946 additions and 227 deletions

View File

@@ -0,0 +1,88 @@
/**
* 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_CLIENT_EXTERNAL_FRAME_
#define _H_LG_CLIENT_EXTERNAL_FRAME_
#include <stdbool.h>
#include <stddef.h>
typedef enum LG_ExternalFrameType
{
LG_EXTERNAL_FRAME_INVALID = 0,
LG_EXTERNAL_FRAME_DMABUF = 1,
}
LG_ExternalFrameType;
typedef struct LG_ExternalFrame LG_ExternalFrame;
/*
* A NULL pointer means there is no external resource. External frames own
* their native resource. Their address is a stable cache identity: a new
* native export must use a new object. Query results are immutable, borrowed,
* and remain valid while any reference to the object is held. Consumers must
* never close or otherwise release a queried resource.
*
* LG_EXTERNAL_FRAME_DMABUF queries return one native file descriptor in an
* int-sized result buffer.
*/
typedef struct LG_ExternalFrameOps
{
LG_ExternalFrameType type;
void (*retain )(LG_ExternalFrame * frame);
void (*release)(LG_ExternalFrame * frame);
bool (*query )(const LG_ExternalFrame * frame, void * result,
size_t resultSize);
}
LG_ExternalFrameOps;
struct LG_ExternalFrame
{
const LG_ExternalFrameOps * ops;
};
static inline LG_ExternalFrameType lgExternalFrameType(
const LG_ExternalFrame * frame)
{
return frame && frame->ops ? frame->ops->type : LG_EXTERNAL_FRAME_INVALID;
}
static inline LG_ExternalFrame * lgExternalFrameRetain(
LG_ExternalFrame * frame)
{
if (frame)
frame->ops->retain(frame);
return frame;
}
static inline void lgExternalFrameRelease(LG_ExternalFrame * frame)
{
if (frame)
frame->ops->release(frame);
}
static inline bool lgExternalFrameQuery(const LG_ExternalFrame * frame,
LG_ExternalFrameType type, void * result, size_t resultSize)
{
return frame && frame->ops && frame->ops->type == type &&
frame->ops->query(frame, result, resultSize);
}
#endif