mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-14 21:17:54 +00:00
[client] egl: cycle through multiple textures for dmabuf
This avoids race conditions in GL drivers when attempting to render and call glEGLImageTargetTexture2DOES on the same texture. Also, when using glEGLImageTargetTexture2DOES, we do not need to allocate storage for textures.
This commit is contained in:
parent
5e13549f74
commit
9b87f4ba5e
1 changed files with 54 additions and 19 deletions
|
@ -63,7 +63,7 @@ static bool egl_texDMABUFInit(EGL_Texture ** texture, EGLDisplay * display)
|
|||
*texture = &this->base.base;
|
||||
|
||||
EGL_Texture * parent = &this->base.base;
|
||||
if (!egl_texBufferInit(&parent, display))
|
||||
if (!egl_texBufferStreamInit(&parent, display))
|
||||
{
|
||||
free(this);
|
||||
*texture = NULL;
|
||||
|
@ -93,21 +93,7 @@ static bool egl_texDMABUFSetup(EGL_Texture * texture, const EGL_TexSetup * setup
|
|||
|
||||
egl_texDMABUFCleanup(this);
|
||||
|
||||
if (!egl_texBufferSetup(&parent->base, setup))
|
||||
return false;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, parent->tex[0]);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
texture->format.intFormat,
|
||||
texture->format.width,
|
||||
texture->format.height,
|
||||
0,
|
||||
texture->format.format,
|
||||
texture->format.dataType,
|
||||
NULL);
|
||||
|
||||
return true;
|
||||
return egl_texBufferSetup(&parent->base, setup);
|
||||
}
|
||||
|
||||
static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
||||
|
@ -172,8 +158,17 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
|||
this->images[index].image = image;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, parent->tex[0]);
|
||||
INTERLOCKED_SECTION(parent->copyLock,
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, parent->tex[parent->bufIndex]);
|
||||
g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
||||
|
||||
if (parent->sync)
|
||||
glDeleteSync(parent->sync);
|
||||
|
||||
parent->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
});
|
||||
glFlush();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -185,8 +180,48 @@ static EGL_TexStatus egl_texDMABUFProcess(EGL_Texture * texture)
|
|||
static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex)
|
||||
{
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
GLsync sync = 0;
|
||||
|
||||
*tex = parent->tex[0];
|
||||
INTERLOCKED_SECTION(parent->copyLock,
|
||||
{
|
||||
if (parent->sync)
|
||||
{
|
||||
sync = parent->sync;
|
||||
parent->sync = 0;
|
||||
parent->rIndex = parent->bufIndex;
|
||||
if (++parent->bufIndex == parent->texCount)
|
||||
parent->bufIndex = 0;
|
||||
}
|
||||
});
|
||||
|
||||
if (sync)
|
||||
{
|
||||
switch(glClientWaitSync(sync, 0, 20000000)) // 20ms
|
||||
{
|
||||
case GL_ALREADY_SIGNALED:
|
||||
case GL_CONDITION_SATISFIED:
|
||||
glDeleteSync(sync);
|
||||
break;
|
||||
|
||||
case GL_TIMEOUT_EXPIRED:
|
||||
INTERLOCKED_SECTION(parent->copyLock,
|
||||
{
|
||||
if (!parent->sync)
|
||||
parent->sync = sync;
|
||||
else
|
||||
glDeleteSync(sync);
|
||||
});
|
||||
return EGL_TEX_STATUS_NOTREADY;
|
||||
|
||||
case GL_WAIT_FAILED:
|
||||
case GL_INVALID_VALUE:
|
||||
glDeleteSync(sync);
|
||||
DEBUG_GL_ERROR("glClientWaitSync failed");
|
||||
return EGL_TEX_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*tex = parent->tex[parent->rIndex];
|
||||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue