From b3db1ba10b50c70d7d6b6560aaa89b2d3b1b1450 Mon Sep 17 00:00:00 2001 From: Quantum Date: Sat, 7 Aug 2021 19:04:49 -0400 Subject: [PATCH] [client] egl: eliminate GLsync object leaks It used to be the case that we overwrite this->sync even if it was non-zero when updating the texture, without deleting the sync object. If we update faster than we render, the result would be leaking sync objects. This commit ensures that sync objects are deleted when they are replaced. --- client/renderers/EGL/texture_buffer.c | 15 ++++++++------- client/renderers/EGL/texture_buffer.h | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/client/renderers/EGL/texture_buffer.c b/client/renderers/EGL/texture_buffer.c index 04e9c10f..7b06f170 100644 --- a/client/renderers/EGL/texture_buffer.c +++ b/client/renderers/EGL/texture_buffer.c @@ -68,6 +68,7 @@ bool eglTexBuffer_init(EGL_Texture ** texture, EGLDisplay * display) this = UPCAST(TextureBuffer, *texture); this->texCount = 1; + atomic_init(&this->sync, 0); return true; } @@ -226,7 +227,8 @@ EGL_TexStatus eglTexBuffer_stream_process(EGL_Texture * texture) glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - this->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glDeleteSync(atomic_exchange(&this->sync, sync)); glFlush(); } @@ -240,14 +242,14 @@ EGL_TexStatus eglTexBuffer_stream_bind(EGL_Texture * texture) if (this->rIndex == -1) return EGL_TEX_STATUS_NOTREADY; - if (this->sync) + GLsync sync = atomic_exchange(&this->sync, 0); + if (sync) { - switch(glClientWaitSync(this->sync, 0, 20000000)) // 20ms + switch(glClientWaitSync(sync, 0, 20000000)) // 20ms { case GL_ALREADY_SIGNALED: case GL_CONDITION_SATISFIED: - glDeleteSync(this->sync); - this->sync = 0; + glDeleteSync(sync); break; case GL_TIMEOUT_EXPIRED: @@ -255,8 +257,7 @@ EGL_TexStatus eglTexBuffer_stream_bind(EGL_Texture * texture) case GL_WAIT_FAILED: case GL_INVALID_VALUE: - glDeleteSync(this->sync); - this->sync = 0; + glDeleteSync(sync); DEBUG_GL_ERROR("glClientWaitSync failed"); return EGL_TEX_STATUS_ERROR; } diff --git a/client/renderers/EGL/texture_buffer.h b/client/renderers/EGL/texture_buffer.h index e40eb814..a549978b 100644 --- a/client/renderers/EGL/texture_buffer.h +++ b/client/renderers/EGL/texture_buffer.h @@ -31,16 +31,16 @@ typedef struct TextureBuffer EGL_Texture base; bool free; - EGL_TexFormat format; - int texCount; - GLuint tex[EGL_TEX_BUFFER_MAX]; - GLuint sampler; - EGL_TexBuffer buf[EGL_TEX_BUFFER_MAX]; - int bufFree; - GLsync sync; - LG_Lock copyLock; - int bufIndex; - int rIndex; + EGL_TexFormat format; + int texCount; + GLuint tex[EGL_TEX_BUFFER_MAX]; + GLuint sampler; + EGL_TexBuffer buf[EGL_TEX_BUFFER_MAX]; + int bufFree; + _Atomic(GLsync) sync; + LG_Lock copyLock; + int bufIndex; + int rIndex; } TextureBuffer;