mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-09-02 21:30:52 +00:00
[client] egl: improve dmabuf import hot path performance
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
* Removes the vector in favour of a two element array * Removes iteration on the vector * Create and track a per-image fence * bind the EGLImage to the texture at creation, avoiding re-binding * sync on GL_SYNC_FLUSH_COMMANDS_BIT and remove glFlush
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
#include "texture_buffer.h"
|
#include "texture_buffer.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include "common/vector.h"
|
#include "common/array.h"
|
||||||
#include "egl_dynprocs.h"
|
#include "egl_dynprocs.h"
|
||||||
#include "egldebug.h"
|
#include "egldebug.h"
|
||||||
|
|
||||||
@@ -30,6 +30,8 @@ struct FdImage
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
EGLImage image;
|
EGLImage image;
|
||||||
|
GLsync sync;
|
||||||
|
int texIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct TexDMABUF
|
typedef struct TexDMABUF
|
||||||
@@ -37,7 +39,9 @@ typedef struct TexDMABUF
|
|||||||
TextureBuffer base;
|
TextureBuffer base;
|
||||||
|
|
||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
Vector images;
|
|
||||||
|
struct FdImage images[2];
|
||||||
|
int lastIndex;
|
||||||
|
|
||||||
EGL_PixelFormat pixFmt;
|
EGL_PixelFormat pixFmt;
|
||||||
unsigned fourcc;
|
unsigned fourcc;
|
||||||
@@ -59,21 +63,26 @@ static void egl_texDMABUFCleanup(EGL_Texture * texture)
|
|||||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||||
|
|
||||||
struct FdImage * image;
|
for(int i = 0; i < ARRAY_LENGTH(this->images); ++i)
|
||||||
vector_forEachRef(image, &this->images)
|
{
|
||||||
g_egl_dynProcs.eglDestroyImage(this->display, image->image);
|
if (this->images[i].image != EGL_NO_IMAGE)
|
||||||
vector_clear(&this->images);
|
{
|
||||||
|
g_egl_dynProcs.eglDestroyImage(this->display, this->images[i].image);
|
||||||
|
this->images[i].image = EGL_NO_IMAGE;
|
||||||
|
}
|
||||||
|
if (this->images[i].sync)
|
||||||
|
{
|
||||||
|
glDeleteSync(this->images[i].sync);
|
||||||
|
this->images[i].sync = 0;
|
||||||
|
}
|
||||||
|
this->images[i].fd = -1;
|
||||||
|
this->images[i].texIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
egl_texUtilFreeBuffers(parent->buf, parent->texCount);
|
egl_texUtilFreeBuffers(parent->buf, parent->texCount);
|
||||||
|
|
||||||
if (parent->tex[0])
|
if (parent->tex[0])
|
||||||
glDeleteTextures(parent->texCount, parent->tex);
|
glDeleteTextures(parent->texCount, parent->tex);
|
||||||
|
|
||||||
if (parent->sync)
|
|
||||||
{
|
|
||||||
glDeleteSync(parent->sync);
|
|
||||||
parent->sync = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dmabuf functions
|
// dmabuf functions
|
||||||
@@ -84,17 +93,18 @@ static bool egl_texDMABUFInit(EGL_Texture ** texture, EGL_TexType type,
|
|||||||
TexDMABUF * this = calloc(1, sizeof(*this));
|
TexDMABUF * this = calloc(1, sizeof(*this));
|
||||||
*texture = &this->base.base;
|
*texture = &this->base.base;
|
||||||
|
|
||||||
if (!vector_create(&this->images, sizeof(struct FdImage), 2))
|
for(int i = 0; i < ARRAY_LENGTH(this->images); ++i)
|
||||||
{
|
{
|
||||||
free(this);
|
this->images[i].fd = -1;
|
||||||
*texture = NULL;
|
this->images[i].image = EGL_NO_IMAGE;
|
||||||
return false;
|
this->images[i].sync = 0;
|
||||||
|
this->images[i].texIndex = -1;
|
||||||
}
|
}
|
||||||
|
this->lastIndex = -1;
|
||||||
|
|
||||||
EGL_Texture * parent = &this->base.base;
|
EGL_Texture * parent = &this->base.base;
|
||||||
if (!egl_texBufferStreamInit(&parent, type, display))
|
if (!egl_texBufferStreamInit(&parent, type, display))
|
||||||
{
|
{
|
||||||
vector_destroy(&this->images);
|
|
||||||
free(this);
|
free(this);
|
||||||
*texture = NULL;
|
*texture = NULL;
|
||||||
return false;
|
return false;
|
||||||
@@ -119,8 +129,6 @@ static void egl_texDMABUFFree(EGL_Texture * texture)
|
|||||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||||
|
|
||||||
egl_texDMABUFCleanup(texture);
|
egl_texDMABUFCleanup(texture);
|
||||||
vector_destroy(&this->images);
|
|
||||||
|
|
||||||
egl_texBufferFree(&parent->base);
|
egl_texBufferFree(&parent->base);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -198,16 +206,12 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
|||||||
|
|
||||||
DEBUG_ASSERT(update->type == EGL_TEXTYPE_DMABUF);
|
DEBUG_ASSERT(update->type == EGL_TEXTYPE_DMABUF);
|
||||||
|
|
||||||
EGLImage image = EGL_NO_IMAGE;
|
struct FdImage *fdImage =
|
||||||
|
(this->images[0].fd == update->dmaFD) ? &this->images[0] :
|
||||||
struct FdImage * fdImage;
|
(this->images[1].fd == update->dmaFD) ? &this->images[1] :
|
||||||
vector_forEachRef(fdImage, &this->images)
|
(this->images[0].fd == -1) ? &this->images[0] :
|
||||||
if (fdImage->fd == update->dmaFD)
|
&this->images[1];
|
||||||
{
|
EGLImage image = fdImage->image;
|
||||||
image = fdImage->image;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(image == EGL_NO_IMAGE))
|
if (unlikely(image == EGL_NO_IMAGE))
|
||||||
{
|
{
|
||||||
bool setup = false;
|
bool setup = false;
|
||||||
@@ -234,28 +238,26 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!vector_push(&this->images, &(struct FdImage) {
|
fdImage->fd = update->dmaFD;
|
||||||
.fd = update->dmaFD,
|
fdImage->image = image;
|
||||||
.image = image,
|
|
||||||
})))
|
int slot = (fdImage == &this->images[0]) ? 0 : 1;
|
||||||
|
fdImage->texIndex = slot;
|
||||||
|
INTERLOCKED_SECTION(parent->copyLock,
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to store EGLImage");
|
glBindTexture(GL_TEXTURE_EXTERNAL_OES, parent->tex[slot]);
|
||||||
g_egl_dynProcs.eglDestroyImage(this->display, image);
|
g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
|
||||||
return false;
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->lastIndex = (fdImage == &this->images[0]) ? 0 : 1;
|
||||||
INTERLOCKED_SECTION(parent->copyLock,
|
INTERLOCKED_SECTION(parent->copyLock,
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, parent->tex[parent->bufIndex]);
|
if (fdImage->sync)
|
||||||
g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
|
glDeleteSync(fdImage->sync);
|
||||||
|
fdImage->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
if (likely(parent->sync))
|
|
||||||
glDeleteSync(parent->sync);
|
|
||||||
|
|
||||||
parent->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
||||||
});
|
});
|
||||||
glFlush();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,23 +272,22 @@ static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex,
|
|||||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||||
|
|
||||||
|
if (unlikely(this->lastIndex < 0))
|
||||||
|
return EGL_TEX_STATUS_NOTREADY;
|
||||||
|
|
||||||
|
struct FdImage *cur = &this->images[this->lastIndex];
|
||||||
GLsync sync = 0;
|
GLsync sync = 0;
|
||||||
|
|
||||||
INTERLOCKED_SECTION(parent->copyLock,
|
INTERLOCKED_SECTION(parent->copyLock, {
|
||||||
{
|
if (cur->sync) {
|
||||||
if (parent->sync)
|
sync = cur->sync;
|
||||||
{
|
cur->sync = 0;
|
||||||
sync = parent->sync;
|
|
||||||
parent->sync = 0;
|
|
||||||
parent->rIndex = parent->bufIndex;
|
|
||||||
if (++parent->bufIndex == parent->texCount)
|
|
||||||
parent->bufIndex = 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (sync)
|
if (sync)
|
||||||
{
|
{
|
||||||
switch(glClientWaitSync(sync, 0, 20000000)) // 20ms
|
switch (glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 20000000)) //20ms
|
||||||
{
|
{
|
||||||
case GL_ALREADY_SIGNALED:
|
case GL_ALREADY_SIGNALED:
|
||||||
case GL_CONDITION_SATISFIED:
|
case GL_CONDITION_SATISFIED:
|
||||||
@@ -294,10 +295,11 @@ static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_TIMEOUT_EXPIRED:
|
case GL_TIMEOUT_EXPIRED:
|
||||||
|
// Put it back for next try
|
||||||
INTERLOCKED_SECTION(parent->copyLock,
|
INTERLOCKED_SECTION(parent->copyLock,
|
||||||
{
|
{
|
||||||
if (!parent->sync)
|
if (!cur->sync)
|
||||||
parent->sync = sync;
|
cur->sync = sync;
|
||||||
else
|
else
|
||||||
glDeleteSync(sync);
|
glDeleteSync(sync);
|
||||||
});
|
});
|
||||||
@@ -311,7 +313,7 @@ static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*tex = parent->tex[parent->rIndex];
|
*tex = parent->tex[cur->texIndex];
|
||||||
|
|
||||||
if (fmt)
|
if (fmt)
|
||||||
*fmt = this->pixFmt;
|
*fmt = this->pixFmt;
|
||||||
|
Reference in New Issue
Block a user