From 2901e7aec573cc62c94c700788adb617e3a1c70e Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Tue, 17 May 2022 00:51:13 +1000 Subject: [PATCH] [client] egl: only upload the damage rects if they actually changed Profiling shows that a considerable amount of time is spent in glBindBuffer and glBufferSubData when the damage rects are updated. Since the amount of data here is quite small it's far faster to check if it's different then to just blindly overwrite the buffer on each call. Profiled on an Intel CPU with UHD P630 Graphics using magic-trace --- client/renderers/EGL/desktop_rects.c | 32 +++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/client/renderers/EGL/desktop_rects.c b/client/renderers/EGL/desktop_rects.c index b268307d..c2ccfc15 100644 --- a/client/renderers/EGL/desktop_rects.c +++ b/client/renderers/EGL/desktop_rects.c @@ -32,6 +32,10 @@ struct EGL_DesktopRects { + GLfloat * lastVertices; + int lastVerticesCount; + int lastVerticesSize; + GLuint buffers[2]; GLuint vao; int count; @@ -88,6 +92,7 @@ void egl_desktopRectsFree(EGL_DesktopRects ** rects_) glDeleteVertexArrays(1, &rects->vao); glDeleteBuffers(2, rects->buffers); + free(rects->lastVertices); free(rects); *rects_ = NULL; } @@ -113,7 +118,8 @@ void egl_desktopRectsUpdate(EGL_DesktopRects * rects, const struct DamageRects * return; } - GLfloat vertices[(!data || data->count < 0 ? 1 : data->count) * 8]; + const int count = (!data || data->count < 0 ? 1 : data->count) * 8; + GLfloat vertices[count]; if (!data || data->count < 0) { FrameDamageRect full = { @@ -131,6 +137,30 @@ void egl_desktopRectsUpdate(EGL_DesktopRects * rects, const struct DamageRects * rectToVertices(vertices + i * 8, data->rects + i); } + // check if the value actually changed and needs updating + if (count == rects->lastVerticesCount && + memcmp(rects->lastVertices, vertices, sizeof(GLfloat) * count) == 0) + return; + + // ensure the local storage is large enough + if (count > rects->lastVerticesSize) + { + if (rects->lastVertices) + free(rects->lastVertices); + + rects->lastVertices = malloc(sizeof(GLfloat) * count); + if (!rects->lastVertices) + { + DEBUG_ERROR("out of memory"); + return; + } + rects->lastVerticesSize = count; + } + + // copy the last value for later comparison + rects->lastVerticesCount = count; + memcpy(rects->lastVertices, vertices, sizeof(GLfloat) * count); + glBindBuffer(GL_ARRAY_BUFFER, rects->buffers[0]); glBufferSubData(GL_ARRAY_BUFFER, 0, rects->count * 8 * sizeof(GLfloat), vertices); glBindBuffer(GL_ARRAY_BUFFER, 0);