summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2020-05-04 23:39:37 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2020-05-04 23:39:37 +0300
commit1c82a80b2e48167ba718b6b79d51135cc7e7b371 (patch)
treecc8a5b339116a317d8329d34ee162d6a80ab013b
parentf4c7c8aff55d0cd8f044d5b7c8cddb2be750dde5 (diff)
parent4a7fd0117a43dca9e30c58c6417ebdf6862561f6 (diff)
Merge branch 'master' into DRTVWR-486
-rwxr-xr-xdoc/contributions.txt1
-rw-r--r--indra/llaudio/llaudiodecodemgr.cpp2
-rw-r--r--indra/llcommon/llprocessor.cpp9
-rw-r--r--indra/llcommon/llsdserialize.cpp2
-rw-r--r--indra/llcorehttp/_httpservice.cpp2
-rw-r--r--indra/llcorehttp/bufferarray.cpp2
-rw-r--r--indra/llimage/llimagejpeg.cpp2
-rw-r--r--indra/llimage/llpngwrapper.cpp2
-rw-r--r--indra/llmath/llvolume.cpp31
-rw-r--r--indra/llmessage/llcorehttputil.cpp4
-rw-r--r--indra/llmessage/llhttpnode.cpp8
-rw-r--r--indra/llrender/llgl.cpp83
-rw-r--r--indra/llrender/llgl.h1
-rw-r--r--indra/llrender/llglheaders.h2
-rw-r--r--indra/llui/tests/llurlentry_test.cpp5
-rw-r--r--indra/llwindow/lldxhardware.cpp70
-rw-r--r--indra/llwindow/lldxhardware.h4
-rw-r--r--indra/llwindow/llwindowwin32.cpp14
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/llagent.cpp8
-rw-r--r--indra/newview/llagentcamera.cpp5
-rw-r--r--indra/newview/llappviewer.cpp16
-rw-r--r--indra/newview/llenvironment.cpp8
-rw-r--r--indra/newview/llfloaterevent.cpp2
-rw-r--r--indra/newview/llimprocessing.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp2
-rw-r--r--indra/newview/lllogininstance.cpp2
-rw-r--r--indra/newview/llmeshrepository.cpp2
-rw-r--r--indra/newview/llrecentpeople.h2
-rw-r--r--indra/newview/llsecapi.cpp2
-rw-r--r--indra/newview/llsettingsvo.h3
-rw-r--r--indra/newview/llstartup.cpp3
-rw-r--r--indra/newview/llviewerkeyboard.cpp5
-rw-r--r--indra/newview/llviewertexturelist.cpp7
-rw-r--r--indra/newview/llviewerwindow.cpp8
-rw-r--r--indra/newview/llvoavatar.cpp106
-rw-r--r--indra/newview/llvoavatar.h4
-rw-r--r--indra/newview/llvoavatarself.cpp2
-rw-r--r--indra/newview/llvoicevivox.cpp1
-rw-r--r--indra/newview/pipeline.cpp37
-rw-r--r--indra/newview/skins/default/xui/en/fonts.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml2
43 files changed, 369 insertions, 109 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index eb8ae60cb7..2153e10888 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 8edb1a5f0b..85b7d7b06f 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -282,6 +282,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/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 8a69acb8dc..873531ef22 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -62,7 +62,7 @@
#include <boost/scoped_ptr.hpp>
#include <sstream>
-const S32 LOGIN_MAX_RETRIES = 3;
+const S32 LOGIN_MAX_RETRIES = 0; // Viewer should not autmatically retry login
const F32 LOGIN_SRV_TIMEOUT_MIN = 10;
const F32 LOGIN_SRV_TIMEOUT_MAX = 120;
const F32 LOGIN_DNS_TIMEOUT_FACTOR = 0.9; // make DNS wait shorter then retry time
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 a1d1e85492..7673bae725 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1879,8 +1879,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 e930eb20d3..a14041717f 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -986,6 +986,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 7579eb1a90..eb461d3140 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)
{
@@ -7591,14 +7628,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;
@@ -7768,8 +7804,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);
}
@@ -7805,13 +7854,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)
{
@@ -8101,6 +8159,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;
@@ -8119,6 +8178,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) ;
@@ -8138,10 +8198,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;
@@ -8535,13 +8600,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);
}
}
@@ -9188,8 +9256,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 61a23851ed..089498dfb9 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"