mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
GLES: Free textures on device lost, and unsubmitted step data at exit
- The texture and fragment test caches dropped their GLRTexture objects on DeviceLost without queueing them for deletion, leaking them on every Android background/resume. The deleter already skips the GL calls when the context is gone. - GLRenderManager::ThreadEnd cleared unsubmitted init and render steps without freeing the data they own. Run them through the dry run instead, which now also frees stereo matrices and shader code. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
b72927bbeb
commit
39049a67fd
5 files changed
+14
-9
No files matched your search
@@ -147,6 +147,7 @@ void GLQueueRunner::RunInitSteps(const FastVec<GLRInitStep> &steps, bool skipGLC
|
||||
case GLRInitStepType::CREATE_SHADER:
|
||||
{
|
||||
WARN_LOG(Log::G3D, "CREATE_SHADER found with skipGLCalls, not good");
|
||||
delete[] step.create_shader.code;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -678,6 +679,9 @@ void GLQueueRunner::RunSteps(const std::vector<GLRStep *> &steps, GLFrameData &f
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GLRRenderCommand::UNIFORMSTEREOMATRIX:
|
||||
delete[] c.uniformStereoMatrix4.mData;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -110,11 +110,11 @@ void GLRenderManager::ThreadEnd() {
|
||||
frameData_[i].deleter_prev.Perform(this, skipGLCalls_);
|
||||
}
|
||||
deleter_.Perform(this, skipGLCalls_);
|
||||
for (int i = 0; i < (int)steps_.size(); i++) {
|
||||
delete steps_[i];
|
||||
}
|
||||
steps_.clear();
|
||||
// Steps that never got submitted. A dry run frees the data they own (texture uploads etc), and the steps.
|
||||
queueRunner_.RunInitSteps(initSteps_, true);
|
||||
initSteps_.clear();
|
||||
queueRunner_.RunSteps(steps_, frameData_[0], true, false, false);
|
||||
steps_.clear();
|
||||
INFO_LOG(Log::G3D, "GLRenderManager::ThreadEnd end");
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ GLRTexture *FragmentTestCacheGLES::CreateTestTexture(const GEComparison funcs[4]
|
||||
}
|
||||
|
||||
void FragmentTestCacheGLES::Clear(bool deleteThem) {
|
||||
if (deleteThem) {
|
||||
if (deleteThem && render_) {
|
||||
for (const auto &[_, v] : cache_) {
|
||||
render_->DeleteTexture(v.texture);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,8 @@ public:
|
||||
void BindTestTexture(int slot);
|
||||
|
||||
void DeviceLost() {
|
||||
Clear(false);
|
||||
// Queue the deletes anyway, the deleter frees the GLRTexture objects and skips the GL calls if needed.
|
||||
Clear(true);
|
||||
render_ = nullptr;
|
||||
}
|
||||
void DeviceRestore(Draw::DrawContext *draw);
|
||||
|
||||
@@ -51,11 +51,11 @@ void TextureCacheGLES::SetFramebufferManager(FramebufferManagerGLES *fbManager)
|
||||
}
|
||||
|
||||
void TextureCacheGLES::ReleaseTexture(TexCacheEntry *entry, bool delete_them) {
|
||||
if (delete_them) {
|
||||
if (entry->textureName) {
|
||||
// Delete even when !delete_them (device lost): the GLRTexture is a heap object that only the deleter
|
||||
// frees, and the deleter skips the GL calls itself once the context is gone.
|
||||
if (entry->textureName && render_) {
|
||||
render_->DeleteTexture(entry->textureName);
|
||||
}
|
||||
}
|
||||
entry->textureName = nullptr;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user