diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index e2d132726f..2a7c290f37 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -110,6 +110,9 @@ public: class GLRProgram { public: ~GLRProgram() { + if (deleteCallback_) { + deleteCallback_(deleteParam_); + } if (program) { glDeleteProgram(program); } @@ -162,6 +165,15 @@ public: return loc; } + void SetDeleteCallback(void(*cb)(void *), void *p) { + deleteCallback_ = cb; + deleteParam_ = p; + } + +private: + void(*deleteCallback_)(void *) = nullptr; + void *deleteParam_ = nullptr; + std::unordered_map uniformCache_; }; diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 5cb0ba71f6..79a63be54c 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -212,8 +212,17 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs, dirtyUniforms = DIRTY_ALL_UNIFORMS; } -LinkedShader::~LinkedShader() { +void LinkedShader::Delete() { + program->SetDeleteCallback([](void *thiz) { + LinkedShader *ls = (LinkedShader *)thiz; + delete ls; + }, this); render_->DeleteProgram(program); + program = nullptr; +} + +LinkedShader::~LinkedShader() { + _assert_(program == nullptr); } // Utility @@ -691,7 +700,7 @@ ShaderManagerGLES::~ShaderManagerGLES() { void ShaderManagerGLES::Clear() { DirtyLastShader(); for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) { - delete iter->ls; + iter->ls->Delete(); } fsCache_.Iterate([&](const FShaderID &key, Shader *shader) { delete shader; diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index a768ff35a1..b37604ba5d 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -42,6 +42,7 @@ public: void use(const ShaderID &VSID); void UpdateUniforms(const ShaderID &VSID, bool useBufferedRendering, const ShaderLanguageDesc &shaderLanguage); + void Delete(); GLRenderManager *render_; Shader *vs_;