diff --git a/.hgtags b/.hgtags index f5c6bf44ff..4fc30353c2 100755 --- a/.hgtags +++ b/.hgtags @@ -514,3 +514,4 @@ d40c66e410741de7e90b1ed6dac28dd8a2d7e1f6 3.6.8-release dcb4981ce255841b6083d8f65444b65d5a733a17 3.7.1-release b842534cb4d76c9ef87676a62b1d2d19e79c015f 3.7.2-release 962d3f98955bfc7310a7867c8cbc3df075e54aa9 3.7.3-release +d076568ff7883b41c149e6afb421f39c29dbfe2b 3.7.4-release diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index d49559038d..82fdfcade1 100755 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -68,8 +68,10 @@ if(WINDOWS) if (FMODEX) if( NOT ND_BUILD64BIT_ARCH ) + set(debug_files ${debug_files} fmodexL.dll) set(release_files ${release_files} fmodex.dll) else( NOT ND_BUILD64BIT_ARCH ) + set(debug_files ${debug_files} fmodexL64.dll) set(release_files ${release_files} fmodex64.dll) endif( NOT ND_BUILD64BIT_ARCH ) endif (FMODEX) @@ -333,7 +335,8 @@ elseif(LINUX) endif (USE_TCMALLOC) if (FMODEX) - set(release_file ${release_files} "libfmodex.so") + set(debug_files ${debug_files} "libfmodexL.so") + set(release_files ${release_files} "libfmodex.so") endif (FMODEX) if (LEAPMOTION) diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 965c85bb6c..61e116bdbb 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -55,11 +55,13 @@ LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler) mWindDSP = NULL; mSystem = NULL; mEnableProfiler = enable_profiler; + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); } LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX() { + delete mWindDSPDesc; } @@ -320,10 +322,10 @@ void LLAudioEngine_FMODEX::shutdown() llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl; if ( mSystem ) // speculative fix for MAINT-2657 { - mSystem->close(); + mSystem->close(); // Additional debug message; viewer might hang somewhere in here llinfos << "LLAudioEngine_FMODEX::shutdown() FMOD Ex system closed. Now releasing..." << llendl; - mSystem->release(); + mSystem->release(); } llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl; @@ -349,15 +351,14 @@ bool LLAudioEngine_FMODEX::initWind() if (!mWindDSP) { - FMOD_DSP_DESCRIPTION dspdesc; - memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero - strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit" - dspdesc.channels=2; - dspdesc.read = &windCallback; //Assign callback. - if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP")) + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->channels = 2; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) return false; - if(mWindGen) + if (mWindGen) delete mWindGen; float frequency = 44100; @@ -366,6 +367,7 @@ bool LLAudioEngine_FMODEX::initWind() mWindDSP->setUserData((void*)mWindGen); } + // *TODO: Should this guard against multiple plays? if (mWindDSP) { mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0); @@ -743,6 +745,9 @@ void LLAudioChannelFMODEX::set3DMode(bool use3d) } } +// *NOTE: This is almost certainly being called on the mixer thread, +// not the main thread. May have implications for callees or audio +// engine shutdown. FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels) { diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h index 415a9ed0ef..ca389d489f 100644 --- a/indra/llaudio/llaudioengine_fmodex.h +++ b/indra/llaudio/llaudioengine_fmodex.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,7 @@ namespace FMOD class Sound; class DSP; } +typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; //Interfaces class LLAudioEngine_FMODEX : public LLAudioEngine @@ -74,6 +75,7 @@ protected: LLWindGen *mWindGen; + FMOD_DSP_DESCRIPTION *mWindDSPDesc; FMOD::DSP *mWindDSP; FMOD::System *mSystem; bool mEnableProfiler; diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp index 0aaf6a684c..4aba28a7ce 100755 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp +++ b/indra/media_plugins/winmmshim/winmm_shim.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2010-2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,70 +30,55 @@ using std::wstring; -static float sVolumeLevel = 1.f; -static bool sMute = false; +static float sVolumeLevel = 1.f; // Could be covered by critical section, +static bool sMute = false; // not needed with atomicity and alignment. static CRITICAL_SECTION sCriticalSection; -static bool initialized; - -class CritSecLock -{ - CRITICAL_SECTION &mSection; -public: - CritSecLock( CRITICAL_SECTION &aSection ) - : mSection( aSection ) - { - ::EnterCriticalSection( &mSection ); - } - - ~CritSecLock( ) - { - ::LeaveCriticalSection( &mSection ); - } -}; - BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { - if( DLL_PROCESS_ATTACH == ul_reason_for_call ) - ::InitializeCriticalSection( &sCriticalSection ); + if (DLL_PROCESS_ATTACH == ul_reason_for_call) + { + InitializeCriticalSection(&sCriticalSection); + } else if( DLL_PROCESS_DETACH == ul_reason_for_call ) ::DeleteCriticalSection( &sCriticalSection ); return TRUE; } void ll_winmm_shim_initialize(){ - // static bool initialized = false; - // do this only once + static volatile bool initialized = false; - // EnterCriticalSection(&sCriticalSection); - CritSecLock oLock( sCriticalSection ); - + // do this only once using double-check locking if (!initialized) - { // bind to original winmm.dll - TCHAR system_path[MAX_PATH]; - TCHAR dll_path[MAX_PATH]; - ::GetSystemDirectory(system_path, MAX_PATH); + { + EnterCriticalSection(&sCriticalSection); + if (!initialized) + { // bind to original winmm.dll + TCHAR system_path[MAX_PATH]; + TCHAR dll_path[MAX_PATH]; + ::GetSystemDirectory(system_path, MAX_PATH); - // grab winmm.dll from system path, where it should live - wsprintf(dll_path, "%s\\winmm.dll", system_path); - HMODULE winmm_handle = ::LoadLibrary(dll_path); + // grab winmm.dll from system path, where it should live + wsprintf(dll_path, "%s\\winmm.dll", system_path); + HMODULE winmm_handle = ::LoadLibrary(dll_path); - if (winmm_handle != NULL) - { // we have a dll, let's get out pointers! - initialized = true; - init_function_pointers(winmm_handle); - ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); - } - else - { - // failed to initialize real winmm.dll - ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n"); + if (winmm_handle != NULL) + { // we have a dll, let's get out pointers! + init_function_pointers(winmm_handle); + ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); + initialized = true; // Last thing after completing setup + } + else + { + // failed to initialize real winmm.dll + ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n"); + } } + LeaveCriticalSection(&sCriticalSection); } - // LeaveCriticalSection(&sCriticalSection); } @@ -108,7 +93,7 @@ extern "C" int mBitsPerSample; }; typedef std::map wave_out_map_t; - static wave_out_map_t sWaveOuts; + static wave_out_map_t sWaveOuts; // Covered by sCriticalSection MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) { @@ -124,9 +109,9 @@ extern "C" && ((fdwOpen & WAVE_FORMAT_QUERY) == 0)) // not just querying for format support { // remember the requested bits per sample, and associate with the given handle WaveOutFormat* wave_outp = new WaveOutFormat(pwfx->wBitsPerSample); - - CritSecLock lock( sCriticalSection ); + EnterCriticalSection(&sCriticalSection); sWaveOuts.insert(std::make_pair(*phwo, wave_outp)); + LeaveCriticalSection(&sCriticalSection); } return result; } @@ -134,16 +119,15 @@ extern "C" MMRESULT WINAPI waveOutClose( HWAVEOUT hwo) { ll_winmm_shim_initialize(); - - CritSecLock lock( sCriticalSection ); - + EnterCriticalSection(&sCriticalSection); wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); if (found_it != sWaveOuts.end()) { // forget what we know about this handle delete found_it->second; sWaveOuts.erase(found_it); } - return waveOutClose_orig( hwo); + LeaveCriticalSection(&sCriticalSection); + return waveOutClose_orig(hwo); } MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) @@ -157,14 +141,19 @@ extern "C" } else if (sVolumeLevel != 1.f) { // need to apply volume level + int bits_per_sample(0); - CritSecLock lock( sCriticalSection ); + EnterCriticalSection(&sCriticalSection); wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); - if (found_it != sWaveOuts.end()) { - WaveOutFormat* formatp = found_it->second; - switch (formatp->mBitsPerSample){ + bits_per_sample = found_it->second->mBitsPerSample; + } + LeaveCriticalSection(&sCriticalSection); + if (bits_per_sample) + { + switch (bits_per_sample) + { case 8: { char volume = (char)(sVolumeLevel * 127.f); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f2dd476f6f..8565171223 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -7,7 +7,7 @@ $LicenseInfo:firstyear=2006&license=viewerlgpl$ Second Life Viewer Source Code -Copyright (C) 2006-2011, Linden Research, Inc. +Copyright (C) 2006-2014, Linden Research, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -929,7 +929,6 @@ class Darwin_i386_Manifest(ViewerManifest): "libaprutil-1.0.dylib", "libexpat.1.5.2.dylib", "libexception_handler.dylib", - "libfmodex.dylib", "libfmodexL.dylib", "libGLOD.dylib", "libgrowl.dylib", @@ -951,6 +950,20 @@ class Darwin_i386_Manifest(ViewerManifest): 'SLVoice', ): self.path2basename(libdir, libfile) + + # dylibs that vary based on configuration + if self.args['configuration'].lower() == 'debug': + for libfile in ( + "libfmodexL.dylib", + ): + dylibs += path_optional(os.path.join("../packages/lib/debug", + libfile), libfile) + else: + for libfile in ( + "libfmodex.dylib", + ): + dylibs += path_optional(os.path.join("../packages/lib/release", + libfile), libfile) # our apps for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),