wdetect: changed gfx_card detect to hopefully support multiple adapters (now returns the primary)
file: add timer h_mgr bugfix: h_force_free wasn't clearing refcnt mem: add note on shutdown order snd: bugfixes: VSrc_validate was overzealous (al_src == 0 is allowed); sd->is_valid wasn't being set -> leaked AL buffers. wsdl: remove overzealous ReleaseDC check (false alarm) gamesetup: clarify (resource) shutdown order This was SVN commit r2913.
This commit is contained in:
parent
dff64f6b96
commit
4285883f3d
@ -424,6 +424,8 @@ static bool dirent_less(const DirEnt* d1, const DirEnt* d2)
|
||||
}
|
||||
|
||||
|
||||
static TimerClient* tc_file_enum_malloc = timer_add_client("file_enum_malloc");
|
||||
|
||||
// call <cb> for each file and subdirectory in <dir> (alphabetical order),
|
||||
// passing the entry name (not full path!), stat info, and <user>.
|
||||
//
|
||||
@ -468,7 +470,7 @@ int file_enum(const char* P_path, const FileCB cb, const uintptr_t user)
|
||||
|
||||
const size_t size = sizeof(DirEnt)+strlen(ent.name)+1;
|
||||
DirEnt* p_ent;
|
||||
{static TimerClient* tc = timer_add_client("file_enum_malloc"); SUM_TIMER(tc);
|
||||
{SUM_TIMER(tc_file_enum_malloc);
|
||||
p_ent = (DirEnt*)malloc(size);}
|
||||
if(!p_ent)
|
||||
{
|
||||
|
@ -856,6 +856,7 @@ int h_force_free(Handle h, H_Type type)
|
||||
return ERR_INVALID_HANDLE;
|
||||
u32 idx = h_idx(h);
|
||||
hd->keep_open = 0;
|
||||
hd->refs = 0;
|
||||
return h_free_idx(idx, hd);
|
||||
}
|
||||
|
||||
@ -908,7 +909,7 @@ int h_get_refcnt(Handle h)
|
||||
|
||||
void h_mgr_shutdown()
|
||||
{
|
||||
// close open handles
|
||||
// forcibly close all open handles
|
||||
for(i32 i = 0; i <= last_in_use; i++)
|
||||
{
|
||||
HDATA* hd = h_data_from_idx(i);
|
||||
|
@ -421,6 +421,9 @@ ssize_t mem_size(void* p)
|
||||
*/
|
||||
|
||||
|
||||
// exception to normal resource shutdown: must not be called before
|
||||
// h_mgr_shutdown! (this is because h_mgr calls us to free memory, which
|
||||
// requires the pointer -> Handle index still be in place)
|
||||
void mem_shutdown()
|
||||
{
|
||||
ptr_to_h_shutdown();
|
||||
|
@ -30,10 +30,16 @@ extern void* mem_get_ptr(Handle h, size_t* size = 0);
|
||||
|
||||
extern int mem_get(Handle hm, u8** pp, size_t* psize);
|
||||
|
||||
|
||||
extern Handle mem_wrap(void* p, size_t size, uint flags, void* raw_p, size_t raw_size, MEM_DTOR dtor, uintptr_t ctx);
|
||||
|
||||
// exception to normal resource shutdown: must not be called before
|
||||
// h_mgr_shutdown! (this is because h_mgr calls us to free memory, which
|
||||
// requires the pointer -> Handle index still be in place)
|
||||
extern void mem_shutdown(void);
|
||||
|
||||
|
||||
extern Handle mem_wrap(void* p, size_t size, uint flags, void* raw_p, size_t raw_size, MEM_DTOR dtor, uintptr_t ctx);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -944,7 +944,9 @@ static int SndData_reload(SndData* sd, const char* fn, Handle hsd)
|
||||
if(file_type != FT_OGG)
|
||||
return -1;
|
||||
|
||||
return stream_open(&sd->s, fn);
|
||||
RETURN_ERR(stream_open(&sd->s, fn));
|
||||
sd->is_valid = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// else: clip
|
||||
@ -992,8 +994,9 @@ else
|
||||
#endif
|
||||
|
||||
sd->al_buf = al_buf_alloc(al_data, al_size, sd->al_fmt, sd->al_freq);
|
||||
sd->is_valid = 1;
|
||||
|
||||
mem_free(file);
|
||||
(void)mem_free(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1071,7 +1074,7 @@ static void hsd_list_free_all()
|
||||
{
|
||||
Handle& hsd = *it;
|
||||
|
||||
h_force_free(hsd, H_SndData);
|
||||
(void)h_force_free(hsd, H_SndData);
|
||||
// ignore errors - if hsd was a stream, and its associated source
|
||||
// was active when al_shutdown was called, it will already have been
|
||||
// freed (list_free_all would free the source; it then releases
|
||||
@ -1298,17 +1301,16 @@ static int VSrc_reload(VSrc* vs, const char* fn, Handle hvs)
|
||||
|
||||
static int VSrc_validate(const VSrc* vs)
|
||||
{
|
||||
if(vs->al_src == 0)
|
||||
return -2;
|
||||
// al_src can legitimately be 0 (if vs is low-pri)
|
||||
if(vs->flags & ~VS_ALL_FLAGS)
|
||||
return -3;
|
||||
return -2;
|
||||
// no limitations on <pos>
|
||||
if(!(0.0f <= vs->gain && vs->gain <= 1.0f))
|
||||
return -4;
|
||||
return -3;
|
||||
if(!(0.0f < vs->pitch && vs->pitch <= 1.0f))
|
||||
return -5;
|
||||
return -4;
|
||||
if(*(u8*)&vs->loop > 1 || *(u8*)&vs->relative > 1)
|
||||
return -6;
|
||||
return -5;
|
||||
// <static_pri> and <cur_pri> have no invariant we could check.
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,17 +70,20 @@
|
||||
|
||||
// EnumDisplayDevices is not available on Win95 or NT.
|
||||
// try to import it manually here; return -1 if not available.
|
||||
static BOOL (WINAPI *pEnumDisplayDevicesA)(void*, DWORD, void*, DWORD);
|
||||
static BOOL (WINAPI *pEnumDisplayDevicesA)(LPCSTR, DWORD, LPDISPLAY_DEVICEA, DWORD);
|
||||
static int import_EnumDisplayDevices()
|
||||
{
|
||||
if(!pEnumDisplayDevicesA)
|
||||
{
|
||||
static HMODULE hUser32Dll = LoadLibrary("user32.dll");
|
||||
*(void**)&pEnumDisplayDevicesA = GetProcAddress(hUser32Dll, "EnumDisplayDevicesA");
|
||||
// FreeLibrary(hUser32Dll);
|
||||
// make sure the reference is released so BoundsChecker
|
||||
// doesn't complain. it won't actually be unloaded anyway -
|
||||
// there is at least one other reference.
|
||||
|
||||
// do not free the DLL reference! if this happens to be the first
|
||||
// use of user32 (possible if it's delay-loaded or otherwise unused),
|
||||
// it would actually be unloaded. that apparently breaks the
|
||||
// Windows cursor.
|
||||
// unfortunately there's no way to get at the reference count,
|
||||
// so this resource leak is unavoidable.
|
||||
}
|
||||
|
||||
return pEnumDisplayDevicesA? 0 : -1;
|
||||
@ -120,11 +123,10 @@ int get_cur_vmode(int* xres, int* yres, int* bpp, int* freq)
|
||||
// if we fail, outputs are unchanged (assumed initialized to defaults)
|
||||
int get_monitor_size(int& width_mm, int& height_mm)
|
||||
{
|
||||
HDC dc = GetDC(0); // dc for entire screen
|
||||
|
||||
// (DC for the primary monitor's entire screen)
|
||||
HDC dc = GetDC(0);
|
||||
width_mm = GetDeviceCaps(dc, HORZSIZE);
|
||||
height_mm = GetDeviceCaps(dc, VERTSIZE);
|
||||
|
||||
ReleaseDC(0, dc);
|
||||
return 0;
|
||||
}
|
||||
@ -262,13 +264,28 @@ static int win_get_gfx_card()
|
||||
// make sure EnumDisplayDevices is available (as pEnumDisplayDevicesA)
|
||||
if(import_EnumDisplayDevices() >= 0)
|
||||
{
|
||||
DISPLAY_DEVICEA dev = { sizeof(dev) };
|
||||
if(pEnumDisplayDevicesA(0, 0, &dev, 0))
|
||||
// loop through all display adapters and put the primary device's
|
||||
// identifier in gfx_card.
|
||||
// (we don't bother returning a list of all of them because it's
|
||||
// likely to be redundant, e.g. "Radeon" and "Radeon Secondary";
|
||||
// we're only interested in the 'main' card anyway)
|
||||
DISPLAY_DEVICEA dd = { sizeof(DISPLAY_DEVICEA) };
|
||||
for(DWORD dev_num = 0; ; dev_num++)
|
||||
{
|
||||
strcpy_s(gfx_card, sizeof(gfx_card), (const char*)dev.DeviceString);
|
||||
if(!pEnumDisplayDevicesA(0, dev_num, &dd, 0))
|
||||
break;
|
||||
|
||||
// ignore mirror pseudo-devices (installed e.g. by NetMeeting)
|
||||
if(dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
|
||||
continue;
|
||||
|
||||
if(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||
{
|
||||
strcpy_s(gfx_card, ARRAY_SIZE(gfx_card), (const char*)dd.DeviceString);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -663,7 +663,9 @@ static int wsdl_shutdown()
|
||||
|
||||
if(hDC != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WARN_IF_FALSE(ReleaseDC(hWnd, hDC));
|
||||
// return value is whether the DC was actually freed.
|
||||
// this seems to sometimes be 0, so don't warn.
|
||||
(void)ReleaseDC(hWnd, hDC);
|
||||
hDC = (HDC)INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
@ -759,25 +759,29 @@ void Shutdown()
|
||||
I18n::Shutdown();
|
||||
TIMER_END("shutdown I18N");
|
||||
|
||||
TIMER_START("shutdown sound");
|
||||
// resource
|
||||
// first shut down all resource owners, and then the handle manager.
|
||||
TIMER_START("resource modules");
|
||||
snd_shutdown();
|
||||
TIMER_END("shutdown sound");
|
||||
|
||||
TIMER_START("shutdown vfs");
|
||||
vfs_shutdown();
|
||||
TIMER_END("shutdown vfs");
|
||||
|
||||
// this forcibly frees all open handles (thus preventing real leaks),
|
||||
// and makes further access to h_mgr impossible.
|
||||
h_mgr_shutdown();
|
||||
|
||||
// must come after h_mgr_shutdown - it causes memory to be freed,
|
||||
// which requires this module to still be active.
|
||||
mem_shutdown();
|
||||
TIMER_END("resource modules");
|
||||
|
||||
TIMER_START("shutdown misc");
|
||||
h_mgr_shutdown();
|
||||
mem_shutdown();
|
||||
file_shutdown();
|
||||
|
||||
timer_display_client_totals();
|
||||
|
||||
// should be last, since the above use them
|
||||
debug_shutdown();
|
||||
|
||||
delete &g_Logger;
|
||||
|
||||
delete &g_Profiler;
|
||||
TIMER_END("shutdown misc");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user