Fix crash clearing the texture cache on shutdown.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2374 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-02-22 20:21:56 +00:00
parent 16584c83d1
commit 769160dfbd
5 changed files with 35 additions and 44 deletions

View File

@ -472,11 +472,11 @@ void ConfigDialog::AdvancedSettingsChanged(wxCommandEvent& event)
case ID_TEXFMTOVERLAY:
g_Config.bTexFmtOverlayEnable = m_TexFmtOverlay->IsChecked();
m_TexFmtCenter->Enable(m_TexFmtOverlay->IsChecked());
TextureMngr::Invalidate();
TextureMngr::Invalidate(false);
break;
case ID_TEXFMTCENTER:
g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked();
TextureMngr::Invalidate();
TextureMngr::Invalidate(false);
break;
case ID_USEXFB:
g_Config.bUseXFB = m_UseXFB->IsChecked();

View File

@ -880,9 +880,9 @@ void Renderer::Swap(const TRectangle& rc)
// The picture width
PictureWidth = WinWidth / Ratio;
// Move the left of the picture to the middle of the screen
FloatXOffset = FloatXOffset + WinWidth / 2.0;
FloatXOffset = FloatXOffset + WinWidth / 2.0f;
// Then remove half the picture height to move it to the horizontal center
FloatXOffset = FloatXOffset - PictureWidth / 2.0;
FloatXOffset = FloatXOffset - PictureWidth / 2.0f;
// --------------------
}
// The window is to high, we have to limit the height
@ -1113,7 +1113,7 @@ void Renderer::SwapBuffers()
// Clean out old stuff from caches
PixelShaderCache::Cleanup();
TextureMngr::Cleanup();
TextureMngr::ProgressiveCleanup();
frameCount++;

View File

@ -129,19 +129,16 @@ void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode)
}
}
void TextureMngr::TCacheEntry::Destroy()
void TextureMngr::TCacheEntry::Destroy(bool shutdown)
{
if (!texture)
return;
glDeleteTextures(1, &texture);
if (!isRenderTarget) {
if (!g_Config.bSafeTextureCache) {
if (!isRenderTarget && !shutdown && !g_Config.bSafeTextureCache) {
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset * 4);
if (*ptr == hash)
if (ptr && *ptr == hash)
*ptr = oldpixel;
}
}
texture = 0;
}
@ -152,20 +149,20 @@ void TextureMngr::Init()
TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter);
}
void TextureMngr::Invalidate()
void TextureMngr::Invalidate(bool shutdown)
{
TexCache::iterator iter = textures.begin();
for (; iter!=textures.end(); iter++)
iter->second.Destroy();
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
iter->second.Destroy(shutdown);
textures.clear();
TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter);
}
void TextureMngr::Shutdown()
{
Invalidate();
Invalidate(true);
std::map<u32, DEPTHTARGET>::iterator itdepth = mapDepthTargets.begin();
for (itdepth = mapDepthTargets.begin(); itdepth != mapDepthTargets.end(); ++itdepth) {
for (itdepth = mapDepthTargets.begin(); itdepth != mapDepthTargets.end(); ++itdepth)
{
glDeleteRenderbuffersEXT(1, &itdepth->second.targ);
}
mapDepthTargets.clear();
@ -179,13 +176,15 @@ void TextureMngr::Shutdown()
temp = NULL;
}
void TextureMngr::Cleanup()
void TextureMngr::ProgressiveCleanup()
{
TexCache::iterator iter = textures.begin();
while (iter != textures.end()) {
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount) {
while (iter != textures.end())
{
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount)
{
if (!iter->second.isRenderTarget) {
iter->second.Destroy();
iter->second.Destroy(false);
#ifdef _WIN32
iter = textures.erase(iter);
#else
@ -193,7 +192,7 @@ void TextureMngr::Cleanup()
#endif
}
else {
iter->second.Destroy();
iter->second.Destroy(false);
#ifdef _WIN32
iter = textures.erase(iter);
#else
@ -206,7 +205,8 @@ void TextureMngr::Cleanup()
}
std::map<u32, DEPTHTARGET>::iterator itdepth = mapDepthTargets.begin();
while (itdepth != mapDepthTargets.end()) {
while (itdepth != mapDepthTargets.end())
{
if (frameCount > 20 + itdepth->second.framecount) {
#ifdef _WIN32
itdepth = mapDepthTargets.erase(itdepth);
@ -218,8 +218,6 @@ void TextureMngr::Cleanup()
}
}
//int dbgTexIdx=0;
TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt)
{
/* notes (about "UNsafe texture cache"):
@ -306,7 +304,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
}
else
{
entry.Destroy();
entry.Destroy(false);
textures.erase(iter);
}
}
@ -422,7 +420,6 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
dbgTexIdx++;
}
*/
//SaveTexture("tex.tga", target, entry.texture, entry.w, entry.h);
return &entry;
}
@ -541,7 +538,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
}
else if (bIsIntensityFmt) {
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f;
switch(copyfmt) {
switch (copyfmt) {
case 0: // I4
case 1: // I8
case 2: // IA4
@ -730,7 +727,6 @@ void TextureMngr::DisableStage(int stage)
void TextureMngr::ClearRenderTargets()
{
TexCache::iterator iter = textures.begin();
for (; iter!=textures.end(); iter++)
for (TexCache::iterator iter = textures.begin(); iter!=textures.end(); iter++)
iter->second.isRenderTarget = false;
}

View File

@ -49,7 +49,7 @@ public:
bool bHaveMipMaps;
void SetTextureParameters(TexMode0& newmode);
void Destroy();
void Destroy(bool shutdown);
void ConvertFromRenderTarget(u32 taddr, int twidth, int theight, int tformat, int tlutaddr, int tlutfmt);
};
@ -61,7 +61,7 @@ public:
};
private:
typedef std::map<u32,TCacheEntry> TexCache;
typedef std::map<u32, TCacheEntry> TexCache;
static u8 *temp;
static TexCache textures;
@ -70,9 +70,9 @@ private:
public:
static void Init();
static void Cleanup();
static void ProgressiveCleanup();
static void Shutdown();
static void Invalidate();
static void Invalidate(bool shutdown);
static TCacheEntry* Load(int texstage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt);
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, TRectangle *source);

View File

@ -255,7 +255,7 @@ void DoState(unsigned char **ptr, int mode) {
OpenGL_MakeCurrent();
#endif
// Clear all caches that touch RAM
TextureMngr::Invalidate();
TextureMngr::Invalidate(false);
// DisplayListManager::Invalidate();
VertexLoaderManager::MarkAllDirty();
@ -306,12 +306,7 @@ void Shutdown(void)
PixelShaderManager::Shutdown();
PixelShaderCache::Shutdown();
VertexManager::Shutdown();
// This cause some kind of crash, at least in the Release build and with this setup option
// If there wasn't so little explanations and comments in this code I would be more interested
// in trying to fix this function, now I'll just leave it like this, because it works
#ifndef SETUP_FREE_VIDEO_PLUGIN_ON_BOOT
TextureMngr::Shutdown();
#endif
OpcodeDecoder_Shutdown();
Renderer::Shutdown();
OpenGL_Shutdown();