Merge viewer-bear

master
Ansariel 2016-08-21 12:39:18 +02:00
commit 4da402dd23
29 changed files with 613 additions and 162 deletions

34
autobuild.xml Executable file → Normal file
View File

@ -3329,14 +3329,6 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>SecondLife.sln</string>
<string>--config</string>
<string>RelWithDebInfo</string>
<string>--startup</string>
<string>secondlife-bin</string>
</array>
<key>options</key>
<array>
@ -3372,20 +3364,11 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>SecondLife.sln</string>
<string>--config</string>
<string>RelWithDebInfo</string>
<string>--startup</string>
<string>secondlife-bin</string>
</array>
<key>options</key>
<array>
<string>-G</string>
<string>"Visual Studio 12"</string>
<string>-DUNATTENDED:BOOL=ON</string>
<string>-DINSTALL_PROPRIETARY=FALSE</string>
<string>-DUSE_KDU=FALSE</string>
</array>
@ -3414,14 +3397,6 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>SecondLife.sln</string>
<string>--config</string>
<string>Release</string>
<string>--startup</string>
<string>secondlife-bin</string>
</array>
<key>options</key>
<array>
@ -3453,20 +3428,11 @@
<key>arguments</key>
<array>
<string>..\indra</string>
<string>&amp;&amp;</string>
<string>..\indra\tools\vstool\VSTool.exe</string>
<string>--solution</string>
<string>SecondLife.sln</string>
<string>--config</string>
<string>Release</string>
<string>--startup</string>
<string>secondlife-bin</string>
</array>
<key>options</key>
<array>
<string>-G</string>
<string>"Visual Studio 12"</string>
<string>-DUNATTENDED:BOOL=ON</string>
<string>-DINSTALL_PROPRIETARY=FALSE</string>
<string>-DUSE_KDU=FALSE</string>
</array>

View File

@ -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\"" \

View File

@ -201,6 +201,7 @@ Ansariel Hiller
STORM-2133
MAINT-6511
MAINT-6612
MAINT-6637
Aralara Rajal
Arare Chantilly
CHUIBUG-191

View File

@ -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> 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;
}
//----------------------------------------------------------------------------

View File

@ -287,6 +287,9 @@ public:
// <FS:Techwolf Lupindo> texture comment metadata reader
std::string mComment;
// </FS:Techwolf Lupindo>
private:
bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst);
};
// Compressed representation of image.

View File

@ -31,9 +31,31 @@
#include "llpointer.h"
#include "llmath.h"
#include "llkdumem.h"
#include "stringize.h"
#include "kdu_block_coding.h"
#include <stdexcept>
#include <iostream>
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.
// <FS:Ansariel> 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!");
// </FS:Ansariel>
}
}
@ -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 (...)

View File

@ -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)
{

View File

@ -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

View File

@ -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 <ShellScalingAPI.h> from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL;
}
}
F32 LLWindowWin32::getSystemUISize()
{
// <FS:Ansariel> 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)
{
// <FS:Ansariel> Set DPI awareness via manifest as recommended
//SetProcessDpiAwarenessType pSPDA;
//pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness");
// </FS:Ansariel>
GetProcessDpiAwarenessType pGPDA;
pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness");
GetDpiForMonitorType pGDFM;
pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor");
if (/*pSPDA != NULL &&*/ pGDFM != NULL) // <FS:Ansariel> Set DPI awareness via manifest as recommended
if (pGPDA != NULL && pGDFM != NULL)
{
//pSPDA(PROCESS_PER_MONITOR_DPI_AWARE); // <FS:Ansariel> 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;
// <FS:Ansariel> Get scaling for primary display, assuming that's where we open the viewer
//hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
// </FS:Ansariel>
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 <ShellScalingAPI.h> 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);

View File

@ -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<std::string> 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,

View File

@ -10358,6 +10358,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>PrimTextMaxDrawDistance</key>
<map>
<key>Comment</key>
<string>Maximum draw distance beyond which PRIM_TEXT won't be rendered</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>64.0</real>
</map>
<key>ProbeHardwareOnStartup</key>
<map>
<key>Comment</key>
@ -12723,6 +12734,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>ComplexityChangesPopUpDelay</key>
<map>
<key>Comment</key>
<string>Delay before viewer will show avatar complexity notice again</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>300</integer>
</map>
<key>RenderAvatarMaxComplexity</key>
<map>
<key>Comment</key>
@ -12735,6 +12757,50 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderHUDObjectsWarning</key>
<map>
<key>Comment</key>
<string>Viewer will warn user about HUD containing to many objects if objects count is above this value</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1000</integer>
</map>
<key>RenderHUDTexturesWarning</key>
<map>
<key>Comment</key>
<string>Viewer will warn user about HUD containing to many textures if texture count is above this value</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>200</integer>
</map>
<key>RenderHUDOversizedTexturesWarning</key>
<map>
<key>Comment</key>
<string>How many textures with size 1024 * 1024 or bigger HUD can contain before notifying user</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>6</integer>
</map>
<key>RenderHUDTexturesVirtualMemoryWarning</key>
<map>
<key>Comment</key>
<string>Viewer will warn user about HUD textures using memory above this value (Virtual memory, in pixels)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>10000000</integer>
</map>
<key>RenderAutoMuteSurfaceAreaLimit</key>
<map>
<key>Comment</key>

View File

@ -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"]);

View File

@ -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.

View File

@ -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<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost
static LLCachedControl<U32> max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT);
static LLCachedControl<U32> max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT);
static LLCachedControl<U32> max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT);
static LLCachedControl<U32> 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<U32> pop_up_delay(gSavedSettings, "ComplexityChangesPopUpDelay", 300);
static LLCachedControl<U32> 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);
}

View File

@ -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<LLAvatarRenderNotifier>
@ -81,4 +100,21 @@ private:
S32 mLastOutfitRezStatus;
};
// Class to notify user about heavy set of HUD
class LLHUDRenderNotifier : public LLSingleton<LLHUDRenderNotifier>
{
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) */

View File

@ -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())
{

View File

@ -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);

View File

@ -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<LLPointer<LLHUDText> > LLHUDText::sTextObjects;
std::vector<LLPointer<LLHUDText> > 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;

View File

@ -233,7 +233,8 @@ void LLInspectGroup::processGroupData()
getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) );
getChild<LLUICtrl>("group_icon")->setValue( LLSD(data->mInsigniaID) );
// LLGroupIconCtrl
getChild<LLUICtrl>("group_icon")->setValue(LLSD(mGroupID));
std::string cost;
bool is_member = LLGroupActions::isInGroup(mGroupID);

View File

@ -1460,7 +1460,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
void LLTextureCtrl::setImageAssetName(const std::string& name)
{
LLPointer<LLUIImage> imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW);
LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
if(imagep)
{
LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());

View File

@ -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);

View File

@ -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);

View File

@ -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;
// <FS:Ansariel> [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<LLVOVolume*>(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<U32> 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);
}
// <FS:Ansariel> Show avatar complexity in appearance floater
if (isSelf())
@ -9363,7 +9415,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
LLSidepanelAppearance::updateAvatarComplexity(mVisualComplexity);
}
// </FS:Ansariel>
}
}
}
void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)

View File

@ -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)

View File

@ -66,7 +66,7 @@ Fear the moose! Fear it! And the mongoose too!
width="220">
L$123 to join
</text>
<icon
<group_icon
follows="all"
height="38"
right="-10"

View File

@ -1675,14 +1675,14 @@ Visit [_URL] for more information?
<notification
icon="alertmodal.tga"
name="IntelOldDriver"
name="OldGPUDriver"
type="alertmodal">
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?
<tag>confirm</tag>
<url option="0" name="url">
http://www.intel.com/p/en_US/support/detect/graphics
[URL]
</url>
<usetemplate
ignoretext="My graphics driver is out of date"
@ -1692,45 +1692,6 @@ Visit [_URL] for more information?
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="AMDOldDriver"
type="alertmodal">
There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance.
Visit [_URL] to check for driver updates?
<tag>confirm</tag>
<url option="0" name="url">
http://support.amd.com/us/Pages/AMDSupportHub.aspx
</url>
<usetemplate
ignoretext="My graphics driver is out of date"
name="okcancelignore"
notext="No"
yestext="Yes"/>
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="NVIDIAOldDriver"
type="alertmodal">
There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance.
Visit [_URL] to check for driver updates?
<tag>confirm</tag>
<url option="0" name="url">
http://www.nvidia.com/Download/index.aspx?lang=en-us
</url>
<usetemplate
ignoretext="My graphics driver is out of date"
name="okcancelignore"
notext="No"
yestext="Yes"/>
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="UnknownGPU"
@ -3472,6 +3433,23 @@ Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Renderin
<context>AgentComplexityNotice</context>
</unique>
Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] is [AGENT_COMPLEXITY].
<usetemplate
ignoretext="Warn me about my avatar complexity changes"
name="notifyignore"/>
</notification>
<notification
icon = "notifytip.tga"
name = "HUDComplexityWarning"
type = "notifytip"
log_to_chat = "false">
<unique combine = "cancel_old">
<context>HUDComplexityWarning</context>
</unique>
[HUD_REASON], it is likely to negatively affect your performance.
<usetemplate
ignoretext="Warn me when my HUD complexity is too high"
name="notifyignore"/>
</notification>
<notification

View File

@ -958,6 +958,13 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f
<string name="av_render_most_of">You may not be rendered by most of those around you.</string>
<string name="av_render_anyone">You may not be rendered by anyone around you.</string>
<!-- HUD complexity rendering messages, see llavatarrendernotifier. -->
<string name="hud_render_memory_warning">Your HUD uses a lot of texture memory</string>
<string name="hud_render_cost_warning">Your HUD contains a lot of expensive objects and textures</string>
<string name="hud_render_heavy_textures_warning">Your HUD contains a lot of large textures</string>
<string name="hud_render_cramped_warning">Your HUD contains too many objects</string>
<string name="hud_render_textures_warning">Your HUD contains too many textures</string>
<!-- AgeYearsA = singular,
AgeYearsB = plural,
AgeYearsC = plural for non-English languages like Russian
@ -1316,6 +1323,12 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh
<string name="Play Media">Play/Pause Media</string>
<string name="StreamtitleNowPlaying">Now playing:</string>
<!-- Drivers support/update pages -->
<string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string>
<string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=en-us</string>
<string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string>
<!-- OSMessageBox messages -->
<string name="MBCmdLineError">
An error was found parsing the command line.

View File

@ -23,9 +23,4 @@
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>

View File

@ -9,9 +9,4 @@
</requestedPrivileges>
</security>
</trustInfo>
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>