Add ability to tag objects in the gl_lost_manager

This commit is contained in:
Henrik Rydgard 2017-03-18 13:01:08 +01:00
parent 961157551a
commit 378170d723
6 changed files with 34 additions and 21 deletions

View File

@ -145,7 +145,7 @@ DrawEngineGLES::DrawEngineGLES()
indexGen.Setup(decIndex);
InitDeviceObjects();
register_gl_resource_holder(this);
register_gl_resource_holder(this, "drawengine_gles");
tessDataTransfer = new TessellationDataTransferGLES(gl_extensions.VersionGEThan(3, 0, 0));
}
@ -200,7 +200,6 @@ void DrawEngineGLES::DestroyDeviceObjects() {
bufferNameInfo_.clear();
freeSizedBuffers_.clear();
bufferNameCacheSize_ = 0;
if (sharedVao_ != 0) {
glDeleteVertexArrays(1, &sharedVao_);
}
@ -209,7 +208,7 @@ void DrawEngineGLES::DestroyDeviceObjects() {
void DrawEngineGLES::GLLost() {
ILOG("TransformDrawEngine::GLLost()");
// The objects have already been deleted.
// The objects have already been deleted by losing the context, so we don't call DestroyDeviceObjects.
bufferNameCache_.clear();
bufferNameInfo_.clear();
freeSizedBuffers_.clear();

View File

@ -16,7 +16,7 @@ class ManagedTexture : public GfxResourceHolder {
public:
ManagedTexture(Draw::DrawContext *draw) : draw_(draw), texture_(nullptr) {
if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL)
register_gl_resource_holder(this);
register_gl_resource_holder(this, "managed_texture");
}
~ManagedTexture() {
if (texture_)

View File

@ -4,18 +4,23 @@
#include "base/logging.h"
#include "gfx/gl_lost_manager.h"
std::vector<GfxResourceHolder *> *holders;
struct Holder {
GfxResourceHolder *holder;
const char *desc;
};
std::vector<Holder> *holders;
static bool inLost;
static bool inRestore;
void register_gl_resource_holder(GfxResourceHolder *holder) {
void register_gl_resource_holder(GfxResourceHolder *holder, const char *desc) {
if (inLost || inRestore) {
FLOG("BAD: Should not call register_gl_resource_holder from lost/restore path");
return;
}
if (holders) {
holders->push_back(holder);
holders->push_back({ holder, desc });
} else {
WLOG("GL resource holder not initialized, cannot register resource");
}
@ -28,7 +33,7 @@ void unregister_gl_resource_holder(GfxResourceHolder *holder) {
}
if (holders) {
for (size_t i = 0; i < holders->size(); i++) {
if ((*holders)[i] == holder) {
if ((*holders)[i].holder == holder) {
holders->erase(holders->begin() + i);
return;
}
@ -47,12 +52,12 @@ void gl_restore() {
return;
}
ILOG("gl_restore() restoring %i items:", (int)holders->size());
ILOG("gl_restore() restoring %d items:", (int)holders->size());
for (size_t i = 0; i < holders->size(); i++) {
ILOG("gl_restore(%i / %i, %p, %08x)", (int)(i + 1), (int)holders->size(), (*holders)[i], *((uint32_t *)((*holders)[i])));
(*holders)[i]->GLRestore();
ILOG("gl_restore(%d / %d, %s)", (int)(i + 1), (int)holders->size(), (*holders)[i].desc);
(*holders)[i].holder->GLRestore();
}
ILOG("gl_restore() completed on %i items:", (int)holders->size());
ILOG("gl_restore() completed on %d items:", (int)holders->size());
inRestore = false;
}
@ -66,8 +71,8 @@ void gl_lost() {
ILOG("gl_lost() clearing %i items:", (int)holders->size());
for (size_t i = 0; i < holders->size(); i++) {
ILOG("gl_lost(%i / %i, %p, %08x)", (int)(i + 1), (int)holders->size(), (*holders)[i], *((uint32_t *)((*holders)[i])));
(*holders)[i]->GLLost();
ILOG("gl_lost(%d / %d, %s)", (int)(i + 1), (int)holders->size(), (*holders)[i].desc);
(*holders)[i].holder->GLLost();
}
ILOG("gl_lost() completed on %i items:", (int)holders->size());
inLost = false;
@ -78,7 +83,7 @@ void gl_lost_manager_init() {
FLOG("Double GL lost manager init");
// Dead here (FLOG), no need to delete holders
}
holders = new std::vector<GfxResourceHolder *>();
holders = new std::vector<Holder>();
}
void gl_lost_manager_shutdown() {

View File

@ -3,17 +3,26 @@
// On Android, even OpenGL can lose allocated resources. This is a utility to keep
// track of them.
// It's important to realize that with OpenGL, there's no Lost event that can be relied upon.
// The only solid indication we get is onSurfaceCreated. That is called every time the graphics
// surface that we render upon has been recreated. When that's called, we know that any
// gl resources we owned before it was called have been killed and need to be recreated.
// However, with D3D UWP, and potentially other platforms, there is a lost event.
// So we keep that infrastructure, but with GL we simply call both Lost and Restore when we detect a Restore.
class GfxResourceHolder {
public:
virtual ~GfxResourceHolder() {}
virtual void GLRestore() = 0;
virtual void GLLost() = 0;
virtual void GLRestore() = 0;
};
void gl_lost_manager_init();
void gl_lost_manager_shutdown();
void register_gl_resource_holder(GfxResourceHolder *holder);
// The string pointed to by desc must be a constant or otherwise live for the entire registered lifetime of the object.
void register_gl_resource_holder(GfxResourceHolder *holder, const char *desc);
void unregister_gl_resource_holder(GfxResourceHolder *holder);
// Notifies all objects it's time to forget / delete things.

View File

@ -49,7 +49,7 @@ GLSLProgram *glsl_create(const char *vshader, const char *fshader, std::string *
delete program;
return 0;
}
register_gl_resource_holder(program);
register_gl_resource_holder(program, "glsl_program");
return program;
}
@ -70,7 +70,7 @@ GLSLProgram *glsl_create_source(const char *vshader_src, const char *fshader_src
delete program;
return 0;
}
register_gl_resource_holder(program);
register_gl_resource_holder(program, "glsl_program_src");
return program;
}

View File

@ -369,7 +369,7 @@ class OpenGLPipeline : public Pipeline, GfxResourceHolder {
public:
OpenGLPipeline() {
program_ = 0;
register_gl_resource_holder(this);
register_gl_resource_holder(this, "drawcontext_pipeline");
}
~OpenGLPipeline() {
unregister_gl_resource_holder(this);
@ -890,7 +890,7 @@ public:
totalSize_ = size;
glBindBuffer(target_, buffer_);
glBufferData(target_, size, NULL, usage_);
register_gl_resource_holder(this);
register_gl_resource_holder(this, "drawcontext_buffer");
}
~OpenGLBuffer() override {
unregister_gl_resource_holder(this);