diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2020-05-04 23:35:54 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2020-05-04 23:35:54 +0300 | 
| commit | 6364e2fff696090253c902bec02d68f036ad509c (patch) | |
| tree | 8f9f6a8834cf392552c7be07086d9cb0cff61631 | |
| parent | d3b10072f4c52b01c8d77ad1990d69dd89fc1310 (diff) | |
| parent | 4a7fd0117a43dca9e30c58c6417ebdf6862561f6 (diff) | |
Merge branch 'master' into DRTVWR-460
42 files changed, 368 insertions, 108 deletions
| diff --git a/doc/contributions.txt b/doc/contributions.txt index 36b65ae84d..7bbbf6430a 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -347,6 +347,7 @@ Charles Courtois  Charlie Sazaland  Chaser Zaks      BUG-225599 +    BUG-227485  Cherry Cheevers  ChickyBabes Zuzu  Christopher  Organiser diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 6ab61689fd..e7db84f6ab 100644 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -271,7 +271,7 @@ BOOL LLVorbisDecodeState::initDecode()  		mWAVBuffer.reserve(size_guess);  		mWAVBuffer.resize(WAV_HEADER_SIZE);  	} -	catch (std::bad_alloc) +	catch (std::bad_alloc&)  	{  		LL_WARNS("AudioEngine") << "Out of memory when trying to alloc buffer: " << size_guess << LL_ENDL;  		delete mInFilep; diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index a618a1cc70..5d16a4b74d 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -195,6 +195,8 @@ namespace  	std::string amd_CPUFamilyName(int composed_family)   	{ +        // https://en.wikipedia.org/wiki/List_of_AMD_CPU_microarchitectures +        // https://developer.amd.com/resources/developer-guides-manuals/  		switch(composed_family)  		{  		case 4: return "AMD 80486/5x86"; @@ -202,6 +204,13 @@ namespace  		case 6: return "AMD K7";  		case 0xF: return "AMD K8";  		case 0x10: return "AMD K8L"; +		case 0x12: return "AMD K10"; +		case 0x14: return "AMD Bobcat"; +		case 0x15: return "AMD Bulldozer"; +		case 0x16: return "AMD Jaguar"; +		case 0x17: return "AMD Zen/Zen+/Zen2"; +		case 0x18: return "AMD Hygon Dhyana"; +		case 0x19: return "AMD Zen 3";  		}  		return STRINGIZE("AMD <unknown 0x" << std::hex << composed_family << ">");  	} diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index c3fb4ebc2c..79934642ae 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -2251,7 +2251,7 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,  			return ZR_SIZE_ERROR;  		}  #endif -		catch (std::bad_alloc) +		catch (std::bad_alloc&)  		{  			free(result);  			return ZR_MEM_ERROR; diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 0b72b53186..34268d94f6 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -318,7 +318,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)          {              LOG_UNHANDLED_EXCEPTION("");          } -        catch (std::bad_alloc) +        catch (std::bad_alloc&)          {              LLMemory::logMemoryInfo(TRUE); diff --git a/indra/llcorehttp/bufferarray.cpp b/indra/llcorehttp/bufferarray.cpp index be534b3ce4..e0b2876a00 100644 --- a/indra/llcorehttp/bufferarray.cpp +++ b/indra/llcorehttp/bufferarray.cpp @@ -147,7 +147,7 @@ size_t BufferArray::append(const void * src, size_t len)          {              block = Block::alloc(BLOCK_ALLOC_SIZE);          } -        catch (std::bad_alloc) +        catch (std::bad_alloc&)          {              LLMemory::logMemoryInfo(TRUE); diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index 3b1b060c02..ead9a37fb8 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -315,7 +315,7 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)  		jpeg_destroy_decompress(&cinfo);  	} -	catch (std::bad_alloc) +	catch (std::bad_alloc&)  	{  		setLastError( "Out of memory");  		jpeg_destroy_decompress(&cinfo); diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index f298764cc0..f7dc6272cf 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -210,7 +210,7 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf  		releaseResources();  		return (FALSE);  	} -	catch (std::bad_alloc) +	catch (std::bad_alloc&)  	{  		mErrorMessage = "LLPngWrapper";  		releaseResources(); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2ac1eb99ce..7da53bf8c8 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2399,9 +2399,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  			{ //face has no geometry, continue  				face.resizeIndices(3);  				face.resizeVertices(1); -				memset(face.mPositions, 0, sizeof(LLVector4a)); -				memset(face.mNormals, 0, sizeof(LLVector4a)); -				memset(face.mTexCoords, 0, sizeof(LLVector2)); +				face.mPositions->clear(); +				face.mNormals->clear(); +				face.mTexCoords->setZero();  				memset(face.mIndices, 0, sizeof(U16)*3);  				continue;  			} @@ -2489,7 +2489,11 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  				}  				else  				{ -					memset(norm_out, 0, sizeof(LLVector4a)*num_verts); +					for (U32 j = 0; j < num_verts; ++j) +					{ +						norm_out->clear(); +						norm_out++; // or just norm_out[j].clear(); +					}  				}  			} @@ -2519,7 +2523,11 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  				}  				else  				{ -					memset(tc_out, 0, sizeof(LLVector2)*num_verts); +					for (U32 j = 0; j < num_verts; j += 2) +					{ +						tc_out->clear(); +						tc_out++; +					}  				}  			} @@ -5288,7 +5296,7 @@ bool LLVolumeFace::cacheOptimize()  		triangle_data.resize(mNumIndices / 3);  		vertex_data.resize(mNumVertices);  	} -	catch (std::bad_alloc) +	catch (std::bad_alloc&)  	{  		LL_WARNS("LLVOLUME") << "Resize failed" << LL_ENDL;  		return false; @@ -5442,7 +5450,7 @@ bool LLVolumeFace::cacheOptimize()  	{  		new_idx.resize(mNumVertices, -1);  	} -	catch (std::bad_alloc) +	catch (std::bad_alloc&)  	{  		ll_aligned_free<64>(pos);  		ll_aligned_free_16(wght); @@ -6968,11 +6976,16 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe  {      //LLVector4a *tan1 = new LLVector4a[vertexCount * 2];  	LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a)); +	// new(tan1) LLVector4a;      LLVector4a* tan2 = tan1 + vertexCount; -	memset(tan1, 0, vertexCount*2*sizeof(LLVector4a)); -         +    U32 count = vertexCount * 2; +    for (U32 i = 0; i < count; i++) +    { +        tan1[i].clear(); +    } +      for (U32 a = 0; a < triangleCount; a++)      {          U32 i1 = *index_array++; diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 24387fbffd..0eae6d9826 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -597,7 +597,7 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:      {          bas >> jsonRoot;      } -    catch (std::runtime_error e) +    catch (std::runtime_error& e)      {   // deserialization failed.  Record the reason and pass back an empty map for markup.          status = LLCore::HttpStatus(499, std::string(e.what()));          return result; @@ -625,7 +625,7 @@ LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &succes      {          bas >> jsonRoot;      } -    catch (std::runtime_error e) +    catch (std::runtime_error&)      {             success = false;          return LLSD(); diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index 04b34a296c..6fd17c9154 100644 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -125,7 +125,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons  	{  		response->result(simpleGet());  	} -	catch (NotImplemented) +	catch (NotImplemented&)  	{  		response->methodNotAllowed();  	} @@ -138,7 +138,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons  	{  		response->result(simplePut(input));  	} -	catch (NotImplemented) +	catch (NotImplemented&)  	{  		response->methodNotAllowed();  	} @@ -151,7 +151,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con  	{  		response->result(simplePost(input));  	} -	catch (NotImplemented) +	catch (NotImplemented&)  	{  		response->methodNotAllowed();  	} @@ -164,7 +164,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons      {  	response->result(simpleDel(context));      } -    catch (NotImplemented) +    catch (NotImplemented&)      {  	response->methodNotAllowed();      } diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c01c15391d..4c56b8eace 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -50,6 +50,10 @@  #include "llglheaders.h"  #include "llglslshader.h" +#if LL_WINDOWS +#include "lldxhardware.h" +#endif +  #ifdef _DEBUG  //#define GL_STATE_VERIFY  #endif @@ -395,6 +399,8 @@ PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;  PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;  #if LL_WINDOWS +PFNWGLGETGPUIDSAMDPROC				wglGetGPUIDsAMD = NULL; +PFNWGLGETGPUINFOAMDPROC				wglGetGPUInfoAMD = NULL;  PFNWGLSWAPINTERVALEXTPROC			wglSwapIntervalEXT = NULL;  #endif @@ -414,6 +420,7 @@ LLGLManager::LLGLManager() :  	mHasMultitexture(FALSE),  	mHasATIMemInfo(FALSE), +	mHasAMDAssociations(FALSE),  	mHasNVXMemInfo(FALSE),  	mNumTextureUnits(1),  	mHasMipMapGeneration(FALSE), @@ -498,7 +505,16 @@ void LLGLManager::initWGL()  	{  		LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;  	} -	 + +	// For retreiving information per AMD adapter,  +	// because we can't trust curently selected/default one when there are multiple +	mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts); +	if (mHasAMDAssociations) +	{ +		GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD"); +		GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD"); +	} +  	if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))  	{          GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT"); @@ -684,23 +700,78 @@ bool LLGLManager::initGL()  	stop_glerror();  	S32 old_vram = mVRAM; +	mVRAM = 0; -	if (mHasATIMemInfo) +#if LL_WINDOWS +	if (mHasAMDAssociations) +	{ +		GLuint gl_gpus_count = wglGetGPUIDsAMD(0, 0); +		if (gl_gpus_count > 0) +		{ +			GLuint* ids = new GLuint[gl_gpus_count]; +			wglGetGPUIDsAMD(gl_gpus_count, ids); + +			GLuint mem_mb = 0; +			for (U32 i = 0; i < gl_gpus_count; i++) +			{ +				wglGetGPUInfoAMD(ids[i], +					WGL_GPU_RAM_AMD, +					GL_UNSIGNED_INT, +					sizeof(GLuint), +					&mem_mb); +				if (mVRAM < mem_mb) +				{ +					// basically pick the best AMD and trust driver/OS to know to switch +					mVRAM = mem_mb; +				} +			} +		} +		if (mVRAM != 0) +		{ +			LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL; +		} +	} +#endif + +	if (mHasATIMemInfo && mVRAM == 0)  	{ //ask the gl how much vram is free at startup and attempt to use no more than half of that  		S32 meminfo[4];  		glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); -		mVRAM = meminfo[0]/1024; +		mVRAM = meminfo[0] / 1024; +		LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL;  	} -	else if (mHasNVXMemInfo) + +	if (mHasNVXMemInfo && mVRAM == 0)  	{  		S32 dedicated_memory;  		glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);  		mVRAM = dedicated_memory/1024; +		LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL;  	} +#if LL_WINDOWS  	if (mVRAM < 256) -	{ //something likely went wrong using the above extensions, fall back to old method +	{ +		// Something likely went wrong using the above extensions +		// try WMI first and fall back to old method (from dxdiag) if all else fails +		// Function will check all GPUs WMI knows of and will pick up the one with most +		// memory. We need to check all GPUs because system can switch active GPU to +		// weaker one, to preserve power when not under load. +		S32 mem = LLDXHardware::getMBVideoMemoryViaWMI(); +		if (mem != 0) +		{ +			mVRAM = mem; +			LL_WARNS("RenderInit") << "VRAM Detected (WMI):" << mVRAM<< LL_ENDL; +		} +	} +#endif + +	if (mVRAM < 256 && old_vram > 0) +	{ +		// fall back to old method +		// Note: on Windows value will be from LLDXHardware. +		// Either received via dxdiag or via WMI by id from dxdiag.  		mVRAM = old_vram;  	} @@ -962,7 +1033,7 @@ void LLGLManager::initExtensions()  	mHasTextureRectangle = FALSE;  #else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called  	mHasMultitexture = glh_init_extensions("GL_ARB_multitexture"); -	mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); +	mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations  	mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);  	mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");  	mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic"); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index a7faea7d33..91ef4e9102 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -78,6 +78,7 @@ public:  	// Extensions used by everyone  	BOOL mHasMultitexture;  	BOOL mHasATIMemInfo; +	BOOL mHasAMDAssociations;  	BOOL mHasNVXMemInfo;  	S32	 mNumTextureUnits;  	BOOL mHasMipMapGeneration; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 722dd9050b..36fbb381bb 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -618,6 +618,8 @@ extern PFNGLVARIANTARRAYOBJECTATIPROC		glVariantObjectArrayATI;  extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC	glGetVariantArrayObjectfvATI;  extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC	glGetVariantArrayObjectivATI; +extern PFNWGLGETGPUIDSAMDPROC				wglGetGPUIDsAMD; +extern PFNWGLGETGPUINFOAMDPROC				wglGetGPUInfoAMD;  extern PFNWGLSWAPINTERVALEXTPROC			wglSwapIntervalEXT;  // GL_ARB_occlusion_query diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 119cbebc81..3c34fd269e 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -36,6 +36,11 @@  #include <boost/regex.hpp> +#if LL_WINDOWS +// because something pulls in window and lldxdiag dependencies which in turn need wbemuuid.lib +    #pragma comment(lib, "wbemuuid.lib") +#endif +  // namespace LLExperienceCache  // { diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 9397b831f7..12a6baa3e6 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -61,7 +61,7 @@ typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSv                                                 OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,                                                 RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities ); -HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam ) +HRESULT GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam)  {      HRESULT hr;      bool bGotMemory = false; @@ -149,21 +149,26 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )                          if ( !pVideoControllers[iController] )                              continue; -                        pPropName = SysAllocString( L"PNPDeviceID" ); -                        hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); +                        // if strInputDeviceID is set find this specific device and return memory or specific device +                        // if strInputDeviceID is not set return the best device +                        if (strInputDeviceID) +                        { +                            pPropName = SysAllocString( L"PNPDeviceID" ); +                            hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );  #ifdef PRINTF_DEBUGGING -                        if( FAILED( hr ) ) -                            wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr ); +                            if( FAILED( hr ) ) +                                wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );  #endif -                        if( SUCCEEDED( hr ) ) -                        { -                            if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 ) -                                bFound = true; +                            if( SUCCEEDED( hr ) && strInputDeviceID) +                            { +                                if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 ) +                                    bFound = true; +                            } +                            VariantClear( &var ); +                            if( pPropName ) SysFreeString( pPropName );                          } -                        VariantClear( &var ); -                        if( pPropName ) SysFreeString( pPropName ); -                        if( bFound ) +                        if( bFound || !strInputDeviceID )                          {                              pPropName = SysAllocString( L"AdapterRAM" );                              hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); @@ -175,13 +180,18 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )                              if( SUCCEEDED( hr ) )                              {                                  bGotMemory = true; -                                *pdwAdapterRam = var.ulVal; +                                *pdwAdapterRam = llmax(var.ulVal, *pdwAdapterRam);                              }                              VariantClear( &var );                              if( pPropName ) SysFreeString( pPropName ); -                            break;                          } +                          SAFE_RELEASE( pVideoControllers[iController] ); + +                        if (bFound) +                        { +                            break; +                        }                      }                  }              } @@ -207,6 +217,17 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )          return E_FAIL;  } +//static +S32 LLDXHardware::getMBVideoMemoryViaWMI() +{ +	DWORD vram = 0; +	if (SUCCEEDED(GetVideoMemoryViaWMI(NULL, &vram))) +	{ +		return vram / (1024 * 1024);; +	} +	return 0; +} +  //Getting the version of graphics controller driver via WMI  std::string LLDXHardware::getDriverVersionWMI()  { @@ -615,6 +636,8 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)  	IDxDiagContainer *driver_containerp = NULL;  	DWORD dw_device_count; +	mVRAM = 0; +      // CoCreate a IDxDiagProvider*  	LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;      hr = CoCreateInstance(CLSID_DxDiagProvider, @@ -677,6 +700,8 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)          }  		// Get device 0 +		// By default 0 device is the primary one, howhever in case of various hybrid graphics +		// like itegrated AMD and PCI AMD GPUs system might switch.  		LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL;  		hr = devices_containerp->GetChildContainer(L"0", &device_containerp);  		if(FAILED(hr) || !device_containerp) @@ -689,12 +714,27 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)  		WCHAR deviceID[512];  		get_wstring(device_containerp, L"szDeviceID", deviceID, 512); -		 +		// Example: searches id like 1F06 in pnp string (aka VEN_10DE&DEV_1F06) +		// doesn't seem to work on some systems since format is unrecognizable +		// but in such case keyDeviceID works  		if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))   		{  			mVRAM = vram/(1024*1024);  		}  		else +		{ +			get_wstring(device_containerp, L"szKeyDeviceID", deviceID, 512); +			LL_WARNS() << "szDeviceID" << deviceID << LL_ENDL; +			// '+9' to avoid ENUM\\PCI\\ prefix +			// Returns string like Enum\\PCI\\VEN_10DE&DEV_1F06&SUBSYS... +			// and since GetVideoMemoryViaWMI searches by PNPDeviceID it is sufficient +			if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram))) +			{ +				mVRAM = vram / (1024 * 1024); +			} +		} +		 +		if (mVRAM == 0)  		{ // Get the English VRAM string  		  std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish"); diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h index cf33db8b37..1cb687e3b6 100644 --- a/indra/llwindow/lldxhardware.h +++ b/indra/llwindow/lldxhardware.h @@ -94,6 +94,10 @@ public:  	LLSD getDisplayInfo(); +	// Will get memory of best GPU in MB, return memory on sucsess, 0 on failure +	// Note: WMI is not accurate in some cases +	static S32 getMBVideoMemoryViaWMI(); +  	// Find a particular device that matches the following specs.  	// Empty strings indicate that you don't care.  	// You can separate multiple devices with '|' chars to indicate you want diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 3c69aa98c4..0b3936f8a5 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -741,17 +741,27 @@ void LLWindowWin32::restore()  	SetFocus(mWindowHandle);  } +// See SL-12170 +// According to callstack "c0000005 Access violation" happened inside __try block, +// deep in DestroyWindow and crashed viewer, which shouldn't be possible. +// I tried manually causing this exception and it was caught without issues, so +// I'm turning off optimizations for this part to be sure code executes as intended +// (it is a straw, but I have no idea why else __try can get overruled) +#pragma optimize("", off)  bool destroy_window_handler(HWND &hWnd)  { +    bool res;      __try      { -        return DestroyWindow(hWnd); +        res = DestroyWindow(hWnd);      }      __except (EXCEPTION_EXECUTE_HANDLER)      { -        return false; +        res = false;      } +    return res;  } +#pragma optimize("", on)  // close() destroys all OS-specific code associated with a window.  // Usually called from LLWindowManager::destroyWindow() diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 4c77920fd2..a4c853ea2e 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.1 +6.4.2 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index c8d2524e0e..f6d6f7c897 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2036,6 +2036,14 @@ U8 LLAgent::getRenderState()  //-----------------------------------------------------------------------------  void LLAgent::endAnimationUpdateUI()  { +	if (LLApp::isExiting() +		|| !gViewerWindow +		|| !gMenuBarView +		|| !gToolBarView +		|| !gStatusBar) +	{ +		return; +	}  	if (gAgentCamera.getCameraMode() == gAgentCamera.getLastCameraMode())  	{  		// We're already done endAnimationUpdateUI for this transition. diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 7a82cf2f66..9e65409256 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -280,6 +280,11 @@ LLAgentCamera::~LLAgentCamera()  //-----------------------------------------------------------------------------  void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)  { +	if (gDisconnected) +	{ +		return; +	} +  	if (gAgent.getAutoPilot())  	{  		gAgent.stopAutoPilot(TRUE); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index cbb47d71f7..ff921dcfdb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -62,7 +62,9 @@  #include "llallocator.h"  #include "llcalc.h"  #include "llconversationlog.h" +#if LL_WINDOWS  #include "lldxhardware.h" +#endif  #include "lltexturestats.h"  #include "lltrace.h"  #include "lltracethreadrecorder.h" @@ -1134,7 +1136,7 @@ bool LLAppViewer::init()  	try {  		initializeSecHandler();  	} -	catch (LLProtectedDataException ex) +	catch (LLProtectedDataException&)  	{  	  LLNotificationsUtil::add("CorruptedProtectedDataStore");  	} @@ -1348,7 +1350,7 @@ bool LLAppViewer::frame()  		{  			LOG_UNHANDLED_EXCEPTION("");  		} -		catch (std::bad_alloc) +		catch (std::bad_alloc&)  		{  			LLMemory::logMemoryInfo(TRUE);  			LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); @@ -1717,6 +1719,11 @@ bool LLAppViewer::cleanup()  	disconnectViewer();  	LL_INFOS() << "Viewer disconnected" << LL_ENDL; +	 +	if (gKeyboard) +	{ +		gKeyboard->resetKeys(); +	}  	display_cleanup(); @@ -3995,7 +4002,10 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q  void LLAppViewer::userQuit()  { -	if (gDisconnected || gViewerWindow->getProgressView()->getVisible()) +	if (gDisconnected +		|| !gViewerWindow +		|| !gViewerWindow->getProgressView() +		|| gViewerWindow->getProgressView()->getVisible())  	{  		requestQuit();  	} diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 0e1c4f9434..342ee3ccf5 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -2800,7 +2800,7 @@ void LLEnvironment::loadSkyWaterFromSettings(const LLSD &env_data, bool &valid,      }      else if (env_data.has("sky_llsd"))      { -        LLSettingsSky::ptr_t sky = std::make_shared<LLSettingsVOSky>(env_data["sky_llsd"]); +        LLSettingsSky::ptr_t sky = LLSettingsVOSky::buildSky(env_data["sky_llsd"]);          setEnvironment(ENV_LOCAL, sky);          valid = true;      } @@ -2814,7 +2814,7 @@ void LLEnvironment::loadSkyWaterFromSettings(const LLSD &env_data, bool &valid,      }      else if (env_data.has("water_llsd"))      { -        LLSettingsWater::ptr_t sky = std::make_shared<LLSettingsVOWater>(env_data["water_llsd"]); +        LLSettingsWater::ptr_t sky = LLSettingsVOWater::buildWater(env_data["water_llsd"]);          setEnvironment(ENV_LOCAL, sky);          valid = true;      } @@ -2899,8 +2899,8 @@ bool LLEnvironment::loadFromSettings()      {          S32 length = env_data["day_length"].asInteger();          S32 offset = env_data["day_offset"].asInteger(); -        LLSettingsDay::ptr_t day = std::make_shared<LLSettingsVODay>(env_data["day_llsd"]); -        setEnvironment(ENV_LOCAL, day, LLSettingsDay::Seconds(length), LLSettingsDay::Seconds(offset)); +        LLSettingsDay::ptr_t pday = LLSettingsVODay::buildDay(env_data["day_llsd"]); +        setEnvironment(ENV_LOCAL, pday, LLSettingsDay::Seconds(length), LLSettingsDay::Seconds(offset));          valid = true;      } diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp index 3e303e0932..a6640cc073 100644 --- a/indra/newview/llfloaterevent.cpp +++ b/indra/newview/llfloaterevent.cpp @@ -110,7 +110,7 @@ void LLFloaterEvent::setEventID(const U32 event_id)          // get the search URL and expand all of the substitutions                                                                 // (also adds things like [LANGUAGE], [VERSION], [OS], etc.)                                                      		std::ostringstream url; -		url <<  gSavedSettings.getString("EventURL") << event_id << "/" << std::endl; +		url <<  gSavedSettings.getString("EventURL") << event_id << std::endl;  		// and load the URL in the web view                                                                                       mBrowser->navigateTo(url.str()); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index c3375a3779..6da7bbe263 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1579,7 +1579,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)      std::vector<U8> data;      S32 binary_bucket_size = 0; -    LLHost sender = gAgent.getRegion()->getHost(); +    LLHost sender = gAgent.getRegionHost();      LLSD::array_iterator i = messages.beginArray();      LLSD::array_iterator iEnd = messages.endArray(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 4b051f3e44..657c65c68d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1809,7 +1809,7 @@ void LLItemBridge::restoreToWorld()  		msg->nextBlockFast(_PREHASH_InventoryData);  		itemp->packMessage(msg); -		msg->sendReliable(gAgent.getRegion()->getHost()); +		msg->sendReliable(gAgent.getRegionHost());  		//remove local inventory copy, sim will deal with permissions and removing the item  		//from the actual inventory if its a no-copy etc diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1d76dd7928..1fce158eb4 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1888,7 +1888,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p  		std::string mesh_string((char*)data, data_size);  		stream.str(mesh_string);  	} -	catch (std::bad_alloc) +	catch (std::bad_alloc&)  	{  		// out of memory, we won't be able to process this mesh  		return MESH_OUT_OF_MEMORY; diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h index 1b4295ddad..18b669ff4f 100644 --- a/indra/newview/llrecentpeople.h +++ b/indra/newview/llrecentpeople.h @@ -53,7 +53,7 @@ class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LL  	LLSINGLETON_EMPTY_CTOR(LLRecentPeople);  	LOG_CLASS(LLRecentPeople);  public: -	typedef std::map <LLUUID, F32> id_to_time_map_t; +	typedef std::map <LLUUID, F64> id_to_time_map_t;  	typedef boost::signals2::signal<void ()> signal_t;  	/** diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp index 72d7cf1e45..10e510b842 100644 --- a/indra/newview/llsecapi.cpp +++ b/indra/newview/llsecapi.cpp @@ -64,7 +64,7 @@ void initializeSecHandler()  		{  			handler->init();  		} -		catch (LLProtectedDataException e) +		catch (LLProtectedDataException& e)  		{  			exception_msg = e.what();  		} diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index 1f29013ecf..65136ad2f5 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -158,6 +158,9 @@ class LLSettingsVODay : public LLSettingsDay  public:      typedef std::function<void(LLSettingsDay::ptr_t day)>  asset_built_fn; +    // Todo: find a way to make this cnstructor private +    // It shouldn't be used outside shared_prt and LLSettingsVODay +    // outside of settings only use buildDay(settings)      LLSettingsVODay(const LLSD &data);      static ptr_t    buildDay(LLSD settings); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3d9de4f925..b532d9a9b4 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1880,8 +1880,7 @@ bool idle_startup()  		display_startup(); -        // Load stored local environment if needed. Only should be done once at least -        // initial region data got loaded to avoid race condition with region's environment +        // Load stored local environment if needed.          LLEnvironment::instance().loadFromSettings();          // *TODO : Uncomment that line once the whole grid migrated to SLM and suppress it from LLAgent::handleTeleportFinished() (llagent.cpp) diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index bccbe61f44..6914e0fc2b 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -988,6 +988,11 @@ EKeyboardMode LLViewerKeyboard::getMode()  // Called from scanKeyboard.  void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)  { +	if (LLApp::isExiting()) +	{ +		return; +	} +  	S32 mode = getMode();  	// Consider keyboard scanning as NOT mouse event. JC  	MASK mask = gKeyboard->currentMask(FALSE); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 06524847d1..561319ca5d 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1385,8 +1385,6 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, fl  		{  			max_texmem = (S32Megabytes)128;  		} - -		LL_WARNS() << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << LL_ENDL;  	}  	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB @@ -1428,6 +1426,11 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)  		return; //listener will re-enter this function  	} +	if (gGLManager.mVRAM == 0) +	{ +		LL_WARNS() << "VRAM amount not detected, defaulting to " << mem << " MB" << LL_ENDL; +	} +  	// TODO: set available resident texture mem based on use by other subsystems  	// currently max(12MB, VRAM/4) assumed... diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ae1eec81e0..f64dfcf0d4 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2008,6 +2008,11 @@ void LLViewerWindow::initBase()  	LLPanel* panel_holder = main_view->getChild<LLPanel>("toolbar_view_holder");  	// Load the toolbar view from file   	gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance()); +	if (!gToolBarView) +	{ +		LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, " +				<< "if this problem happens again, please validate your installation." << LL_ENDL; +	}  	gToolBarView->setShape(panel_holder->getLocalRect());  	// Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI())  	gToolBarView->setVisible(FALSE); @@ -2893,7 +2898,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  	// If "Pressing letter keys starts local chat" option is selected, we are not in mouselook,   	// no view has keyboard focus, this is a printable character key (and no modifier key is   	// pressed except shift), then give focus to nearby chat (STORM-560) -	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&  +	if ( LLStartUp::getStartupState() >= STATE_STARTED &&  +		gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&   		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )  	{  		// Initialize nearby chat if it's missing diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f391621e48..d567623ac0 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -198,6 +198,8 @@ const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;  const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0;  const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024; +const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60; +  enum ERenderName  {  	RENDER_NAME_NEVER, @@ -664,6 +666,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mFullyLoadedInitialized(FALSE),  	mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),  	mLoadedCallbacksPaused(FALSE), +	mLoadedCallbackTextures(0),  	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)),  	mLastRezzedStatus(-1),  	mIsEditingAppearance(FALSE), @@ -884,8 +887,9 @@ BOOL LLVOAvatar::hasGray() const  S32 LLVOAvatar::getRezzedStatus() const  {  	if (getIsCloud()) return 0; -	if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3; -	if (isFullyTextured()) return 2; +	bool textured = isFullyTextured(); +	if (textured && allBakedTexturesCompletelyDownloaded()) return 3; +	if (textured) return 2;  	llassert(hasGray());  	return 1; // gray  } @@ -4807,6 +4811,15 @@ U32 LLVOAvatar::renderSkinned()  		BOOL first_pass = TRUE;  		if (!LLDrawPoolAvatar::sSkipOpaque)  		{ +			if (isUIAvatar() && mIsDummy) +			{ +				LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); +				if (hair_mesh) +				{ +					num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +				} +				first_pass = FALSE; +			}  			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  			{  				if (isTextureVisible(TEX_HEAD_BAKED) || isUIAvatar()) @@ -4814,7 +4827,7 @@ U32 LLVOAvatar::renderSkinned()  					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);  					if (head_mesh)  					{ -						num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); +						num_indices += head_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);  					}  					first_pass = FALSE;  				} @@ -5321,12 +5334,28 @@ void LLVOAvatar::checkTextureLoading()  	}  	if(mLoadedCallbacksPaused == pause)  	{ +        if (!pause && mFirstFullyVisible && mLoadedCallbackTextures < mCallbackTextureList.size()) +        { +            // We still need to update 'loaded' textures count to decide on 'cloud' visibility +            // Alternatively this can be done on TextureLoaded callbacks, but is harder to properly track +            mLoadedCallbackTextures = 0; +            for (LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin(); +                iter != mCallbackTextureList.end(); ++iter) +            { +                LLViewerFetchedTexture* tex = gTextureList.findImage(*iter); +                if (tex && (tex->getDiscardLevel() >= 0 || tex->isMissingAsset())) +                { +                    mLoadedCallbackTextures++; +                } +            } +        }  		return ;   	}  	if(mCallbackTextureList.empty()) //when is self or no callbacks. Note: this list for self is always empty.  	{  		mLoadedCallbacksPaused = pause ; +		mLoadedCallbackTextures = 0;  		return ; //nothing to check.  	} @@ -5334,7 +5363,9 @@ void LLVOAvatar::checkTextureLoading()  	{  		return ; //have not been invisible for enough time.  	} -	 + +	mLoadedCallbackTextures = pause ? mCallbackTextureList.size() : 0; +  	for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = mCallbackTextureList.begin();  		iter != mCallbackTextureList.end(); ++iter)  	{ @@ -5355,9 +5386,15 @@ void LLVOAvatar::checkTextureLoading()  				tex->unpauseLoadedCallbacks(&mCallbackTextureList) ;  				tex->addTextureStats(START_AREA); //jump start the fetching again + +				// technically shouldn't need to account for missing, but callback might not have happened yet +				if (tex->getDiscardLevel() >= 0 || tex->isMissingAsset()) +				{ +					mLoadedCallbackTextures++; // consider it loaded (we have at least some data) +				}  			} -		}		 -	}			 +		} +	}  	if(!pause)  	{ @@ -7592,14 +7629,13 @@ bool LLVOAvatar::getIsCloud() const  			);  } -void LLVOAvatar::updateRezzedStatusTimers() +void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status)  {  	// State machine for rezzed status. Statuses are -1 on startup, 0  	// = cloud, 1 = gray, 2 = downloading, 3 = full.  	// Purpose is to collect time data for each it takes avatar to reach  	// various loading landmarks: gray, textured (partial), textured fully. -	S32 rez_status = getRezzedStatus();  	if (rez_status != mLastRezzedStatus)  	{  		LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL; @@ -7769,8 +7805,21 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse  // returns true if the value has changed.  BOOL LLVOAvatar::updateIsFullyLoaded()  { -	const bool loading = getIsCloud(); -	updateRezzedStatusTimers(); +	S32 rez_status = getRezzedStatus(); +	bool loading = getIsCloud(); +	if (mFirstFullyVisible && !mIsControlAvatar) +	{ +        loading = ((rez_status < 2) +                   // Wait at least 60s for unfinished textures to finish on first load, +                   // don't wait forever, it might fail. Even if it will eventually load by +                   // itself and update mLoadedCallbackTextures (or fail and clean the list), +                   // avatars are more time-sensitive than textures and can't wait that long. +                   || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC) +                   || !mPendingAttachment.empty() +                   || (rez_status < 3 && !isFullyBaked()) +                  ); +	} +	updateRezzedStatusTimers(rez_status);  	updateRuthTimer(loading);  	return processFullyLoadedChange(loading);  } @@ -7806,13 +7855,22 @@ void LLVOAvatar::updateRuthTimer(bool loading)  BOOL LLVOAvatar::processFullyLoadedChange(bool loading)  { -	// we wait a little bit before giving the all clear, -	// to let textures settle down -	const F32 PAUSE = 1.f; +	// We wait a little bit before giving the 'all clear', to let things to +	// settle down (models to snap into place, textures to get first packets) +	const F32 LOADED_DELAY = 1.f; +	const F32 FIRST_USE_DELAY = 3.f; +  	if (loading)  		mFullyLoadedTimer.reset(); -	 -	mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE); + +	if (mFirstFullyVisible) +	{ +		mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > FIRST_USE_DELAY); +	} +	else +	{ +		mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > LOADED_DELAY); +	}  	if (!mPreviousFullyLoaded && !loading && mFullyLoaded)  	{ @@ -8102,6 +8160,7 @@ void LLVOAvatar::updateMeshTextures()  		LLViewerTexLayerSet* layerset = getTexLayerSet(i);  		if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )  		{ +			// use last known good layer (no new one)  			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);  			mBakedTextureDatas[i].mIsUsed = TRUE; @@ -8120,6 +8179,7 @@ void LLVOAvatar::updateMeshTextures()  		}  		else if (!isUsingLocalAppearance() && is_layer_baked[i])  		{ +			// use new layer  			LLViewerFetchedTexture* baked_img =  				LLViewerTextureManager::staticCastToFetchedTexture(  					getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ; @@ -8139,10 +8199,15 @@ void LLVOAvatar::updateMeshTextures()  					 ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )  				{			  					baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ),  -						src_callback_list, paused);	 +						src_callback_list, paused);  				}  				baked_img->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, FALSE, new LLUUID( mID ),   					src_callback_list, paused ); +				if (baked_img->getDiscardLevel() < 0 && !paused) +				{ +					// mLoadedCallbackTextures will be updated by checkTextureLoading() below +					mLastTexCallbackAddedTime.reset(); +				}  				// this could add paused texture callbacks  				mLoadedCallbacksPaused |= paused;  @@ -8536,13 +8601,16 @@ void LLVOAvatar::onFirstTEMessageReceived()  				LL_DEBUGS("Avatar") << avString() << "layer_baked, setting onInitialBakedTextureLoaded as callback" << LL_ENDL;  				image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, FALSE, new LLUUID( mID ),   					src_callback_list, paused ); - +				if (image->getDiscardLevel() < 0 && !paused) +				{ +					mLastTexCallbackAddedTime.reset(); +				}                                 // this could add paused texture callbacks                                 mLoadedCallbacksPaused |= paused;   			}  		} -		mMeshTexturesDirty = TRUE; +        mMeshTexturesDirty = TRUE;  		gPipeline.markGLRebuild(this);  	}  } @@ -9189,8 +9257,6 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  // static  void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )  { - -	  	LLUUID *avatar_idp = (LLUUID *)userdata;  	LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 00dccc5d12..ca6ac5c902 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -348,7 +348,7 @@ public:  	BOOL			isFullyTextured() const;  	BOOL			hasGray() const;   	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded. -	void			updateRezzedStatusTimers(); +	void			updateRezzedStatusTimers(S32 status);  	S32				mLastRezzedStatus; @@ -629,6 +629,8 @@ protected:  	LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ;   	BOOL mLoadedCallbacksPaused; +	S32 mLoadedCallbackTextures; // count of 'loaded' baked textures, filled from mCallbackTextureList +	LLFrameTimer mLastTexCallbackAddedTime;  	std::set<LLUUID>	mTextureIDs;  	//--------------------------------------------------------------------  	// Local Textures diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 63ace4fe52..16b27fd144 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1250,7 +1250,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)  		gMessageSystem->nextBlockFast(_PREHASH_ObjectData);  		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());  		gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); -		gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); +		gMessageSystem->sendReliable(gAgent.getRegionHost());  		// This object might have been selected, so let the selection manager know it's gone now  		LLViewerObject *found_obj = gObjectList.findObject(item_id); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 739f7bd47c..530adb8975 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -5158,6 +5158,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)  		{  			// Turning voice off looses your current channel -- this makes sure the UI isn't out of sync when you re-enable it.  			LLVoiceChannel::getCurrentVoiceChannel()->deactivate(); +			gAgent.setVoiceConnected(false);  			status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;  		} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f0ed303f66..01438bfb9f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8740,29 +8740,24 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)  						}  					} -					const LLViewerObject *vobj = drawablep->getVObj(); -					if (vobj) -					{ -						LLVOAvatar *av = vobj->getAvatar(); -						if (av) -						{ -							if (av->isTooComplex() || av->isInMuteList() || dist_vec(av->getPosition(), LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip) -							{ -								continue; -							} -						} -						else -						{ -							const LLViewerObject *root_obj = drawablep->getParent() ? drawablep->getParent()->getVObj() : vobj; -							if (root_obj && dist_vec(root_obj->getPosition(), LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip) -					{ -						continue; -					} -						} -					} +                    const LLViewerObject *vobj = drawablep->getVObj(); +                    if (vobj) +                    { +                        LLVOAvatar *av = vobj->getAvatar(); +                        if (av && (av->isTooComplex() || av->isInMuteList())) +                        { +                            continue; +                        } +                    } + +                    const LLVector3 position = drawablep->getPositionAgent(); +                    if (dist_vec(position, LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip + volume->getLightRadius()) +                    { +                        continue; +                    }  					LLVector4a center; -					center.load3(drawablep->getPositionAgent().mV); +					center.load3(position.mV);  					const F32* c = center.getF32ptr();  					F32 s = volume->getLightRadius()*1.5f; diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index 2d5263b78f..76df0abdfd 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -21,6 +21,7 @@        <file>AppleGothic.dfont</file>        <file>AppleGothic.ttf</file>        <file>AppleSDGothicNeo-Regular.otf</file> +      <file>AppleSDGothicNeo.ttc</file>        <file>华文细黑.ttf</file>        <file>PingFang.ttc</file>        <file>STIXGeneral.otf</file> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index e228c5bdba..873b95926b 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -461,7 +461,7 @@               name="Events">              <menu_item_call.on_click               function="Advanced.ShowURL" -             parameter="http://events.secondlife.com"/> +             parameter="https://secondlife.com/my/community/events"/>          </menu_item_call>          <menu_item_check          label="Search..." diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 98bb77d9e0..8a91a1f721 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1513,7 +1513,7 @@ Go to the [SECOND_LIFE] events web page?      <tag>confirm</tag>      <url option="0" name="url"> -			http://secondlife.com/events/ +			https://secondlife.com/my/community/events      </url>      <usetemplate       name="okcancelbuttons" | 
