Commit 85260dd7 authored by hybrid's avatar hybrid

Add texture cache with proper reference handling. This avoids deletion of...

Add texture cache with proper reference handling. This avoids deletion of textures while still being active on the GPU. Test case and fix by m(att)giuca

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4151 dfc29bdd-3216-0410-991c-e03cc46cb475
parent cf9e1223
......@@ -624,9 +624,9 @@ COpenGLDriver::~COpenGLDriver()
deleteMaterialRenders();
CurrentTexture.clear();
// I get a blue screen on my laptop, when I do not delete the
// textures manually before releasing the dc. Oh how I love this.
deleteAllTextures();
removeAllOcclusionQueries();
removeAllHardwareBuffers();
......@@ -673,8 +673,7 @@ bool COpenGLDriver::genericDriverInit()
}
u32 i;
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
CurrentTexture[i]=0;
CurrentTexture.clear();
// load extensions
initExtensions(Params.Stencilbuffer);
if (queryFeature(EVDF_ARB_GLSL))
......@@ -2433,7 +2432,7 @@ bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
if (MultiTextureExtension)
extGlActiveTexture(GL_TEXTURE0_ARB + stage);
CurrentTexture[stage]=texture;
CurrentTexture.set(stage,texture);
if (!texture)
{
......@@ -2445,7 +2444,7 @@ bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
if (texture->getDriverType() != EDT_OPENGL)
{
glDisable(GL_TEXTURE_2D);
CurrentTexture[stage]=0;
CurrentTexture.set(stage, 0);
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
return false;
}
......@@ -3818,6 +3817,17 @@ void COpenGLDriver::draw3DLine(const core::vector3df& start,
}
//! Removes a texture from the texture cache and deletes it, freeing lot of memory.
void COpenGLDriver::removeTexture(ITexture* texture)
{
if (!texture)
return;
CNullDriver::removeTexture(texture);
// Remove this texture from CurrentTexture as well
CurrentTexture.remove(texture);
}
//! Only used by the internal engine. Used to notify the driver that
//! the window was resized.
......
......@@ -387,6 +387,9 @@ namespace video
ITexture* createDepthTexture(ITexture* texture, bool shared=true);
void removeDepthTexture(ITexture* texture);
//! Removes a texture from the texture cache and deletes it, freeing lot of memory.
void removeTexture(ITexture* texture);
//! Convert E_PRIMITIVE_TYPE to OpenGL equivalent
GLenum primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const;
......@@ -467,7 +470,70 @@ namespace video
SMaterial Material, LastMaterial;
COpenGLTexture* RenderTargetTexture;
core::array<video::IRenderTarget> MRTargets;
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
class STextureStageCache
{
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
public:
STextureStageCache()
{
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{
CurrentTexture[i] = 0;
}
}
~STextureStageCache()
{
clear();
}
void set(u32 stage, const ITexture* tex)
{
if (stage<MATERIAL_MAX_TEXTURES)
{
const ITexture* oldTexture=CurrentTexture[stage];
if (tex)
tex->grab();
CurrentTexture[stage]=tex;
if (oldTexture)
oldTexture->drop();
}
}
const ITexture* operator[](int stage) const
{
if (stage<MATERIAL_MAX_TEXTURES)
return CurrentTexture[stage];
else
return 0;
}
void remove(const ITexture* tex)
{
for (s32 i = MATERIAL_MAX_TEXTURES-1; i>= 0; --i)
{
if (CurrentTexture[i] == tex)
{
tex->drop();
CurrentTexture[i] = 0;
}
}
}
void clear()
{
// Drop all the CurrentTexture handles
for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
{
if (CurrentTexture[i])
{
CurrentTexture[i]->drop();
CurrentTexture[i] = 0;
}
}
}
};
STextureStageCache CurrentTexture;
core::array<ITexture*> DepthTextures;
struct SUserClipPlane
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment