mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-10-09 00:48:06 +00:00
[obs] dmabuf: fix repeated re-creation of dmabuf texture
This commit is contained in:

committed by
Geoffrey McRae

parent
d5ee54e23e
commit
d02d46283c
358
obs/lg.c
358
obs/lg.c
@@ -64,10 +64,10 @@ LGState;
|
|||||||
#if LIBOBS_API_MAJOR_VER >= 27
|
#if LIBOBS_API_MAJOR_VER >= 27
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
KVMFRFrame * frame;
|
const KVMFRFrame * frame;
|
||||||
size_t dataSize;
|
size_t dataSize;
|
||||||
int fd;
|
int fd;
|
||||||
gs_texture_t * texture;
|
gs_texture_t * texture;
|
||||||
}
|
}
|
||||||
DMAFrameInfo;
|
DMAFrameInfo;
|
||||||
#endif
|
#endif
|
||||||
@@ -98,6 +98,7 @@ typedef struct
|
|||||||
bool hideMouse;
|
bool hideMouse;
|
||||||
#if LIBOBS_API_MAJOR_VER >= 27
|
#if LIBOBS_API_MAJOR_VER >= 27
|
||||||
bool dmabuf;
|
bool dmabuf;
|
||||||
|
bool dmabufTested;
|
||||||
DMAFrameInfo dmaInfo[LGMP_Q_FRAME_LEN];
|
DMAFrameInfo dmaInfo[LGMP_Q_FRAME_LEN];
|
||||||
gs_texture_t * dmaTexture;
|
gs_texture_t * dmaTexture;
|
||||||
#endif
|
#endif
|
||||||
@@ -515,7 +516,7 @@ static void lgUpdate(void * data, obs_data_t * settings)
|
|||||||
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 27
|
#if LIBOBS_API_MAJOR_VER >= 27
|
||||||
static DMAFrameInfo * dmabufOpenDMAFrameInfo(LGPlugin * this, LGMPMessage * msg,
|
static DMAFrameInfo * dmabufOpenDMAFrameInfo(LGPlugin * this, LGMPMessage * msg,
|
||||||
KVMFRFrame * frame, size_t dataSize)
|
const KVMFRFrame * frame, size_t dataSize)
|
||||||
{
|
{
|
||||||
DMAFrameInfo * fi = NULL;
|
DMAFrameInfo * fi = NULL;
|
||||||
|
|
||||||
@@ -569,11 +570,173 @@ static DMAFrameInfo * dmabufOpenDMAFrameInfo(LGPlugin * this, LGMPMessage * msg,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void lgFormatInit(LGPlugin * this, const KVMFRFrame * frame,
|
||||||
|
LGMPMessage * msg)
|
||||||
|
{
|
||||||
|
this->formatVer = frame->formatVer;
|
||||||
|
this->screenWidth = frame->screenWidth;
|
||||||
|
this->screenHeight = frame->screenHeight;
|
||||||
|
this->dataWidth = frame->dataWidth;
|
||||||
|
this->dataHeight = frame->dataHeight;
|
||||||
|
this->frameWidth = frame->frameWidth;
|
||||||
|
this->frameHeight = frame->frameHeight;
|
||||||
|
this->type = frame->type;
|
||||||
|
|
||||||
|
this->screenScale.x = this->screenWidth / this->frameWidth ;
|
||||||
|
this->screenScale.y = this->screenHeight / this->frameHeight;
|
||||||
|
|
||||||
|
obs_enter_graphics();
|
||||||
|
if (this->texture)
|
||||||
|
{
|
||||||
|
if (this->unpack && this->dstTexture)
|
||||||
|
{
|
||||||
|
gs_texture_destroy(this->dstTexture);
|
||||||
|
this->dstTexture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->dmabuf)
|
||||||
|
gs_texture_unmap(this->texture);
|
||||||
|
|
||||||
|
gs_texture_destroy(this->texture);
|
||||||
|
this->texture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->dataWidth = frame->dataWidth;
|
||||||
|
this->unpack = false;
|
||||||
|
|
||||||
|
this->bpp = 4;
|
||||||
|
switch(this->type)
|
||||||
|
{
|
||||||
|
case FRAME_TYPE_BGRA:
|
||||||
|
this->format = GS_BGRA_UNORM;
|
||||||
|
this->drmFormat = DRM_FORMAT_ARGB8888;
|
||||||
|
#if LIBOBS_API_MAJOR_VER >= 28
|
||||||
|
this->colorSpace = GS_CS_SRGB;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FRAME_TYPE_RGBA:
|
||||||
|
this->format = GS_RGBA_UNORM;
|
||||||
|
this->drmFormat = DRM_FORMAT_ARGB8888;
|
||||||
|
#if LIBOBS_API_MAJOR_VER >= 28
|
||||||
|
this->colorSpace = GS_CS_SRGB;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FRAME_TYPE_RGBA10:
|
||||||
|
this->format = GS_R10G10B10A2;
|
||||||
|
this->drmFormat = DRM_FORMAT_BGRA1010102;
|
||||||
|
#if LIBOBS_API_MAJOR_VER >= 28
|
||||||
|
this->colorSpace = GS_CS_709_SCRGB;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FRAME_TYPE_RGB_24:
|
||||||
|
this->bpp = 3;
|
||||||
|
this->dataWidth = frame->pitch / 4;
|
||||||
|
/* fallthrough */
|
||||||
|
|
||||||
|
case FRAME_TYPE_BGR_32:
|
||||||
|
this->format = GS_BGRA_UNORM;
|
||||||
|
this->drmFormat = DRM_FORMAT_ARGB8888;
|
||||||
|
#if LIBOBS_API_MAJOR_VER >= 28
|
||||||
|
this->colorSpace = GS_CS_SRGB;
|
||||||
|
#endif
|
||||||
|
this->unpack = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FRAME_TYPE_RGBA16F:
|
||||||
|
this->bpp = 8;
|
||||||
|
this->format = GS_RGBA16F;
|
||||||
|
this->drmFormat = DRM_FORMAT_ABGR16161616F;
|
||||||
|
#if LIBOBS_API_MAJOR_VER >= 28
|
||||||
|
this->colorSpace = GS_CS_709_SCRGB;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("invalid type %d\n", this->type);
|
||||||
|
lgmpClientMessageDone(this->frameQueue);
|
||||||
|
os_sem_post(this->frameSem);
|
||||||
|
obs_leave_graphics();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LIBOBS_API_MAJOR_VER >= 27
|
||||||
|
if (this->dmabuf)
|
||||||
|
{
|
||||||
|
DMAFrameInfo * fi = dmabufOpenDMAFrameInfo(this, msg, frame,
|
||||||
|
frame->frameHeight * frame->pitch);
|
||||||
|
if (fi && !fi->texture)
|
||||||
|
{
|
||||||
|
// create the first texture now so we can test if dmabuf is usable
|
||||||
|
fi->texture = gs_texture_create_from_dmabuf(
|
||||||
|
this->dataWidth,
|
||||||
|
this->dataHeight,
|
||||||
|
this->drmFormat,
|
||||||
|
this->format,
|
||||||
|
1,
|
||||||
|
&fi->fd,
|
||||||
|
&(uint32_t) { frame->pitch },
|
||||||
|
&(uint32_t) { 0 },
|
||||||
|
&(uint64_t) { 0 });
|
||||||
|
|
||||||
|
if (!fi->texture)
|
||||||
|
{
|
||||||
|
puts("Failed to create dmabuf texture");
|
||||||
|
this->dmabuf = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->dmabufTested = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)drmFormat;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!this->dmabuf)
|
||||||
|
{
|
||||||
|
this->texture = gs_texture_create(
|
||||||
|
this->dataWidth,
|
||||||
|
this->dataHeight,
|
||||||
|
this->format,
|
||||||
|
1,
|
||||||
|
NULL,
|
||||||
|
GS_DYNAMIC);
|
||||||
|
|
||||||
|
if (!this->texture)
|
||||||
|
{
|
||||||
|
printf("create texture failed\n");
|
||||||
|
lgmpClientMessageDone(this->frameQueue);
|
||||||
|
os_sem_post(this->frameSem);
|
||||||
|
obs_leave_graphics();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gs_texture_map(this->texture, &this->texData, &this->linesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->unpack)
|
||||||
|
{
|
||||||
|
// create the render target for format unpacking
|
||||||
|
this->dstTexture = gs_texture_create(
|
||||||
|
this->frameWidth,
|
||||||
|
this->frameHeight,
|
||||||
|
GS_BGRA,
|
||||||
|
1,
|
||||||
|
NULL,
|
||||||
|
GS_RENDER_TARGET);
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_leave_graphics();
|
||||||
|
}
|
||||||
|
|
||||||
static void lgVideoTick(void * data, float seconds)
|
static void lgVideoTick(void * data, float seconds)
|
||||||
{
|
{
|
||||||
LGPlugin * this = (LGPlugin *)data;
|
LGPlugin * this = (LGPlugin *)data;
|
||||||
|
|
||||||
if (this->state == STATE_RESTARTING) {
|
if (this->state == STATE_RESTARTING)
|
||||||
|
{
|
||||||
waitThreads(this);
|
waitThreads(this);
|
||||||
|
|
||||||
this->state = STATE_STARTING;
|
this->state = STATE_STARTING;
|
||||||
@@ -674,164 +837,11 @@ static void lgVideoTick(void * data, float seconds)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
|
const KVMFRFrame * frame = (KVMFRFrame *)msg.mem;
|
||||||
if (!this->texture || this->formatVer != frame->formatVer)
|
|
||||||
{
|
|
||||||
this->formatVer = frame->formatVer;
|
|
||||||
this->screenWidth = frame->screenWidth;
|
|
||||||
this->screenHeight = frame->screenHeight;
|
|
||||||
this->dataWidth = frame->dataWidth;
|
|
||||||
this->dataHeight = frame->dataHeight;
|
|
||||||
this->frameWidth = frame->frameWidth;
|
|
||||||
this->frameHeight = frame->frameHeight;
|
|
||||||
this->type = frame->type;
|
|
||||||
|
|
||||||
this->screenScale.x = this->screenWidth / this->frameWidth ;
|
bool textureValid = (this->dmabufTested && this->dmabuf) || this->texture;
|
||||||
this->screenScale.y = this->screenHeight / this->frameHeight;
|
if (!textureValid || this->formatVer != frame->formatVer)
|
||||||
|
lgFormatInit(this, frame, &msg);
|
||||||
obs_enter_graphics();
|
|
||||||
if (this->texture)
|
|
||||||
{
|
|
||||||
if (this->unpack && this->dstTexture)
|
|
||||||
{
|
|
||||||
gs_texture_destroy(this->dstTexture);
|
|
||||||
this->dstTexture = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->dmabuf)
|
|
||||||
gs_texture_unmap(this->texture);
|
|
||||||
|
|
||||||
gs_texture_destroy(this->texture);
|
|
||||||
this->texture = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->dataWidth = frame->dataWidth;
|
|
||||||
this->unpack = false;
|
|
||||||
|
|
||||||
this->bpp = 4;
|
|
||||||
switch(this->type)
|
|
||||||
{
|
|
||||||
case FRAME_TYPE_BGRA:
|
|
||||||
this->format = GS_BGRA_UNORM;
|
|
||||||
this->drmFormat = DRM_FORMAT_ARGB8888;
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 28
|
|
||||||
this->colorSpace = GS_CS_SRGB;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA:
|
|
||||||
this->format = GS_RGBA_UNORM;
|
|
||||||
this->drmFormat = DRM_FORMAT_ARGB8888;
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 28
|
|
||||||
this->colorSpace = GS_CS_SRGB;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA10:
|
|
||||||
this->format = GS_R10G10B10A2;
|
|
||||||
this->drmFormat = DRM_FORMAT_BGRA1010102;
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 28
|
|
||||||
this->colorSpace = GS_CS_709_SCRGB;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FRAME_TYPE_RGB_24:
|
|
||||||
this->bpp = 3;
|
|
||||||
this->dataWidth = frame->pitch / 4;
|
|
||||||
/* fallthrough */
|
|
||||||
|
|
||||||
case FRAME_TYPE_BGR_32:
|
|
||||||
this->format = GS_BGRA_UNORM;
|
|
||||||
this->drmFormat = DRM_FORMAT_ARGB8888;
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 28
|
|
||||||
this->colorSpace = GS_CS_SRGB;
|
|
||||||
#endif
|
|
||||||
this->unpack = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA16F:
|
|
||||||
this->bpp = 8;
|
|
||||||
this->format = GS_RGBA16F;
|
|
||||||
this->drmFormat = DRM_FORMAT_ABGR16161616F;
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 28
|
|
||||||
this->colorSpace = GS_CS_709_SCRGB;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("invalid type %d\n", this->type);
|
|
||||||
lgmpClientMessageDone(this->frameQueue);
|
|
||||||
os_sem_post(this->frameSem);
|
|
||||||
obs_leave_graphics();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 27
|
|
||||||
if (this->dmabuf)
|
|
||||||
{
|
|
||||||
DMAFrameInfo * fi = dmabufOpenDMAFrameInfo(this, &msg, frame,
|
|
||||||
frame->frameHeight * frame->pitch);
|
|
||||||
if (fi && !fi->texture)
|
|
||||||
{
|
|
||||||
// create the first texture now so we can test if dmabuf is usable
|
|
||||||
fi->texture = gs_texture_create_from_dmabuf(
|
|
||||||
this->dataWidth,
|
|
||||||
this->dataHeight,
|
|
||||||
this->drmFormat,
|
|
||||||
this->format,
|
|
||||||
1,
|
|
||||||
&fi->fd,
|
|
||||||
&(uint32_t) { frame->pitch },
|
|
||||||
&(uint32_t) { 0 },
|
|
||||||
&(uint64_t) { 0 });
|
|
||||||
|
|
||||||
if (!fi->texture)
|
|
||||||
{
|
|
||||||
puts("Failed to create dmabuf texture");
|
|
||||||
this->dmabuf = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
(void)drmFormat;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!this->dmabuf)
|
|
||||||
{
|
|
||||||
this->texture = gs_texture_create(
|
|
||||||
this->dataWidth,
|
|
||||||
this->dataHeight,
|
|
||||||
this->format,
|
|
||||||
1,
|
|
||||||
NULL,
|
|
||||||
GS_DYNAMIC);
|
|
||||||
|
|
||||||
if (!this->texture)
|
|
||||||
{
|
|
||||||
printf("create texture failed\n");
|
|
||||||
lgmpClientMessageDone(this->frameQueue);
|
|
||||||
os_sem_post(this->frameSem);
|
|
||||||
obs_leave_graphics();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gs_texture_map(this->texture, &this->texData, &this->linesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->unpack)
|
|
||||||
{
|
|
||||||
// create the render target for format unpacking
|
|
||||||
this->dstTexture = gs_texture_create(
|
|
||||||
this->frameWidth,
|
|
||||||
this->frameHeight,
|
|
||||||
GS_BGRA,
|
|
||||||
1,
|
|
||||||
NULL,
|
|
||||||
GS_RENDER_TARGET);
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LIBOBS_API_MAJOR_VER >= 27
|
#if LIBOBS_API_MAJOR_VER >= 27
|
||||||
if (this->dmabuf)
|
if (this->dmabuf)
|
||||||
@@ -841,16 +851,18 @@ static void lgVideoTick(void * data, float seconds)
|
|||||||
|
|
||||||
if (!fi->texture)
|
if (!fi->texture)
|
||||||
{
|
{
|
||||||
fi->texture = gs_texture_create_from_dmabuf(
|
obs_enter_graphics();
|
||||||
this->dataWidth,
|
fi->texture = gs_texture_create_from_dmabuf(
|
||||||
this->dataHeight,
|
this->dataWidth,
|
||||||
this->drmFormat,
|
this->dataHeight,
|
||||||
this->format,
|
this->drmFormat,
|
||||||
1,
|
this->format,
|
||||||
&fi->fd,
|
1,
|
||||||
&(uint32_t) { frame->pitch },
|
&fi->fd,
|
||||||
&(uint32_t) { 0 },
|
&(uint32_t) { frame->pitch },
|
||||||
&(uint64_t) { 0 });
|
&(uint32_t) { 0 },
|
||||||
|
&(uint64_t) { 0 });
|
||||||
|
obs_leave_graphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
lgmpClientMessageDone(this->frameQueue);
|
lgmpClientMessageDone(this->frameQueue);
|
||||||
|
Reference in New Issue
Block a user