From 8324f61db034a86d142355f8127afe8ed4503b6f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 6 Nov 2025 17:46:07 -0600 Subject: [PATCH] Reduce per-frame GL calls in EGLRenderer Uniforms are attached to the program object, so they don't need to be set each time we swap between the YUV shader and the overlay shader. Since 0 overlays is by far the most common case and > 1 is highly unlikely, move the glViewport() call into renderOverlay() to let us skip it in the common case (and be no worse than today in the 2nd most common case of 1 overlay). --- .../video/ffmpeg-renderers/eglvid.cpp | 50 +++++++++++-------- app/streaming/video/ffmpeg-renderers/eglvid.h | 3 -- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.cpp b/app/streaming/video/ffmpeg-renderers/eglvid.cpp index ac405b68..1859a7d0 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp @@ -271,6 +271,9 @@ void EGLRenderer::renderOverlay(Overlay::OverlayType type, int viewportWidth, in return; } + // Adjust the viewport to the whole window before rendering the overlays + glViewport(0, 0, viewportWidth, viewportHeight); + glUseProgram(m_OverlayShaderProgram); glBindBuffer(GL_ARRAY_BUFFER, m_OverlayVbos[type]); @@ -281,7 +284,6 @@ void EGLRenderer::renderOverlay(Overlay::OverlayType type, int viewportWidth, in glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_OverlayTextures[type]); - glUniform1i(m_OverlayShaderProgramParams[OVERLAY_PARAM_TEXTURE], 0); glDrawArrays(GL_TRIANGLES, 0, 6); } @@ -367,6 +369,12 @@ bool EGLRenderer::compileShaders() { m_ShaderProgramParams[NV12_PARAM_CHROMA_OFFSET] = glGetUniformLocation(m_ShaderProgram, "chromaOffset"); m_ShaderProgramParams[NV12_PARAM_PLANE1] = glGetUniformLocation(m_ShaderProgram, "plane1"); m_ShaderProgramParams[NV12_PARAM_PLANE2] = glGetUniformLocation(m_ShaderProgram, "plane2"); + + // Set up constant uniforms + glUseProgram(m_ShaderProgram); + glUniform1i(m_ShaderProgramParams[NV12_PARAM_PLANE1], 0); + glUniform1i(m_ShaderProgramParams[NV12_PARAM_PLANE2], 1); + glUseProgram(0); } else if (m_EGLImagePixelFormat == AV_PIX_FMT_DRM_PRIME) { m_ShaderProgram = compileShader("egl_opaque.vert", "egl_opaque.frag"); @@ -375,6 +383,11 @@ bool EGLRenderer::compileShaders() { } m_ShaderProgramParams[OPAQUE_PARAM_TEXTURE] = glGetUniformLocation(m_ShaderProgram, "uTexture"); + + // Set up constant uniforms + glUseProgram(m_ShaderProgram); + glUniform1i(m_ShaderProgramParams[OPAQUE_PARAM_TEXTURE], 0); + glUseProgram(0); } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, @@ -391,6 +404,10 @@ bool EGLRenderer::compileShaders() { m_OverlayShaderProgramParams[OVERLAY_PARAM_TEXTURE] = glGetUniformLocation(m_OverlayShaderProgram, "uTexture"); + glUseProgram(m_OverlayShaderProgram); + glUniform1i(m_OverlayShaderProgramParams[OVERLAY_PARAM_TEXTURE], 0); + glUseProgram(0); + return true; } @@ -805,33 +822,26 @@ void EGLRenderer::renderFrame(AVFrame* frame) glUseProgram(m_ShaderProgram); m_glBindVertexArrayOES(m_VAO); - // Bind parameters for the shaders - if (m_EGLImagePixelFormat == AV_PIX_FMT_NV12 || m_EGLImagePixelFormat == AV_PIX_FMT_P010) { - // If the frame format has changed, we'll need to recompute the constants - if (hasFrameFormatChanged(frame)) { - getFramePremultipliedCscConstants(frame, m_PremultipliedColorMatrix, m_YuvOffsets); + // If the frame format has changed, we'll need to recompute the constants + if (hasFrameFormatChanged(frame) && (m_EGLImagePixelFormat == AV_PIX_FMT_NV12 || m_EGLImagePixelFormat == AV_PIX_FMT_P010)) { + std::array colorMatrix; + std::array yuvOffsets; + std::array chromaOffset; - getFrameChromaCositingOffsets(frame, m_ChromaOffset); - m_ChromaOffset[0] /= frame->width; - m_ChromaOffset[1] /= frame->height; - } + getFramePremultipliedCscConstants(frame, colorMatrix, yuvOffsets); + getFrameChromaCositingOffsets(frame, chromaOffset); + chromaOffset[0] /= frame->width; + chromaOffset[1] /= frame->height; - glUniformMatrix3fv(m_ShaderProgramParams[NV12_PARAM_YUVMAT], 1, GL_FALSE, m_PremultipliedColorMatrix.data()); - glUniform3fv(m_ShaderProgramParams[NV12_PARAM_OFFSET], 1, m_YuvOffsets.data()); - glUniform2fv(m_ShaderProgramParams[NV12_PARAM_CHROMA_OFFSET], 1, m_ChromaOffset.data()); - glUniform1i(m_ShaderProgramParams[NV12_PARAM_PLANE1], 0); - glUniform1i(m_ShaderProgramParams[NV12_PARAM_PLANE2], 1); - } - else if (m_EGLImagePixelFormat == AV_PIX_FMT_DRM_PRIME) { - glUniform1i(m_ShaderProgramParams[OPAQUE_PARAM_TEXTURE], 0); + glUniformMatrix3fv(m_ShaderProgramParams[NV12_PARAM_YUVMAT], 1, GL_FALSE, colorMatrix.data()); + glUniform3fv(m_ShaderProgramParams[NV12_PARAM_OFFSET], 1, yuvOffsets.data()); + glUniform2fv(m_ShaderProgramParams[NV12_PARAM_CHROMA_OFFSET], 1, chromaOffset.data()); } glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); m_glBindVertexArrayOES(0); - // Adjust the viewport to the whole window before rendering the overlays - glViewport(0, 0, drawableWidth, drawableHeight); for (int i = 0; i < Overlay::OverlayMax; i++) { renderOverlay((Overlay::OverlayType)i, drawableWidth, drawableHeight); } diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.h b/app/streaming/video/ffmpeg-renderers/eglvid.h index 6ae79b08..09e953e0 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.h +++ b/app/streaming/video/ffmpeg-renderers/eglvid.h @@ -63,9 +63,6 @@ private: #define NV12_PARAM_PLANE1 3 #define NV12_PARAM_PLANE2 4 #define OPAQUE_PARAM_TEXTURE 0 - std::array m_PremultipliedColorMatrix; - std::array m_YuvOffsets; - std::array m_ChromaOffset; int m_ShaderProgramParams[5]; #define OVERLAY_PARAM_TEXTURE 0