diff --git a/rts/Lua/LuaContextData.h b/rts/Lua/LuaContextData.h index ee3d78c4f8d..9c14354021b 100644 --- a/rts/Lua/LuaContextData.h +++ b/rts/Lua/LuaContextData.h @@ -49,7 +49,7 @@ struct GLMatrixStateTracker { return matrixData.mode; } - int &GetDepth(unsigned int mode) { + int& GetDepth(unsigned int mode) { switch (mode) { case GL_MODELVIEW: return matrixData.modelView; case GL_PROJECTION: return matrixData.projection; @@ -63,7 +63,7 @@ struct GLMatrixStateTracker { bool PushMatrix() { unsigned int mode = GetMode(); - int &depth = GetDepth(mode); + int& depth = GetDepth(mode); if (!listMode && depth >= 255) return false; depth += 1; @@ -72,7 +72,7 @@ struct GLMatrixStateTracker { bool PopMatrix() { unsigned int mode = GetMode(); - int &depth = GetDepth(mode); + int& depth = GetDepth(mode); if (listMode) { depth -= 1; return true; @@ -165,6 +165,7 @@ struct GLMatrixStateTracker { struct luaContextData { +public: luaContextData() : owner(nullptr) , luamutex(nullptr) @@ -184,6 +185,15 @@ struct luaContextData { , selectTeam(CEventClient::NoAccessTeam) , parser(nullptr) {} + void Clear() { + shaders.Clear(); + textures.Clear(); + fbos.Clear(); + rbos.Clear(); + displayLists.Clear(); + } + +public: CLuaHandle* owner; spring::recursive_mutex* luamutex; diff --git a/rts/Lua/LuaDisplayLists.h b/rts/Lua/LuaDisplayLists.h index 7619934d5b6..bec898c5f44 100644 --- a/rts/Lua/LuaDisplayLists.h +++ b/rts/Lua/LuaDisplayLists.h @@ -20,21 +20,20 @@ struct SMatrixStateData { class CLuaDisplayLists { public: - CLuaDisplayLists() - { - active.push_back(DLdata(0)); - } - + CLuaDisplayLists() { Clear(); } ~CLuaDisplayLists() { // free the display lists - for (int i = 0; i < (int)active.size(); i++) { + // NOTE: + // it is not an error to delete a list with id=0, but we might + // be called from ~LuaParser which can run in multiple threads + // and the null-list is always present (even after Clear()) + for (size_t i = 1; i < active.size(); i++) { glDeleteLists(active[i].id, 1); } } - void Clear() - { + void Clear() { unused.clear(); active.clear(); active.push_back(DLdata(0)); @@ -44,27 +43,25 @@ class CLuaDisplayLists { GLuint GetDList(unsigned int index) const { - if (index < active.size()) { + if (index < active.size()) return active[index].id; - } else { - return 0; - } + + return 0; } SMatrixStateData GetMatrixState(unsigned int index) const { - if (index < active.size()) { + if (index < active.size()) return active[index].matData; - } else { - return SMatrixStateData(); - } + + return SMatrixStateData(); } unsigned int NewDList(GLuint dlist, SMatrixStateData& m) { - if (dlist == 0) { + if (dlist == 0) return 0; - } + if (!unused.empty()) { const unsigned int index = unused[unused.size() - 1]; active[index] = DLdata(dlist, m); diff --git a/rts/Lua/LuaFBOs.h b/rts/Lua/LuaFBOs.h index 16d84889801..32857c3bea6 100644 --- a/rts/Lua/LuaFBOs.h +++ b/rts/Lua/LuaFBOs.h @@ -16,6 +16,8 @@ class LuaFBOs { LuaFBOs() { fbos.reserve(8); } ~LuaFBOs(); + void Clear() { fbos.clear(); } + struct FBO { void Init(lua_State* L); void Free(lua_State* L); diff --git a/rts/Lua/LuaParser.cpp b/rts/Lua/LuaParser.cpp index 73f6013276b..3be79f408c9 100644 --- a/rts/Lua/LuaParser.cpp +++ b/rts/Lua/LuaParser.cpp @@ -85,6 +85,10 @@ LuaParser::LuaParser(const string& _textChunk, const string& _accessModes, const LuaParser::~LuaParser() { + // prevent crashes in glDelete* calls since LuaParser + // might be constructed by multiple different threads + D.Clear(); + if (L != nullptr) LUA_CLOSE(&L); diff --git a/rts/Lua/LuaRBOs.h b/rts/Lua/LuaRBOs.h index 2fb04e3a817..fe96fe7265f 100644 --- a/rts/Lua/LuaRBOs.h +++ b/rts/Lua/LuaRBOs.h @@ -16,6 +16,8 @@ class LuaRBOs { LuaRBOs() { rbos.reserve(8); } ~LuaRBOs(); + void Clear() { rbos.clear(); } + static bool PushEntries(lua_State* L); struct RBO; diff --git a/rts/Lua/LuaShaders.h b/rts/Lua/LuaShaders.h index 510d9a4eed6..5c8463eee0e 100644 --- a/rts/Lua/LuaShaders.h +++ b/rts/Lua/LuaShaders.h @@ -19,6 +19,11 @@ class LuaShaders { LuaShaders(); ~LuaShaders(); + void Clear() { + programs.clear(); + unused.clear(); + } + std::string errorLog; GLuint GetProgramName(unsigned int progIdx) const; diff --git a/rts/Lua/LuaTextures.h b/rts/Lua/LuaTextures.h index 07ed33e36f2..d000a7f18ba 100644 --- a/rts/Lua/LuaTextures.h +++ b/rts/Lua/LuaTextures.h @@ -21,6 +21,12 @@ class LuaTextures { lastCode = 0; } + void Clear() { + textureVec.clear(); + textureMap.clear(); + freeIndices.clear(); + } + struct Texture { Texture() : name(""), id(0), fbo(0), fboDepth(0),