mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 05:53:40 +00:00
[client] added initial framework for dma buffer support
This commit is contained in:
parent
5522e93fb9
commit
0bf73d862d
@ -51,6 +51,12 @@ typedef struct LG_RendererParams
|
||||
}
|
||||
LG_RendererParams;
|
||||
|
||||
typedef enum LG_RendererSupport
|
||||
{
|
||||
LG_SUPPORTS_DMABUF
|
||||
}
|
||||
LG_RendererSupport;
|
||||
|
||||
typedef struct LG_RendererFormat
|
||||
{
|
||||
FrameType type; // frame type
|
||||
@ -89,12 +95,13 @@ typedef void (* LG_RendererSetup)();
|
||||
typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params);
|
||||
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
||||
typedef void (* LG_RendererDeInitialize )(void * opaque);
|
||||
typedef bool (* LG_RendererSupports )(void * opaque, LG_RendererSupport support);
|
||||
typedef void (* LG_RendererOnRestart )(void * opaque);
|
||||
typedef void (* LG_RendererOnResize )(void * opaque, const int width, const int height, const LG_RendererRect destRect);
|
||||
typedef bool (* LG_RendererOnMouseShape )(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data);
|
||||
typedef bool (* LG_RendererOnMouseEvent )(void * opaque, const bool visible , const int x, const int y);
|
||||
typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format);
|
||||
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame);
|
||||
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame, int dmaFD);
|
||||
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
||||
typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window);
|
||||
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
|
||||
@ -107,6 +114,7 @@ typedef struct LG_Renderer
|
||||
LG_RendererCreate create;
|
||||
LG_RendererInitialize initialize;
|
||||
LG_RendererDeInitialize deinitialize;
|
||||
LG_RendererSupports supports;
|
||||
LG_RendererOnRestart on_restart;
|
||||
LG_RendererOnResize on_resize;
|
||||
LG_RendererOnMouseShape on_mouse_shape;
|
||||
|
@ -338,7 +338,7 @@ bool egl_on_frame_format(void * opaque, const LG_RendererFormat format)
|
||||
return egl_desktop_setup(this->desktop, format);
|
||||
}
|
||||
|
||||
bool egl_on_frame(void * opaque, const FrameBuffer * frame)
|
||||
bool egl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
|
||||
|
@ -386,7 +386,7 @@ bool opengl_on_frame_format(void * opaque, const LG_RendererFormat format)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool opengl_on_frame(void * opaque, const FrameBuffer * frame)
|
||||
bool opengl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd)
|
||||
{
|
||||
struct Inst * this = (struct Inst *)opaque;
|
||||
|
||||
|
@ -358,13 +358,29 @@ static int cursorThread(void * unused)
|
||||
|
||||
static int frameThread(void * unused)
|
||||
{
|
||||
struct DMAFrameInfo
|
||||
{
|
||||
KVMFRFrame * frame;
|
||||
size_t dataSize;
|
||||
int fd;
|
||||
};
|
||||
|
||||
LGMP_STATUS status;
|
||||
PLGMPClientQueue queue;
|
||||
|
||||
uint32_t formatVer = 0;
|
||||
bool formatValid = false;
|
||||
size_t dataSize;
|
||||
LG_RendererFormat lgrFormat;
|
||||
|
||||
//FIXME: Should use LGMP_Q_FRAME_LEN
|
||||
struct DMAFrameInfo dmaInfo[2] = {0};
|
||||
const bool useDMA = ivshmemHasDMA(&state.shm) && state.lgr->supports &&
|
||||
state.lgr->supports(state.lgrData, LG_SUPPORTS_DMABUF);
|
||||
|
||||
if (useDMA)
|
||||
DEBUG_INFO("Using DMA buffer support");
|
||||
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
|
||||
lgWaitEvent(e_startup, TIMEOUT_INFINITE);
|
||||
if (state.state != APP_STATE_RUNNING)
|
||||
@ -409,7 +425,8 @@ static int frameThread(void * unused)
|
||||
break;
|
||||
}
|
||||
|
||||
KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
|
||||
KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
|
||||
struct DMAFrameInfo *dma = NULL;
|
||||
|
||||
if (!formatValid || frame->formatVer != formatVer)
|
||||
{
|
||||
@ -420,8 +437,7 @@ static int frameThread(void * unused)
|
||||
lgrFormat.stride = frame->stride;
|
||||
lgrFormat.pitch = frame->pitch;
|
||||
|
||||
size_t dataSize;
|
||||
bool error = false;
|
||||
bool error = false;
|
||||
switch(frame->type)
|
||||
{
|
||||
case FRAME_TYPE_RGBA:
|
||||
@ -471,6 +487,54 @@ static int frameThread(void * unused)
|
||||
}
|
||||
}
|
||||
|
||||
if (useDMA)
|
||||
{
|
||||
/* find the existing dma buffer if it exists */
|
||||
for(int i = 0; i < sizeof(dmaInfo) / sizeof(struct DMAFrameInfo); ++i)
|
||||
{
|
||||
if (dmaInfo[i].frame == frame)
|
||||
{
|
||||
dma = &dmaInfo[i];
|
||||
/* if it's too small close it */
|
||||
if (dma->dataSize < dataSize)
|
||||
{
|
||||
close(dma->fd);
|
||||
dma->fd = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise find a free buffer for use */
|
||||
if (!dma)
|
||||
for(int i = 0; i < sizeof(dmaInfo) / sizeof(struct DMAFrameInfo); ++i)
|
||||
{
|
||||
if (!dmaInfo[i].frame)
|
||||
{
|
||||
dma = &dmaInfo[i];
|
||||
dma->frame = frame;
|
||||
dma->fd = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* open the buffer */
|
||||
if (dma->fd == -1)
|
||||
{
|
||||
const uintptr_t pos = (uintptr_t)msg.mem - (uintptr_t)state.shm.mem;
|
||||
const uintptr_t offset = (uintptr_t)frame->offset + FrameBufferStructSize;
|
||||
|
||||
dma->dataSize = dataSize;
|
||||
dma->fd = ivshmemGetDMABuf(&state.shm, pos + offset, dataSize);
|
||||
if (dma->fd < 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to get the DMA buffer for the frame");
|
||||
state.state = APP_STATE_SHUTDOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lgrFormat.width != state.srcSize.x || lgrFormat.height != state.srcSize.y)
|
||||
{
|
||||
state.srcSize.x = lgrFormat.width;
|
||||
@ -483,7 +547,7 @@ static int frameThread(void * unused)
|
||||
}
|
||||
|
||||
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
|
||||
if (!state.lgr->on_frame(state.lgrData, fb))
|
||||
if (!state.lgr->on_frame(state.lgrData, fb, useDMA ? dma->fd : -1))
|
||||
{
|
||||
lgmpClientMessageDone(queue);
|
||||
DEBUG_ERROR("renderer on frame returned failure");
|
||||
@ -500,6 +564,14 @@ static int frameThread(void * unused)
|
||||
lgmpClientUnsubscribe(&queue);
|
||||
state.lgr->on_restart(state.lgrData);
|
||||
|
||||
if (useDMA)
|
||||
{
|
||||
for(int i = 0; i < sizeof(dmaInfo) / sizeof(struct DMAFrameInfo); ++i)
|
||||
if (dmaInfo[i].fd >= 0)
|
||||
close(dmaInfo[i].fd);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user