diff --git a/autobuild.xml b/autobuild.xml old mode 100755 new mode 100644 index f5d46ce929..92a4ca5528 --- a/autobuild.xml +++ b/autobuild.xml @@ -3329,14 +3329,6 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - RelWithDebInfo - --startup - secondlife-bin options @@ -3372,20 +3364,11 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - RelWithDebInfo - --startup - secondlife-bin options -G "Visual Studio 12" - -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE @@ -3414,14 +3397,6 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - Release - --startup - secondlife-bin options @@ -3453,20 +3428,11 @@ arguments ..\indra - && - ..\indra\tools\vstool\VSTool.exe - --solution - SecondLife.sln - --config - Release - --startup - secondlife-bin options -G "Visual Studio 12" - -DUNATTENDED:BOOL=ON -DINSTALL_PROPRIETARY=FALSE -DUSE_KDU=FALSE diff --git a/build.sh b/build.sh index 185b7c9592..bed79302e4 100755 --- a/build.sh +++ b/build.sh @@ -97,6 +97,7 @@ pre_build() "$autobuild" configure --quiet -c $variant -- \ -DPACKAGE:BOOL=ON \ + -DUNATTENDED:BOOL=ON \ -DRELEASE_CRASH_REPORTING:BOOL=ON \ -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \ -DGRID:STRING="\"$viewer_grid\"" \ diff --git a/doc/contributions.txt b/doc/contributions.txt index cedc723395..6e7d734bd4 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -201,6 +201,7 @@ Ansariel Hiller STORM-2133 MAINT-6511 MAINT-6612 + MAINT-6637 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 809583557a..27d2f3a1d3 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -961,6 +961,12 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a) { llassert( getComponents() <= 4 ); // This is fairly bogus, but it'll do for now. + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + U8 *pos = getData(); U32 x, y; for (x = 0; x < getWidth(); x++) @@ -1088,6 +1094,11 @@ void LLImageRaw::composite( LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::composite", src, dst)) + { + return; + } + llassert(3 == src->getComponents()); llassert(3 == dst->getComponents()); @@ -1155,7 +1166,6 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src ) llassert( (3 == src->getComponents()) || (4 == src->getComponents()) ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); - U8* src_data = src->getData(); U8* dst_data = dst->getData(); S32 pixels = getWidth() * getHeight(); @@ -1190,6 +1200,11 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst)) + { + return; + } + llassert( 1 == src->getComponents() ); llassert( 4 == dst->getComponents() ); llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); @@ -1212,6 +1227,12 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill) // Fill the buffer with a constant color void LLImageRaw::fill( const LLColor4U& color ) { + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return; + } + S32 pixels = getWidth() * getHeight(); if( 4 == getComponents() ) { @@ -1250,14 +1271,13 @@ LLPointer LLImageRaw::duplicate() // Src and dst can be any size. Src and dst can each have 3 or 4 components. void LLImageRaw::copy(LLImageRaw* src) { - if (!src) + LLImageRaw* dst = this; // Just for clarity. + + if (!validateSrcAndDst("LLImageRaw::copy", src, dst)) { - LL_WARNS() << "LLImageRaw::copy called with a null src pointer" << LL_ENDL; return; } - LLImageRaw* dst = this; // Just for clarity. - if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) { // No scaling needed @@ -1384,6 +1404,11 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) { LLImageRaw* dst = this; // Just for clarity. + if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst)) + { + return; + } + llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) ); llassert_always( src->getComponents() == dst->getComponents() ); @@ -1422,6 +1447,12 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data ) { llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) ); + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return false; + } + S32 old_width = getWidth(); S32 old_height = getHeight(); @@ -1721,6 +1752,25 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3 } } +bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst) +{ + if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid()) + { + LL_WARNS() << func << ": Source: "; + if (!src) LL_CONT << "Null pointer"; + else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer"; + else LL_CONT << "OK"; + + LL_CONT << "; Destination: "; + if (!dst) LL_CONT << "Null pointer"; + else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer"; + else LL_CONT << "OK"; + LL_CONT << "." << LL_ENDL; + + return false; + } + return true; +} //---------------------------------------------------------------------------- diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index f62aa69b2a..76d53b3f09 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -287,6 +287,9 @@ public: // texture comment metadata reader std::string mComment; // + +private: + bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst); }; // Compressed representation of image. diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 4bffe586f6..7978ecc845 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -31,9 +31,31 @@ #include "llpointer.h" #include "llmath.h" #include "llkdumem.h" +#include "stringize.h" #include "kdu_block_coding.h" +#include +#include + +namespace { +// exception used to keep KDU from terminating entire program -- see comments +// in LLKDUMessageError::flush() +struct KDUError: public std::runtime_error +{ + KDUError(const std::string& msg): std::runtime_error(msg) {} +}; +} // anonymous namespace + +// stream kdu_dims to std::ostream +// Turns out this must NOT be in the anonymous namespace! +inline +std::ostream& operator<<(std::ostream& out, const kdu_dims& dims) +{ + return out << "(" << dims.pos.x << "," << dims.pos.y << ")," + "[" << dims.size.x << "x" << dims.size.y << "]"; +} + class kdc_flow_control { public: @@ -172,9 +194,15 @@ struct LLKDUMessageError : public LLKDUMessage // terminating handler→flush call." // So throwing an exception here isn't arbitrary: we MUST throw an // exception if we want to recover from a KDU error. + // Because this confused me: the above quote specifically refers to + // the kdu_error class, which is constructed internally within KDU at + // the point where a fatal error is discovered and reported. It is NOT + // talking about the kdu_message subclass passed to + // kdu_customize_errors(). Destroying this static object at program + // shutdown will NOT engage the behavior described above. if (end_of_message) { - throw "KDU throwing an exception"; + throw KDUError("LLKDUMessageError::flush()"); } } }; @@ -203,6 +231,10 @@ LLImageJ2CKDU::~LLImageJ2CKDU() // Stuff for new simple decode void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision); +// This is called by the real (private) initDecode() (keep_codestream true) +// and getMetadata() methods (keep_codestream false). As far as nat can tell, +// mode is always MODE_FAST. It was called by findDiscardLevelsBoundaries() +// as well, when that still existed, with keep_codestream true and MODE_FAST. void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode) { S32 data_size = base.getDataSize(); @@ -213,6 +245,12 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // mCodeStreamp.reset(); + // It's not clear to nat under what circumstances we would reuse a + // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of + // two U32s and a pointer, so it's not as if it would be a huge overhead + // to allocate a new one every time. + // Also -- why is base.getData() tested specifically here? If that returns + // NULL, shouldn't we bail out of the whole method? if (!mInputp && base.getData()) { // The compressed data has been loaded @@ -269,13 +307,22 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod S32 components = mCodeStreamp->get_num_components(); - if (components >= 3) - { // Check that components have consistent dimensions (for PPM file) - kdu_dims dims1; mCodeStreamp->get_dims(1,dims1); - kdu_dims dims2; mCodeStreamp->get_dims(2,dims2); - if ((dims1 != dims) || (dims2 != dims)) + // Check that components have consistent dimensions (for PPM file) + for (int idx = 1; idx < components; ++idx) + { + kdu_dims other_dims; + mCodeStreamp->get_dims(idx, other_dims); + if (other_dims != dims) { - LL_ERRS() << "Components don't have matching dimensions!" << LL_ENDL; + // This method is only called from methods that catch KDUError. + // We want to fail the image load, not crash the viewer. + // Can't use operator << with kdu_core::kdu_dims + //throw KDUError(STRINGIZE("Component " << idx << " dimensions " + // << other_dims + // << " do not match component 0 dimensions " + // << dims << "!")); + throw KDUError("Components don't have matching dimensions!"); + // } } @@ -302,6 +349,9 @@ void LLImageJ2CKDU::cleanupCodeStream() mTileIndicesp.reset(); } +// This is the protected virtual method called by LLImageJ2C::initDecode(). +// However, as far as nat can tell, LLImageJ2C::initDecode() is called only by +// llimage_libtest.cpp's load_image() function. No detectable production use. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) { return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region); @@ -334,6 +384,9 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc return true; } +// This is the real (private) initDecode() called both by the protected +// initDecode() method and by decodeImpl(). As far as nat can tell, only the +// decodeImpl() usage matters for production. bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region) { base.resetLastError(); @@ -391,9 +444,9 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco mTPosp->x = 0; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch (...) @@ -501,9 +554,9 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco return false; } } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); base.decodeFailed(); cleanupCodeStream(); return true; // done @@ -695,9 +748,9 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.updateData(); // set width, height delete[] output_buffer; } - catch(const char* msg) + catch(const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch( ... ) @@ -719,9 +772,9 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) setupCodeStream(base, false, MODE_FAST); return true; } - catch (const char* msg) + catch (const KDUError& msg) { - base.setLastError(ll_safe_string(msg)); + base.setLastError(msg.what()); return false; } catch (...) diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index d2afb3f91b..474953d3a4 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -175,6 +175,11 @@ BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window) return FALSE; } +void LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) +{ + +} + void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg) { diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 6a7137e593..de789a71d9 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -65,6 +65,7 @@ public: virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data); virtual BOOL handleTimerEvent(LLWindow *window); virtual BOOL handleDeviceChange(LLWindow *window); + virtual void handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); enum DragNDropAction { DNDA_START_TRACKING = 0,// Start tracking an incoming drag diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 1144b75257..0d326641fd 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -71,6 +71,11 @@ const S32 MAX_MESSAGE_PER_UPDATE = 20; const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; const F32 ICON_FLASH_TIME = 0.5f; +const F32 DEFAULT_DPI = 96.0f; + +#ifndef WM_DPICHANGED +const S32 WM_DPICHANGED = 0x02E0; +#endif extern BOOL gDebugWindowProc; @@ -97,6 +102,10 @@ typedef enum MONITOR_DPI_TYPE { typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value); +typedef HRESULT(STDAPICALLTYPE *GetProcessDpiAwarenessType)( + _In_ HANDLE hprocess, + _Out_ PROCESS_DPI_AWARENESS *value); + typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)( _In_ HMONITOR hmonitor, _In_ MONITOR_DPI_TYPE dpiType, @@ -2639,6 +2648,24 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ return 0; } + + case WM_DPICHANGED: + { + LPRECT lprc_new_scale; + F32 new_scale = LOWORD(w_param) / 96.0f; + lprc_new_scale = (LPRECT)l_param; + S32 new_width = lprc_new_scale->right - lprc_new_scale->left; + S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top; + window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height); + SetWindowPos(h_wnd, + HWND_TOP, + lprc_new_scale->left, + lprc_new_scale->top, + new_width, + new_height, + SWP_NOZORDER | SWP_NOACTIVATE); + return 0; + } case WM_SETFOCUS: window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS"); @@ -3966,6 +3993,31 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res return FALSE; } +//static +void LLWindowWin32::setDPIAwareness() +{ + HMODULE hShcore = LoadLibrary(L"shcore.dll"); + if (hShcore != NULL) + { + SetProcessDpiAwarenessType pSPDA; + pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); + if (pSPDA) + { + + HRESULT hr = pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); + if (hr != S_OK) + { + LL_WARNS() << "SetProcessDpiAwareness() function returned an error. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } + } + FreeLibrary(hShcore); + } + else + { + LL_WARNS() << "Could not load shcore.dll library (included by from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL; + } +} + F32 LLWindowWin32::getSystemUISize() { // Type fix @@ -3974,39 +4026,55 @@ F32 LLWindowWin32::getSystemUISize() HWND hWnd = (HWND)getPlatformWindow(); HDC hdc = GetDC(hWnd); HMONITOR hMonitor; + HANDLE hProcess = GetCurrentProcess(); + PROCESS_DPI_AWARENESS dpi_awareness; HMODULE hShcore = LoadLibrary(L"shcore.dll"); if (hShcore != NULL) { - // Set DPI awareness via manifest as recommended - //SetProcessDpiAwarenessType pSPDA; - //pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness"); - // + GetProcessDpiAwarenessType pGPDA; + pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness"); GetDpiForMonitorType pGDFM; pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor"); - if (/*pSPDA != NULL &&*/ pGDFM != NULL) // Set DPI awareness via manifest as recommended + if (pGPDA != NULL && pGDFM != NULL) { - //pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); // Set DPI awareness via manifest as recommended - POINT pt; - UINT dpix = 0, dpiy = 0; - HRESULT hr = E_FAIL; + pGPDA(hProcess, &dpi_awareness); + if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE) + { + POINT pt; + UINT dpix = 0, dpiy = 0; + HRESULT hr = E_FAIL; + RECT rect; - // Get the DPI for the main monitor, and set the scaling factor - pt.x = 1; - pt.y = 1; - // Get scaling for primary display, assuming that's where we open the viewer - //hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); - // - hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); - scale_value = dpix / 96.0f; + GetWindowRect(hWnd, &rect); + // Get the DPI for the monitor, on which the center of window is displayed and set the scaling factor + pt.x = (rect.left + rect.right) / 2; + pt.y = (rect.top + rect.bottom) / 2; + hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy); + if (hr == S_OK) + { + scale_value = dpix / DEFAULT_DPI; + } + else + { + LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } + } + else + { + LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL; + scale_value = 1.0f; + } } + FreeLibrary(hShcore); } else { LL_WARNS() << "Could not load shcore.dll library (included by from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL; - scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f; + scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / DEFAULT_DPI; } ReleaseDC(hWnd, hdc); diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 15c968e82f..a94f93a776 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -120,7 +120,7 @@ public: LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); static std::vector getDynamicFallbackFontList(); - + static void setDPIAwareness(); protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3a5d694b02..125c453c66 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10358,6 +10358,17 @@ Change of this parameter will affect the layout of buttons in notification toast Backup 0 + PrimTextMaxDrawDistance + + Comment + Maximum draw distance beyond which PRIM_TEXT won't be rendered + Persist + 1 + Type + F32 + Value + 64.0 + ProbeHardwareOnStartup Comment @@ -12723,6 +12734,17 @@ Change of this parameter will affect the layout of buttons in notification toast Backup 0 + ComplexityChangesPopUpDelay + + Comment + Delay before viewer will show avatar complexity notice again + Persist + 1 + Type + U32 + Value + 300 + RenderAvatarMaxComplexity Comment @@ -12735,6 +12757,50 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + RenderHUDObjectsWarning + + Comment + Viewer will warn user about HUD containing to many objects if objects count is above this value + Persist + 1 + Type + U32 + Value + 1000 + + RenderHUDTexturesWarning + + Comment + Viewer will warn user about HUD containing to many textures if texture count is above this value + Persist + 1 + Type + U32 + Value + 200 + + RenderHUDOversizedTexturesWarning + + Comment + How many textures with size 1024 * 1024 or bigger HUD can contain before notifying user + Persist + 1 + Type + U32 + Value + 6 + + RenderHUDTexturesVirtualMemoryWarning + + Comment + Viewer will warn user about HUD textures using memory above this value (Virtual memory, in pixels) + Persist + 1 + Type + U32 + Value + 10000000 + RenderAutoMuteSurfaceAreaLimit Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5d8958b392..3d1668d0f5 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1310,17 +1310,23 @@ bool LLAppViewer::init() #if LL_WINDOWS if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion()) { + std::string url; if (gGLManager.mIsIntel) { - LLNotificationsUtil::add("IntelOldDriver"); + url = LLTrans::getString("IntelDriverPage"); } else if (gGLManager.mIsNVIDIA) { - LLNotificationsUtil::add("NVIDIAOldDriver"); + url = LLTrans::getString("NvidiaDriverPage"); } else if (gGLManager.mIsATI) { - LLNotificationsUtil::add("AMDOldDriver"); + url = LLTrans::getString("AMDDriverPage"); + } + + if (!url.empty()) + { + LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url)); } } #endif @@ -6748,7 +6754,9 @@ void LLAppViewer::launchUpdater() */ void LLAppViewer::showReleaseNotesIfRequired() { - if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion && gSavedSettings.getBOOL("UpdaterShowReleaseNotes")) + if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion + && gSavedSettings.getBOOL("UpdaterShowReleaseNotes") + && !gSavedSettings.getBOOL("FirstLoginThisInstall")) { LLSD info(getViewerInfo()); LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index a526095af7..6cac44b5f3 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -304,6 +304,8 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, DWORD heap_enable_lfh_error[MAX_HEAPS]; S32 num_heaps = 0; + LLWindowWin32::setDPIAwareness(); + #if WINDOWS_CRT_MEM_CHECKS && !INCLUDE_VLD _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // dump memory leaks on exit #elif 0 @@ -642,7 +644,7 @@ bool LLAppViewerWin32::initHardwareTest() // Do driver verification and initialization based on DirectX // hardware polling and driver versions // - if (FALSE == gSavedSettings.getBOOL("NoHardwareProbe")) + if (TRUE == gSavedSettings.getBOOL("ProbeHardwareOnStartup") && FALSE == gSavedSettings.getBOOL("NoHardwareProbe")) { // per DEV-11631 - disable hardware probing for everything // but vram. diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp index 414c641f80..7fe5859399 100644 --- a/indra/newview/llavatarrendernotifier.cpp +++ b/indra/newview/llavatarrendernotifier.cpp @@ -51,6 +51,11 @@ static const F32 RENDER_ALLOWED_CHANGE_PCT = 0.1f; // wait seconds before processing over limit updates after last complexity change static const U32 OVER_LIMIT_UPDATE_DELAY = 70; +static const U32 WARN_HUD_OBJECTS_LIMIT = 1000; +static const U32 WARN_HUD_TEXTURES_LIMIT = 200; +static const U32 WARN_HUD_OVERSIZED_TEXTURES_LIMIT = 6; +static const U32 WARN_HUD_TEXTURE_MEMORY_LIMIT = 10000000; // in pixels + LLAvatarRenderNotifier::LLAvatarRenderNotifier() : mAgentsCount(0), @@ -264,3 +269,128 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity) } } +// LLHUDRenderNotifier + +LLHUDRenderNotifier::LLHUDRenderNotifier() +{ +} + +LLHUDRenderNotifier::~LLHUDRenderNotifier() +{ +} + +void LLHUDRenderNotifier::updateNotificationHUD(LLHUDComplexity new_complexity) +{ + if (!isAgentAvatarValid()) + { + // data not ready. + return; + } + + static const char* hud_memory = "hud_render_memory_warning"; + static const char* hud_cost = "hud_render_cost_warning"; + static const char* hud_heavy = "hud_render_heavy_textures_warning"; + static const char* hud_cramped = "hud_render_cramped_warning"; + static const char* hud_textures = "hud_render_textures_warning"; + + static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost + static LLCachedControl max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT); + static LLCachedControl max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT); + static LLCachedControl max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT); + static LLCachedControl max_texture_memory(gSavedSettings, "RenderHUDTexturesVirtualMemoryWarning", WARN_HUD_TEXTURE_MEMORY_LIMIT); + + if (mHUDPopUpDelayTimer.hasExpired()) + { + // Show warning with highest importance (5m delay between warnings by default) + // TODO: + // Consider showing message with list of issues. + // For now shows one after another if update arrives and timer expired, so + // consider showing only one most important or consider triggering not + // only in case of update + if (mReportedHUDComplexity.texturesSizeTotal < new_complexity.texturesSizeTotal + && new_complexity.texturesSizeTotal > max_texture_memory) + { + displayHUDNotification(hud_memory); + LL_DEBUGS("HUDdetail") << "HUD memory usage over limit," + << " was " << mReportedHUDComplexity.texturesSizeTotal + << " is " << new_complexity.texturesSizeTotal << LL_ENDL; + mReportedHUDComplexity.texturesSizeTotal = new_complexity.texturesSizeTotal; + } + else if ((mReportedHUDComplexity.objectsCost < new_complexity.objectsCost + || mReportedHUDComplexity.texturesCost < new_complexity.texturesCost) + && max_render_cost > 0 + && new_complexity.objectsCost + new_complexity.texturesCost > max_render_cost) + { + LL_DEBUGS("HUDdetail") << "HUD complexity over limit," + << " HUD textures cost: " << new_complexity.texturesCost + << " HUD objects cost: " << new_complexity.objectsCost << LL_ENDL; + displayHUDNotification(hud_cost); + mReportedHUDComplexity.objectsCost = new_complexity.objectsCost; + mReportedHUDComplexity.texturesCost = new_complexity.texturesCost; + } + else if (mReportedHUDComplexity.largeTexturesCount < new_complexity.largeTexturesCount + && new_complexity.largeTexturesCount > max_oversized_count) + { + LL_DEBUGS("HUDdetail") << "HUD contains to many large textures: " + << new_complexity.largeTexturesCount << LL_ENDL; + displayHUDNotification(hud_heavy); + mReportedHUDComplexity.largeTexturesCount = new_complexity.largeTexturesCount; + } + else if (mReportedHUDComplexity.texturesCount < new_complexity.texturesCount + && new_complexity.texturesCount > max_textures_count) + { + LL_DEBUGS("HUDdetail") << "HUD contains too many textures: " + << new_complexity.texturesCount << LL_ENDL; + displayHUDNotification(hud_cramped); + mReportedHUDComplexity.texturesCount = new_complexity.texturesCount; + } + else if (mReportedHUDComplexity.objectsCount < new_complexity.objectsCount + && new_complexity.objectsCount > max_objects_count) + { + LL_DEBUGS("HUDdetail") << "HUD contains too many objects: " + << new_complexity.objectsCount << LL_ENDL; + displayHUDNotification(hud_textures); + mReportedHUDComplexity.objectsCount = new_complexity.objectsCount; + } + else + { + // all warnings displayed, just store everything so that we will + // be able to reduce values and show warnings again later + mReportedHUDComplexity = new_complexity; + } + } + + if (mLatestHUDComplexity.objectsCost != new_complexity.objectsCost + || mLatestHUDComplexity.objectsCount != new_complexity.objectsCount + || mLatestHUDComplexity.texturesCost != new_complexity.texturesCost + || mLatestHUDComplexity.texturesCount != new_complexity.texturesCount + || mLatestHUDComplexity.largeTexturesCount != new_complexity.largeTexturesCount + || mLatestHUDComplexity.texturesSizeTotal != new_complexity.texturesSizeTotal) + { + LL_INFOS("HUDdetail") << "HUD textures count: " << new_complexity.texturesCount + << " HUD textures cost: " << new_complexity.texturesCost + << " Large textures: " << new_complexity.largeTexturesCount + << " HUD objects cost: " << new_complexity.objectsCost + << " HUD objects count: " << new_complexity.objectsCount << LL_ENDL; + + mLatestHUDComplexity = new_complexity; + } + +} + +void LLHUDRenderNotifier::displayHUDNotification(const char* message) +{ + static LLCachedControl pop_up_delay(gSavedSettings, "ComplexityChangesPopUpDelay", 300); + static LLCachedControl expire_delay(gSavedSettings, "ShowMyComplexityChanges", 20); + LLDate expire_date(LLDate::now().secondsSinceEpoch() + expire_delay); + + LLSD args; + args["HUD_REASON"] = LLTrans::getString(message); + + LLNotifications::instance().add(LLNotification::Params() + .name("HUDComplexityWarning") + .expiry(expire_date) + .substitutions(args)); + mHUDPopUpDelayTimer.resetWithExpiry(pop_up_delay); +} + diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h index 2a2704de28..959bebef02 100644 --- a/indra/newview/llavatarrendernotifier.h +++ b/indra/newview/llavatarrendernotifier.h @@ -33,6 +33,25 @@ class LLViewerRegion; +struct LLHUDComplexity +{ + LLHUDComplexity() + { + objectsCost = 0; + objectsCount = 0; + texturesCost = 0; + texturesCount = 0; + largeTexturesCount = 0; + texturesSizeTotal = 0; + } + U32 objectsCost; + U32 objectsCount; + U32 texturesCost; + U32 texturesCount; + U32 largeTexturesCount; + F64 texturesSizeTotal; +}; + // Class to notify user about drastic changes in agent's render weights or if other agents // reported that user's agent is too 'heavy' for their settings class LLAvatarRenderNotifier : public LLSingleton @@ -81,4 +100,21 @@ private: S32 mLastOutfitRezStatus; }; +// Class to notify user about heavy set of HUD +class LLHUDRenderNotifier : public LLSingleton +{ +public: + LLHUDRenderNotifier(); + ~LLHUDRenderNotifier(); + + void updateNotificationHUD(LLHUDComplexity new_complexity); + +private: + void displayHUDNotification(const char* message); + + LLHUDComplexity mReportedHUDComplexity; + LLHUDComplexity mLatestHUDComplexity; + LLFrameTimer mHUDPopUpDelayTimer; +}; + #endif /* ! defined(LL_llavatarrendernotifier_H) */ diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp index 271dd44c1f..7c2a3cad43 100644 --- a/indra/newview/llgroupiconctrl.cpp +++ b/indra/newview/llgroupiconctrl.cpp @@ -74,9 +74,16 @@ LLGroupIconCtrl::~LLGroupIconCtrl() LLGroupMgr::getInstance()->removeObserver(this); } -void LLGroupIconCtrl::setIconId(const LLSD& value) +void LLGroupIconCtrl::setIconId(const LLUUID& icon_id) { - LLIconCtrl::setValue(value); + if (icon_id.notNull()) + { + LLIconCtrl::setValue(icon_id); + } + else + { + LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); + } } void LLGroupIconCtrl::setValue(const LLSD& value) @@ -122,14 +129,7 @@ bool LLGroupIconCtrl::updateFromCache() LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mGroupId); if (!group_data) return false; - if (group_data->mInsigniaID.notNull()) - { - LLIconCtrl::setValue(group_data->mInsigniaID); - } - else - { - LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); - } + setIconId(group_data->mInsigniaID); if (mDrawTooltip && !group_data->mName.empty()) { diff --git a/indra/newview/llgroupiconctrl.h b/indra/newview/llgroupiconctrl.h index f8b22cf581..43e384d3e2 100644 --- a/indra/newview/llgroupiconctrl.h +++ b/indra/newview/llgroupiconctrl.h @@ -66,7 +66,13 @@ public: */ virtual void setValue(const LLSD& value); - void setIconId(const LLSD& value); + /** + * Sets icon_id as icon value directly. Avoids LLGroupMgr cache checks for group id + * Uses default icon in case id is null. + * + * @params icon_id - it is processed as icon id, default image will be used in case id is null. + */ + void setIconId(const LLUUID& icon_id); // LLGroupMgrObserver observer trigger virtual void changed(LLGroupChange gc); diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 3539b6cd1f..08c8a555f8 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -56,7 +56,7 @@ const F32 VERTICAL_PADDING = 12.f; const F32 BUFFER_SIZE = 2.f; const F32 HUD_TEXT_MAX_WIDTH = 190.f; const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f; -const F32 MAX_DRAW_DISTANCE = 64.f; +const F32 MAX_DRAW_DISTANCE = 300.f; std::set > LLHUDText::sTextObjects; std::vector > LLHUDText::sVisibleTextObjects; @@ -436,7 +436,20 @@ void LLHUDText::updateVisibility() LLVector3 pos_agent_center = gAgent.getPosAgentFromGlobal(mPositionGlobal) - dir_from_camera; F32 last_distance_center = (pos_agent_center - LLViewerCamera::getInstance()->getOrigin()).magVec(); - if(last_distance_center > MAX_DRAW_DISTANCE) + F32 max_draw_distance = gSavedSettings.getF32("PrimTextMaxDrawDistance"); + + if(max_draw_distance < 0) + { + max_draw_distance = 0; + gSavedSettings.setF32("PrimTextMaxDrawDistance", max_draw_distance); + } + else if(max_draw_distance > MAX_DRAW_DISTANCE) + { + max_draw_distance = MAX_DRAW_DISTANCE; + gSavedSettings.setF32("PrimTextMaxDrawDistance", MAX_DRAW_DISTANCE); + } + + if(last_distance_center > max_draw_distance) { mVisible = FALSE; return; diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp index 8e91af321e..0c5a91e48a 100644 --- a/indra/newview/llinspectgroup.cpp +++ b/indra/newview/llinspectgroup.cpp @@ -233,7 +233,8 @@ void LLInspectGroup::processGroupData() getChild("group_details")->setValue( LLSD(data->mCharter) ); - getChild("group_icon")->setValue( LLSD(data->mInsigniaID) ); + // LLGroupIconCtrl + getChild("group_icon")->setValue(LLSD(mGroupID)); std::string cost; bool is_member = LLGroupActions::isInGroup(mGroupID); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 61e1660f4d..cba6e96800 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1460,7 +1460,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) void LLTextureCtrl::setImageAssetName(const std::string& name) { - LLPointer imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW); + LLPointer imagep = LLUI::getUIImage(name); if(imagep) { LLViewerFetchedTexture* pTexture = dynamic_cast(imagep->getImage().get()); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2eae87250a..e8afbf0837 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1664,6 +1664,13 @@ BOOL LLViewerWindow::handleDeviceChange(LLWindow *window) return FALSE; } +void LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height) +{ + gSavedSettings.setF32("UIScaleFactor", ui_scale_factor); + LLViewerWindow::reshape(window_width, window_height); + mResDirty = true; +} + void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg) { LLAppViewer::instance()->pingMainloopTimeout(msg); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index c0f605daa8..6bb56926bc 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -211,6 +211,7 @@ public: /*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data); /*virtual*/ BOOL handleTimerEvent(LLWindow *window); /*virtual*/ BOOL handleDeviceChange(LLWindow *window); + /*virtual*/ void handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height); /*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg); /*virtual*/ void handlePauseWatchdog(LLWindow *window); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c31306f020..a8a30bc598 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -201,6 +201,7 @@ const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f; const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f; const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0; +const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024; enum ERenderName { @@ -8190,15 +8191,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // No backsies zone - if we get here, the message should be valid and usable, will be processed. LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL; - if (isSelf()) - { - // Note: - // locally the COF is maintained via LLInventoryModel::accountForUpdate - // which is called from various places. This should match the simhost's - // idea of what the COF version is. AIS however maintains its own version - // of the COF that should be considered canonical. - mLastUpdateReceivedCOFVersion = thisAppearanceVersion; - } + // Note: + // locally the COF is maintained via LLInventoryModel::accountForUpdate + // which is called from various places. This should match the simhost's + // idea of what the COF version is. AIS however maintains its own version + // of the COF that should be considered canonical. + mLastUpdateReceivedCOFVersion = thisAppearanceVersion; // [Legacy Bake] setIsUsingServerBakes(appearance_version > 0); @@ -9205,6 +9203,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() { U32 cost = VISUAL_COMPLEXITY_UNKNOWN; LLVOVolume::texture_cost_t textures; + LLHUDComplexity hud_complexity; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { @@ -9289,6 +9288,55 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } } } + if (isSelf() + && attached_object + && attached_object->isHUDAttachment() + && attached_object->mDrawable) + { + textures.clear(); + + const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); + if (volume) + { + // get cost and individual textures + hud_complexity.objectsCost += volume->getRenderCost(textures); + hud_complexity.objectsCount++; + + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + const LLVOVolume* chld_volume = dynamic_cast(childp); + if (chld_volume) + { + // get cost and individual textures + hud_complexity.objectsCost += chld_volume->getRenderCost(textures); + hud_complexity.objectsCount++; + } + } + + hud_complexity.texturesCount += textures.size(); + + for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); + volume_texture != textures.end(); + ++volume_texture) + { + // add the cost of each individual texture (ignores duplicates) + hud_complexity.texturesCost += volume_texture->second; + LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first); + if (tex) + { + F64 size = tex->getMaxVirtualSize(); // in pixels + hud_complexity.texturesSizeTotal += size; + if (size >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) + { + hud_complexity.largeTexturesCount++; + } + } + } + } + } } } @@ -9352,10 +9400,14 @@ void LLVOAvatar::calculateUpdateRenderComplexity() static LLCachedControl show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); - if (isSelf() && show_my_complexity_changes) - { - LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); - } + if (isSelf() && show_my_complexity_changes) + { + // Avatar complexity + LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity); + + // HUD complexity + LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity); + } // Show avatar complexity in appearance floater if (isSelf()) @@ -9363,7 +9415,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() LLSidepanelAppearance::updateAvatarComplexity(mVisualComplexity); } // - } + } } void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c66234d4d1..1f5c33e460 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4568,7 +4568,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE); if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT)) { - LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; + LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL; } // if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) diff --git a/indra/newview/skins/default/xui/en/inspect_group.xml b/indra/newview/skins/default/xui/en/inspect_group.xml index 1d926ec94d..924582939f 100644 --- a/indra/newview/skins/default/xui/en/inspect_group.xml +++ b/indra/newview/skins/default/xui/en/inspect_group.xml @@ -66,7 +66,7 @@ Fear the moose! Fear it! And the mongoose too! width="220"> L$123 to join - There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - Visit [_URL] to check for driver updates? + Visit [URL] to check for driver updates? confirm - http://www.intel.com/p/en_US/support/detect/graphics + [URL] fail - - There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - - Visit [_URL] to check for driver updates? - confirm - - http://support.amd.com/us/Pages/AMDSupportHub.aspx - - - fail - - - - There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance. - - Visit [_URL] to check for driver updates? - confirm - - http://www.nvidia.com/Download/index.aspx?lang=en-us - - - fail - - - AgentComplexityNotice Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] is [AGENT_COMPLEXITY]. + + + + + + HUDComplexityWarning + + [HUD_REASON], it is likely to negatively affect your performance. + You may not be rendered by most of those around you. You may not be rendered by anyone around you. + + Your HUD uses a lot of texture memory + Your HUD contains a lot of expensive objects and textures + Your HUD contains a lot of large textures + Your HUD contains too many objects + Your HUD contains too many textures + + http://www.intel.com/p/en_US/support/detect/graphics + http://www.nvidia.com/Download/index.aspx?lang=en-us + http://support.amd.com/us/Pages/AMDSupportHub.aspx + + An error was found parsing the command line. diff --git a/indra/tools/manifests/compatibility.manifest b/indra/tools/manifests/compatibility.manifest index 6e80aff779..31106cc4d5 100644 --- a/indra/tools/manifests/compatibility.manifest +++ b/indra/tools/manifests/compatibility.manifest @@ -23,9 +23,4 @@ - - - true/PM - - diff --git a/indra/tools/manifests/legacy.manifest b/indra/tools/manifests/legacy.manifest index 899438c020..2ec1cfcee6 100644 --- a/indra/tools/manifests/legacy.manifest +++ b/indra/tools/manifests/legacy.manifest @@ -9,9 +9,4 @@ - - - true/PM - -