Fix shutdown crash caused by C# finalizers deleting texture objects after renderdevice already left the building

This commit is contained in:
Magnus Norddahl 2019-12-26 00:37:47 +01:00
parent 718405b580
commit 994eda4852
6 changed files with 27 additions and 5 deletions

View file

@ -27,6 +27,8 @@ GLIndexBuffer::~GLIndexBuffer()
{
if (Device && mBuffer != 0)
{
Device->mIndexBuffers.erase(ItBuffer);
Device = nullptr;
glDeleteBuffers(1, &mBuffer);
mBuffer = 0;
}

View file

@ -22,6 +22,7 @@
#pragma once
#include "../Backend.h"
#include <list>
class GLRenderDevice;
@ -33,6 +34,7 @@ public:
GLuint GetBuffer();
GLRenderDevice* Device = nullptr;
std::list<GLIndexBuffer*>::iterator ItBuffer;
private:
GLuint mBuffer = 0;

View file

@ -82,6 +82,11 @@ GLRenderDevice::~GLRenderDevice()
{
Context->MakeCurrent();
ProcessDeleteList();
for (GLTexture* tex : mTextures) mDeleteList.Textures.push_back(tex);
for (GLIndexBuffer* buffer : mIndexBuffers) mDeleteList.IndexBuffers.push_back(buffer);
for (GLVertexBuffer* buffer : mSharedVertexBuffers[0]->VertexBuffers) mDeleteList.VertexBuffers.push_back(buffer);
for (GLVertexBuffer* buffer : mSharedVertexBuffers[1]->VertexBuffers) mDeleteList.VertexBuffers.push_back(buffer);
ProcessDeleteList();
glDeleteBuffers(1, &mStreamVertexBuffer);
@ -89,9 +94,6 @@ GLRenderDevice::~GLRenderDevice()
for (auto& sharedbuf : mSharedVertexBuffers)
{
for (GLVertexBuffer* buf : sharedbuf->VertexBuffers)
buf->Device = nullptr;
GLuint handle = sharedbuf->GetBuffer();
glDeleteBuffers(1, &handle);
handle = sharedbuf->GetVAO();
@ -107,6 +109,7 @@ GLRenderDevice::~GLRenderDevice()
}
}
mShaderManager->ReleaseResources();
Context->ClearCurrent();
}
@ -584,6 +587,11 @@ bool GLRenderDevice::SetIndexBufferData(IndexBuffer* ibuffer, void* data, int64_
{
CheckContext();
GLIndexBuffer* buffer = static_cast<GLIndexBuffer*>(ibuffer);
if (buffer->Device == nullptr)
{
buffer->ItBuffer = mIndexBuffers.insert(mIndexBuffers.end(), buffer);
buffer->Device = this;
}
GLint oldbinding = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &oldbinding);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->GetBuffer());
@ -960,9 +968,11 @@ void GLRenderDevice::DeleteObject(GLTexture* texture)
void GLRenderDevice::ProcessDeleteList()
{
std::unique_lock<std::mutex> lock(GLRenderDevice::GetMutex());
for (auto buffer : mDeleteList.IndexBuffers) delete buffer;
for (auto buffer : mDeleteList.VertexBuffers) delete buffer;
for (auto texture : mDeleteList.Textures) delete texture;
mDeleteList.IndexBuffers.clear();
mDeleteList.VertexBuffers.clear();
mDeleteList.Textures.clear();

View file

@ -23,6 +23,7 @@
#include "../Backend.h"
#include "OpenGLContext.h"
#include <list>
class GLSharedVertexBuffer;
class GLShader;
@ -150,6 +151,9 @@ public:
std::unique_ptr<GLSharedVertexBuffer> mSharedVertexBuffers[2];
std::list<GLTexture*> mTextures;
std::list<GLIndexBuffer*> mIndexBuffers;
std::unique_ptr<GLShaderManager> mShaderManager;
ShaderName mShaderName = {};

View file

@ -120,6 +120,7 @@ void GLTexture::Invalidate()
mFramebuffer = 0;
mTexture = 0;
mPBO = 0;
if (Device) Device->mTextures.erase(ItTexture);
Device = nullptr;
}
@ -128,6 +129,7 @@ GLuint GLTexture::GetTexture(GLRenderDevice* device)
if (mTexture == 0)
{
Device = device;
ItTexture = Device->mTextures.insert(Device->mTextures.end(), this);
GLint oldActiveTex = GL_TEXTURE0;
glGetIntegerv(GL_ACTIVE_TEXTURE, &oldActiveTex);
@ -174,7 +176,7 @@ GLuint GLTexture::GetFramebuffer(GLRenderDevice* device, bool usedepthbuffer)
{
if (mFramebuffer == 0)
{
GLuint texture = GetTexture(Device);
GLuint texture = GetTexture(device);
glGenFramebuffers(1, &mFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
@ -197,7 +199,7 @@ GLuint GLTexture::GetFramebuffer(GLRenderDevice* device, bool usedepthbuffer)
if (mFramebuffer == 0)
{
GLuint texture = GetTexture(Device);
GLuint texture = GetTexture(device);
glGenFramebuffers(1, &mFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

View file

@ -22,6 +22,7 @@
#pragma once
#include "../Backend.h"
#include <list>
class GLRenderDevice;
@ -49,6 +50,7 @@ public:
GLuint GetPBO(GLRenderDevice* device);
GLRenderDevice* Device = nullptr;
std::list<GLTexture*>::iterator ItTexture;
private:
int mWidth = 0;