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;
|
LG_RendererParams;
|
||||||
|
|
||||||
|
typedef enum LG_RendererSupport
|
||||||
|
{
|
||||||
|
LG_SUPPORTS_DMABUF
|
||||||
|
}
|
||||||
|
LG_RendererSupport;
|
||||||
|
|
||||||
typedef struct LG_RendererFormat
|
typedef struct LG_RendererFormat
|
||||||
{
|
{
|
||||||
FrameType type; // frame type
|
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_RendererCreate )(void ** opaque, const LG_RendererParams params);
|
||||||
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
||||||
typedef void (* LG_RendererDeInitialize )(void * opaque);
|
typedef void (* LG_RendererDeInitialize )(void * opaque);
|
||||||
|
typedef bool (* LG_RendererSupports )(void * opaque, LG_RendererSupport support);
|
||||||
typedef void (* LG_RendererOnRestart )(void * opaque);
|
typedef void (* LG_RendererOnRestart )(void * opaque);
|
||||||
typedef void (* LG_RendererOnResize )(void * opaque, const int width, const int height, const LG_RendererRect destRect);
|
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_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_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_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 void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
||||||
typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window);
|
typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window);
|
||||||
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
|
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
|
||||||
@ -107,6 +114,7 @@ typedef struct LG_Renderer
|
|||||||
LG_RendererCreate create;
|
LG_RendererCreate create;
|
||||||
LG_RendererInitialize initialize;
|
LG_RendererInitialize initialize;
|
||||||
LG_RendererDeInitialize deinitialize;
|
LG_RendererDeInitialize deinitialize;
|
||||||
|
LG_RendererSupports supports;
|
||||||
LG_RendererOnRestart on_restart;
|
LG_RendererOnRestart on_restart;
|
||||||
LG_RendererOnResize on_resize;
|
LG_RendererOnResize on_resize;
|
||||||
LG_RendererOnMouseShape on_mouse_shape;
|
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);
|
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;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ bool opengl_on_frame_format(void * opaque, const LG_RendererFormat format)
|
|||||||
return true;
|
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;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
|
@ -358,13 +358,29 @@ static int cursorThread(void * unused)
|
|||||||
|
|
||||||
static int frameThread(void * unused)
|
static int frameThread(void * unused)
|
||||||
{
|
{
|
||||||
|
struct DMAFrameInfo
|
||||||
|
{
|
||||||
|
KVMFRFrame * frame;
|
||||||
|
size_t dataSize;
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
LGMP_STATUS status;
|
LGMP_STATUS status;
|
||||||
PLGMPClientQueue queue;
|
PLGMPClientQueue queue;
|
||||||
|
|
||||||
uint32_t formatVer = 0;
|
uint32_t formatVer = 0;
|
||||||
bool formatValid = false;
|
bool formatValid = false;
|
||||||
|
size_t dataSize;
|
||||||
LG_RendererFormat lgrFormat;
|
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);
|
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
|
||||||
lgWaitEvent(e_startup, TIMEOUT_INFINITE);
|
lgWaitEvent(e_startup, TIMEOUT_INFINITE);
|
||||||
if (state.state != APP_STATE_RUNNING)
|
if (state.state != APP_STATE_RUNNING)
|
||||||
@ -409,7 +425,8 @@ static int frameThread(void * unused)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
|
KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
|
||||||
|
struct DMAFrameInfo *dma = NULL;
|
||||||
|
|
||||||
if (!formatValid || frame->formatVer != formatVer)
|
if (!formatValid || frame->formatVer != formatVer)
|
||||||
{
|
{
|
||||||
@ -420,8 +437,7 @@ static int frameThread(void * unused)
|
|||||||
lgrFormat.stride = frame->stride;
|
lgrFormat.stride = frame->stride;
|
||||||
lgrFormat.pitch = frame->pitch;
|
lgrFormat.pitch = frame->pitch;
|
||||||
|
|
||||||
size_t dataSize;
|
bool error = false;
|
||||||
bool error = false;
|
|
||||||
switch(frame->type)
|
switch(frame->type)
|
||||||
{
|
{
|
||||||
case FRAME_TYPE_RGBA:
|
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)
|
if (lgrFormat.width != state.srcSize.x || lgrFormat.height != state.srcSize.y)
|
||||||
{
|
{
|
||||||
state.srcSize.x = lgrFormat.width;
|
state.srcSize.x = lgrFormat.width;
|
||||||
@ -483,7 +547,7 @@ static int frameThread(void * unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
|
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);
|
lgmpClientMessageDone(queue);
|
||||||
DEBUG_ERROR("renderer on frame returned failure");
|
DEBUG_ERROR("renderer on frame returned failure");
|
||||||
@ -500,6 +564,14 @@ static int frameThread(void * unused)
|
|||||||
lgmpClientUnsubscribe(&queue);
|
lgmpClientUnsubscribe(&queue);
|
||||||
state.lgr->on_restart(state.lgrData);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user