From b534e640ca3da898cc737414696f59b23a3b62f9 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Thu, 16 Dec 2004 12:01:47 +0000 Subject: [PATCH] Resource leak fixes This was SVN commit r1513. --- source/graphics/MeshManager.h | 2 +- source/graphics/Model.cpp | 5 ++++ source/graphics/TextureEntry.cpp | 12 ++++++-- source/graphics/TextureEntry.h | 3 +- source/gui/GUIRenderer.cpp | 47 ++++++++++++++++++++++++++++---- source/gui/GUIRenderer.h | 12 +++++++- source/renderer/Renderer.cpp | 17 ++++-------- 7 files changed, 76 insertions(+), 22 deletions(-) diff --git a/source/graphics/MeshManager.h b/source/graphics/MeshManager.h index 488c0b4ef4..6ba9a319cd 100755 --- a/source/graphics/MeshManager.h +++ b/source/graphics/MeshManager.h @@ -6,7 +6,7 @@ #include "boost/shared_ptr.hpp" #include "boost/weak_ptr.hpp" -// + #define g_MeshManager CMeshManager::GetSingleton() class CModelDef; diff --git a/source/graphics/Model.cpp b/source/graphics/Model.cpp index 9de1f6a195..d895760611 100755 --- a/source/graphics/Model.cpp +++ b/source/graphics/Model.cpp @@ -16,6 +16,7 @@ #include "SkeletonAnimDef.h" #include "SkeletonAnimManager.h" #include "MeshManager.h" +#include "lib/res/ogl_tex.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -43,6 +44,10 @@ void CModel::ReleaseData() } m_Props.clear(); m_pModelDef = CModelDefPtr(); + + Handle h = m_Texture.GetHandle(); + tex_free(h); + m_Texture.SetHandle(0); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/graphics/TextureEntry.cpp b/source/graphics/TextureEntry.cpp index 2a784e978d..46bcef0a92 100755 --- a/source/graphics/TextureEntry.cpp +++ b/source/graphics/TextureEntry.cpp @@ -10,11 +10,19 @@ ///////////////////////////////////////////////////////////////////////////////////// // CTextureEntry constructor -CTextureEntry::CTextureEntry(const char* name,int type) - : m_Name(name), m_Bitmap(0), m_Handle(0xffffffff), m_BaseColor(0), m_Type(type), m_BaseColorValid(false) +CTextureEntry::CTextureEntry(const char* name,int type) + : m_Name(name), m_Bitmap(0), m_Handle(-1), m_BaseColor(0), m_Type(type), m_BaseColorValid(false) { } +///////////////////////////////////////////////////////////////////////////////////// +// CTextureEntry destructor +CTextureEntry::~CTextureEntry() +{ + if (m_Handle > 0) + tex_free(m_Handle); +} + ///////////////////////////////////////////////////////////////////////////////////// // LoadTexture: actually load the texture resource from file void CTextureEntry::LoadTexture() diff --git a/source/graphics/TextureEntry.h b/source/graphics/TextureEntry.h index 0ad3786e06..5c923af532 100755 --- a/source/graphics/TextureEntry.h +++ b/source/graphics/TextureEntry.h @@ -11,6 +11,7 @@ class CTextureEntry { public: CTextureEntry(const char* name,int type); + ~CTextureEntry(); // accessor - return texture name const char* GetName() const { return (const char*) m_Name; } @@ -22,7 +23,7 @@ public: // accessor - get texture handle Handle GetHandle() { - if (m_Handle==0xffffffff) LoadTexture(); + if (m_Handle==-1) LoadTexture(); return m_Handle; } // accessor - get mipmap color diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index 6bd3c70848..1d67bc12de 100644 --- a/source/gui/GUIRenderer.cpp +++ b/source/gui/GUIRenderer.cpp @@ -3,10 +3,45 @@ #include "GUIRenderer.h" #include "lib/ogl.h" +#include "lib/res/h_mgr.h" #include "ps/CLogger.h" #define LOG_CATEGORY "gui" +using namespace GUIRenderer; + +// Copyable texture Handle, for use in STL containers where the Handle should +// be freed when it's finished with. + +Handle_rfcnt_tex::Handle_rfcnt_tex() +: h(0) +{ +} + +Handle_rfcnt_tex::Handle_rfcnt_tex(Handle h_) +: h(h_) +{ +} + +Handle_rfcnt_tex::Handle_rfcnt_tex(const Handle_rfcnt_tex& that) +{ + h = that.h; + if (h) h_add_ref(h); +} + +Handle_rfcnt_tex::~Handle_rfcnt_tex() +{ + if (h) tex_free(h); +} + +Handle_rfcnt_tex& Handle_rfcnt_tex::operator=(Handle h_) +{ + h = h_; + return *this; +} + +// Functions to perform drawing-related actions: + void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, CStr &SpriteName, CRect &Size, std::map &Sprites) { Calls.clear(); @@ -42,17 +77,17 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, CStr &SpriteName, CRect return; } - Call.m_TexHandle = h; - - int err = tex_upload(Call.m_TexHandle); + int err = tex_upload(h); if (err < 0) { LOG(ERROR, LOG_CATEGORY, "Error uploading texture '%s': %d", (const char*)cit->m_TextureName, err); return; } + Call.m_TexHandle = h; + int fmt, t_w, t_h; - tex_info(Call.m_TexHandle, &t_w, &t_h, &fmt, NULL, NULL); + tex_info(h, &t_w, &t_h, &fmt, NULL, NULL); Call.m_EnableBlending = (fmt == GL_RGBA || fmt == GL_BGRA); CRect real = cit->m_Size.GetClientArea(Size); @@ -121,14 +156,14 @@ void GUIRenderer::Draw(DrawCalls &Calls) glDisable(GL_BLEND); } - if (cit->m_TexHandle) + if (cit->m_TexHandle.h) { // TODO: Handle the GL state in a nicer way glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - tex_bind(cit->m_TexHandle); + tex_bind(cit->m_TexHandle.h); glBegin(GL_QUADS); diff --git a/source/gui/GUIRenderer.h b/source/gui/GUIRenderer.h index 1c190e9240..d4e15522ae 100644 --- a/source/gui/GUIRenderer.h +++ b/source/gui/GUIRenderer.h @@ -8,9 +8,19 @@ namespace GUIRenderer { + struct Handle_rfcnt_tex + { + Handle h; + Handle_rfcnt_tex(); + Handle_rfcnt_tex(Handle h_); + Handle_rfcnt_tex(const Handle_rfcnt_tex& that); + ~Handle_rfcnt_tex(); + Handle_rfcnt_tex& operator=(Handle h_); + }; + struct SDrawCall { - Handle m_TexHandle; + Handle_rfcnt_tex m_TexHandle; bool m_EnableBlending; diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 7b8b96e1f9..4ade9dfa85 100755 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -995,25 +995,17 @@ void CRenderer::Submit(COverlay* overlay) void CRenderer::RenderPatchSubmissions() { // switch on required client states - MICROLOG(L"enable vertex array"); glEnableClientState(GL_VERTEX_ARRAY); - MICROLOG(L"enable color array"); glEnableClientState(GL_COLOR_ARRAY); - MICROLOG(L"enable tex coord array"); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // render everything - MICROLOG(L"render base splats"); CPatchRData::RenderBaseSplats(); - MICROLOG(L"render blend splats"); CPatchRData::RenderBlendSplats(); // switch off all client states - MICROLOG(L"disable tex coord array"); glDisableClientState(GL_TEXTURE_COORD_ARRAY); - MICROLOG(L"disable color array"); glDisableClientState(GL_COLOR_ARRAY); - MICROLOG(L"disable vertex array"); glDisableClientState(GL_VERTEX_ARRAY); } @@ -1023,16 +1015,18 @@ void CRenderer::RenderPatchSubmissions() // LoadTexture: try and load the given texture; set clamp/repeat flags on texture object if necessary bool CRenderer::LoadTexture(CTexture* texture,u32 wrapflags) { + const Handle errorhandle = -1; + Handle h=texture->GetHandle(); if (h) { // already tried to load this texture, nothing to do here - just return success according // to whether this is a valid handle or not - return h==0xffffffff ? true : false; + return h==errorhandle ? true : false; } else { h=tex_load(texture->GetName()); if (h <= 0) { LOG(ERROR, LOG_CATEGORY, "LoadTexture failed on \"%s\"",(const char*) texture->GetName()); - texture->SetHandle(0xffffffff); + texture->SetHandle(errorhandle); return false; } else { int tw,th; @@ -1041,8 +1035,9 @@ bool CRenderer::LoadTexture(CTexture* texture,u32 wrapflags) tw&=(tw-1); th&=(th-1); if (tw || th) { - texture->SetHandle(0xffffffff); LOG(ERROR, LOG_CATEGORY, "LoadTexture failed on \"%s\" : not a power of 2 texture",(const char*) texture->GetName()); + tex_free(h); + texture->SetHandle(errorhandle); return false; } else { BindTexture(0,tex_id(h));