From db8f7fc72d6abd6df84200e1917672ec0b9a6d08 Mon Sep 17 00:00:00 2001 From: Nick Renieris Date: Mon, 14 Oct 2019 18:20:48 +0200 Subject: [PATCH] retroplayer/gl: Don't allocate render buffers every frame Fixes stuttering (occasional black frames every few seconds). --- .../VideoRenderers/RPRendererOpenGL.cpp | 38 +++++++++++++------ .../VideoRenderers/RPRendererOpenGL.h | 11 ++++++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp index 4cdb706bed375..93d06c712f54e 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp @@ -293,11 +293,31 @@ void CRPRendererOpenGL::Render(uint8_t alpha) const uint32_t color = (alpha << 24) | 0xFFFFFF; - const std::unique_ptr sourceTexture(new CGLTexture( - static_cast(renderBuffer->GetWidth()), - static_cast(renderBuffer->GetHeight()), - GL_RGB, - renderBuffer->TextureID())); + RenderBufferTextures *rbTextures; + const auto it = m_RBTexturesMap.find(renderBuffer); + if (it != m_RBTexturesMap.end()) + { + rbTextures = it->second.get(); + } else { + // We can't copy or move CGLTexture, so construct source/target in-place + rbTextures = new RenderBufferTextures{ + { // source texture + static_cast(renderBuffer->GetWidth()), + static_cast(renderBuffer->GetHeight()), + GL_RGB, + renderBuffer->TextureID() + }, + { + // target texture + static_cast(m_context.GetScreenWidth()), + static_cast(m_context.GetScreenHeight()) + } + }; + m_RBTexturesMap.emplace(renderBuffer, rbTextures); + } + + const auto sourceTexture = &rbTextures->source; + const auto targetTexture = &rbTextures->target; glBindTexture(m_textureTarget, sourceTexture->getMTexture()); @@ -320,14 +340,10 @@ void CRPRendererOpenGL::Render(uint8_t alpha) m_rotatedDestCoords[3] }; - const std::unique_ptr renderTargetTexture(new CGLTexture( - static_cast(m_context.GetScreenWidth()), - static_cast(m_context.GetScreenHeight()))); - - renderTargetTexture->CreateTextureObject(); + targetTexture->CreateTextureObject(); SHADER::CShaderTextureGL source(*sourceTexture); - SHADER::CShaderTextureGL target(*renderTargetTexture); + SHADER::CShaderTextureGL target(*targetTexture); if (!m_shaderPreset->RenderUpdate(destPoints, &source, &target)) { m_shadersNeedUpdate = false; diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.h b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.h index 6ebd4b81009ad..92bd0299285d7 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.h +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.h @@ -10,14 +10,19 @@ #include "RPBaseRenderer.h" #include "cores/RetroPlayer/process/RPProcessInfo.h" +#include "guilib/TextureGL.h" #include "system_gl.h" +#include + namespace KODI { namespace RETRO { class CRenderContext; + class CRenderBufferOpenGL; + class CRendererFactoryOpenGL : public IRendererFactory { @@ -54,6 +59,10 @@ namespace RETRO float y; float z; }; + struct RenderBufferTextures { + CGLTexture source; + CGLTexture target; + }; // implementation of CRPBaseRenderer bool ConfigureInternal() override; @@ -76,6 +85,8 @@ namespace RETRO virtual void Render(uint8_t alpha); + std::map> m_RBTexturesMap; + GLuint m_mainVAO; GLuint m_mainVertexVBO; GLuint m_mainIndexVBO;