Ansariel 2023-05-02 17:52:00 +02:00
commit 2a6c81f1d6
120 changed files with 5616 additions and 2611 deletions

View File

@ -1,8 +1,14 @@
name: Build viewer
on: push
env:
on:
push:
branches:
- "*release"
- master
schedule:
- cron: '00 03 * * *' # Run every day at 3am UTC
env:
AUTOBUILD_VARIABLES_FILE: ${{github.workspace}}/build-variables/variables
EXTRA_ARGS: -DFMODSTUDIO=ON -DUSE_KDU=ON --crashreporting
EXTRA_ARGS: -DUSE_FMODSTUDIO=ON -DUSE_KDU=ON --crashreporting
build_secrets_checkout: ${{github.workspace}}/signing
@ -67,15 +73,22 @@ jobs:
- name: find channel from Branch name
run: |
if [[ "${{ github.ref_name }}" == *"Release"* ]]; then
FS_RELEASE_CHAN="Release"
if [[ "${{ github.ref_name }}" == *Release* ]]; then
FS_RELEASE_TYPE=Release
else
FS_RELEASE_CHAN="Beta"
if [[ "${{github.event_name}}" == 'schedule' ]]; then
FS_RELEASE_TYPE=Nightly
else
FS_RELEASE_TYPE=Beta
fi
fi
if [[ "${{ matrix.addrsize }}" == "64" ]]; then
FS_RELEASE_CHAN="${FS_RELEASE_CHAN}x64"
FS_RELEASE_CHAN="${FS_RELEASE_TYPE}x64"
else
FS_RELEASE_CHAN=${FS_RELEASE_TYPE}
fi
echo "FS_RELEASE_CHAN=\"${FS_RELEASE_CHAN}\"" >> $GITHUB_ENV
echo "FS_RELEASE_TYPE=${FS_RELEASE_TYPE}" >> $GITHUB_ENV
echo "FS_RELEASE_CHAN=${FS_RELEASE_CHAN}" >> $GITHUB_ENV
echo "Building for channel ${FS_RELEASE_CHAN}"
shell: bash
@ -187,18 +200,18 @@ jobs:
run: rm *${{ env.fallback_platform }}*bz2
shell: bash
- name: Configure
run: autobuild configure --debug -c ReleaseFS -A${{matrix.addrsize}} -- --package --chan ${{env.FS_RELEASE_CHAN}} ${{env.EXTRA_ARGS}} ${{env.FS_GRID}}
run: autobuild configure -c ReleaseFS -A${{matrix.addrsize}} -- --package --chan ${{env.FS_RELEASE_CHAN}} ${{env.EXTRA_ARGS}} ${{env.FS_GRID}}
shell: bash
- name: build
run: autobuild build --debug -c ReleaseFS -A${{matrix.addrsize}} --no-configure
run: autobuild build -c ReleaseFS -A${{matrix.addrsize}} --no-configure
shell: bash
- name: publish Windows artifacts
- name: Publish artifacts
if: runner.os == 'Windows'
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{ matrix.addrsize }}-${{ matrix.grid }}-artifacts.zip
path: |
build-*/newview/Release/*Setup.exe
build-*/newview/Release/*.xz
@ -207,7 +220,7 @@ jobs:
if: runner.os == 'Linux'
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip
path: |
build-linux-*/newview/*.xz
build-linux-*/newview/*.bz2
@ -216,7 +229,53 @@ jobs:
if: runner.os == 'macOS'
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip
name: ${{ env.FS_RELEASE_TYPE }}-${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip
path: |
build-darwin-*/newview/*.dmg
build-darwin-*/newview/*.bz2
deploy:
runs-on: ubuntu-latest
needs: build_matrix
if: always()
steps:
- name: Checkout files
uses: Bhacaz/checkout-files@v2
with:
files: fsutils/download_list.py
branch: ${{ github.head_ref || github.ref_name || 'master' }}
- name: Install discord-webhook library
run: pip install discord-webhook
- name: find channel from Branch name
run: |
if [[ "${{ github.ref_name }}" == *Release* ]]; then
FS_RELEASE_FOLDER=release
else
if [[ "${{github.event_name}}" == 'schedule' ]]; then
FS_RELEASE_FOLDER=nightly
else
FS_RELEASE_FOLDER=preview
fi
fi
echo "FS_RELEASE_FOLDER=${FS_RELEASE_FOLDER}" >> $GITHUB_ENV
- name: Download artifacts
uses: actions/download-artifact@v3
id: download
with:
path: to_deploy
- name: List artifacts download
run: ls -R
working-directory: ${{steps.download.outputs.download-path}}
- name: Reorganise artifacts ready for server upload.
run: python ./fsutils/download_list.py -u ${{steps.download.outputs.download-path}} -w ${{ secrets.RELEASE_WEBHOOK_URL }}
- name: Setup rclone and download the folder
uses: beqjanus/setup-rclone@main
with:
rclone_config: ${{ secrets.RCLONE_CONFIG }}
- name: Copy files to remote host
run: rclone copy ${{steps.download.outputs.download-path}}/${{ env.FS_RELEASE_FOLDER }} fs_deploy:${{ env.FS_RELEASE_FOLDER }}

View File

@ -3848,6 +3848,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
</map>
<key>configure</key>
<map>
<key>arguments</key>
<array>
<string>../indra</string>
</array>
<key>options</key>
<array>
<string>-G</string>

View File

@ -285,9 +285,11 @@ Beq Janus
SL-11300
SL-15709
SL-16021
SL-16027
SL-18202
SL-18586
SL-18592
SL-18637
SL-19317
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani

View File

@ -6,14 +6,9 @@ import time
import zipfile
import glob
import shutil
from discord_webhook import DiscordWebhook
# iterate over the files in a directory and pass them to a command line subshell
def get_files(path):
files = []
for root, dirs, files in os.walk(path):
# print(f"Found : {files}")
return files
return None
# run a command line subshell and return the output
@ -65,6 +60,14 @@ def get_files(path):
# MD5: 9D5D8021F376194B42F6E7D8E537E45E
# -------------------------------------------------------------------------------------------------------
# iterate over the files in a directory and pass them to a command line subshell
def get_files(path):
files = []
for root, dirs, filenames in os.walk(path):
for filename in filenames:
files.append(filename)
print(f"Found : {files} on {path}")
return files
def run_cmd(cmd):
# print(cmd)
@ -73,12 +76,12 @@ def run_cmd(cmd):
#using the md5sum command get the md5 for the file
def get_md5(mdfile):
# print(f"mdfile is {mdfile}")
md5sum = run_cmd(f"md5sum {mdfile}")
#split md5sum on space
md5sum = md5sum.split()[0]
#remove leading '\'
md5sum = md5sum[1:]
print(f"generating md5sum for {mdfile} as {md5sum}")
return md5sum
def unzip_file(zip_file, unzip_dir):
@ -86,6 +89,7 @@ def unzip_file(zip_file, unzip_dir):
zip_ref.extractall(unzip_dir)
def flatten_tree(tree_root):
print(f"Flattening tree {tree_root}")
for root, flatten_dirs, files in os.walk(tree_root, topdown=False):
for file in files:
# Construct the full path to the file
@ -107,6 +111,8 @@ parser = argparse.ArgumentParser(
)
parser.add_argument("-r", "--release", required=False, default=False, action="store_true", help="use the release folder in the target URL")
parser.add_argument("-u", "--unzip", required=False, default=False, action="store_true", help="unzip the github artifact first")
parser.add_argument("-w", "--webhook", help="post details to the webhook")
# add path_to_directory required parameter to parser
parser.add_argument("path_to_directory", help="path to the directory in which we'll look for the files")
@ -114,102 +120,162 @@ args = parser.parse_args()
path_to_directory = args.path_to_directory
release = args.release
# Create a webhook object with the webhook URL
if args.webhook:
webhook = DiscordWebhook(url=args.webhook)
dirs = ["windows", "mac", "linux"]
if args.unzip:
# unzip the github artifact for this OS (`dir`) into the folder `dir`
# get the .zip files in args.path_to_directory using glob
zips = glob.glob(f"{args.path_to_directory}/*.zip")
for file in zips:
# print(f"unzipping {file}")
if "ubuntu" in file.lower():
unzip_file(file, os.path.join(args.path_to_directory, "linux"))
if "windows" in file.lower():
unzip_file(file, os.path.join(args.path_to_directory, "windows"))
if "macos" in file.lower():
unzip_file(file, os.path.join(args.path_to_directory, "mac"))
# build_types is a map from Beta, Release and Nightly to folder names preview release and nightly
build_types = {
"Beta": "preview",
"Release": "release",
"Nightly": "nightly"
}
target_folder = {
"ubuntu":"linux",
"windows":"windows",
"macos":"mac"
}
# unzip the github artifact for this OS (`dir`) into the folder `dir`
# get the .zip files in args.path_to_directory using glob
print(f"Processing artifacts in {args.path_to_directory}")
build_types_created = set()
zips = glob.glob(f"{args.path_to_directory}/*.zip")
for file in zips:
# print(f"unzipping {file}")
#extract first word (delimited by '-' from the file name)
# build_type is a fullpath but we only want the last folder, remove the leading part of the path leaving just the foldername using basename
filename = os.path.basename(file)
build_type = filename.split("-")[0]
platform = filename.split("-")[1].lower()
# print(f"build_type is {build_type}")
if build_type not in build_types:
print(f"Invalid build_type {build_type} using file {file}")
continue
else:
build_folder = build_types[build_type]
build_types_created.add(build_type)
build_type_dir = os.path.join(args.path_to_directory, build_folder)
if platform not in target_folder:
print(f"Invalid platform {platform} using file {file}")
continue
unpack_folder = os.path.join(build_type_dir, target_folder[platform])
print(f"unpacking {filename} to {unpack_folder}")
if os.path.isfile(file):
# this is an actual zip file
unzip_file(file, unpack_folder)
else:
# Create the destination folder if it doesn't exist
# if not os.path.exists(unpack_folder):
# os.makedirs(unpack_folder)
# Copy the contents of the source folder to the destination folder recursively
shutil.copytree(file, unpack_folder, dirs_exist_ok=True)
output = ""
for build_type in build_types_created:
build_type_dir = os.path.join(args.path_to_directory, build_types[build_type])
if not os.path.exists(build_type_dir):
print(f"Unexpected error: {build_type_dir} does not exist, even though it was in the set.")
continue
# loop over the folder in the build_type_dir
for dir in dirs:
flatten_tree(os.path.join(args.path_to_directory, dir))
print(f"Cleaning up {dir}")
# Traverse the directory tree and move all of the files to the root directory
flatten_tree(os.path.join(build_type_dir, dir))
# Now move the symbols files to the symbols folder
symbols_folder = os.path.join(args.path_to_directory, "symbols")
# prep the symbols folder
symbols_folder = os.path.join(build_type_dir, "symbols")
os.mkdir(symbols_folder)
# Traverse the directory tree and move all of the files to the root directory
symbol_archives = glob.glob(f"{args.path_to_directory}/**/*_hvk*", recursive=True)
symbol_archives = glob.glob(f"{build_type_dir}/**/*_hvk*", recursive=True)
for sym_file in symbol_archives:
print(f"Moving {sym_file} to {symbols_folder}")
shutil.move(sym_file, symbols_folder)
symbol_archives = glob.glob(f"{args.path_to_directory}/**/*_oss*", recursive=True)
symbol_archives = glob.glob(f"{build_type_dir}/**/*_oss*", recursive=True)
for sym_file in symbol_archives:
print(f"Moving {sym_file} to {symbols_folder}")
shutil.move(sym_file, symbols_folder)
file_dict = {}
md5_dict = {}
# While we're at it, let's print the md5 listing
file_dict = {}
md5_dict = {}
platforms_printable = {"windows":"MS Windows", "mac":"MacOS", "linux":"Linux"}
grids_printable = {"SL":"Second Life", "OS":"OpenSim"}
for dir in dirs:
dir = dir.lower()
files = get_files(os.path.join(args.path_to_directory, dir))
for file in files:
full_file = os.path.join(args.path_to_directory, dir, file)
md5 = get_md5(full_file)
base_name = os.path.basename(file)
if "-Release-" in base_name or "-Beta-" in base_name:
wordsize = "32"
else:
wordsize = "64"
if "FirestormOS-" in base_name:
grid = "OS"
else:
grid = "SL"
if dir in dirs:
file_dict[f"{grid}{dir}{wordsize}"] = full_file
md5_dict[f"{grid}{dir}{wordsize}"] = md5
download_root_preview = "https://downloads.firestormviewer.org/preview"
download_root_release = "https://downloads.firestormviewer.org/release"
if args.release:
download_root = download_root_release
else:
download_root = download_root_preview
print('''
DOWNLOADS''')
platforms_printable = {"windows":"MS Windows", "mac":"MacOS", "linux":"Linux"}
grids_printable = {"SL":"Second Life", "OS":"OpenSim"}
for dir in dirs:
print(f'''-------------------------------------------------------------------------------------------------------
{platforms_printable[dir]}
''')
dir=dir.lower()
wordsize = "64"
platform = f"{platforms_printable[dir]}"
for grid in ["SL", "OS"]:
grid_printable = f"{grids_printable[grid]}"
download_root = f"https://downloads.firestormviewer.org/{build_types[build_type]}/"
for dir in dirs:
print(f"Getting files for {dir} in {build_type_dir}")
files = get_files(os.path.join(build_type_dir, dir))
try:
print (f"{platform} for {grid_printable} ({wordsize}-bit)")
print ( "{}/{}/{}".format(download_root,dir,os.path.basename(file_dict[f"{grid}{dir}{wordsize}"])) )
print ()
print ( "MD5: {}".format(md5_dict[f"{grid}{dir}{wordsize}"]) )
print ()
if(dir == "windows"):
# Need to do 32 bit as well
wordsize = "32"
print (f"{platform} for {grid_printable} ({wordsize}-bit)")
print ( "{}/{}/{}".format(download_root,dir,os.path.basename(file_dict[f"{grid}{dir}{wordsize}"])) )
print ()
print ( "MD5: {}".format(md5_dict[f"{grid}{dir}{wordsize}"]) )
print ()
wordsize = "64"
except KeyError:
print (f"{platform} for {grid_printable} ({wordsize}-bit) - NOT AVAILABLE")
print ()
for file in files:
full_file = os.path.join(build_type_dir, dir, file)
md5 = get_md5(full_file)
base_name = os.path.basename(file)
if "x64" in base_name:
wordsize = "64"
else:
wordsize = "32"
if "FirestormOS-" in base_name:
grid = "OS"
else:
grid = "SL"
print('''
-------------------------------------------------------------------------------------------------------''')
if dir in dirs:
file_dict[f"{grid}{dir}{wordsize}"] = full_file
md5_dict[f"{grid}{dir}{wordsize}"] = md5
except TypeError:
print(f"No files found for {dir} in {build_type_dir}")
output += f'''
DOWNLOADS - {build_type}
'''
output += f'''-------------------------------------------------------------------------------------------------------
{platforms_printable[dir]}
'''
dir = dir.lower()
wordsize = "64"
platform = f"{platforms_printable[dir]}"
for grid in ["SL", "OS"]:
grid_printable = f"{grids_printable[grid]}"
try:
output += f"{platform} for {grid_printable} ({wordsize}-bit)\n"
output += f"{download_root}/{dir}/{os.path.basename(file_dict[f'{grid}{dir}{wordsize}'])}\n"
output += "\n"
output += f"MD5: {md5_dict[f'{grid}{dir}{wordsize}']}\n"
output += "\n"
if dir == "windows":
# Need to do 32 bit as well
wordsize = "32"
output += f"{platform} for {grid_printable} ({wordsize}-bit)\n"
output += f"{download_root}/{dir}/{os.path.basename(file_dict[f'{grid}{dir}{wordsize}'])}\n"
output += "\n"
output += f"MD5: {md5_dict[f'{grid}{dir}{wordsize}']}\n"
output += "\n"
wordsize = "64"
except KeyError:
output += f"{platform} for {grid_printable} ({wordsize}-bit) - NOT AVAILABLE\n"
output += "\n"
output += '''
-------------------------------------------------------------------------------------------------------
'''
if args.webhook:
# Add the message to the webhook
webhook.set_content(content=output)
# Send the webhook
response = webhook.execute()
# Print the response
print(f"Webhook response: {response}")
print(output)

View File

@ -272,6 +272,7 @@ elseif(LINUX)
libhunspell-1.3.so.0.0.0
libopenjp2.so
libuuid.so.16
libuuid.so.16.0.22
@ -347,6 +348,6 @@ if(DARWIN)
# that end up in any of the above SHARED_LIB_STAGING_DIR_MUMBLE
# directories.
add_custom_command( TARGET stage_third_party_libs POST_BUILD
COMMAND cmake -E create_symlink ${SHARED_LIB_STAGING_DIR} ${CMAKE_BINARY_DIR}/sharedlibs/Resources
COMMAND ${CMAKE_COMMAND} -E create_symlink ${SHARED_LIB_STAGING_DIR} ${CMAKE_BINARY_DIR}/sharedlibs/Resources
)
endif()

View File

@ -1,4 +1 @@
euclid 5/29/2020
euclid 7/23/2020
euclid 4/29/2021
euclid 10/5/2021 DRTVWR-546

View File

@ -356,7 +356,7 @@ namespace tut
// Create a script file in a temporary place.
NamedTempFile script("py",
"from __future__ import print_function" EOL
"from __future__ import print_function" EOL
"import sys" EOL
"import time" EOL
EOL
@ -366,7 +366,7 @@ namespace tut
"time.sleep(2)" EOL
"print('stderr after wait',file=sys.stderr)" EOL
"sys.stderr.flush()" EOL
);
);
// Arrange to track the history of our interaction with child: what we
// fetched, which pipe it came from, how many tries it took before we
@ -862,8 +862,8 @@ namespace tut
set_test_name("'bogus' test");
CaptureLog recorder;
PythonProcessLauncher py(get_test_name(),
"from __future__ import print_function\n"
"print('Hello world')\n");
"from __future__ import print_function\n"
"print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam("bogus"));
py.mPy = LLProcess::create(py.mParams);
ensure("should have rejected 'bogus'", ! py.mPy);
@ -878,8 +878,8 @@ namespace tut
// Replace this test with one or more real 'file' tests when we
// implement 'file' support
PythonProcessLauncher py(get_test_name(),
"from __future__ import print_function\n"
"print('Hello world')\n");
"from __future__ import print_function\n"
"print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam("file"));
py.mPy = LLProcess::create(py.mParams);
@ -894,8 +894,8 @@ namespace tut
// implement 'tpipe' support
CaptureLog recorder;
PythonProcessLauncher py(get_test_name(),
"from __future__ import print_function\n"
"print('Hello world')\n");
"from __future__ import print_function\n"
"print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam("tpipe"));
py.mPy = LLProcess::create(py.mParams);
@ -912,8 +912,8 @@ namespace tut
// implement 'npipe' support
CaptureLog recorder;
PythonProcessLauncher py(get_test_name(),
"from __future__ import print_function\n"
"print('Hello world')\n");
"from __future__ import print_function\n"
"print('Hello world')\n");
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam());
py.mParams.files.add(LLProcess::FileParam("npipe"));
@ -989,20 +989,20 @@ namespace tut
{
set_test_name("get*Pipe() validation");
PythonProcessLauncher py(get_test_name(),
"from __future__ import print_function\n"
"print('this output is expected')\n");
"from __future__ import print_function\n"
"print('this output is expected')\n");
py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stdin
py.mParams.files.add(LLProcess::FileParam()); // inherit stdout
py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr
py.run();
TEST_getPipe(*py.mPy, getWritePipe, getOptWritePipe,
LLProcess::STDIN, // VALID
LLProcess::STDOUT, // NOPIPE
LLProcess::STDERR); // BADPIPE
LLProcess::STDIN, // VALID
LLProcess::STDOUT, // NOPIPE
LLProcess::STDERR); // BADPIPE
TEST_getPipe(*py.mPy, getReadPipe, getOptReadPipe,
LLProcess::STDERR, // VALID
LLProcess::STDOUT, // NOPIPE
LLProcess::STDIN); // BADPIPE
LLProcess::STDERR, // VALID
LLProcess::STDOUT, // NOPIPE
LLProcess::STDIN); // BADPIPE
}
template<> template<>
@ -1129,8 +1129,8 @@ namespace tut
{
set_test_name("ReadPipe \"eof\" event");
PythonProcessLauncher py(get_test_name(),
"from __future__ import print_function\n"
"print('Hello from Python!')\n");
"from __future__ import print_function\n"
"print('Hello from Python!')\n");
py.mParams.files.add(LLProcess::FileParam()); // stdin
py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout
py.launch();

View File

@ -286,6 +286,20 @@ F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const
if (underwater && underwater_fog_mod > 0.0f)
{
underwater_fog_mod = llclamp(underwater_fog_mod, 0.0f, 10.0f);
// <FS:Beq> BUG-233797/BUG-233798 -ve underwater fog density can cause (unrecoverable) blackout.
// raising a negative number to a non-integral power results in a non-real result (which is NaN for our purposes)
// Two methods were tested, number 2 is being used:
// 1) Force the fog_mod to be integral. The effect is unlikely to be nice, but it is better than blackness.
// In this method a few of the combinations are "usable" but the water colour is effectively inverted (blue becomes yellow)
// this seems to be unlikely to be a desirable use case for the majority.
// 2) Force density to be an arbitrary non-negative (i.e. 1) when underwater and modifier is not an integer (1 was aribtrarily chosen as it gives at least some notion of fog in the transition)
// This is more restrictive, effectively forcing a density under certain conditions, but allowing the range of #1 and avoiding blackness in other cases
// at the cost of overriding the fog density.
if(fog_density < 0.0f && underwater_fog_mod != (F32)llround(underwater_fog_mod) )
{
fog_density = 1.0f;
}
// </FS:Beq>
fog_density = pow(fog_density, underwater_fog_mod);
}
return fog_density;

View File

@ -126,7 +126,8 @@ LLWindow::LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags)
mSwapMethod(SWAP_METHOD_UNDEFINED),
mHideCursorPermanent(FALSE),
mFlags(flags),
mHighSurrogate(0)
mHighSurrogate(0),
mRefreshRate(0)
{
}

View File

@ -197,6 +197,8 @@ public:
// windows only DirectInput8 for joysticks
virtual void* getDirectInput8() { return NULL; };
virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
virtual S32 getRefreshRate() { return mRefreshRate; }
protected:
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
virtual ~LLWindow();
@ -230,6 +232,7 @@ protected:
U16 mHighSurrogate;
S32 mMinWindowWidth;
S32 mMinWindowHeight;
S32 mRefreshRate;
// Handle a UTF-16 encoding unit received from keyboard.
// Converting the series of UTF-16 encoding units to UTF-32 data,

View File

@ -53,6 +53,8 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card);
const char* cursorIDToName(int id);
// </FS:CR>
const S32 DEFAULT_REFRESH_RATE = 60;
namespace
{
NSKeyEventRef mRawKeyEvent = NULL;
@ -664,6 +666,13 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
}
}
mRefreshRate = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(mDisplay));
if(mRefreshRate == 0)
{
//consider adding more appropriate fallback later
mRefreshRate = DEFAULT_REFRESH_RATE;
}
// Disable vertical sync for swap
toggleVSync(enable_vsync);

View File

@ -589,7 +589,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
{
current_refresh = 60;
}
mRefreshRate = current_refresh;
//-----------------------------------------------------------------------
// Drop resolution and go fullscreen
// use a display mode with our desired size and depth, with a refresh
@ -1075,6 +1075,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO
{
current_refresh = 60;
}
mRefreshRate = current_refresh;
gGLManager.shutdownGL();
//destroy gl context

View File

@ -365,8 +365,8 @@ set(viewer_SOURCE_FILES
llfloaterpathfindinglinksets.cpp
llfloaterpathfindingobjects.cpp
llfloaterpay.cpp
# llfloaterperformance.cpp <FS:Beq/> replaced with fs version due to large changes and likelihood that LL version will not release.
fsfloaterperformance.cpp
# llfloaterperformance.cpp
fsfloaterperformance.cpp # <FS:Beq> restore fs perf floater
llfloaterperms.cpp
llfloaterpostprocess.cpp
llfloaterprofile.cpp
@ -1622,6 +1622,9 @@ set(viewer_HEADER_FILES
NACLfloaterexploresounds.h
)
list(APPEND viewer_SOURCE_FILES llperfstats.cpp)
list(APPEND viewer_HEADER_FILES llperfstats.h)
# <FS:Ansariel> Flickr / Discord keys and fsversionvalues headers are generated in here
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
@ -1655,10 +1658,6 @@ configure_file(
list(APPEND viewer_HEADER_FILES ${CMAKE_CURRENT_BINARY_DIR}/fsversionvalues.h)
# </FS:TS>
# <FS:Beq> Performance stast support
list(APPEND viewer_SOURCE_FILES fsperfstats.cpp)
list(APPEND viewer_HEADER_FILES fsperfstats.h)
# </FS:Beq>
source_group("CMake Rules" FILES ViewerInstall.cmake)
#build_data.json creation moved to viewer_manifest.py MAINT-6413

View File

@ -103,18 +103,18 @@ NACLAntiSpamQueueEntry* NACLAntiSpamQueue::getEntry(const LLUUID& source)
}
else
{
return NULL;
return nullptr;
}
}
void NACLAntiSpamQueue::clearEntries()
{
for (spam_queue_entry_map_t::iterator it = mEntries.begin(); it != mEntries.end(); ++it)
for (auto& [id, entry] : mEntries)
{
//AO: Only clear entries that are not blocked.
if (!it->second->getBlocked())
if (!entry->getBlocked())
{
it->second->clearEntry();
entry->clearEntry();
}
}
}
@ -139,15 +139,14 @@ void NACLAntiSpamQueue::blockEntry(const LLUUID& source)
mEntries[source]->setBlocked();
}
S32 NACLAntiSpamQueue::checkEntry(const LLUUID& name, U32 multiplier)
// Returns 0 if unblocked, 1 if check results in a new block, 2 if by an existing block
EAntispamCheckResult NACLAntiSpamQueue::checkEntry(const LLUUID& name, U32 multiplier)
{
spam_queue_entry_map_t::iterator it = mEntries.find(name);
if (it != mEntries.end())
{
if (it->second->getBlocked())
{
return 2;
return EAntispamCheckResult::ExistingBlock;
}
U32 eTime = it->second->getEntryTime();
U32 currentTime = time(0);
@ -158,11 +157,11 @@ S32 NACLAntiSpamQueue::checkEntry(const LLUUID& name, U32 multiplier)
if (eAmount > (mQueueAmount * multiplier))
{
it->second->setBlocked();
return 1;
return EAntispamCheckResult::NewBlock;
}
else
{
return 0;
return EAntispamCheckResult::Unblocked;
}
}
else
@ -170,7 +169,7 @@ S32 NACLAntiSpamQueue::checkEntry(const LLUUID& name, U32 multiplier)
it->second->clearEntry();
it->second->updateEntryAmount();
it->second->updateEntryTime();
return 0;
return EAntispamCheckResult::Unblocked;
}
}
else
@ -180,7 +179,7 @@ S32 NACLAntiSpamQueue::checkEntry(const LLUUID& name, U32 multiplier)
entry->updateEntryAmount();
entry->updateEntryTime();
mEntries[name] = entry;
return 0;
return EAntispamCheckResult::Unblocked;
}
}
@ -219,7 +218,7 @@ NACLAntiSpamRegistry::~NACLAntiSpamRegistry()
const char* NACLAntiSpamRegistry::getQueueName(EAntispamQueue queue)
{
if (queue >= ANTISPAM_QUEUE_MAX)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT)
{
return "Unknown";
}
@ -228,7 +227,7 @@ const char* NACLAntiSpamRegistry::getQueueName(EAntispamQueue queue)
void NACLAntiSpamRegistry::setRegisteredQueueTime(EAntispamQueue queue, U32 time)
{
if (queue >= ANTISPAM_QUEUE_MAX || mQueues[queue] == NULL)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT || mQueues[queue] == nullptr)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(queue) << LL_ENDL;
return;
@ -239,7 +238,7 @@ void NACLAntiSpamRegistry::setRegisteredQueueTime(EAntispamQueue queue, U32 time
void NACLAntiSpamRegistry::setRegisteredQueueAmount(EAntispamQueue queue, U32 amount)
{
if (queue >= ANTISPAM_QUEUE_MAX || mQueues[queue] == NULL)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT || mQueues[queue] == nullptr)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(queue) << LL_ENDL;
return;
@ -283,7 +282,7 @@ void NACLAntiSpamRegistry::setAllQueueAmounts(U32 amount)
void NACLAntiSpamRegistry::clearRegisteredQueue(EAntispamQueue queue)
{
if (queue >= ANTISPAM_QUEUE_MAX || mQueues[queue] == NULL)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT || mQueues[queue] == nullptr)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(queue) << LL_ENDL;
return;
@ -294,7 +293,7 @@ void NACLAntiSpamRegistry::clearRegisteredQueue(EAntispamQueue queue)
void NACLAntiSpamRegistry::purgeRegisteredQueue(EAntispamQueue queue)
{
if (queue >= ANTISPAM_QUEUE_MAX || mQueues[queue] == NULL)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT || mQueues[queue] == nullptr)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(queue) << LL_ENDL;
return;
@ -317,7 +316,7 @@ void NACLAntiSpamRegistry::blockOnQueue(EAntispamQueue queue, const LLUUID& sour
}
else
{
if (queue >= ANTISPAM_QUEUE_MAX || mQueues[queue] == NULL)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT || mQueues[queue] == nullptr)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(queue) << LL_ENDL;
return;
@ -362,14 +361,14 @@ bool NACLAntiSpamRegistry::checkQueue(EAntispamQueue queue, const LLUUID& source
}
}
S32 result = 0;
EAntispamCheckResult result{ EAntispamCheckResult::Unblocked };
if (mGlobalQueue)
{
result = checkGlobalEntry(source, multiplier);
}
else
{
if (queue >= ANTISPAM_QUEUE_MAX || mQueues[queue] == NULL)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT || mQueues[queue] == nullptr)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(queue) << LL_ENDL;
return false;
@ -377,17 +376,17 @@ bool NACLAntiSpamRegistry::checkQueue(EAntispamQueue queue, const LLUUID& source
result = mQueues[queue]->checkEntry(source, multiplier);
}
if (result == 0) // safe
if (result == EAntispamCheckResult::Unblocked) // safe
{
return false;
}
if (result == 2) // previously blocked
if (result == EAntispamCheckResult::ExistingBlock) // previously blocked
{
return true;
}
if (result == 1) // newly blocked, result == 1
if (result == EAntispamCheckResult::NewBlock) // newly blocked, result == 1
{
if (!LLMuteList::getInstance()->isMuted(source))
{
@ -402,16 +401,14 @@ bool NACLAntiSpamRegistry::checkQueue(EAntispamQueue queue, const LLUUID& source
{
bool sent = false;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
for (auto region : LLWorld::getInstance()->getRegionList())
{
LLViewerRegion* region = *iter;
if (gMessageSystem && region && region->isAlive())
{
gMessageSystem->newMessage(_PREHASH_RequestObjectPropertiesFamily);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_RequestFlags, 0);
gMessageSystem->addUUIDFast(_PREHASH_ObjectID, source);
@ -499,7 +496,7 @@ bool NACLAntiSpamRegistry::isBlockedOnQueue(EAntispamQueue queue, const LLUUID&
}
else
{
if (queue >= ANTISPAM_QUEUE_MAX || mQueues[queue] == NULL)
if (queue >= ANTISPAM_QUEUE_MAX || queue < ANTISPAM_QUEUE_CHAT || mQueues[queue] == nullptr)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(queue) << LL_ENDL;
return false;
@ -547,12 +544,11 @@ void NACLAntiSpamRegistry::clearAllQueues()
void NACLAntiSpamRegistry::purgeAllQueues()
{
std::map<LLUUID, LLAvatarNameCache::callback_connection_t>::iterator it = mAvatarNameCallbackConnections.begin();
for (; it != mAvatarNameCallbackConnections.end(); ++it)
for (auto& [avid, callback] : mAvatarNameCallbackConnections)
{
if (it->second.connected())
if (callback.connected())
{
it->second.disconnect();
callback.disconnect();
}
}
mAvatarNameCallbackConnections.clear();
@ -574,14 +570,14 @@ void NACLAntiSpamRegistry::purgeAllQueues()
mObjectData.clear();
}
S32 NACLAntiSpamRegistry::checkGlobalEntry(const LLUUID& source, U32 multiplier)
EAntispamCheckResult NACLAntiSpamRegistry::checkGlobalEntry(const LLUUID& source, U32 multiplier)
{
spam_queue_entry_map_t::iterator it = mGlobalEntries.find(source);
if (it != mGlobalEntries.end())
{
if (it->second->getBlocked())
{
return 2;
return EAntispamCheckResult::ExistingBlock;
}
U32 eTime = it->second->getEntryTime();
@ -592,11 +588,11 @@ S32 NACLAntiSpamRegistry::checkGlobalEntry(const LLUUID& source, U32 multiplier)
U32 eAmount = it->second->getEntryAmount();
if (eAmount > (mGlobalAmount * multiplier))
{
return 1;
return EAntispamCheckResult::NewBlock;
}
else
{
return 0;
return EAntispamCheckResult::Unblocked;
}
}
else
@ -604,7 +600,7 @@ S32 NACLAntiSpamRegistry::checkGlobalEntry(const LLUUID& source, U32 multiplier)
it->second->clearEntry();
it->second->updateEntryAmount();
it->second->updateEntryTime();
return 0;
return EAntispamCheckResult::Unblocked;
}
}
else
@ -613,15 +609,15 @@ S32 NACLAntiSpamRegistry::checkGlobalEntry(const LLUUID& source, U32 multiplier)
entry->updateEntryAmount();
entry->updateEntryTime();
mGlobalEntries[source] = entry;
return 0;
return EAntispamCheckResult::Unblocked;
}
}
void NACLAntiSpamRegistry::clearGlobalEntries()
{
for (spam_queue_entry_map_t::iterator it = mGlobalEntries.begin(); it != mGlobalEntries.end(); ++it)
for (auto& [id, entry] : mGlobalEntries)
{
it->second->clearEntry();
entry->clearEntry();
}
}

View File

@ -1,8 +1,8 @@
#ifndef NACL_ANTISPAM_H
#define NACL_ANTISPAM_H
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <unordered_map>
#include <unordered_set>
#include "llsingleton.h"
#include "llavatarnamecache.h"
@ -25,6 +25,14 @@ typedef enum e_antispam_source_type
ANTISPAM_SOURCE_OBJECT
} EAntispamSource;
enum class EAntispamCheckResult
{
Unblocked,
NewBlock,
ExistingBlock
};
struct AntispamObjectData
{
std::string mName;
@ -58,8 +66,8 @@ private:
bool mBlocked;
};
typedef boost::unordered_map<LLUUID, NACLAntiSpamQueueEntry*, FSUUIDHash> spam_queue_entry_map_t;
typedef boost::unordered_set<LLUUID, FSUUIDHash> collision_sound_set_t;
typedef std::unordered_map<LLUUID, NACLAntiSpamQueueEntry*, FSUUIDHash> spam_queue_entry_map_t;
typedef std::unordered_set<LLUUID, FSUUIDHash> collision_sound_set_t;
class NACLAntiSpamQueue
{
@ -77,7 +85,7 @@ protected:
void setTime(U32 time);
void blockEntry(const LLUUID& source);
S32 checkEntry(const LLUUID& source, U32 multiplier);
EAntispamCheckResult checkEntry(const LLUUID& source, U32 multiplier);
NACLAntiSpamQueueEntry* getEntry(const LLUUID& source);
void clearEntries();
@ -119,7 +127,7 @@ private:
const char* getQueueName(EAntispamQueue queue);
void blockGlobalEntry(const LLUUID& source);
S32 checkGlobalEntry(const LLUUID& source, U32 multiplier);
EAntispamCheckResult checkGlobalEntry(const LLUUID& source, U32 multiplier);
void clearGlobalEntries();
void purgeGlobalEntries();

View File

@ -1 +1 @@
6.6.11
6.6.12

View File

@ -11717,6 +11717,28 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderClass0MemoryBandwidth</key>
<map>
<key>Comment</key>
<string>Memory bandwidth at which to default to Class 0 in gigabytes per second. Used as basis for other classes.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>16.0</real>
</map>
<key>RenderCPUBasis</key>
<map>
<key>Comment</key>
<string>Reference CPU clockspeed to use to bias GPU class (in MHz).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>3000.0</real>
</map>
<key>RenderComplexityColorMin</key>
<map>
<key>Comment</key>
@ -11992,6 +12014,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>RenderShadowSplits</key>
<map>
<key>Comment</key>
<string>Amount of shadow map splits to render (0 - 3).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>3</integer>
</map>
<key>RenderSSAOScale</key>
<map>
<key>Comment</key>
@ -21979,6 +22012,160 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>TargetFPS</key>
<map>
<key>Comment</key>
<string>Desired minimum FPS</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>15</integer>
</map>
<key>AutoTuneFPS</key>
<map>
<key>Comment</key>
<string>Allow the viewer to adjust your settings to achieve target FPS</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>AutoTuneLock</key>
<map>
<key>Comment</key>
<string>When enabled the viewer will dynamically change settings until auto tune is explicitly turned off.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>KeepAutoTuneLock</key>
<map>
<key>Comment</key>
<string>When enabled the AutoTuneLock will be maintainted all following sessions.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>AllowSelfImpostor</key>
<map>
<key>Comment</key>
<string>Allow own render time to impostor your avatar.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>ShowTunedART</key>
<map>
<key>Comment</key>
<string>Show the current render time not the pre-tuning render time in the avatar display.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderAvatarMaxART</key>
<map>
<key>Comment</key>
<string>Render Time Limit in microseconds (0.0 = no limit)</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>4.699</real>
</map>
<key>AutoTuneRenderFarClipMin</key>
<map>
<key>Comment</key>
<string>The lowest draw distance that auto tune is allowed to use</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>32.0</real>
</map>
<key>AutoTuneRenderFarClipTarget</key>
<map>
<key>Comment</key>
<string>The draw distance that auto tune will try to achieve</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>256.0</real>
</map>
<key>UserTargetReflections</key>
<map>
<key>Comment</key>
<string>Set by auto tune floater on build</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>PerfStatsCaptureEnabled</key>
<map>
<key>Comment</key>
<string>Enable/disable render time data to support autotune.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>AutoTuneImpostorByDistEnabled</key>
<map>
<key>Comment</key>
<string>Enable/disable using MaxNonImpostor to limit avatar rendering by distance.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>AutoTuneImpostorFarAwayDistance</key>
<map>
<key>Comment</key>
<string>Avatars beyond this range will automatically be optimized</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>64.0</real>
</map>
<key>TuningFPSStrategy</key>
<map>
<key>Comment</key>
<string>Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings, 2=Tune only global scene.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>CameraOpacity</key>
<map>
<key>Comment</key>
@ -26030,28 +26217,6 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>0</integer>
</map>
<key>FSTargetFPS</key>
<map>
<key>Comment</key>
<string>Desired minimum FPS</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>25</integer>
</map>
<key>FSAutoTuneFPS</key>
<map>
<key>Comment</key>
<string>Allow the viewer to adjust your settings to achieve target FPS</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSPerfFloaterSmoothingPeriods</key>
<map>
<key>Comment</key>
@ -26096,127 +26261,6 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>FSPerfStatsCaptureEnabled</key>
<map>
<key>Comment</key>
<string>Enable/disable render time data to support autotune.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSAutoTuneImpostorByDistEnabled</key>
<map>
<key>Comment</key>
<string>Enable/disable using MaxNonImpostor to limit avatar rendering by distance.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSAutoTuneLock</key>
<map>
<key>Comment</key>
<string>When enabled the viewer will dynamically change settings until auto tune is explicitly turned off.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>FSAllowSelfImpostor</key>
<map>
<key>Comment</key>
<string>Allow own render time to impostor your avatar.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSShowTunedART</key>
<map>
<key>Comment</key>
<string>Show the tuned render time in the avatar display.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSRenderAvatarMaxART</key>
<map>
<key>Comment</key>
<string>Render Time Limit in microseconds (0.0 = no limit)</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>4.699</real>
</map>
<key>FSAutoTuneRenderFarClipMin</key>
<map>
<key>Comment</key>
<string>The lowest draw distance that auto tune is allowed to use</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>32.0</real>
</map>
<key>FSAutoTuneRenderFarClipTarget</key>
<map>
<key>Comment</key>
<string>The draw distance that auto tune will try to achieve</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>256.0</real>
</map>
<key>FSAutoTuneImpostorFarAwayDistance</key>
<map>
<key>Comment</key>
<string>Avatars beyond this range will automatically be optimized</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>64.0</real>
</map>
<key>FSTuningFPSStrategy</key>
<map>
<key>Comment</key>
<string>Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>FSUserTargetReflections</key>
<map>
<key>Comment</key>
<string>Set by auto tune floater on build</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>FSReportRegionRestartToChat</key>
<map>
<key>Comment</key>
@ -26239,17 +26283,6 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>473405</integer>
</map>
<key>FSUseCoRoFor360Capture</key>
<map>
<key>Comment</key>
<string>Use co-routine to extract 360 photos.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>SDL2IMEDefaultVerticalOffset</key>
<map>
<key>Comment</key>

View File

@ -112,6 +112,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
RenderAvatarMaxNonImpostors 1 5
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@ -141,6 +142,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 7
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -170,6 +172,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 9
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -199,6 +202,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 11
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -228,6 +232,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -255,6 +260,7 @@ list Ultra
RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0

View File

@ -1,10 +1,10 @@
version 29
version 30
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
// defaults. This should be as rare an event as we can manage.
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
//
@ -112,6 +112,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
RenderAvatarMaxNonImpostors 1 5
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@ -141,6 +142,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 7
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -170,6 +172,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 9
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -199,6 +202,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 11
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -228,6 +232,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -255,6 +260,7 @@ list Ultra
RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0

View File

@ -111,6 +111,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
RenderAvatarMaxNonImpostors 1 5
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
@ -140,6 +141,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 7
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -169,6 +171,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 9
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -198,6 +201,7 @@ RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 11
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
@ -225,6 +229,7 @@ list HighUltra
RenderAnisotropic 1 1
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 128
@ -255,6 +260,7 @@ RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9

View File

@ -1,5 +1,5 @@
/**
* @file llfloaterperformance.cpp
* @file fsfloaterperformance.cpp
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
@ -48,11 +48,12 @@
#include "llviewermediafocus.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llperfstats.h"
#include "pipeline.h"
#include "llviewercontrol.h"
#include "fsavatarrenderpersistence.h"
#include "llpresetsmanager.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "llwindow.h"
#include "fslslbridge.h"
#include <llbutton.h>
@ -63,10 +64,10 @@ const S32 BAR_LEFT_PAD = 2;
const S32 BAR_RIGHT_PAD = 5;
const S32 BAR_BOTTOM_PAD = 9;
constexpr auto AvType {FSPerfStats::ObjType_t::OT_AVATAR};
constexpr auto AttType {FSPerfStats::ObjType_t::OT_ATTACHMENT};
constexpr auto HudType {FSPerfStats::ObjType_t::OT_HUD};
constexpr auto SceneType {FSPerfStats::ObjType_t::OT_GENERAL};
constexpr auto AvType {LLPerfStats::ObjType_t::OT_AVATAR};
constexpr auto AttType {LLPerfStats::ObjType_t::OT_ATTACHMENT};
constexpr auto HudType {LLPerfStats::ObjType_t::OT_HUD};
constexpr auto SceneType {LLPerfStats::ObjType_t::OT_GENERAL};
class FSExceptionsContextMenu : public LLListContextMenu
{
public:
@ -124,7 +125,7 @@ BOOL FSFloaterPerformance::postBuild()
if (tgt_panel)
{
tgt_panel->getChild<LLButton>("target_btn")->setCommitCallback(boost::bind(&FSFloaterPerformance::showSelectedPanel, this, mAutoTunePanel));
tgt_panel->getChild<LLComboBox>("FSTuningFPSStrategy")->setCurrentByIndex(gSavedSettings.getU32("FSTuningFPSStrategy"));
tgt_panel->getChild<LLComboBox>("FSTuningFPSStrategy")->setCurrentByIndex(gSavedSettings.getU32("TuningFPSStrategy"));
tgt_panel->getChild<LLButton>("PrefSaveButton")->setCommitCallback(boost::bind(&FSFloaterPerformance::savePreset, this));
tgt_panel->getChild<LLButton>("PrefLoadButton")->setCommitCallback(boost::bind(&FSFloaterPerformance::loadPreset, this));
tgt_panel->getChild<LLButton>("Defaults")->setCommitCallback(boost::bind(&FSFloaterPerformance::setHardwareDefaults, this));
@ -159,21 +160,21 @@ BOOL FSFloaterPerformance::postBuild()
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&FSFloaterPerformance::updateComplexityText, this));
mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity")->setCommitCallback(boost::bind(&FSFloaterPerformance::updateMaxComplexity, this));
mMaxARTChangedSignal = gSavedSettings.getControl("FSRenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this));
mNearbyPanel->getChild<LLSliderCtrl>("FSRenderAvatarMaxART")->setCommitCallback(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this));
mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this));
mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this));
LLAvatarComplexityControls::setIndirectMaxArc();
// store the current setting as the users desired reflection detail and DD
gSavedSettings.setS32("FSUserTargetReflections", LLPipeline::RenderReflectionDetail);
if(!FSPerfStats::tunables.userAutoTuneEnabled)
gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail);
if(!LLPerfStats::tunables.userAutoTuneEnabled)
{
if (gSavedDrawDistance)
{
gSavedSettings.setF32("FSAutoTuneRenderFarClipTarget", gSavedDrawDistance);
gSavedSettings.setF32("AutoTuneRenderFarClipTarget", gSavedDrawDistance);
}
else
{
gSavedSettings.setF32("FSAutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
}
}
@ -182,9 +183,9 @@ BOOL FSFloaterPerformance::postBuild()
void FSFloaterPerformance::resetMaxArtSlider()
{
FSPerfStats::renderAvatarMaxART_ns = 0;
FSPerfStats::tunables.updateSettingsFromRenderCostLimit();
FSPerfStats::tunables.applyUpdates();
LLPerfStats::renderAvatarMaxART_ns = 0;
LLPerfStats::tunables.updateSettingsFromRenderCostLimit();
LLPerfStats::tunables.applyUpdates();
updateMaxRenderTime();
}
@ -236,8 +237,10 @@ void FSFloaterPerformance::draw()
constexpr auto NANOS = 1000000000;
static LLCachedControl<U32> fpsCap(gSavedSettings, "FramePerSecondLimit"); // user limited FPS
static LLCachedControl<U32> targetFPS(gSavedSettings, "FSTargetFPS"); // desired FPS
static LLCachedControl<U32> tuningStrategy(gSavedSettings, "FSTuningFPSStrategy");
static LLCachedControl<U32> targetFPS(gSavedSettings, "TargetFPS"); // desired FPS
static LLCachedControl<U32> tuningStrategy(gSavedSettings, "TuningFPSStrategy");
static LLCachedControl<bool> vsyncEnabled(gSavedSettings, "RenderVSyncEnable");
if (mUpdateTimer->hasExpired())
{
@ -248,47 +251,47 @@ void FSFloaterPerformance::draw()
auto target_frame_time_ns = NANOS/(targetFPS==0?1:targetFPS);
FSPerfStats::bufferToggleLock.lock(); // prevent toggle for a moment
LLPerfStats::bufferToggleLock.lock(); // prevent toggle for a moment
auto tot_frame_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FRAME);
auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
// cumulative avatar time (includes idle processing, attachments and base av)
auto tot_avatar_time_raw = FSPerfStats::StatsRecorder::getSum(AvType, FSPerfStats::StatType_t::RENDER_COMBINED);
auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_COMBINED);
// cumulative avatar render specific time (a bit arbitrary as the processing is too.)
// auto tot_av_idle_time_raw = FSPerfStats::StatsRecorder::getSum(AvType, FSPerfStats::StatType_t::RENDER_IDLE);
// auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE);
// auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw;
// the time spent this frame on the "display()" call. Treated as "tot time rendering"
auto tot_render_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_DISPLAY);
auto tot_render_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_DISPLAY);
// sleep time is basically forced sleep when window out of focus
auto tot_sleep_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_SLEEP);
auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP);
// time spent on UI
auto tot_ui_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_UI);
auto tot_ui_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_UI);
// cumulative time spent rendering HUDS
auto tot_huds_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_HUDS);
auto tot_huds_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_HUDS);
// "idle" time. This is the time spent in the idle poll section of the main loop
auto tot_idle_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_IDLE);
auto tot_idle_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_IDLE);
// similar to sleep time, induced by FPS limit
auto tot_limit_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FPSLIMIT);
auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT);
// swap time is time spent in swap buffer
auto tot_swap_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_SWAP);
auto tot_swap_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SWAP);
FSPerfStats::bufferToggleLock.unlock();
LLPerfStats::bufferToggleLock.unlock();
auto unreliable = false; // if there is something to skew the stats such as sleep of fps cap
auto tot_frame_time_ns = FSPerfStats::raw_to_ns(tot_frame_time_raw);
auto tot_avatar_time_ns = FSPerfStats::raw_to_ns( tot_avatar_time_raw );
auto tot_huds_time_ns = FSPerfStats::raw_to_ns( tot_huds_time_raw );
auto tot_frame_time_ns = LLPerfStats::raw_to_ns(tot_frame_time_raw);
auto tot_avatar_time_ns = LLPerfStats::raw_to_ns( tot_avatar_time_raw );
auto tot_huds_time_ns = LLPerfStats::raw_to_ns( tot_huds_time_raw );
// UI time includes HUD time so dedut that before we calc percentages
auto tot_ui_time_ns = FSPerfStats::raw_to_ns( tot_ui_time_raw - tot_huds_time_raw);
auto tot_ui_time_ns = LLPerfStats::raw_to_ns( tot_ui_time_raw - tot_huds_time_raw);
// auto tot_sleep_time_ns = FSPerfStats::raw_to_ns( tot_sleep_time_raw );
// auto tot_limit_time_ns = FSPerfStats::raw_to_ns( tot_limit_time_raw );
// auto tot_sleep_time_ns = LLPerfStats::raw_to_ns( tot_sleep_time_raw );
// auto tot_limit_time_ns = LLPerfStats::raw_to_ns( tot_limit_time_raw );
// auto tot_render_time_ns = FSPerfStats::raw_to_ns( tot_render_time_raw );
auto tot_idle_time_ns = FSPerfStats::raw_to_ns( tot_idle_time_raw );
auto tot_swap_time_ns = FSPerfStats::raw_to_ns( tot_swap_time_raw );
auto tot_scene_time_ns = FSPerfStats::raw_to_ns( tot_render_time_raw - tot_avatar_time_raw - tot_swap_time_raw - tot_ui_time_raw);
// auto tot_overhead_time_ns = FSPerfStats::raw_to_ns( tot_frame_time_raw - tot_render_time_raw - tot_idle_time_raw );
// auto tot_render_time_ns = LLPerfStats::raw_to_ns( tot_render_time_raw );
auto tot_idle_time_ns = LLPerfStats::raw_to_ns( tot_idle_time_raw );
auto tot_swap_time_ns = LLPerfStats::raw_to_ns( tot_swap_time_raw );
auto tot_scene_time_ns = LLPerfStats::raw_to_ns( tot_render_time_raw - tot_avatar_time_raw - tot_swap_time_raw - tot_ui_time_raw);
// auto tot_overhead_time_ns = LLPerfStats::raw_to_ns( tot_frame_time_raw - tot_render_time_raw - tot_idle_time_raw );
// // remove time spent sleeping for fps limit or out of focus.
// tot_frame_time_ns -= tot_limit_time_ns;
@ -314,7 +317,13 @@ void FSFloaterPerformance::draw()
args["TOT_FRAME_TIME"] = llformat("%02u", (U32)llround(tot_frame_time_ns/1000000));
args["FPSCAP"] = llformat("%02u", (U32)fpsCap);
args["FPSTARGET"] = llformat("%02u", (U32)targetFPS);
S32 refresh_rate = gViewerWindow->getWindow()->getRefreshRate();
args["VSYNCFREQ"] = llformat("%02d", (U32)refresh_rate);
auto textbox = getChild<LLTextBox>("fps_warning");
// Note: the ordering of these is important.
// 1) background_yield should override others
// 2) viewer fps limits take place irrespective of vsync and so should come first.
// 3) vsync last.
if (tot_sleep_time_raw > 0) // We are sleeping because view is not focussed
{
textbox->setVisible(true);
@ -329,7 +338,16 @@ void FSFloaterPerformance::draw()
textbox->setColor(LLUIColorTable::instance().getColor("DrYellow"));
unreliable = true;
}
else if (FSPerfStats::tunables.userAutoTuneEnabled)
else if (vsyncEnabled)
{
textbox->setVisible(true);
textbox->setText(getString("max_fps", args));
// TODO(Beq) : When FPS is more than the frequency we can notify the user.
// When the FPS is lower than the frequency and also lower than the core stats then VSync might be the constraint
// we can notify this too. For now just display the frequency until we are sure that refresh rate is detected properly.
textbox->setColor(LLUIColorTable::instance().getColor("green"));
}
else if (LLPerfStats::tunables.userAutoTuneEnabled)
{
textbox->setVisible(true);
textbox->setText(getString("tuning_fps", args));
@ -364,11 +382,11 @@ void FSFloaterPerformance::draw()
getChild<LLTextBox>("frame_breakdown")->setText(getString("frame_stats", args));
auto button = getChild<LLButton>("AutoTuneFPS");
if((bool)button->getToggleState() != FSPerfStats::tunables.userAutoTuneEnabled)
if((bool)button->getToggleState() != LLPerfStats::tunables.userAutoTuneEnabled)
{
button->toggleState();
}
if (FSPerfStats::tunables.userAutoTuneEnabled && !unreliable )
if (LLPerfStats::tunables.userAutoTuneEnabled && !unreliable )
{
// the tuning itself is managed from another thread but we can report progress here
@ -387,7 +405,7 @@ void FSFloaterPerformance::draw()
textbox->setColor(LLUIColorTable::instance().getColor("red"));
}
}
else if (target_frame_time_ns > (tot_frame_time_ns + FSPerfStats::renderAvatarMaxART_ns))
else if (target_frame_time_ns > (tot_frame_time_ns + LLPerfStats::renderAvatarMaxART_ns))
{
// if we have more time to spare. Display this (the service will update things)
textbox->setColor(LLUIColorTable::instance().getColor("green"));
@ -459,7 +477,7 @@ void FSFloaterPerformance::populateHUDList()
max_complexity = llmax(max_complexity, (*iter).objectsCost);
}
auto huds_max_render_time_raw = FSPerfStats::StatsRecorder::getMax(HudType, FSPerfStats::StatType_t::RENDER_GEOMETRY);
auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY);
for (iter = complexity_list.begin(); iter != end; ++iter)
{
LLHUDComplexity hud_object_complexity = *iter;
@ -469,7 +487,7 @@ void FSFloaterPerformance::populateHUDList()
continue;
}
auto hud_render_time_raw = FSPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, FSPerfStats::StatType_t::RENDER_GEOMETRY);
auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY);
LLSD item;
item["special_id"] = hud_object_complexity.objectId;
@ -485,7 +503,7 @@ void FSFloaterPerformance::populateHUDList()
row[1]["column"] = "art_value";
row[1]["type"] = "text";
row[1]["value"] = llformat( "%.2f",FSPerfStats::raw_to_us(hud_render_time_raw) );
row[1]["value"] = llformat( "%.2f",LLPerfStats::raw_to_us(hud_render_time_raw) );
row[1]["font"]["name"] = "SANSSERIF";
row[2]["column"] = "name";
@ -541,9 +559,9 @@ void FSFloaterPerformance::populateObjectList()
// for consistency we lock the buffer while we build the list. In theory this is uncontended as th ebuffer should only toggle on end of frame
{
std::lock_guard<std::mutex> guard{FSPerfStats::bufferToggleLock};
auto att_max_render_time_raw = FSPerfStats::StatsRecorder::getMax(AttType, FSPerfStats::StatType_t::RENDER_COMBINED);
auto att_sum_render_time_raw = FSPerfStats::StatsRecorder::getSum(AttType, FSPerfStats::StatType_t::RENDER_COMBINED);
std::lock_guard<std::mutex> guard{LLPerfStats::bufferToggleLock};
auto att_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(AttType, LLPerfStats::StatType_t::RENDER_COMBINED);
auto att_sum_render_time_raw = LLPerfStats::StatsRecorder::getSum(AttType, LLPerfStats::StatType_t::RENDER_COMBINED);
LL_DEBUGS("PerfFloater") << "Attachments for frame : " << gFrameCount << " Max:" << att_max_render_time_raw << LL_ENDL;
for (iter = attachment_list.begin(); iter != end; ++iter)
{
@ -552,8 +570,8 @@ void FSFloaterPerformance::populateObjectList()
auto& attID{attachment_complexity.objectId};
auto& attName{attachment_complexity.objectName};
auto attach_render_time_raw = FSPerfStats::StatsRecorder::get(AttType, attID, FSPerfStats::StatType_t::RENDER_COMBINED);
LL_DEBUGS("PerfFloater") << "Att: " << attName << " (" << attID.asString() << ") Cost: " << FSPerfStats::raw_to_us(attach_render_time_raw) << LL_ENDL;
auto attach_render_time_raw = LLPerfStats::StatsRecorder::get(AttType, attID, LLPerfStats::StatType_t::RENDER_COMBINED);
LL_DEBUGS("PerfFloater") << "Att: " << attName << " (" << attID.asString() << ") Cost: " << LLPerfStats::raw_to_us(attach_render_time_raw) << LL_ENDL;
LLSD item;
item["special_id"] = attID;
item["target"] = LLNameListCtrl::SPECIAL;
@ -569,7 +587,7 @@ void FSFloaterPerformance::populateObjectList()
row[1]["column"] = "art_value";
row[1]["type"] = "text";
// row[1]["value"] = std::to_string(obj_cost_short);
row[1]["value"] = llformat( "%.2f", FSPerfStats::raw_to_us(attach_render_time_raw) );
row[1]["value"] = llformat( "%.2f", LLPerfStats::raw_to_us(attach_render_time_raw) );
row[1]["font"]["name"] = "SANSSERIF";
row[2]["column"] = "complex_value";
@ -603,7 +621,7 @@ void FSFloaterPerformance::populateObjectList()
auto textbox = getChild<LLTextBox>("tot_att_count");
LLStringUtil::format_map_t args;
args["TOT_ATT"] = llformat("%d", (int64_t)attachment_list.size());
args["TOT_ATT_TIME"] = llformat("%.2f", FSPerfStats::raw_to_us(att_sum_render_time_raw));
args["TOT_ATT_TIME"] = llformat("%.2f", LLPerfStats::raw_to_us(att_sum_render_time_raw));
textbox->setText(getString("tot_att_template", args));
}
@ -615,7 +633,7 @@ void FSFloaterPerformance::populateObjectList()
void FSFloaterPerformance::populateNearbyList()
{
static LLCachedControl<bool> showTunedART(gSavedSettings, "FSShowTunedART");
static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART");
S32 prev_pos = mNearbyList->getScrollPos();
LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem();
std::string current_sort_col = mNearbyList->getSortColumnName();
@ -635,10 +653,10 @@ void FSFloaterPerformance::populateNearbyList()
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
FSPerfStats::bufferToggleLock.lock();
auto av_render_max_raw = FSPerfStats::StatsRecorder::getMax(AvType, FSPerfStats::StatType_t::RENDER_COMBINED);
auto av_render_tot_raw = FSPerfStats::StatsRecorder::getSum(AvType, FSPerfStats::StatType_t::RENDER_COMBINED);
FSPerfStats::bufferToggleLock.unlock();
LLPerfStats::bufferToggleLock.lock();
auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(AvType, LLPerfStats::StatType_t::RENDER_COMBINED);
auto av_render_tot_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_COMBINED);
LLPerfStats::bufferToggleLock.unlock();
// FSPlot("max ART", (int64_t)av_render_max_raw);
// FSPlot("Num av", (int64_t)valid_nearby_avs.size());
@ -657,85 +675,128 @@ void FSFloaterPerformance::populateNearbyList()
S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);
FSPerfStats::bufferToggleLock.lock();
auto render_av_raw = FSPerfStats::StatsRecorder::get(AvType, avatar->getID(),FSPerfStats::StatType_t::RENDER_COMBINED);
FSPerfStats::bufferToggleLock.unlock();
LLPerfStats::bufferToggleLock.lock();
auto render_av_raw = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED);
auto render_av_geom = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_GEOMETRY);
auto render_av_shadow = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_SHADOWS);
auto render_av_idle = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_IDLE);
LLPerfStats::bufferToggleLock.unlock();
auto is_slow = avatar->isTooSlowWithShadows();
auto is_slow = avatar->isTooSlow();
LLSD item;
item["id"] = avatar->getID();
LLSD& row = item["columns"];
row[0]["column"] = "art_visual";
row[0]["type"] = "bar";
LLSD& value = row[0]["value"];
int colno = 0;
row[colno]["column"] = "art_visual";
row[colno]["type"] = "bar";
LLSD& value = row[colno]["value"];
// The ratio used in the bar is the current cost, as soon as we take action this changes so we keep the
// pre-tune value for the numerical column and sorting.
value["ratio"] = (double)render_av_raw / av_render_max_raw;
value["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD;
colno++;
row[1]["column"] = "art_value";
row[1]["type"] = "text";
if (is_slow && !showTunedART)
row[colno]["column"] = "art_value";
row[colno]["type"] = "text";
if (is_slow)
{
row[1]["value"] = llformat( "%.2f", FSPerfStats::raw_to_us( avatar->getLastART() ) );
row[colno]["value"] = llformat( "%.2f", LLPerfStats::raw_to_us( avatar->getLastART() ) );
}
else
{
row[1]["value"] = llformat( "%.2f", FSPerfStats::raw_to_us( render_av_raw ) );
row[colno]["value"] = llformat( "%.2f", LLPerfStats::raw_to_us( render_av_raw ) );
}
row[1]["font"]["name"] = "SANSSERIF";
row[1]["width"] = "50";
row[colno]["font"]["name"] = "SANSSERIF";
row[colno]["width"] = "50";
colno++;
row[2]["column"] = "complex_value";
row[2]["type"] = "text";
row[2]["value"] = std::to_string(complexity_short);
row[2]["font"]["name"] = "SANSSERIF";
row[2]["width"] = "50";
if (showTunedART)
{
row[colno]["column"] = "adj_art_value";
row[colno]["type"] = "text";
if (is_slow )
{
row[colno]["value"] = llformat( "%.2f", LLPerfStats::raw_to_us( render_av_raw ) );
}
else
{
row[colno]["value"] = llformat( "--" );
}
row[colno]["font"]["name"] = "SANSSERIF";
row[colno]["width"] = "50";
colno++;
}
row[3]["column"] = "state";
row[3]["type"] = "text";
row[colno]["column"] = "complex_value";
row[colno]["type"] = "text";
row[colno]["value"] = std::to_string(complexity_short);
row[colno]["font"]["name"] = "SANSSERIF";
row[colno]["width"] = "50";
colno++;
row[colno]["column"] = "state";
row[colno]["type"] = "text";
if (is_slow)
{
if (avatar->isTooSlowWithoutShadows())
{
row[3]["value"] = std::string{"I"};
row[colno]["value"] = std::string{"I"};
}
else
{
row[3]["value"] = std::string{"S"};
row[colno]["value"] = std::string{"S"};
}
}
else
{
row[3]["value"] = std::string{" "};
row[colno]["value"] = std::string{" "};
}
row[3]["font"]["name"] = "SANSSERIF";
row[colno]["font"]["name"] = "SANSSERIF";
row[4]["column"] = "name";
colno++;
row[colno]["column"] = "name";
colno++;
row[colno]["column"] = "breakdown";
row[colno]["type"] = "text";
row[colno]["value"] = llformat( "%.2f/%.2f/%.2f", LLPerfStats::raw_to_us( render_av_geom ), LLPerfStats::raw_to_us( render_av_shadow ), LLPerfStats::raw_to_us( render_av_idle ) );
colno++;
LLScrollListItem* av_item = mNearbyList->addElement(item);
if (av_item)
{
LLScrollListText* art_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(1));
int colno{1};
LLScrollListText* art_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(colno));
if (art_text)
{
art_text->setAlignment(LLFontGL::RIGHT);
}
LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(2));
colno++;
LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(colno));
if (value_text)
{
value_text->setAlignment(LLFontGL::RIGHT);
}
LLScrollListText* state_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(3));
colno++;
if (showTunedART)
{
LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(colno));
if (value_text)
{
value_text->setAlignment(LLFontGL::RIGHT);
}
colno++;
}
LLScrollListText* state_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(colno));
if (state_text)
{
state_text->setAlignment(LLFontGL::HCENTER);
}
LLScrollListText* name_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(4));
colno++;
LLScrollListText* name_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(colno));
if (name_text)
{
if (avatar->isSelf())
@ -761,6 +822,7 @@ void FSFloaterPerformance::populateNearbyList()
name_text->setColor(LLUIColorTable::instance().getColor(color));
}
}
colno++;
}
}
char_iter++;
@ -772,7 +834,7 @@ void FSFloaterPerformance::populateNearbyList()
auto textbox = getChild<LLTextBox>("tot_av_count");
LLStringUtil::format_map_t args;
args["TOT_AV"] = llformat("%d", (int64_t)valid_nearby_avs.size());
args["TOT_AV_TIME"] = llformat("%.2f", FSPerfStats::raw_to_us(av_render_tot_raw));
args["TOT_AV_TIME"] = llformat("%.2f", LLPerfStats::raw_to_us(av_render_tot_raw));
textbox->setText(getString("tot_av_template", args));
}
@ -820,7 +882,7 @@ void FSFloaterPerformance::onClickHideAvatars()
void FSFloaterPerformance::onClickFocusAvatar()
{
FSPerfStats::StatsRecorder::setFocusAv(mNearbyCombo->getSelectedValue().asUUID());
LLPerfStats::StatsRecorder::setFocusAv(mNearbyCombo->getSelectedValue().asUUID());
}
void FSFloaterPerformance::onClickExceptions()
@ -850,8 +912,8 @@ void FSFloaterPerformance::updateMaxRenderTime()
void FSFloaterPerformance::updateMaxRenderTimeText()
{
LLAvatarComplexityControls::setRenderTimeText(
gSavedSettings.getF32("FSRenderAvatarMaxART"),
mNearbyPanel->getChild<LLTextBox>("FSRenderAvatarMaxARTText", true),
gSavedSettings.getF32("RenderAvatarMaxART"),
mNearbyPanel->getChild<LLTextBox>("RenderAvatarMaxARTText", true),
true);
}

View File

@ -69,6 +69,7 @@
// <FS:Zi> We don't use the mini location panel in Firestorm
// #include "llpaneltopinfobar.h"
#include "llparcel.h"
#include "llperfstats.h"
#include "llrendersphere.h"
#include "llscriptruntimeperms.h"
#include "llsdutil.h"
@ -4886,6 +4887,7 @@ void LLAgent::handleTeleportFinished()
mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
}
}
LLPerfStats::tunables.autoTuneTimeout = true;
}
void LLAgent::handleTeleportFailed()
@ -4917,6 +4919,8 @@ void LLAgent::handleTeleportFailed()
}
mTPNeedsNeabyChatSeparator = false;
LLPerfStats::tunables.autoTuneTimeout = true;
}
/*static*/

View File

@ -122,6 +122,7 @@
#include "llscenemonitor.h"
#include "llavatarrenderinfoaccountant.h"
#include "lllocalbitmaps.h"
#include "llperfstats.h"
// Linden library includes
#include "llavatarnamecache.h"
@ -288,7 +289,6 @@ using namespace LL;
#include "fsassetblacklist.h"
// #include "fstelemetry.h" // <FS:Beq> Tracy profiler support
#include "fsperfstats.h" // <FS:Beq> performance stats support
#if LL_LINUX && LL_GTK
#include "glib.h"
@ -1588,131 +1588,125 @@ bool LLAppViewer::frame()
bool LLAppViewer::doFrame()
{
LL_RECORD_BLOCK_TIME(FTM_FRAME);
// <FS:Beq> Perfstats collection Frame boundary
{
// and now adjust the visuals from previous frame.
if(FSPerfStats::tunables.userAutoTuneEnabled && FSPerfStats::tunables.tuningFlag != FSPerfStats::Tunables::Nothing)
LL_RECORD_BLOCK_TIME(FTM_FRAME);
{
FSPerfStats::tunables.applyUpdates();
// and now adjust the visuals from previous frame.
if(LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.tuningFlag != LLPerfStats::Tunables::Nothing)
{
LLPerfStats::tunables.applyUpdates();
}
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_FRAME);
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_FRAME);
if (!LLWorld::instanceExists())
{
LLWorld::createInstance();
}
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD newFrame;
LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
LLSD newFrame;
LLTimer frameTimer; // <FS:Beq/> relocated - <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
{
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); // perf stats
// <FS:Beq> profiling enablement.
// This ifdef is optional but better to avoid even low overhead code in main loop where not needed.
#ifdef TRACY_ENABLE
static bool one_time{false};
static LLCachedControl<bool> defer_profiling(gSavedSettings, "DeferProfilingUntilConnected");
if( !one_time && (gFrameCount % 10 == 0) )
{
// LL_INFOS() << "Profiler active: " << (LLProfiler::active?"True":"False") << LL_ENDL;
// LL_INFOS() << "deferred_profiling: " << (defer_profiling?"True":"False") << LL_ENDL;
// LL_INFOS() << "connected: " << (LL_PROFILE_IS_CONNECTED?"True":"False") << LL_ENDL;
if( ( !LLProfiler::active ) && ( defer_profiling && LL_PROFILE_IS_CONNECTED ) )
static bool one_time{false};
static LLCachedControl<bool> defer_profiling(gSavedSettings, "DeferProfilingUntilConnected");
if( !one_time && (gFrameCount % 10 == 0) )
{
LLProfiler::active = true;
gSavedSettings.setBOOL( "ProfilingActive", LLProfiler::active );
one_time=true; // prevent reset race if we disable manually.
LL_INFOS() << "Profiler or collector connected" << LL_ENDL;
// LL_INFOS() << "Profiler active: " << (LLProfiler::active?"True":"False") << LL_ENDL;
// LL_INFOS() << "deferred_profiling: " << (defer_profiling?"True":"False") << LL_ENDL;
// LL_INFOS() << "connected: " << (LL_PROFILE_IS_CONNECTED?"True":"False") << LL_ENDL;
if( ( !LLProfiler::active ) && ( defer_profiling && LL_PROFILE_IS_CONNECTED ) )
{
LLProfiler::active = true;
gSavedSettings.setBOOL( "ProfilingActive", LLProfiler::active );
one_time=true; // prevent reset race if we disable manually.
LL_INFOS() << "Profiler or collector connected" << LL_ENDL;
}
if( !defer_profiling )
{
// no point in checking if we are not waiting.
// TODO(Beq): At the moment we have only two options
// 1) start capturing immediately
// 2) start capturing only when a profiler is connected
// Ideally we could have another flag to control profiling at start
// this would then allow a fully manual enablement.
one_time = true;
LL_INFOS() << "Manual profiling control selected" << LL_ENDL;
}
}
if( !defer_profiling )
{
// no point in checking if we are not waiting.
// TODO(Beq): At the moment we have only two options
// 1) start capturing immediately
// 2) start capturing only when a profiler is connected
// Ideally we could have another flag to control profiling at start
// this would then allow a fully manual enablement.
one_time = true;
LL_INFOS() << "Manual profiling control selected" << LL_ENDL;
}
}
#endif
// </FS:Beq>
// <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
LLTimer frameTimer;
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // <FS:Beq/> perf stats
nd::etw::logFrame(); // <FS:ND> Write the start of each frame. Even if our Provider (Firestorm) would be enabled, this has only light impact. Does nothing on OSX and Linux.
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace");
if (LLFloaterReg::instanceVisible("block_timers"))
{
LLTrace::BlockTimer::processTimes();
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace");
if (LLFloaterReg::instanceVisible("block_timers"))
{
LLTrace::BlockTimer::processTimes();
}
LLTrace::get_frame_recording().nextPeriod();
LLTrace::BlockTimer::logStats();
}
LLTrace::get_frame_recording().nextPeriod();
LLTrace::BlockTimer::logStats();
}
LLTrace::get_thread_recorder()->pullFromChildren();
LLTrace::get_thread_recorder()->pullFromChildren();
//clear call stack records
LL_CLEAR_CALLSTACKS();
} // <FS:Beq/> perf stats (close NonRender/IDLE tracking starting at event pump)
{
{FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // <FS:Beq> ensure we have the entire top scope of frame covered (input event and coro)
//clear call stack records
LL_CLEAR_CALLSTACKS();
}
{
{
LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE); // <FS:Beq/> ensure we have the entire top scope of frame covered (input event and coro)
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df processMiscNativeEvents");
pingMainloopTimeout("Main:MiscNativeWindowEvents");
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df processMiscNativeEvents" )
pingMainloopTimeout("Main:MiscNativeWindowEvents");
if (gViewerWindow)
{
LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
gViewerWindow->getWindow()->processMiscNativeEvents();
}
if (gViewerWindow)
{
LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
gViewerWindow->getWindow()->processMiscNativeEvents();
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df gatherInput")
pingMainloopTimeout("Main:GatherInput");
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gatherInput" )
pingMainloopTimeout("Main:GatherInput");
}
if (gViewerWindow)
{
if (gViewerWindow)
{
LL_RECORD_BLOCK_TIME(FTM_MESSAGES2);
if (!restoreErrorTrap())
{
LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
}
if (!restoreErrorTrap())
{
LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
}
gViewerWindow->getWindow()->gatherInput();
}
gViewerWindow->getWindow()->gatherInput();
}
//memory leaking simulation
if (gSimulateMemLeak)
{
LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if (mem_leak_instance)
{
mem_leak_instance->idle();
}
}
//memory leaking simulation
if (gSimulateMemLeak)
{
LLFloaterMemLeak* mem_leak_instance =
LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
if (mem_leak_instance)
{
mem_leak_instance->idle();
}
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df mainloop" )
// canonical per-frame event
mainloop.post(newFrame);
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
// if one of our coroutines threw an uncaught exception, rethrow it now
LLCoros::instance().rethrow();
}
}// <FS:Beq> ensure we have the entire top scope of frame covered (close input event and coro "idle")
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df mainloop")
// canonical per-frame event
mainloop.post(newFrame);
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df suspend")
// give listeners a chance to run
llcoro::suspend();
}
}
if (!LLApp::isExiting())
{
@ -1729,8 +1723,7 @@ bool LLAppViewer::doFrame()
&& (gHeadlessClient || !gViewerWindow->getShowProgress())
&& !gFocusMgr.focusLocked())
{
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df JoystickKeyboard" )
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
joystick->scanJoystick();
gKeyboard->scanKeyboard();
gViewerInput.scanMouse();
@ -1746,19 +1739,21 @@ bool LLAppViewer::doFrame()
// Update state based on messages, user input, object idle.
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df pauseMainloopTimeout" )
pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds!
}
{
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE);
idle();
}
{
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE);
idle();
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
resumeMainloopTimeout();
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
resumeMainloopTimeout();
}
}
if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
@ -1786,15 +1781,15 @@ bool LLAppViewer::doFrame()
display();
{
FSPerfStats::RecordSceneTime T(FSPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot")
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterSimpleOutfitSnapshot::update();
gGLActive = FALSE;
}
}
{
LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE);
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterSimpleOutfitSnapshot::update();
gGLActive = FALSE;
}
}
}
{
@ -1842,8 +1837,8 @@ bool LLAppViewer::doFrame()
// of equal priority on Windows
if (milliseconds_to_sleep > 0)
{
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_SLEEP );
ms_sleep(milliseconds_to_sleep);
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SLEEP );
ms_sleep(milliseconds_to_sleep);
// also pause worker threads during this wait period
LLAppViewer::getTextureCache()->pause();
LLAppViewer::getImageDecodeThread()->pause();
@ -1871,8 +1866,6 @@ bool LLAppViewer::doFrame()
// <FS:Beq> instrument image decodes
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("updateTextureThreads");
// FSPlot("max_time_ms",max_time);
// <FS:Beq/>
work_pending += updateTextureThreads(max_time);
} // <FS:Beq/> instrument image decodes
@ -1927,7 +1920,7 @@ bool LLAppViewer::doFrame()
if (fsLimitFramerate && LLStartUp::getStartupState() == STATE_STARTED && !gTeleportDisplay && !logoutRequestSent() && max_fps > F_APPROXIMATELY_ZERO)
{
// Sleep a while to limit frame rate.
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_FPSLIMIT );
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_FPSLIMIT );
F32 min_frame_time = 1.f / (F32)max_fps;
S32 milliseconds_to_sleep = llclamp((S32)((min_frame_time - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000);
if (milliseconds_to_sleep > 0)
@ -1966,8 +1959,7 @@ bool LLAppViewer::doFrame()
LL_INFOS() << "Exiting main_loop" << LL_ENDL;
}
}FSPerfStats::StatsRecorder::endFrame();
}LLPerfStats::StatsRecorder::endFrame();
LL_PROFILER_FRAME_END
return ! LLApp::isRunning();
@ -3588,15 +3580,9 @@ void LLAppViewer::initStrings()
// </FS:Ansariel>
}
//
// This function decides whether the client machine meets the minimum requirements to
// run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011.
//
bool LLAppViewer::meetsRequirementsForMaximizedStart()
{
bool maximizedOk = (LLFeatureManager::getInstance()->getGPUClass() >= GPU_CLASS_2);
maximizedOk &= (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1));
bool maximizedOk = (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1));
return maximizedOk;
}
@ -5858,7 +5844,7 @@ void LLAppViewer::idle()
if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
{
FSPerfStats::tunedAvatars=0; // <FS:Beq> reset the number of avatars that have been tweaked.
LLPerfStats::tunedAvatars=0; // <FS:Beq> reset the number of avatars that have been tweaked.
gObjectList.update(gAgent);
}
}

View File

@ -52,7 +52,7 @@
#include "llglcommonfunc.h"
#include "llvoavatar.h"
#include "llviewershadermgr.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "llperfstats.h"
S32 LLDrawPool::sNumDrawPools = 0;
@ -392,24 +392,22 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo *pparams = *k;
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, false,&ratPtr);
}
}
// </FS:Beq>
pushBatch(*pparams, mask, texture);
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments(vobj, false, &ratPtr);
}
}
pushBatch(*pparams, mask, texture);
}
}
}
@ -422,22 +420,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo* pparams = *k;
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true ,&ratPtr);
}
}
// </FS:Beq>
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true ,&ratPtr);
}
}
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
uploadMatrixPalette(*pparams);
@ -453,23 +450,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, false, &ratPtr);
}
}
// </FS:Beq>
pushBatch(*pparams, mask, texture, batch_textures);
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, false, &ratPtr);
}
}
pushBatch(*pparams, mask, texture, batch_textures);
}
}
}
@ -480,22 +475,21 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true, &ratPtr);
}
}
// </FS:Beq>
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true, &ratPtr);
}
}
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
{
uploadMatrixPalette(*pparams);
@ -511,22 +505,20 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc
void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
{
// <FS:Beq> Capture render times
if((*pparams).mFace)
{
LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, false, &ratPtr);
}
}
// </FS:Beq>
if((*pparams).mFace)
{
LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, false, &ratPtr);
}
}
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
pushBatch(*pparams, mask, texture, batch_textures);
}
@ -538,22 +530,20 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
{
// <FS:Beq> Capture render times
if((*pparams).mFace)
{
LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true, &ratPtr);
}
}
// </FS:Beq>
if((*pparams).mFace)
{
LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true, &ratPtr);
}
}
if (LLGLSLShader::sCurBoundShaderPtr)
{
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);

View File

@ -49,7 +49,7 @@
#include "llspatialpartition.h"
#include "llglcommonfunc.h"
#include "llvoavatar.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "llperfstats.h"
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
BOOL LLDrawPoolAlpha::sShowDebugAlphaRigged = FALSE;
@ -346,11 +346,20 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
if (params.mParticle)
{
continue;
@ -543,17 +552,15 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLDrawInfo* draw : emissives)
{
// <FS:Beq> Capture render times
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives");
auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
if(vobj && vobj->isAttachment())
{
trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
}
// </FS:Beq>
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives");
auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
if(vobj && vobj->isAttachment())
{
trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
}
bool tex_setup = TexSetup(draw, false);
if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
@ -628,8 +635,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
if ((bool)params.mAvatar != rigged)
@ -651,17 +658,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
continue;
}
// <FS:Beq> Capture render times
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
// </FS:Beq>
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
if(depth_only)
{
@ -854,6 +859,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives
// </FS:Beq>
ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives
// render emissive faces into alpha channel for bloom effects
if (!depth_only)
{

View File

@ -52,6 +52,7 @@
#include "llviewerpartsim.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewertexturelist.h"
#include "llperfstats.h"
// <FS:Zi> Add avatar hitbox debug
#include "llviewercontrol.h"
@ -59,7 +60,6 @@
// void drawBoxOutline(const LLVector3& pos,const LLVector3& size); // llspatialpartition.cpp
// </FS:Zi>
#include "llnetmap.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
@ -389,14 +389,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
{
return;
}
FSPerfStats::RecordAvatarTime T(avatarp->getID(), FSPerfStats::StatType_t::RENDER_SHADOWS);
LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_SHADOWS);
LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
// <FS:Beq> no shadows if the shadows are causing this avatar to breach the limit.
//if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
if (avatarp->isTooSlowWithShadows() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
// </FS:Beq>
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
// no shadows if the shadows are causing this avatar to breach the limit.
if (avatarp->isTooSlow() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
{
// No shadows for impostored (including jellydolled) or invisible avs.
return;
@ -805,7 +803,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
{
return;
}
FSPerfStats::RecordAvatarTime T(avatarp->getID(), FSPerfStats::StatType_t::RENDER_GEOMETRY);
LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_GEOMETRY);
// <FS:Zi> Add avatar hitbox debug
static LLCachedControl<bool> render_hitbox(gSavedSettings, "DebugRenderHitboxes", false);

View File

@ -49,7 +49,7 @@
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
#include "llmodel.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "llperfstats.h"
//#include "llimagebmp.h"
//#include "../tools/imdebug/imdebug.h"
@ -548,18 +548,18 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
// <FS:Beq> Capture render times
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
// </FS:Beq>
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
applyModelMatrix(params);
if (params.mGroup)
@ -728,22 +728,20 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
LLVOAvatar* avatar = nullptr;
U64 skin = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
// <FS:Beq> Capture render times
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj && vobj->isAttachment())
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
// </FS:Beq>
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
LLDrawPoolBump::bindBumpMap(params, bump_channel);
@ -1374,7 +1372,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
@ -1390,6 +1388,16 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
}
// </FS:Beq>
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
if (LLDrawPoolBump::bindBumpMap(params))
{
if (mRigged)

View File

@ -32,7 +32,7 @@
#include "pipeline.h"
#include "llglcommonfunc.h"
#include "llvoavatar.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "llperfstats.h"
S32 diffuse_channel = -1;
@ -165,23 +165,21 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
// <FS:Beq> Capture render times
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
// </FS:Beq>
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);

View File

@ -60,7 +60,7 @@
// [RLVa:KB] - Checked: RLVa-2.0.0
#include "rlvhandler.h"
// [/RLVa:KB]
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "llperfstats.h"
#if LL_LINUX
// Work-around spurious used before init warning on Vector4a

View File

@ -413,6 +413,7 @@ bool LLFeatureManager::loadGPUClass()
{
if (!gSavedSettings.getBOOL("SkipBenchmark"))
{
F32 class0_gbps = gSavedSettings.getF32("RenderClass0MemoryBandwidth");
//get memory bandwidth from benchmark
F32 gbps;
try
@ -434,6 +435,14 @@ bool LLFeatureManager::loadGPUClass()
LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;
}
mGPUMemoryBandwidth = gbps;
// bias by CPU speed
F32 cpu_basis_mhz = gSavedSettings.getF32("RenderCPUBasis");
F32 cpu_mhz = (F32) gSysCPU.getMHz();
F32 cpu_bias = llclamp(cpu_mhz / cpu_basis_mhz, 0.5f, 1.f);
gbps *= cpu_bias;
if (gbps < 0.f)
{ //couldn't bench, use GLVersion
#if LL_DARWIN
@ -476,23 +485,23 @@ bool LLFeatureManager::loadGPUClass()
{
mGPUClass = GPU_CLASS_1;
}
else if (gbps <= 5.f)
else if (gbps <= class0_gbps)
{
mGPUClass = GPU_CLASS_0;
}
else if (gbps <= 8.f)
else if (gbps <= class0_gbps*2.f)
{
mGPUClass = GPU_CLASS_1;
}
else if (gbps <= 16.f)
else if (gbps <= class0_gbps*4.f)
{
mGPUClass = GPU_CLASS_2;
}
else if (gbps <= 40.f)
else if (gbps <= class0_gbps*8.f)
{
mGPUClass = GPU_CLASS_3;
}
else if (gbps <= 80.f)
else if (gbps <= class0_gbps*16.f)
{
mGPUClass = GPU_CLASS_4;
}

View File

@ -111,6 +111,10 @@ public:
EGPUClass getGPUClass() { return mGPUClass; }
std::string& getGPUString() { return mGPUString; }
// get the measured GPU memory bandwidth in GB/sec
// may return 0 of benchmark has not been run or failed to run
F32 getGPUMemoryBandwidth() { return mGPUMemoryBandwidth; }
BOOL isGPUSupported() { return mGPUSupported; }
F32 getExpectedGLVersion() { return mExpectedGLVersion; }
@ -162,6 +166,7 @@ protected:
S32 mTableVersion;
BOOL mSafe; // Reinitialize everything to the "safe" mask
EGPUClass mGPUClass;
F32 mGPUMemoryBandwidth = 0.f; // measured memory bandwidth of GPU in GB/second
F32 mExpectedGLVersion; //expected GL version according to gpu table
std::string mGPUString;
BOOL mGPUSupported;

View File

@ -323,25 +323,7 @@ const std::string LLFloater360Capture::getHTMLBaseFolder()
// triggered when the 'capture' button in the UI is pressed
void LLFloater360Capture::onCapture360ImagesBtn()
{
// <FS:Beq> FIRE-31942 Avoid CoRo that appears to never usefully yield
// Allow option to re-enable on the off chance a low power machine can benefit
if(gSavedSettings.getBOOL("FSUseCoRoFor360Capture"))
{
// </FS:Beq>
// launch the main capture code in a coroutine so we can
// yield/suspend at some points to give the main UI
// thread a look-in occasionally.
LLCoros::instance().launch("capture360cap", [this]()
{
capture360Images();
});
// <FS:Beq> FIRE-31942 Avoid CoRo that appears to never usefully yield
}
else
{
capture360Images();
}
// </FS:Beq>
capture360Images();
}
// Gets the full path name for a given JavaScript file in the HTML folder. We
@ -702,10 +684,6 @@ void LLFloater360Capture::capture360Images()
mCaptureBtn->setEnabled(true);
mSaveLocalBtn->setEnabled(true);
// allow the UI to update by suspending and waiting for the
// main render loop to update the UI
if(gSavedSettings.getBOOL("FSUseCoRoFor360Capture")) // <FS:Beq/> FIRE-31942 - make apparently pointless CoRo optional (just in case)
suspendForAFrame();
}
// once the request is made to navigate to the web page containing the code

View File

@ -91,8 +91,6 @@ BOOL LLFloaterAvatarRenderSettings::postBuild()
LLFloater::postBuild();
mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
mAvatarSettingsList->setAlternateSort();
getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
return TRUE;
}
@ -136,37 +134,13 @@ void LLFloaterAvatarRenderSettings::updateList()
{
item_params.value = iter->first;
LLAvatarNameCache::get(iter->first, &av_name);
if(!isHiddenRow(av_name.getCompleteName()))
{
item_params.columns.add().value(av_name.getCompleteName()).column("name");
std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
item_params.columns.add().value(setting).column("setting");
S32 mute_date = LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first);
item_params.columns.add().value(createTimestamp(mute_date)).column("timestamp").alt_value(std::to_string(mute_date));
mAvatarSettingsList->addNameItemRow(item_params);
}
item_params.columns.add().value(av_name.getCompleteName()).column("name");
std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
item_params.columns.add().value(setting).column("setting");
mAvatarSettingsList->addNameItemRow(item_params);
}
}
void LLFloaterAvatarRenderSettings::onFilterEdit(const std::string& search_string)
{
std::string filter_upper = search_string;
LLStringUtil::toUpper(filter_upper);
if (mNameFilter != filter_upper)
{
mNameFilter = filter_upper;
mNeedsUpdate = true;
}
}
bool LLFloaterAvatarRenderSettings::isHiddenRow(const std::string& av_name)
{
if (mNameFilter.empty()) return false;
std::string upper_name = av_name;
LLStringUtil::toUpper(upper_name);
return std::string::npos == upper_name.find(mNameFilter);
}
static LLVOAvatar* find_avatar(const LLUUID& id)
{
LLViewerObject *obj = gObjectList.findObject(id);
@ -217,6 +191,10 @@ bool LLFloaterAvatarRenderSettings::isActionChecked(const LLSD& userdata, const
{
return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY));
}
else if ("non_default" == command_name)
{
return (visual_setting != S32(LLVOAvatar::AV_RENDER_NORMALLY));
}
else if ("never" == command_name)
{
return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER));

View File

@ -164,6 +164,49 @@ BOOL LLFloaterImagePreview::postBuild()
}
getChild<LLCheckBoxCtrl>("temp_check")->setVisible(enable_temp_uploads);
// </FS:CR>
// <FS:Zi> detect and strip empty alpha layers from images on upload
getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnUpload, this));
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[X_RES]", llformat("%d", mRawImagep->getWidth()));
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[Y_RES]", llformat("%d", mRawImagep->getHeight()));
mEmptyAlphaCheck = getChild<LLCheckBoxCtrl>("strip_alpha_check");
if (mRawImagep->getComponents() != 4)
{
getChild<LLUICtrl>("image_alpha_warning")->setVisible(false);
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[ALPHA]", getString("no_alpha"));
return true;
}
U32 imageBytes = mRawImagep->getWidth() * mRawImagep->getHeight() * 4;
U32 emptyAlphaCount = 0;
U8* data = mRawImagep->getData();
for (U32 i = 3; i < imageBytes; i += 4)
{
if (data[i] > ALPHA_EMPTY_THRESHOLD)
{
emptyAlphaCount++;
}
}
if (emptyAlphaCount > (imageBytes / 4 * ALPHA_EMPTY_THRESHOLD_RATIO))
{
getChild<LLUICtrl>("image_alpha_warning")->setVisible(true);
mEmptyAlphaCheck->setCommitCallback(boost::bind(&LLFloaterImagePreview::emptyAlphaCheckboxCallback, this));
mEmptyAlphaCheck->setValue(true);
}
else
{
getChild<LLUICtrl>("image_alpha_warning")->setVisible(false);
mEmptyAlphaCheck->setValue(false);
}
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[ALPHA]", getString(mEmptyAlphaCheck->getValue() ? "no_alpha" : "with_alpha"));
// </FS:Zi>
}
else
{
@ -181,47 +224,6 @@ BOOL LLFloaterImagePreview::postBuild()
// <FS:Zi> detect and strip empty alpha layers from images on upload
// getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnUpload, this));
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[X_RES]", llformat("%d", mRawImagep->getWidth()));
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[Y_RES]", llformat("%d", mRawImagep->getHeight()));
mEmptyAlphaCheck = getChild<LLCheckBoxCtrl>("strip_alpha_check");
if (mRawImagep->getComponents() != 4)
{
getChild<LLUICtrl>("image_alpha_warning")->setVisible(false);
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[ALPHA]", getString("no_alpha"));
return true;
}
U32 imageBytes = mRawImagep->getWidth() * mRawImagep->getHeight() * 4;
U32 emptyAlphaCount = 0;
U8* data = mRawImagep->getData();
for (U32 i = 3; i < imageBytes; i += 4)
{
if (data[i] > ALPHA_EMPTY_THRESHOLD)
{
emptyAlphaCount++;
}
}
if (emptyAlphaCount > (imageBytes / 4 * ALPHA_EMPTY_THRESHOLD_RATIO))
{
getChild<LLUICtrl>("image_alpha_warning")->setVisible(true);
mEmptyAlphaCheck->setCommitCallback(boost::bind(&LLFloaterImagePreview::emptyAlphaCheckboxCallback, this));
mEmptyAlphaCheck->setValue(true);
}
else
{
getChild<LLUICtrl>("image_alpha_warning")->setVisible(false);
mEmptyAlphaCheck->setValue(false);
}
getChild<LLUICtrl>("uploaded_size_text")->setTextArg("[ALPHA]", getString(mEmptyAlphaCheck->getValue() ? "no_alpha" : "with_alpha"));
// </FS:Zi>
return TRUE;
}

View File

@ -0,0 +1,699 @@
/**
* @file llfloaterperformance.cpp
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterperformance.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llappearancemgr.h"
#include "llavataractions.h"
#include "llavatarrendernotifier.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llfeaturemanager.h"
#include "llfloaterpreference.h" // LLAvatarComplexityControls
#include "llfloaterreg.h"
#include "llnamelistctrl.h"
#include "llnotificationsutil.h"
#include "llperfstats.h"
#include "llpresetsmanager.h"
#include "llradiogroup.h"
#include "llsliderctrl.h"
#include "lltextbox.h"
#include "lltrans.h"
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llworld.h"
#include "pipeline.h"
const F32 REFRESH_INTERVAL = 1.0f;
const S32 BAR_LEFT_PAD = 2;
const S32 BAR_RIGHT_PAD = 5;
const S32 BAR_BOTTOM_PAD = 9;
constexpr auto AvType {LLPerfStats::ObjType_t::OT_AVATAR};
constexpr auto AttType {LLPerfStats::ObjType_t::OT_ATTACHMENT};
constexpr auto HudType {LLPerfStats::ObjType_t::OT_HUD};
class LLExceptionsContextMenu : public LLListContextMenu
{
public:
LLExceptionsContextMenu(LLFloaterPerformance* floater_settings)
: mFloaterPerformance(floater_settings)
{}
protected:
LLContextMenu* createMenu()
{
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
registrar.add("Settings.SetRendering", boost::bind(&LLFloaterPerformance::onCustomAction, mFloaterPerformance, _2, mUUIDs.front()));
enable_registrar.add("Settings.IsSelected", boost::bind(&LLFloaterPerformance::isActionChecked, mFloaterPerformance, _2, mUUIDs.front()));
LLContextMenu* menu = createFromFile("menu_avatar_rendering_settings.xml");
return menu;
}
LLFloaterPerformance* mFloaterPerformance;
};
LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
: LLFloater(key),
mUpdateTimer(new LLTimer()),
mNearbyMaxComplexity(0)
{
mContextMenu = new LLExceptionsContextMenu(this);
}
LLFloaterPerformance::~LLFloaterPerformance()
{
mMaxARTChangedSignal.disconnect();
delete mContextMenu;
delete mUpdateTimer;
}
BOOL LLFloaterPerformance::postBuild()
{
mMainPanel = getChild<LLPanel>("panel_performance_main");
mNearbyPanel = getChild<LLPanel>("panel_performance_nearby");
mComplexityPanel = getChild<LLPanel>("panel_performance_complexity");
mSettingsPanel = getChild<LLPanel>("panel_performance_preferences");
mHUDsPanel = getChild<LLPanel>("panel_performance_huds");
mAutoadjustmentsPanel = getChild<LLPanel>("panel_performance_autoadjustments");
getChild<LLPanel>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel));
getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel));
getChild<LLPanel>("autoadjustments_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mAutoadjustmentsPanel));
initBackBtn(mNearbyPanel);
initBackBtn(mComplexityPanel);
initBackBtn(mSettingsPanel);
initBackBtn(mHUDsPanel);
initBackBtn(mAutoadjustmentsPanel);
mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
mHUDList->setHoverIconName("StopReload_Off");
mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
mObjectList = mComplexityPanel->getChild<LLNameListCtrl>("obj_list");
mObjectList->setNameListType(LLNameListCtrl::SPECIAL);
mObjectList->setHoverIconName("StopReload_Off");
mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this));
mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2));
mSettingsPanel->getChild<LLCheckBoxCtrl>("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this));
mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this));
mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3));
mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
// store the current setting as the users desired reflection detail and DD
gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail);
if(!LLPerfStats::tunables.userAutoTuneEnabled)
{
gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
}
LLStringExplicit fps_limit(llformat("%d", gViewerWindow->getWindow()->getRefreshRate()));
mAutoadjustmentsPanel->getChild<LLTextBox>("vsync_desc_limit")->setTextArg("[FPS_LIMIT]", fps_limit);
mAutoadjustmentsPanel->getChild<LLTextBox>("display_desc")->setTextArg("[FPS_LIMIT]", fps_limit);
mAutoadjustmentsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this));
mStartAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("start_autotune");
mStopAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("stop_autotune");
mStartAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::startAutotune, this));
mStopAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::stopAutotune, this));
gSavedPerAccountSettings.declareBOOL("HadEnabledAutoFPS", FALSE, "User had enabled AutoFPS at least once", LLControlVariable::PERSIST_ALWAYS);
return TRUE;
}
void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
{
hidePanels();
mMainPanel->setVisible(FALSE);
selected_panel->setVisible(TRUE);
if (mHUDsPanel == selected_panel)
{
populateHUDList();
}
else if (mNearbyPanel == selected_panel)
{
populateNearbyList();
}
else if (mComplexityPanel == selected_panel)
{
populateObjectList();
}
}
void LLFloaterPerformance::showAutoadjustmentsPanel()
{
showSelectedPanel(mAutoadjustmentsPanel);
}
void LLFloaterPerformance::draw()
{
enableAutotuneWarning();
if (mUpdateTimer->hasExpired() &&
!LLFloaterReg::instanceVisible("save_pref_preset", PRESETS_GRAPHIC)) // give user a chance to save the graphics settings before updating them
{
setFPSText();
if (mHUDsPanel->getVisible())
{
populateHUDList();
}
else if (mNearbyPanel->getVisible())
{
populateNearbyList();
mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
}
else if (mComplexityPanel->getVisible())
{
populateObjectList();
}
mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL);
}
updateAutotuneCtrls(LLPerfStats::tunables.userAutoTuneEnabled);
LLFloater::draw();
}
void LLFloaterPerformance::showMainPanel()
{
hidePanels();
mMainPanel->setVisible(TRUE);
}
void LLFloaterPerformance::hidePanels()
{
mNearbyPanel->setVisible(FALSE);
mComplexityPanel->setVisible(FALSE);
mHUDsPanel->setVisible(FALSE);
mSettingsPanel->setVisible(FALSE);
mAutoadjustmentsPanel->setVisible(FALSE);
}
void LLFloaterPerformance::initBackBtn(LLPanel* panel)
{
panel->getChild<LLButton>("back_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this));
panel->getChild<LLTextBox>("back_lbl")->setShowCursorHand(false);
panel->getChild<LLTextBox>("back_lbl")->setSoundFlags(LLView::MOUSE_UP);
panel->getChild<LLTextBox>("back_lbl")->setClickedCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this));
}
void LLFloaterPerformance::populateHUDList()
{
S32 prev_pos = mHUDList->getScrollPos();
LLUUID prev_selected_id = mHUDList->getSelectedSpecialId();
mHUDList->clearRows();
mHUDList->updateColumns(true);
hud_complexity_list_t complexity_list = LLHUDRenderNotifier::getInstance()->getHUDComplexityList();
hud_complexity_list_t::iterator iter = complexity_list.begin();
hud_complexity_list_t::iterator end = complexity_list.end();
auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY);
for (iter = complexity_list.begin(); iter != end; ++iter)
{
LLHUDComplexity hud_object_complexity = *iter;
auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY);
LLSD item;
item["special_id"] = hud_object_complexity.objectId;
item["target"] = LLNameListCtrl::SPECIAL;
LLSD& row = item["columns"];
row[0]["column"] = "complex_visual";
row[0]["type"] = "bar";
LLSD& value = row[0]["value"];
value["ratio"] = (F32)hud_render_time_raw / huds_max_render_time_raw;
value["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD;
row[1]["column"] = "complex_value";
row[1]["type"] = "text";
row[1]["value"] = llformat( "%.f", llmax(LLPerfStats::raw_to_us(hud_render_time_raw), (double)1));
row[1]["font"]["name"] = "SANSSERIF";
row[2]["column"] = "name";
row[2]["type"] = "text";
row[2]["value"] = hud_object_complexity.objectName;
row[2]["font"]["name"] = "SANSSERIF";
LLScrollListItem* obj = mHUDList->addElement(item);
if (obj)
{
LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
if (value_text)
{
value_text->setAlignment(LLFontGL::HCENTER);
}
}
}
mHUDList->sortByColumnIndex(1, FALSE);
mHUDList->setScrollPos(prev_pos);
mHUDList->selectItemBySpecialId(prev_selected_id);
}
void LLFloaterPerformance::populateObjectList()
{
S32 prev_pos = mObjectList->getScrollPos();
LLUUID prev_selected_id = mObjectList->getSelectedSpecialId();
mObjectList->clearRows();
mObjectList->updateColumns(true);
object_complexity_list_t complexity_list = LLAvatarRenderNotifier::getInstance()->getObjectComplexityList();
object_complexity_list_t::iterator iter = complexity_list.begin();
object_complexity_list_t::iterator end = complexity_list.end();
// for consistency we lock the buffer while we build the list. In theory this is uncontended as the buffer should only toggle on end of frame
{
std::lock_guard<std::mutex> guard{ LLPerfStats::bufferToggleLock };
auto att_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(AttType, LLPerfStats::StatType_t::RENDER_COMBINED);
for (iter = complexity_list.begin(); iter != end; ++iter)
{
LLObjectComplexity object_complexity = *iter;
auto attach_render_time_raw = LLPerfStats::StatsRecorder::get(AttType, object_complexity.objectId, LLPerfStats::StatType_t::RENDER_COMBINED);
LLSD item;
item["special_id"] = object_complexity.objectId;
item["target"] = LLNameListCtrl::SPECIAL;
LLSD& row = item["columns"];
row[0]["column"] = "complex_visual";
row[0]["type"] = "bar";
LLSD& value = row[0]["value"];
value["ratio"] = ((F32)attach_render_time_raw) / att_max_render_time_raw;
value["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD;
row[1]["column"] = "complex_value";
row[1]["type"] = "text";
row[1]["value"] = llformat("%.f", llmax(LLPerfStats::raw_to_us(attach_render_time_raw), (double)1));
row[1]["font"]["name"] = "SANSSERIF";
row[2]["column"] = "name";
row[2]["type"] = "text";
row[2]["value"] = object_complexity.objectName;
row[2]["font"]["name"] = "SANSSERIF";
LLScrollListItem* obj = mObjectList->addElement(item);
if (obj)
{
LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
if (value_text)
{
value_text->setAlignment(LLFontGL::HCENTER);
}
}
}
}
mObjectList->sortByColumnIndex(1, FALSE);
mObjectList->setScrollPos(prev_pos);
mObjectList->selectItemBySpecialId(prev_selected_id);
}
void LLFloaterPerformance::populateNearbyList()
{
static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART");
S32 prev_pos = mNearbyList->getScrollPos();
LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem();
mNearbyList->clearRows();
mNearbyList->updateColumns(true);
static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
std::vector<LLCharacter*> valid_nearby_avs;
mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
LLPerfStats::bufferToggleLock.lock();
auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(AvType, LLPerfStats::StatType_t::RENDER_COMBINED);
LLPerfStats::bufferToggleLock.unlock();
while (char_iter != valid_nearby_avs.end())
{
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
{
LLPerfStats::bufferToggleLock.lock();
auto render_av_raw = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED);
LLPerfStats::bufferToggleLock.unlock();
auto is_slow = avatar->isTooSlow();
LLSD item;
item["id"] = avatar->getID();
LLSD& row = item["columns"];
row[0]["column"] = "complex_visual";
row[0]["type"] = "bar";
LLSD& value = row[0]["value"];
// The ratio used in the bar is the current cost, as soon as we take action this changes so we keep the
// pre-tune value for the numerical column and sorting.
value["ratio"] = (double)render_av_raw / av_render_max_raw;
value["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD;
row[1]["column"] = "complex_value";
row[1]["type"] = "text";
if (is_slow && !showTunedART)
{
row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( avatar->getLastART() ) );
}
else
{
row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( render_av_raw ) );
}
row[1]["font"]["name"] = "SANSSERIF";
row[2]["column"] = "name";
row[2]["type"] = "text";
row[2]["value"] = avatar->getFullname();
row[2]["font"]["name"] = "SANSSERIF";
LLScrollListItem* av_item = mNearbyList->addElement(item);
if(av_item)
{
LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(1));
if (value_text)
{
value_text->setAlignment(LLFontGL::HCENTER);
}
LLScrollListText* name_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(2));
if (name_text)
{
if (avatar->isSelf())
{
name_text->setColor(LLUIColorTable::instance().getColor("DrYellow"));
}
else
{
std::string color = "white";
if (is_slow || LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance())
{
color = "LabelDisabledColor";
LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
if (bar)
{
bar->setColor(LLUIColorTable::instance().getColor(color));
}
}
else if (LLVOAvatar::AOA_NORMAL == avatar->getOverallAppearance())
{
color = LLAvatarActions::isFriend(avatar->getID()) ? "ConversationFriendColor" : "white";
}
name_text->setColor(LLUIColorTable::instance().getColor(color));
}
}
}
}
char_iter++;
}
mNearbyList->sortByColumnIndex(1, FALSE);
mNearbyList->setScrollPos(prev_pos);
mNearbyList->selectByID(prev_selected_id);
}
void LLFloaterPerformance::setFPSText()
{
const S32 NUM_PERIODS = 50;
S32 current_fps = (S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, NUM_PERIODS));
getChild<LLTextBox>("fps_value")->setValue(current_fps);
std::string fps_text = getString("fps_text");
static LLCachedControl<bool> vsync_enabled(gSavedSettings, "RenderVSyncEnable", true);
S32 refresh_rate = gViewerWindow->getWindow()->getRefreshRate();
if (vsync_enabled && (refresh_rate > 0) && (current_fps >= refresh_rate))
{
fps_text += getString("max_text");
}
getChild<LLTextBox>("fps_lbl")->setValue(fps_text);
}
void LLFloaterPerformance::detachItem(const LLUUID& item_id)
{
LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
}
void LLFloaterPerformance::onClickAdvanced()
{
LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
if (instance)
{
instance->saveSettings();
}
LLFloaterReg::showInstance("prefs_graphics_advanced");
}
void LLFloaterPerformance::onClickDefaults()
{
LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
if (instance)
{
instance->setRecommendedSettings();
}
}
void LLFloaterPerformance::onChangeQuality(const LLSD& data)
{
LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
if (instance)
{
instance->onChangeQuality(data);
}
}
void LLFloaterPerformance::onClickHideAvatars()
{
LLPipeline::toggleRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR);
}
void LLFloaterPerformance::onClickExceptions()
{
LLFloaterReg::showInstance("avatar_render_settings");
}
void LLFloaterPerformance::updateMaxRenderTime()
{
LLAvatarComplexityControls::updateMaxRenderTime(
mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART"),
mNearbyPanel->getChild<LLTextBox>("RenderAvatarMaxARTText"),
true);
}
static LLVOAvatar* find_avatar(const LLUUID& id)
{
LLViewerObject *obj = gObjectList.findObject(id);
while (obj && obj->isAttachment())
{
obj = (LLViewerObject *)obj->getParent();
}
if (obj && obj->isAvatar())
{
return (LLVOAvatar*)obj;
}
else
{
return NULL;
}
}
void LLFloaterPerformance::onCustomAction(const LLSD& userdata, const LLUUID& av_id)
{
const std::string command_name = userdata.asString();
S32 new_setting = 0;
if ("default" == command_name)
{
new_setting = S32(LLVOAvatar::AV_RENDER_NORMALLY);
}
else if ("never" == command_name)
{
new_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER);
}
else if ("always" == command_name)
{
new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
}
LLVOAvatar *avatarp = find_avatar(av_id);
if (avatarp)
{
avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
}
else
{
LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
}
}
bool LLFloaterPerformance::isActionChecked(const LLSD& userdata, const LLUUID& av_id)
{
const std::string command_name = userdata.asString();
S32 visual_setting = LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(av_id);
if ("default" == command_name)
{
return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY));
}
else if ("non_default" == command_name)
{
return (visual_setting != S32(LLVOAvatar::AV_RENDER_NORMALLY));
}
else if ("never" == command_name)
{
return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER));
}
else if ("always" == command_name)
{
return (visual_setting == S32(LLVOAvatar::AV_ALWAYS_RENDER));
}
return false;
}
void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
{
LLNameListCtrl* list = dynamic_cast<LLNameListCtrl*>(ctrl);
if (!list) return;
list->selectItemAt(x, y, MASK_NONE);
uuid_vec_t selected_uuids;
if((list->getCurrentID().notNull()) && (list->getCurrentID() != gAgentID))
{
selected_uuids.push_back(list->getCurrentID());
mContextMenu->show(ctrl, selected_uuids, x, y);
}
}
const U32 RENDER_QUALITY_LEVEL = 3;
void LLFloaterPerformance::changeQualityLevel(const std::string& notif)
{
LLNotificationsUtil::add(notif, LLSD(), LLSD(),
[](const LLSD&notif, const LLSD&resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{
LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
if (instance)
{
gSavedSettings.setU32("RenderQualityPerformance", RENDER_QUALITY_LEVEL);
instance->onChangeQuality(LLSD((S32)RENDER_QUALITY_LEVEL));
}
}
});
}
bool is_ALM_available()
{
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
return LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny &&
shaders;
}
void LLFloaterPerformance::onClickAdvancedLighting()
{
if (!is_ALM_available())
{
changeQualityLevel("AdvancedLightingConfirm");
}
}
void LLFloaterPerformance::onClickShadows()
{
if (!is_ALM_available() || !gSavedSettings.getBOOL("RenderDeferred"))
{
changeQualityLevel("ShadowsConfirm");
}
}
void LLFloaterPerformance::startAutotune()
{
LLPerfStats::tunables.userAutoTuneEnabled = true;
}
void LLFloaterPerformance::stopAutotune()
{
LLPerfStats::tunables.userAutoTuneEnabled = false;
}
void LLFloaterPerformance::updateAutotuneCtrls(bool autotune_enabled)
{
static LLCachedControl<bool> auto_tune_locked(gSavedSettings, "AutoTuneLock");
mStartAutotuneBtn->setEnabled(!autotune_enabled && !auto_tune_locked);
mStopAutotuneBtn->setEnabled(autotune_enabled && !auto_tune_locked);
getChild<LLCheckBoxCtrl>("AutoTuneContinuous")->setEnabled(!autotune_enabled || (autotune_enabled && auto_tune_locked));
getChild<LLTextBox>("wip_desc")->setVisible(autotune_enabled && !auto_tune_locked);
getChild<LLTextBox>("display_desc")->setVisible(LLPerfStats::tunables.vsyncEnabled);
}
void LLFloaterPerformance::enableAutotuneWarning()
{
if (!gSavedPerAccountSettings.getBOOL("HadEnabledAutoFPS") && LLPerfStats::tunables.userAutoTuneEnabled)
{
gSavedPerAccountSettings.setBOOL("HadEnabledAutoFPS", TRUE);
LLNotificationsUtil::add("EnableAutoFPSWarning", LLSD(), LLSD(),
[](const LLSD& notif, const LLSD& resp)
{
S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
if (opt == 0)
{ // offer user to save current graphics settings as a preset
LLFloaterReg::showInstance("save_pref_preset", PRESETS_GRAPHIC);
}
});
}
}
// EOF

View File

@ -0,0 +1,102 @@
/**
* @file llfloaterperformance.h
*
* $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERPERFORMANCE_H
#define LL_LLFLOATERPERFORMANCE_H
#include "llfloater.h"
#include "lllistcontextmenu.h"
class LLCharacter;
class LLNameListCtrl;
class LLFloaterPerformance : public LLFloater
{
public:
LLFloaterPerformance(const LLSD& key);
virtual ~LLFloaterPerformance();
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
void showSelectedPanel(LLPanel* selected_panel);
void showMainPanel();
void hidePanels();
void showAutoadjustmentsPanel();
void detachItem(const LLUUID& item_id);
void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
private:
void initBackBtn(LLPanel* panel);
void populateHUDList();
void populateObjectList();
void populateNearbyList();
void setFPSText();
void onClickAdvanced();
void onClickDefaults();
void onChangeQuality(const LLSD& data);
void onClickHideAvatars();
void onClickExceptions();
void onClickShadows();
void onClickAdvancedLighting();
void startAutotune();
void stopAutotune();
void updateAutotuneCtrls(bool autotune_enabled);
void enableAutotuneWarning();
void updateMaxRenderTime();
static void changeQualityLevel(const std::string& notif);
LLPanel* mMainPanel;
LLPanel* mNearbyPanel;
LLPanel* mComplexityPanel;
LLPanel* mHUDsPanel;
LLPanel* mSettingsPanel;
LLPanel* mAutoadjustmentsPanel;
LLNameListCtrl* mHUDList;
LLNameListCtrl* mObjectList;
LLNameListCtrl* mNearbyList;
LLButton* mStartAutotuneBtn;
LLButton* mStopAutotuneBtn;
LLListContextMenu* mContextMenu;
LLTimer* mUpdateTimer;
S32 mNearbyMaxComplexity;
boost::signals2::connection mMaxARTChangedSignal;
};
#endif // LL_LLFLOATERPERFORMANCE_H

View File

@ -54,6 +54,7 @@
#include "llfloaterabout.h"
#include "llfavoritesbar.h"
#include "llfloaterpreferencesgraphicsadvanced.h"
#include "llfloaterperformance.h"
#include "llfloatersidepanelcontainer.h"
// <FS:Ansariel> [FS communication UI]
//#include "llfloaterimsession.h"
@ -128,6 +129,7 @@
#include "llpresetsmanager.h"
#include "llsearchableui.h"
#include "llperfstats.h"
// Firestorm Includes
#include "exogroupmutelist.h"
@ -165,8 +167,6 @@
#endif
// </FS:LO>
#include "fsperfstats.h"// <FS:Beq/> perfstats
// <FS:Zi> FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search.
#include "llfiltereditor.h"
#include "llviewershadermgr.h"
@ -468,6 +468,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
// </FS:Zi>
mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
mCommitCallbackRegistrar.add("Pref.RenderExceptions", boost::bind(&LLFloaterPreference::onClickRenderExceptions, this));
// mCommitCallbackRegistrar.add("Pref.AutoAdjustments", boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this)); // <FS:Beq/> Not required in FS at present
mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
@ -505,6 +506,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2));
gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged, _2));
gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAtmosShaderChange, this));
LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
@ -1234,17 +1236,18 @@ void LLFloaterPreference::onOpen(const LLSD& key)
// <FS:Ansariel> FIRE-19810: Make presets global since PresetGraphicActive setting is global as well
//bool started = (LLStartUp::getStartupState() == STATE_STARTED);
//LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
//LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
//LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
//LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
//LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
//if (load_btn && save_btn && delete_btn && exceptions_btn)
// LLButton* auto_adjustments_btn = findChild<LLButton>("AutoAdjustmentsButton");
//if (load_btn && save_btn && delete_btn && exceptions_btn && auto_adjustments_btn)
//{
// load_btn->setEnabled(started);
// save_btn->setEnabled(started);
// delete_btn->setEnabled(started);
// exceptions_btn->setEnabled(started);
// auto_adjustments_btn->setEnabled(started);
//}
// </FS:Ansariel>
collectSearchableItems();
@ -1257,6 +1260,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
tabcontainer->selectFirstTab();
// </FS:ND>
}
// <FS:Zi> Support for tab/subtab links like:
// secondlife:///app/openfloater/preferences?tab=backup
@ -1375,6 +1379,13 @@ void LLFloaterPreference::setHardwareDefaults()
// saveSettings(); // save here to be able to return to the previous preset by Cancel
//}
// </FS:Ansariel>
setRecommendedSettings();
}
void LLFloaterPreference::setRecommendedSettings()
{
resetAutotuneSettings();
gSavedSettings.getControl("RenderVSyncEnable")->resetToDefault(true);
LLFeatureManager::getInstance()->applyRecommendedSettings();
@ -1399,6 +1410,28 @@ void LLFloaterPreference::setHardwareDefaults()
}
}
void LLFloaterPreference::resetAutotuneSettings()
{
gSavedSettings.setBOOL("AutoTuneFPS", FALSE);
const std::string autotune_settings[] = {
"AutoTuneLock",
"KeepAutoTuneLock",
"TargetFPS",
"TuningFPSStrategy",
"AutoTuneImpostorByDistEnabled",
"AutoTuneImpostorFarAwayDistance" ,
"AutoTuneRenderFarClipMin",
"AutoTuneRenderFarClipTarget",
"RenderAvatarMaxART"
};
for (auto it : autotune_settings)
{
gSavedSettings.getControl(it)->resetToDefault(true);
}
}
void LLFloaterPreference::getControlNames(std::vector<std::string>& names)
{
LLView* view = findChild<LLView>("display");
@ -2853,24 +2886,23 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool sh
}
}
// <FS:Beq> redner time controls
void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
{
setRenderTimeText((F32)(FSPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val);
setRenderTimeText((F32)(LLPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val);
}
void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val)
{
if (0 == value)
{
text_box->setText(LLTrans::getString("no_limit"));
}
else
{
text_box->setText(llformat("%.0f", value));
}
if (0 == value)
{
text_box->setText(LLTrans::getString("no_limit"));
}
else
{
text_box->setText(llformat("%.0f", value));
}
}
// </FS:Beq>
void LLFloaterPreference::updateMaxComplexity()
{
// Called when the IndirectMaxComplexity control changes
@ -3034,6 +3066,17 @@ void LLFloaterPreference::onClickRenderExceptions()
LLFloaterReg::showInstance("avatar_render_settings");
}
// <FS:Beq> Not currently used in FS
// void LLFloaterPreference::onClickAutoAdjustments()
// {
// LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance");
// if (performance_floater)
// {
// performance_floater->showAutoadjustmentsPanel();
// }
// }
// </FS:Beq>
void LLFloaterPreference::onClickAdvanced()
{
LLFloaterReg::showInstance("prefs_graphics_advanced");
@ -3056,6 +3099,22 @@ void LLFloaterPreference::onClickActionChange()
updateClickActionControls();
}
void LLFloaterPreference::onAtmosShaderChange()
{
LLCheckBoxCtrl* ctrl_alm = getChild<LLCheckBoxCtrl>("UseLightShaders");
if(ctrl_alm)
{
//Deferred/SSAO/Shadows
BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny &&
shaders;
ctrl_alm->setEnabled(enabled);
}
}
void LLFloaterPreference::onClickPermsDefault()
{
LLFloaterReg::showInstance("perms_default");

View File

@ -158,6 +158,8 @@ protected:
// updates click/double-click action keybindngs depending on view values
void updateClickActionControls();
void onAtmosShaderChange();
// <FS:PP> updates UI Sounds controls depending on values from settings.xml
void updateUISoundsControls();
@ -276,6 +278,7 @@ public:
void onClickAutoReplace();
void onClickSpellChecker();
void onClickRenderExceptions();
void onClickAutoAdjustments();
void onClickAdvanced();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
@ -296,6 +299,9 @@ public:
// <FS:Zi> Support preferences search SLURLs
void onCopySearch();
void setRecommendedSettings();
void resetAutotuneSettings();
private:
void onDeleteTranscripts();
@ -487,10 +493,8 @@ class LLAvatarComplexityControls
public:
static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false);
static void setText(U32 value, LLTextBox* text_box, bool short_val = false);
// <FS:Beq> for render time support
static void updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false);
static void setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val = false);
// </FS:Beq>
static void setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val = false);
static void setIndirectControls();
static void setIndirectMaxNonImpostors();
static void setIndirectMaxArc();

View File

@ -32,6 +32,7 @@
#include "llfeaturemanager.h"
#include "llfloaterpreference.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsliderctrl.h"
#include "lltextbox.h"
#include "lltrans.h"
@ -51,11 +52,14 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2));
}
LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
{
mComplexityChangedSignal.disconnect();
mLODFactorChangedSignal.disconnect();
}
BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
@ -75,8 +79,8 @@ BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
use_HiDPI->setVisible(FALSE);
#endif
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
mLODFactorChangedSignal = gSavedSettings.getControl("RenderVolumeLODFactor")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateObjectMeshDetailText, this));
return TRUE;
}
@ -162,6 +166,11 @@ void LLFloaterPreferenceGraphicsAdvanced::updateComplexityText()
getChild<LLTextBox>("IndirectMaxComplexityText", true));
}
void LLFloaterPreferenceGraphicsAdvanced::updateObjectMeshDetailText()
{
updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail", true), getChild<LLTextBox>("ObjectMeshDetailText", true));
}
void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
{
if (text_box == NULL || ctrl== NULL)
@ -207,6 +216,16 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
void LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors(const LLSD& newvalue)
{
U32 value = newvalue.asInteger();
if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))
{
gSavedSettings.setU32("IndirectMaxNonImpostors", value);
setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
}
void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
{
if (0 == value)
@ -259,8 +278,7 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
}
// disabled deferred
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
!gGLManager.mHasFramebufferObject)
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
{
ctrl_shadows->setEnabled(FALSE);
ctrl_shadows->setValue(0);
@ -341,9 +359,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
ctrl_reflections->setEnabled(reflections);
reflections_text->setEnabled(reflections);
// Transparent Water
LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
// Bump & Shiny
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
@ -400,9 +415,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
gGLManager.mHasFramebufferObject &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);

View File

@ -45,9 +45,11 @@ public:
void refreshEnabledState();
void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
void updateMaxNonImpostors();
void updateIndirectMaxNonImpostors(const LLSD& newvalue);
void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
void updateMaxComplexity();
void updateComplexityText();
void updateObjectMeshDetailText();
void refresh();
// callback for when client modifies a render option
void onRenderOptionEnable();
@ -59,6 +61,7 @@ protected:
void onBtnCancel(const LLSD& userdata);
boost::signals2::connection mComplexityChangedSignal;
boost::signals2::connection mLODFactorChangedSignal;
};
#endif //LLFLOATERPREFERENCEGRAPHICSADVANCED_H

View File

@ -1134,6 +1134,7 @@ private:
//-----------------------------------------------------------------------------
// gpu_benchmark()
// returns measured memory bandwidth of GPU in gigabytes per second
//-----------------------------------------------------------------------------
F32 gpu_benchmark()
{

View File

@ -191,6 +191,7 @@ public:
/*virtual*/ void updateColumns(bool force_update);
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
bool isSpecialType() { return (mNameListType == SPECIAL); }

View File

@ -86,15 +86,18 @@ void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id)
mSelfProfile = (getAvatarId() == gAgentID);
// <FS:Zi> FIRE-32179: Make drag-n-drop sharing of items possible again
LLProfileDropTarget* target = getChild<LLProfileDropTarget>("drop_target");
if (avatar_id == gAgentID)
LLProfileDropTarget* target = findChild<LLProfileDropTarget>("drop_target");
if (target)
{
// hide drop target on own profile
target->setVisible(false);
}
else
{
target->setAgentID(avatar_id);
if (avatar_id == gAgentID)
{
// hide drop target on own profile
target->setVisible(false);
}
else
{
target->setAgentID(avatar_id);
}
}
// </FS:Zi>
}

View File

@ -1561,7 +1561,7 @@ void LLPanelObject::activateMeshFields(LLViewerObject * objectp)
childSetVisible("ObjectLODbehaviourLabel", true);
// Setup the LL defaults
factor = 1.125f; // LL default for most people http://wiki.firestormviewer.org/support:whirly_fizzle#lod_comparison
factor = 1.25f; // LL default for most people http://wiki.firestormviewer.org/support:whirly_fizzle#lod_comparison
args["FACTOR"] = llformat("%.3f", factor);
tb = getChild<LLTextBox>("LOD_swap_ll_default");
tb->setToolTip(getString("ll_lod_tooltip_msg",args));

View File

@ -34,6 +34,8 @@
#include "llbutton.h"
#include "lltabcontainer.h"
#include "llfloater.h"
//#include "llfloaterperformance.h"
#include "fsfloaterperformance.h"
#include "llfloaterreg.h"
#include "llpresetsmanager.h"
#include "llsliderctrl.h"
@ -48,6 +50,7 @@
LLPanelPresetsPulldown::LLPanelPresetsPulldown()
{
mCommitCallbackRegistrar.add("Presets.GoGraphicsPrefs", boost::bind(&LLPanelPresetsPulldown::onGraphicsButtonClick, this, _2));
mCommitCallbackRegistrar.add("Presets.GoAutofpsPrefs", boost::bind(&LLPanelPresetsPulldown::onAutofpsButtonClick, this, _2));
mCommitCallbackRegistrar.add("Presets.RowClick", boost::bind(&LLPanelPresetsPulldown::onRowClick, this, _2));
buildFromFile( "panel_presets_pulldown.xml");
@ -155,3 +158,15 @@ void LLPanelPresetsPulldown::onGraphicsButtonClick(const LLSD& user_data)
}
}
}
void LLPanelPresetsPulldown::onAutofpsButtonClick(const LLSD& user_data)
{
setVisible(FALSE);
//LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance");
FSFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<FSFloaterPerformance>("performance");
if (performance_floater)
{
//performance_floater->showAutoadjustmentsPanel();
performance_floater->showMainPanel();
}
}

View File

@ -41,6 +41,7 @@ class LLPanelPresetsPulldown : public LLPanelPulldown
private:
void onGraphicsButtonClick(const LLSD& user_data);
void onAutofpsButtonClick(const LLSD& user_data);
void onRowClick(const LLSD& user_data);
std::list<std::string> mPresetNames;

View File

@ -1201,7 +1201,9 @@ void LLPanelProfileSecondLife::resetData()
resetLoading();
// Set default image and 1:1 dimensions for it
mSecondLifePic->setValue("Generic_Person_Large");
// <FS:Ansariel> Retain texture picker for profile images
//mSecondLifePic->setValue("Generic_Person_Large");
mSecondLifePic->setImageAssetID(LLUUID::null);
mImageId = LLUUID::null;
// <FS:Ansariel> Fix LL UI/UX design accident
@ -3030,7 +3032,9 @@ void LLPanelProfileFirstLife::apply(LLAvatarData* data)
void LLPanelProfileFirstLife::resetData()
{
setDescriptionText(std::string());
mPicture->setValue("Generic_Person_Large");
// <FS:Ansariel> Retain texture picker for profile images
//mPicture->setValue("Generic_Person_Large");
mPicture->setImageAssetID(LLUUID::null);
mImageId = LLUUID::null;
// <FS:Beq> remove the buttons and just have click image to update profile

View File

@ -1,43 +1,45 @@
/**
* @file fsperfstats.cpp
* @brief Stats collection to support perf floater and auto tune
*
* $LicenseInfo:firstyear=2021&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (C) 2021, The Phoenix Firestorm Project, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
* @file llperfstats.cpp
* @brief Statistics collection to support autotune and perf flaoter.
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "fsperfstats.h"
#include "llperfstats.h"
#include "llcontrol.h"
#include "pipeline.h"
#include "llagentcamera.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
#include "llwindow.h"
#include "llworld.h"
#include <llthread.h>
extern LLControlGroup gSavedSettings;
namespace FSPerfStats
namespace LLPerfStats
{
// <FS:Beq> extra profiling
#ifdef USAGE_TRACKING
std::atomic<int64_t> inUse{0};
std::atomic<int64_t> inUseAvatar{0};
@ -46,20 +48,24 @@ namespace FSPerfStats
std::atomic<int64_t> inUseAttachmentRigged{0};
std::atomic<int64_t> inUseAttachmentUnRigged{0};
#endif
// </FS:Beq>
std::atomic<int64_t> tunedAvatars{0};
std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
bool belowTargetFPS{false};
U32 lastGlobalPrefChange{0};
U32 lastSleepedFrame{0};
U64 meanFrameTime{0};
std::mutex bufferToggleLock{};
F64 cpu_hertz{0.0};
U32 vsync_max_fps{60};
Tunables tunables;
std::atomic<int> StatsRecorder::writeBuffer{0};
bool StatsRecorder::collectionEnabled{true};
LLUUID StatsRecorder::focusAv{LLUUID::null};
bool StatsRecorder::autotuneInit{false};
std::array<StatsRecorder::StatsTypeMatrix,2> StatsRecorder::statsDoubleBuffer{ {} };
std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::max{ {} };
std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::sum{ {} };
@ -71,46 +77,46 @@ namespace FSPerfStats
if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImpostors); };
if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); };
if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); };
if( tuningFlag & UserMinDrawDistance ){ gSavedSettings.setF32("FSAutoTuneRenderFarClipMin", userMinDrawDistance); };
if( tuningFlag & UserTargetDrawDistance ){ gSavedSettings.setF32("FSAutoTuneRenderFarClipTarget", userTargetDrawDistance); };
if( tuningFlag & UserImpostorDistance ){ gSavedSettings.setF32("FSAutoTuneImpostorFarAwayDistance", userImpostorDistance); };
if( tuningFlag & UserImpostorDistanceTuningEnabled ){ gSavedSettings.setBOOL("FSAutoTuneImpostorByDistEnabled", userImpostorDistanceTuningEnabled); };
if( tuningFlag & UserFPSTuningStrategy ){ gSavedSettings.setU32("FSTuningFPSStrategy", userFPSTuningStrategy); };
if( tuningFlag & UserAutoTuneEnabled ){ gSavedSettings.setBOOL("FSAutoTuneFPS", userAutoTuneEnabled); };
if( tuningFlag & UserAutoTuneLock ){ gSavedSettings.setBOOL("FSAutoTuneLock", userAutoTuneLock); };
if( tuningFlag & UserTargetFPS ){ gSavedSettings.setU32("FSTargetFPS", userTargetFPS); };
if( tuningFlag & UserTargetReflections ){ gSavedSettings.setS32("FSUserTargetReflections", userTargetReflections); };
if( tuningFlag & UserMinDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipMin", userMinDrawDistance); };
if( tuningFlag & UserTargetDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipTarget", userTargetDrawDistance); };
if( tuningFlag & UserImpostorDistance ){ gSavedSettings.setF32("AutoTuneImpostorFarAwayDistance", userImpostorDistance); };
if( tuningFlag & UserImpostorDistanceTuningEnabled ){ gSavedSettings.setBOOL("AutoTuneImpostorByDistEnabled", userImpostorDistanceTuningEnabled); };
if( tuningFlag & UserFPSTuningStrategy ){ gSavedSettings.setU32("TuningFPSStrategy", userFPSTuningStrategy); };
if( tuningFlag & UserAutoTuneEnabled ){ gSavedSettings.setBOOL("AutoTuneFPS", userAutoTuneEnabled); };
if( tuningFlag & UserAutoTuneLock ){ gSavedSettings.setBOOL("AutoTuneLock", userAutoTuneLock); };
if( tuningFlag & UserTargetFPS ){ gSavedSettings.setU32("TargetFPS", userTargetFPS); };
if( tuningFlag & UserTargetReflections ){ gSavedSettings.setS32("UserTargetReflections", userTargetReflections); };
// Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
if( tuningFlag & UserARTCutoff ){ gSavedSettings.setF32("FSRenderAvatarMaxART", userARTCutoffSliderValue); };
if( tuningFlag & UserARTCutoff ){ gSavedSettings.setF32("RenderAvatarMaxART", userARTCutoffSliderValue); };
resetChanges();
}
void Tunables::updateRenderCostLimitFromSettings()
{
assert_main_thread();
const auto newval = gSavedSettings.getF32("FSRenderAvatarMaxART");
if(newval < log10(FSPerfStats::ART_UNLIMITED_NANOS/1000))
{
FSPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
}
else
{
FSPerfStats::renderAvatarMaxART_ns = 0;
};
const auto newval = gSavedSettings.getF32("RenderAvatarMaxART");
if(newval < log10(LLPerfStats::ART_UNLIMITED_NANOS/1000))
{
LLPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
}
else
{
LLPerfStats::renderAvatarMaxART_ns = 0;
}
}
// static
void Tunables::updateSettingsFromRenderCostLimit()
{
if( userARTCutoffSliderValue != log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) )
if( userARTCutoffSliderValue != log10( ( (F32)LLPerfStats::renderAvatarMaxART_ns )/1000 ) )
{
if( FSPerfStats::renderAvatarMaxART_ns != 0 )
if( LLPerfStats::renderAvatarMaxART_ns != 0 )
{
updateUserARTCutoffSlider(log10( ( (F32)FSPerfStats::renderAvatarMaxART_ns )/1000 ) );
updateUserARTCutoffSlider(log10( ( (F32)LLPerfStats::renderAvatarMaxART_ns )/1000 ) );
}
else
{
updateUserARTCutoffSlider(log10( (F32)FSPerfStats::ART_UNLIMITED_NANOS/1000 ) );
updateUserARTCutoffSlider(log10( (F32)LLPerfStats::ART_UNLIMITED_NANOS/1000 ) );
}
}
}
@ -119,15 +125,29 @@ namespace FSPerfStats
{
assert_main_thread();
// the following variables are two way and have "push" in llviewercontrol
FSPerfStats::tunables.userMinDrawDistance = gSavedSettings.getF32("FSAutoTuneRenderFarClipMin");
FSPerfStats::tunables.userTargetDrawDistance = gSavedSettings.getF32("FSAutoTuneRenderFarClipTarget");
FSPerfStats::tunables.userImpostorDistance = gSavedSettings.getF32("FSAutoTuneImpostorFarAwayDistance");
FSPerfStats::tunables.userImpostorDistanceTuningEnabled = gSavedSettings.getBOOL("FSAutoTuneImpostorByDistEnabled");
FSPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("FSTuningFPSStrategy");
FSPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("FSTargetFPS");
FSPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("FSUserTargetReflections");
FSPerfStats::tunables.userAutoTuneEnabled = gSavedSettings.getBOOL("FSAutoTuneFPS");
FSPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("FSAutoTuneLock");
LLPerfStats::tunables.userMinDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipMin");
LLPerfStats::tunables.userTargetDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipTarget");
LLPerfStats::tunables.userImpostorDistance = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance");
LLPerfStats::tunables.userImpostorDistanceTuningEnabled = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled");
LLPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("TuningFPSStrategy");
LLPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("TargetFPS");
LLPerfStats::tunables.vsyncEnabled = gSavedSettings.getBOOL("RenderVSyncEnable");
LLPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("UserTargetReflections");
LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock") && gSavedSettings.getU32("KeepAutoTuneLock");
if(gSavedSettings.getBOOL("AutoTuneLock") && !gSavedSettings.getU32("KeepAutoTuneLock"))
{
gSavedSettings.setBOOL("AutoTuneLock", FALSE);
}
LLPerfStats::tunables.userAutoTuneEnabled = LLPerfStats::tunables.userAutoTuneLock;
if (LLPerfStats::tunables.userAutoTuneEnabled && !gSavedSettings.getBOOL("AutoTuneFPS"))
{
gSavedSettings.setBOOL("AutoTuneFPS", TRUE);
}
// Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
updateRenderCostLimitFromSettings();
resetChanges();
@ -138,8 +158,8 @@ namespace FSPerfStats
// create a queue
// create a thread to consume from the queue
tunables.initialiseFromSettings();
FSPerfStats::cpu_hertz = (F64)LLTrace::BlockTimer::countsPerSecond();
LLPerfStats::cpu_hertz = (F64)LLTrace::BlockTimer::countsPerSecond();
LLPerfStats::vsync_max_fps = gViewerWindow->getWindow()->getRefreshRate();
t.detach();
}
@ -150,7 +170,7 @@ namespace FSPerfStats
using ST = StatType_t;
bool unreliable{false};
FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FRAME);
LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
auto& sceneStats = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
auto& lastStats = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
@ -170,11 +190,13 @@ namespace FSPerfStats
StatType_t::RENDER_COMBINED,
StatType_t::RENDER_IDLE };
// <FS:Beq> restore FPSLimit reporting
// if( /*sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] != 0 ||*/ sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] != 0 )
if( sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] != 0 || sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] != 0 )
// </FS:Beq>
{
unreliable = true;
lastStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)];
lastStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)];// <FS:Beq/> restore FPSLimit reporting
lastStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)];
lastStats[static_cast<size_t>(StatType_t::RENDER_FRAME)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FRAME)]; // bring over the total frame render time to deal with region crossing overlap issues
}
@ -243,7 +265,7 @@ namespace FSPerfStats
}
// and now adjust the proxy vars so that the main thread can adjust the visuals.
if(tunables.userAutoTuneEnabled)
if(autotuneInit && tunables.userAutoTuneEnabled)
{
updateAvatarParams();
}
@ -307,9 +329,69 @@ namespace FSPerfStats
return positions.size();
}
const U32 NUM_PERIODS = 50;
void StatsRecorder::updateMeanFrameTime(U64 cur_frame_time_raw)
{
static std::deque<U64> frame_time_deque;
frame_time_deque.push_front(cur_frame_time_raw);
if (frame_time_deque.size() > NUM_PERIODS)
{
frame_time_deque.pop_back();
}
std::vector<U64> buf(frame_time_deque.begin(), frame_time_deque.end());
std::sort(buf.begin(), buf.end());
LLPerfStats::meanFrameTime = (buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2];
}
U64 StatsRecorder::getMeanTotalFrameTime()
{
return LLPerfStats::meanFrameTime;
}
// static
void StatsRecorder::updateAvatarParams()
{
if(tunables.autoTuneTimeout)
{
LLPerfStats::lastSleepedFrame = gFrameCount;
tunables.autoTuneTimeout = false;
return;
}
// sleep time is basically forced sleep when window out of focus
auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP);
// similar to sleep time, induced by FPS limit
auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT);// <FS:Beq/> restore FPSLimit reporting
// the time spent this frame on the "doFrame" call. Treated as "tot time for frame"
auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
if( tot_sleep_time_raw != 0 )
{
// Note: we do not average sleep
// if at some point we need to, the averaging will need to take this into account or
// we forever think we're in the background due to residuals.
LL_DEBUGS() << "No tuning when not in focus" << LL_ENDL;
LLPerfStats::lastSleepedFrame = gFrameCount;
return;
}
U32 target_fps = tunables.vsyncEnabled ? std::min(LLPerfStats::vsync_max_fps, tunables.userTargetFPS) : tunables.userTargetFPS;
if(LLPerfStats::lastSleepedFrame != 0)
{
// wait a short time after viewer regains focus
if((gFrameCount - LLPerfStats::lastSleepedFrame) > target_fps * 5)
{
LLPerfStats::lastSleepedFrame = 0;
}
else
{
return;
}
}
updateMeanFrameTime(tot_frame_time_raw);
if(tunables.userImpostorDistanceTuningEnabled)
{
@ -323,46 +405,39 @@ namespace FSPerfStats
}
}
auto av_render_max_raw = FSPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, FSPerfStats::StatType_t::RENDER_COMBINED);
auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
// Is our target frame time lower than current? If so we need to take action to reduce draw overheads.
// cumulative avatar time (includes idle processing, attachments and base av)
auto tot_avatar_time_raw = FSPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, FSPerfStats::StatType_t::RENDER_COMBINED);
// sleep time is basically forced sleep when window out of focus
auto tot_sleep_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_SLEEP);
// similar to sleep time, induced by FPS limit
auto tot_limit_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FPSLIMIT);
// the time spent this frame on the "doFrame" call. Treated as "tot time for frame"
auto tot_frame_time_raw = FSPerfStats::StatsRecorder::getSceneStat(FSPerfStats::StatType_t::RENDER_FRAME);
if( tot_sleep_time_raw != 0 )
{
// Note: we do not average sleep
// if at some point we need to, the averaging will need to take this into account or
// we forever think we're in the background due to residuals.
LL_DEBUGS() << "No tuning when not in focus" << LL_ENDL;
return;
}
auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
// The frametime budget we have based on the target FPS selected
auto target_frame_time_raw = (U64)llround(FSPerfStats::cpu_hertz/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps));
// LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
auto inferredFPS{1000/(U32)std::max(raw_to_ms(tot_frame_time_raw),1.0)};
U32 settingsChangeFrequency{inferredFPS > 25?inferredFPS:25};
if( tot_limit_time_raw != 0)
U32 settingsChangeFrequency{inferredFPS > 50?inferredFPS:50};
if( tot_limit_time_raw != 0)// <FS:Beq/> restore FPSLimit reporting
{
// This could be problematic.
tot_frame_time_raw -= tot_limit_time_raw;
}
}// <FS:Beq/> restore FPSLimit reporting
F64 time_buf = target_frame_time_raw * 0.1;
// 1) Is the target frame time lower than current?
if( target_frame_time_raw <= tot_frame_time_raw )
if ((target_frame_time_raw + time_buf) <= tot_frame_time_raw)
{
if (target_frame_time_raw - time_buf >= getMeanTotalFrameTime())
{
belowTargetFPS = false;
LLPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
if(belowTargetFPS == false)
{
// this is the first frame under. hold fire to add a little hysteresis
belowTargetFPS = true;
FSPerfStats::lastGlobalPrefChange = gFrameCount;
LLPerfStats::lastGlobalPrefChange = gFrameCount;
}
// if so we've got work to do
@ -374,16 +449,16 @@ namespace FSPerfStats
if(target_frame_time_raw < non_avatar_time_raw)
{
// we cannnot do this by avatar adjustment alone.
if((gFrameCount - FSPerfStats::lastGlobalPrefChange) > settingsChangeFrequency) // give changes a short time to take effect.
if((gFrameCount - LLPerfStats::lastGlobalPrefChange) > settingsChangeFrequency) // give changes a short time to take effect.
{
if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY)
{
// 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
// the other reflection options make comparatively little change and if this overshoots we'll be stepping back up later
if(LLPipeline::RenderReflectionDetail != -2)
{
FSPerfStats::tunables.updateReflectionDetail(-2);
FSPerfStats::lastGlobalPrefChange = gFrameCount;
LLPerfStats::tunables.updateReflectionDetail(-2);
LLPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
else // deliberately "else" here so we only do one of these in any given frame
@ -392,8 +467,8 @@ namespace FSPerfStats
auto new_dd = (LLPipeline::RenderFarClip - DD_STEP > tunables.userMinDrawDistance)?(LLPipeline::RenderFarClip - DD_STEP) : tunables.userMinDrawDistance;
if(new_dd != LLPipeline::RenderFarClip)
{
FSPerfStats::tunables.updateFarClip( new_dd );
FSPerfStats::lastGlobalPrefChange = gFrameCount;
LLPerfStats::tunables.updateFarClip( new_dd );
LLPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
}
@ -414,19 +489,19 @@ namespace FSPerfStats
target_avatar_time_raw = target_frame_time_raw - non_avatar_time_raw;
}
if( target_avatar_time_raw < tot_avatar_time_raw )
if ((target_avatar_time_raw < tot_avatar_time_raw) && (tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY))
{
// we need to spend less time drawing avatars to meet our budget
auto new_render_limit_ns {FSPerfStats::raw_to_ns(av_render_max_raw)};
auto new_render_limit_ns {LLPerfStats::raw_to_ns(av_render_max_raw)};
// max render this frame may be higher than the last (cos new entrants and jitter) so make sure we are heading in the right direction
if( new_render_limit_ns > renderAvatarMaxART_ns )
{
new_render_limit_ns = renderAvatarMaxART_ns;
}
new_render_limit_ns -= FSPerfStats::ART_MIN_ADJUST_DOWN_NANOS;
new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS;
// bounce at the bottom to prevent "no limit"
new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)FSPerfStats::ART_MINIMUM_NANOS);
new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)LLPerfStats::ART_MINIMUM_NANOS);
// assign the new value
if(renderAvatarMaxART_ns != new_render_limit_ns)
@ -436,9 +511,10 @@ namespace FSPerfStats
}
// LL_DEBUGS() << "AUTO_TUNE: avatar_budget adjusted to:" << new_render_limit_ns << LL_ENDL;
}
// LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< FSPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << FSPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL;
// LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< LLPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << LLPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL;
}
else if( FSPerfStats::raw_to_ns(target_frame_time_raw) > (FSPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) )
else if(( LLPerfStats::raw_to_ns(target_frame_time_raw) > (LLPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) ) ||
(tunables.vsyncEnabled && (target_fps == LLPerfStats::vsync_max_fps) && (target_frame_time_raw > getMeanTotalFrameTime())))
{
if(belowTargetFPS == true)
{
@ -456,28 +532,29 @@ namespace FSPerfStats
// turn off if we are not locked.
tunables.updateUserAutoTuneEnabled(false);
}
if( FSPerfStats::tunedAvatars > 0 )
if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 && (tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY) )
{
// if we have more time to spare let's shift up little in the hope we'll restore an avatar.
renderAvatarMaxART_ns += FSPerfStats::ART_MIN_ADJUST_UP_NANOS;
U64 up_step = LLPerfStats::tunedAvatars > 2 ? LLPerfStats::ART_MIN_ADJUST_UP_NANOS : LLPerfStats::ART_MIN_ADJUST_UP_NANOS * 2;
renderAvatarMaxART_ns += up_step;
tunables.updateSettingsFromRenderCostLimit();
return;
}
if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY)
{
if( LLPipeline::RenderFarClip < tunables.userTargetDrawDistance )
{
FSPerfStats::tunables.updateFarClip( std::min(LLPipeline::RenderFarClip + DD_STEP, tunables.userTargetDrawDistance) );
FSPerfStats::lastGlobalPrefChange = gFrameCount;
LLPerfStats::tunables.updateFarClip( std::min(LLPipeline::RenderFarClip + DD_STEP, tunables.userTargetDrawDistance) );
LLPerfStats::lastGlobalPrefChange = gFrameCount;
return;
}
if( (tot_frame_time_raw * 1.5) < target_frame_time_raw )
{
// if everything else is "max" and we have >50% headroom let's knock the water quality up a notch at a time.
FSPerfStats::tunables.updateReflectionDetail( std::min(LLPipeline::RenderReflectionDetail + 1, tunables.userTargetReflections) );
LLPerfStats::tunables.updateReflectionDetail( std::min(LLPipeline::RenderReflectionDetail + 1, tunables.userTargetReflections) );
}
}
}
}
}
}
}

View File

@ -1,32 +1,31 @@
#pragma once
#ifndef FS_PERFSTATS_H_INCLUDED
#define FS_PERFSTATS_H_INCLUDED
/**
* @file fsperfstats.h
* @brief Statistics collection to support autotune and perf flaoter.
*
* $LicenseInfo:firstyear=2021&license=fsviewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (C) 2021, The Phoenix Firestorm Project, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
* http://www.firestormviewer.org
* $/LicenseInfo$
*/
* @file llperfstats.h
* @brief Statistics collection to support autotune and perf flaoter.
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#pragma once
#ifndef LL_PERFSTATS_H_INCLUDED
#define LL_PERFSTATS_H_INCLUDED
#include <atomic>
#include <chrono>
@ -35,12 +34,12 @@
#include <mutex>
#include "lluuid.h"
#include "llfasttimer.h"
#include "blockingconcurrentqueue.h"
#include "blockingconcurrentqueue.h" // <FS:Beq/> reinstate faster queues
#include "llapp.h"
#include "llprofiler.h"
#include "pipeline.h"
// Additional logging options. These can skew inworld numbers so onyl use for debugging and tracking issues
// <FS:Beq> Additional logging options. These can skew inworld numbers so onyl use for debugging and tracking issues
#ifdef TRACY_ENABLE
// USAGE_TRACKING - displays overlapping stats that may imply double counting.
// ATTACHMENT_TRACKING - displays detailed tracking info for Avatar and Attachment. very heavy overhead.
@ -50,11 +49,12 @@
#undef USAGE_TRACKING
#undef ATTACHMENT_TRACKING
#endif
// </FS:Beq>
extern U32 gFrameCount;
extern LLUUID gAgentID;
namespace FSPerfStats
namespace LLPerfStats
{
// <FS:Beq> Additional logging options. These can skew inworld numbers so onyl use for debugging and tracking issues
#ifdef USAGE_TRACKING
extern std::atomic<int64_t> inUse;
extern std::atomic<int64_t> inUseAvatar;
@ -63,10 +63,11 @@ namespace FSPerfStats
extern std::atomic<int64_t> inUseAttachmentRigged;
extern std::atomic<int64_t> inUseAttachmentUnRigged;
#endif
// </FS:Beq>
// Note if changing these, they should correspond with the log range of the correpsonding sliders
static constexpr U64 ART_UNLIMITED_NANOS{50000000};
static constexpr U64 ART_MINIMUM_NANOS{100000};
static constexpr U64 ART_MIN_ADJUST_UP_NANOS{10000};
static constexpr U64 ART_MIN_ADJUST_UP_NANOS{5000};
static constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000};
static constexpr F32 PREFERRED_DD{180};
@ -75,6 +76,7 @@ namespace FSPerfStats
static constexpr U32 TUNE_AVATARS_ONLY{0};
static constexpr U32 TUNE_SCENE_AND_AVATARS{1};
static constexpr U32 TUNE_SCENE_ONLY{2};
extern F64 cpu_hertz;
@ -82,6 +84,8 @@ namespace FSPerfStats
extern std::atomic<U64> renderAvatarMaxART_ns;
extern bool belowTargetFPS;
extern U32 lastGlobalPrefChange;
extern U32 lastSleepedFrame;
extern U64 meanFrameTime;
extern std::mutex bufferToggleLock;
enum class ObjType_t{
@ -103,7 +107,7 @@ namespace FSPerfStats
RENDER_SLEEP,
RENDER_LFS,
RENDER_MESHREPO,
RENDER_FPSLIMIT,
RENDER_FPSLIMIT,// <FS:Beq/> restore this for FS
RENDER_FPS,
RENDER_IDLE,
RENDER_DONE, // toggle buffer & clearbuffer (see processUpdate for hackery)
@ -154,6 +158,8 @@ namespace FSPerfStats
U32 userTargetFPS{0};
F32 userARTCutoffSliderValue{0};
S32 userTargetReflections{0};
bool autoTuneTimeout{true};
bool vsyncEnabled{true};
void updateNonImposters(U32 nv){nonImpostors=nv; tuningFlag |= NonImpostors;};
void updateReflectionDetail(S32 nv){reflectionDetail=nv; tuningFlag |= ReflectionDetail;};
@ -179,7 +185,10 @@ namespace FSPerfStats
extern Tunables tunables;
class StatsRecorder{
// <FS:Beq> we don't want to be using lock based queues
// using Queue = LLThreadSafeQueue<StatsRecord>;
using Queue = moodycamel::BlockingConcurrentQueue<StatsRecord>;
// </FS:Beq>
public:
static inline StatsRecorder& getInstance()
@ -189,10 +198,15 @@ namespace FSPerfStats
}
static inline void setFocusAv(const LLUUID& avID){focusAv = avID;};
static inline const LLUUID& getFocusAv(){return focusAv;};
static inline void setAutotuneInit(){autotuneInit = true;};
// <FS:Beq> We do not want to use lock based queues
// static inline void send(StatsRecord && upd){StatsRecorder::getInstance().q.pushFront(std::move(upd));};
// static void endFrame(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});};
// static void clearStats(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});};
static inline void send(StatsRecord && upd){StatsRecorder::getInstance().q.enqueue(std::move(upd));};
static void endFrame(){StatsRecorder::getInstance().q.enqueue(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});};
static void clearStats(){StatsRecorder::getInstance().q.enqueue(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});};
// </FS:Beq>
static inline void setEnabled(bool on_or_off){collectionEnabled=on_or_off;};
static inline void enable() { collectionEnabled=true; };
static inline void disable() { collectionEnabled=false; };
@ -222,14 +236,17 @@ namespace FSPerfStats
StatsRecorder();
static int countNearbyAvatars(S32 distance);
static U64 getMeanTotalFrameTime();
static void updateMeanFrameTime(U64 tot_frame_time_raw);
// StatsArray is a uint64_t for each possible statistic type.
using StatsArray = std::array<uint64_t, static_cast<size_t>(FSPerfStats::StatType_t::STATS_COUNT)>;
using StatsMap = std::unordered_map<LLUUID, StatsArray, FSUUIDHash>;
using StatsTypeMatrix = std::array<StatsMap, static_cast<size_t>(FSPerfStats::ObjType_t::OT_COUNT)>;
using StatsSummaryArray = std::array<StatsArray, static_cast<size_t>(FSPerfStats::ObjType_t::OT_COUNT)>;
using StatsArray = std::array<uint64_t, static_cast<size_t>(LLPerfStats::StatType_t::STATS_COUNT)>;
using StatsMap = std::unordered_map<LLUUID, StatsArray, FSUUIDHash>; // <FS:Beq/>
using StatsTypeMatrix = std::array<StatsMap, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>;
using StatsSummaryArray = std::array<StatsArray, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>;
static std::atomic<int> writeBuffer;
static LLUUID focusAv;
static bool autotuneInit;
static std::array<StatsTypeMatrix,2> statsDoubleBuffer;
static std::array<StatsSummaryArray,2> max;
static std::array<StatsSummaryArray,2> sum;
@ -264,12 +281,13 @@ namespace FSPerfStats
auto& avKey{upd.avID};
auto type {upd.statType};
auto val {upd.time};
// <FS:Beq> markup to support coverage testing on stats collection
#ifdef TRACY_ENABLE
LL_PROFILE_ZONE_TEXT(key.toStringFast(obstr), 36);
LL_PROFILE_ZONE_TEXT(avKey.toStringFast(avstr), 36);
LL_PROFILE_ZONE_NUM(val);
#endif
// </FS:Beq>
if (ot == ObjType_t::OT_GENERAL)
{
@ -346,8 +364,24 @@ namespace FSPerfStats
while( enabled() && !LLApp::isExiting() )
{
// <FS:Beq> We don't want these queues
// auto count = 0;
// while (count < 10)
// {
// if (instance.q.tryPopFor(std::chrono::milliseconds(10), upd[count]))
// {
// count++;
// }
// else
// {
// break;
// }
// }
// //LL_PROFILER_THREAD_BEGIN("PerfStats");
auto count = instance.q.wait_dequeue_bulk_timed(upd, 10, std::chrono::milliseconds(10));
LL_PROFILER_THREAD_BEGIN("PerfStats");
// </FS:Beq>
if(count)
{
// LL_INFOS("perfstats") << "processing " << count << " updates." << LL_ENDL;
@ -356,7 +390,7 @@ namespace FSPerfStats
instance.processUpdate(upd[i]);
}
}
LL_PROFILER_THREAD_END("PerfStats");
LL_PROFILER_THREAD_END("PerfStats"); // <FS:Beq/>
}
}
@ -384,29 +418,35 @@ namespace FSPerfStats
start{LLTrace::BlockTimer::getCPUClockCount64()},
stat{type, ObjTypeDiscriminator, std::move(av), std::move(id), 0, isRiggedAtt, isHUDAtt}
{
// <FS:Beq> extra profiling coverage tracking
// LL_PROFILE_ZONE_COLOR(tracy::Color::Orange);
LL_PROFILE_ZONE_COLOR(tracy::Color::Orange);
#ifdef USAGE_TRACKING
if(stat.objType == FSPerfStats::ObjType_t::OT_ATTACHMENT)
{
if(!stat.isRigged && FSPerfStats::inUseAvatar){LL_PROFILE_ZONE_TEXT("OVERLAP AVATAR",14);}
LL_PROFILE_PLOT_CONFIG_SQUARE("InUse");
LL_PROFILE_PLOT_CONFIG_SQUARE("InUseAttachment");
LL_PROFILE_PLOT_CONFIG_SQUARE("InUseAttachmentRigged");
LL_PROFILE_PLOT_CONFIG_SQUARE("InUseAttachmentUnRigged");
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse, (int64_t)FSPerfStats::inUse+1);
if(!stat.isRigged && FSPerfStats::inUseAvatar){LL_PROFILE_ZONE_TEXT("OVERLAP AVATAR",14);}
FSPerfStats::inUse++;
LL_PROFILE_PLOT_SQ("InUseAttachment", (int64_t)FSPerfStats::inUseAttachment, (int64_t)FSPerfStats::inUseAttachment+1);
LL_PROFILE_PLOT("InUse", (int64_t)FSPerfStats::inUse);
FSPerfStats::inUseAttachment++;
LL_PROFILE_PLOT("InUseAttachment", (int64_t)FSPerfStats::inUseAttachment);
if (stat.isRigged)
{
LL_PROFILE_PLOT_SQ("InUseAttachmentRigged", (int64_t)FSPerfStats::inUseAttachmentRigged,(int64_t)FSPerfStats::inUseAttachmentRigged+1);
FSPerfStats::inUseAttachmentRigged++;
LL_PROFILE_PLOT("InUseAttachmentRigged", (int64_t)FSPerfStats::inUseAttachmentRigged);
}
else
{
LL_PROFILE_PLOT_SQ("InUseAttachmentUnRigged", (int64_t)FSPerfStats::inUseAttachmentUnRigged,(int64_t)FSPerfStats::inUseAttachmentUnRigged+1);
FSPerfStats::inUseAttachmentUnRigged++;
LL_PROFILE_PLOT("InUseAttachmentUnRigged", (int64_t)FSPerfStats::inUseAttachmentUnRigged);
}
}
#endif
// </FS:Beq>
};
template < ObjType_t OD = ObjTypeDiscriminator,
@ -414,71 +454,75 @@ namespace FSPerfStats
explicit RecordTime( StatType_t type ):RecordTime<ObjTypeDiscriminator>(LLUUID::null, LLUUID::null, type )
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
// <FS:Beq> extra profiling coverage tracking
#ifdef USAGE_TRACKING
LL_PROFILE_PLOT_SQ("InUseScene", (int64_t)FSPerfStats::inUseScene, (int64_t)FSPerfStats::inUseScene+1);
FSPerfStats::inUseScene++;
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse, (int64_t)FSPerfStats::inUse+1);
FSPerfStats::inUse++;
LLPerfStats::inUseScene++;
LL_PROFILE_PLOT("InUseScene", (int64_t)LLPerfStats::inUseScene);
LLPerfStats::inUse++;
LL_PROFILE_PLOT("InUse", (int64_t)LLPerfStats::inUse);
#endif
// </FS:Beq>
};
template < ObjType_t OD = ObjTypeDiscriminator,
std::enable_if_t<OD == ObjType_t::OT_AVATAR> * = nullptr>
RecordTime( const LLUUID & av, StatType_t type ):RecordTime<ObjTypeDiscriminator>(std::move(av), LLUUID::null, type)
{
// <FS:Beq> extra profiling coverage tracking
// LL_PROFILE_ZONE_COLOR(tracy::Color::Purple)
LL_PROFILE_ZONE_COLOR(tracy::Color::Purple);
#ifdef USAGE_TRACKING
if(FSPerfStats::inUseAvatar){LL_PROFILE_ZONE_TEXT("OVERLAP AVATAR",14);}
LL_PROFILE_PLOT_SQ("InUseAv", (int64_t)FSPerfStats::inUseAvatar, (int64_t)FSPerfStats::inUseAvatar+1);
if(LLPerfStats::inUseAvatar){LL_PROFILE_ZONE_TEXT("OVERLAP AVATAR",14);}
FSPerfStats::inUseAvatar++;
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse, (int64_t)FSPerfStats::inUse+1);
FSPerfStats::inUse++;
LL_PROFILE_PLOT("InUseAv", (int64_t)LLPerfStats::inUseAvatar);
LLPerfStats::inUse++;
LL_PROFILE_PLOT("InUse", (int64_t)LLPerfStats::inUse);
#endif
// </FS:Beq>
};
~RecordTime()
{
if(!FSPerfStats::StatsRecorder::enabled())
if(!LLPerfStats::StatsRecorder::enabled())
{
return;
}
LL_PROFILE_ZONE_COLOR(tracy::Color::Red);
//LL_PROFILE_ZONE_COLOR(tracy::Color::Red);
// <FS:Beq> extra profiling coverage tracking
#ifdef USAGE_TRACKING
LL_PROFILE_PLOT_SQ("InUse", (int64_t)FSPerfStats::inUse,(int64_t)FSPerfStats::inUse-1);
--FSPerfStats::inUse;
LL_PROFILE_PLOT("InUse", (int64_t)FSPerfStats::inUse);
if (stat.objType == FSPerfStats::ObjType_t::OT_ATTACHMENT)
{
LL_PROFILE_PLOT_SQ("InUseAttachment", (int64_t)FSPerfStats::inUseAttachment,(int64_t)FSPerfStats::inUseAttachment-1);
--FSPerfStats::inUseAttachment;
LL_PROFILE_PLOT("InUseAttachment", (int64_t)FSPerfStats::inUseAttachment);
if (stat.isRigged)
{
LL_PROFILE_PLOT_SQ("InUseAttachmentRigged", (int64_t)FSPerfStats::inUseAttachmentRigged,(int64_t)FSPerfStats::inUseAttachmentRigged-1);
--FSPerfStats::inUseAttachmentRigged;
LL_PROFILE_PLOT("InUseAttachmentRigged", (int64_t)FSPerfStats::inUseAttachmentRigged);
}
else
{
LL_PROFILE_PLOT_SQ("InUseAttachmentUnRigged", (int64_t)FSPerfStats::inUseAttachmentUnRigged,(int64_t)FSPerfStats::inUseAttachmentUnRigged-1);
--FSPerfStats::inUseAttachmentUnRigged;
LL_PROFILE_PLOT("InUseAttachmentUnRigged", (int64_t)FSPerfStats::inUseAttachmentUnRigged);
}
}
if (stat.objType == FSPerfStats::ObjType_t::OT_GENERAL)
{
LL_PROFILE_PLOT_SQ("InUseScene", (int64_t)FSPerfStats::inUseScene,(int64_t)FSPerfStats::inUseScene-1);
--FSPerfStats::inUseScene;
LL_PROFILE_PLOT("InUseScene", (int64_t)FSPerfStats::inUseScene);
}
if( stat.objType == FSPerfStats::ObjType_t::OT_AVATAR )
{
LL_PROFILE_PLOT_SQ("InUseAv", (int64_t)FSPerfStats::inUseAvatar, (int64_t)FSPerfStats::inUseAvatar-1);
--FSPerfStats::inUseAvatar;
LL_PROFILE_PLOT("InUseAv", (int64_t)FSPerfStats::inUseAvatar);
}
#endif
// </FS:Beq>
stat.time = LLTrace::BlockTimer::getCPUClockCount64() - start;
// <FS:Beq> extra profiling coverage tracking
#ifdef ATTACHMENT_TRACKING
static char obstr[36];
static char avstr[36];
@ -487,26 +531,25 @@ namespace FSPerfStats
LL_PROFILE_ZONE_TEXT(stat.objID.toStringFast(obstr), 36);
LL_PROFILE_ZONE_NUM(stat.time);
#endif
// </FS:Beq>
StatsRecorder::send(std::move(stat));
};
};
inline double raw_to_ns(U64 raw) { return (static_cast<double>(raw) * 1000000000.0) / FSPerfStats::cpu_hertz; };
inline double raw_to_us(U64 raw) { return (static_cast<double>(raw) * 1000000.0) / FSPerfStats::cpu_hertz; };
inline double raw_to_ms(U64 raw) { return (static_cast<double>(raw) * 1000.0) / FSPerfStats::cpu_hertz; };
inline double raw_to_ns(U64 raw) { return (static_cast<double>(raw) * 1000000000.0) / LLPerfStats::cpu_hertz; };
inline double raw_to_us(U64 raw) { return (static_cast<double>(raw) * 1000000.0) / LLPerfStats::cpu_hertz; };
inline double raw_to_ms(U64 raw) { return (static_cast<double>(raw) * 1000.0) / LLPerfStats::cpu_hertz; };
using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;
using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>;
using RecordAttachmentTime = RecordTime<ObjType_t::OT_ATTACHMENT>;
using RecordHudAttachmentTime = RecordTime<ObjType_t::OT_HUD>;
};// namespace FSPerfStats
};// namespace LLPerfStats
// helper functions
using RATptr = std::unique_ptr<FSPerfStats::RecordAttachmentTime>;
using RSTptr = std::unique_ptr<FSPerfStats::RecordSceneTime>;
using RATptr = std::unique_ptr<LLPerfStats::RecordAttachmentTime>;
using RSTptr = std::unique_ptr<LLPerfStats::RecordSceneTime>;
template <typename T>
static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPtrp)
@ -530,6 +573,7 @@ static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPt
auto& obj = rootAtt->getAttachmentItemID();
if (!*ratPtrp || (*ratPtrp)->stat.objID != obj || (*ratPtrp)->stat.avID != av)
{
// <FS:Beq> extra profiling coverage tracking
#if TRACY_ENABLE && defined(ATTACHMENT_TRACKING)
LL_PROFILE_ZONE_NAMED_COLOR( "trackAttachments:new", tracy::Color::Red);
auto& str = rootAtt->getAttachmentItemName();
@ -542,15 +586,16 @@ static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPt
LL_PROFILE_ZONE_TEXT( avStr, 36);
LL_PROFILE_ZONE_TEXT( obStr, 4);
#endif
// </FS:Beq>
if (*ratPtrp)
{
// deliberately reset to ensure destruction before construction of replacement.
ratPtrp->reset();
};
*ratPtrp = std::make_unique<FSPerfStats::RecordAttachmentTime>(
*ratPtrp = std::make_unique<LLPerfStats::RecordAttachmentTime>(
av,
obj,
( LLPipeline::sShadowRender?FSPerfStats::StatType_t::RENDER_SHADOWS : FSPerfStats::StatType_t::RENDER_GEOMETRY ),
( LLPipeline::sShadowRender?LLPerfStats::StatType_t::RENDER_SHADOWS : LLPerfStats::StatType_t::RENDER_GEOMETRY ),
isRigged,
rootAtt->isHUDAttachment());
}
@ -558,4 +603,4 @@ static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPt
return;
};
#endif
#endif

View File

@ -42,7 +42,7 @@
#include "llagentcamera.h"
#include "llfile.h"
#include "quickprefs.h"
#include "fsperfstats.h" // <FS:Beq/> avoid triggering reloads while autotuning
#include "llperfstats.h"
LLPresetsManager::LLPresetsManager()
// <FS:Ansariel> Graphic preset controls independent from XUI
@ -723,7 +723,7 @@ void LLPresetsManager::handleGraphicPresetControlChanged(LLControlVariablePtr co
if (!mIsLoadingPreset &&
(!mIsDrawDistanceSteppingActive || control->getName() != "RenderFarClip") &&
(!FSPerfStats::tunables.userAutoTuneEnabled) )
(!LLPerfStats::tunables.userAutoTuneEnabled) )
{
LL_DEBUGS() << "Trigger graphic preset control changed signal" << LL_ENDL;

View File

@ -212,8 +212,8 @@
#include "llenvironment.h"
#include "llstacktrace.h"
#include "fsperfstats.h"
#include "threadpool.h"
#include "llperfstats.h"
#if LL_WINDOWS
@ -2217,9 +2217,8 @@ bool idle_startup()
update_static_eyes();
// </FS:KC>
// <FS:Beq>
gAgent.addRegionChangedCallback(boost::bind(&FSPerfStats::StatsRecorder::clearStats));
// </FS:Beq>
gAgent.addRegionChangedCallback(boost::bind(&LLPerfStats::StatsRecorder::clearStats));
// *Note: this is where gWorldMap used to be initialized.
@ -3086,7 +3085,7 @@ bool idle_startup()
if (STATE_CLEANUP == LLStartUp::getStartupState())
{
set_startup_status(1.0, "", "");
set_startup_status(1.0, "", "");
display_startup();
if (!mBenefitsSuccessfullyInit)
@ -3213,6 +3212,8 @@ bool idle_startup()
LLUIUsage::instance().clear();
LLPerfStats::StatsRecorder::setAutotuneInit();
// <FS:Techwolf Lupindo> FIRE-6643 Display MOTD when login screens are disabled
if (gSavedSettings.getBOOL("FSDisableLoginScreens"))
{
@ -4389,10 +4390,6 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
// unpack login data needed by the application
text = response["agent_id"].asString();
if(!text.empty()) gAgentID.set(text);
// <FS:Beq> Performance floater initialisation
FSPerfStats::StatsRecorder::setEnabled(gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled"));
FSPerfStats::StatsRecorder::setFocusAv(gAgentID);
// </FS:Beq>
// gDebugInfo["AgentID"] = text;
// [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b
if (gCrashSettings.getBOOL("CrashSubmitName"))
@ -4402,6 +4399,9 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
}
// [/SL:KB]
LLPerfStats::StatsRecorder::setEnabled(gSavedSettings.getBOOL("PerfStatsCaptureEnabled"));
LLPerfStats::StatsRecorder::setFocusAv(gAgentID);
// Agent id needed for parcel info request in LLUrlEntryParcel
// to resolve parcel name.
LLUrlEntryParcel::setAgentID(gAgentID);

View File

@ -44,6 +44,7 @@
#include "llagent.h" // HACK for destinations guide on startup
#include "llfloaterreg.h" // HACK for destinations guide on startup
#include "llviewercontrol.h" // HACK for destinations guide on startup
#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX
#include <boost/foreach.hpp>
@ -382,6 +383,25 @@ bool LLToolBarView::loadToolbars(bool force_default)
}
}
}
// SL-18581: Don't show the starter avatar toolbar button for NUX users
LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
if (gAgent.isFirstLogin())
{
LL_WARNS() << "First login: checking for NUX user." << LL_ENDL;
if (my_outfits_cat != NULL && my_outfits_cat->getDescendentCount() > 0)
{
LL_WARNS() << "First login: My Outfits folder is not empty, removing the avatar picker button." << LL_ENDL;
for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
if (mToolbars[i])
{
mToolbars[i]->removeCommand(LLCommandId("avatar"));
}
}
}
}
mToolbarsLoaded = true;
return true;
}

View File

@ -85,6 +85,7 @@
#include "llspellcheck.h"
#include "llslurl.h"
#include "llstartup.h"
#include "llperfstats.h"
// [RLVa:KB] - Checked: 2015-12-27 (RLVa-1.5.0)
#include "llvisualeffect.h"
#include "rlvactions.h"
@ -112,7 +113,6 @@
#include "llviewerregion.h"
#include "NACLantispam.h"
#include "nd/ndlogthrottle.h"
#include "fsperfstats.h"
// <FS:Zi> Run Prio 0 default bento pose in the background to fix splayed hands, open mouths, etc.
#include "llanimationstates.h"
@ -259,6 +259,12 @@ bool handleSetShaderChanged(const LLSD& newvalue)
return true;
}
static bool handleShadowDetailChanged(const LLSD& newvalue)
{
gPipeline.handleShadowDetailChanged();
return true;
}
static bool handleRenderPerfTestChanged(const LLSD& newvalue)
{
bool status = !newvalue.asBoolean();
@ -353,8 +359,15 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
static bool handleVSyncChanged(const LLSD& newvalue)
{
LLPerfStats::tunables.vsyncEnabled = newvalue.asBoolean();
gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean());
if(newvalue.asBoolean() == true)
{
U32 current_target = gSavedSettings.getU32("TargetFPS");
gSavedSettings.setU32("TargetFPS", std::min((U32)gViewerWindow->getWindow()->getRefreshRate(), current_target));
}
return true;
}
@ -1074,68 +1087,76 @@ void handleDiskCacheSizeChanged(const LLSD& newValue)
}
// </FS:Ansariel>
// <FS:Beq> perrf floater stuffs
void handleTargetFPSChanged(const LLSD& newValue)
{
const auto targetFPS = gSavedSettings.getU32("FSTargetFPS");
FSPerfStats::tunables.userTargetFPS = targetFPS;
}
// <FS:Beq> perf floater stuffs
void handleAutoTuneLockChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("FSAutoTuneLock");
FSPerfStats::tunables.userAutoTuneLock = newval;
const auto targetFPS = gSavedSettings.getU32("TargetFPS");
U32 frame_rate_limit = gViewerWindow->getWindow()->getRefreshRate();
if(LLPerfStats::tunables.vsyncEnabled && (targetFPS > frame_rate_limit))
{
gSavedSettings.setU32("TargetFPS", std::min(frame_rate_limit, targetFPS));
}
else
{
LLPerfStats::tunables.userTargetFPS = targetFPS;
}
}
void handleAutoTuneLockChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("AutoTuneLock");
LLPerfStats::tunables.userAutoTuneLock = newval;
gSavedSettings.setBOOL("AutoTuneFPS", newval);
}
// <FS:Beq> perrf floater stuffs
void handleAutoTuneFPSChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("FSAutoTuneFPS");
FSPerfStats::tunables.userAutoTuneEnabled = newval;
if(newval && FSPerfStats::renderAvatarMaxART_ns == 0) // If we've enabled autotune we override "unlimited" to max
{
gSavedSettings.setF32("FSRenderAvatarMaxART",log10(FSPerfStats::ART_UNLIMITED_NANOS-1000));//triggers callback to update static var
}
const auto newval = gSavedSettings.getBOOL("AutoTuneFPS");
LLPerfStats::tunables.userAutoTuneEnabled = newval;
if(newval && LLPerfStats::renderAvatarMaxART_ns == 0) // If we've enabled autotune we override "unlimited" to max
{
gSavedSettings.setF32("RenderAvatarMaxART",log10(LLPerfStats::ART_UNLIMITED_NANOS-1000));//triggers callback to update static var
}
}
void handleRenderAvatarMaxARTChanged(const LLSD& newValue)
{
FSPerfStats::tunables.updateRenderCostLimitFromSettings();
LLPerfStats::tunables.updateRenderCostLimitFromSettings();
}
void handleUserTargetDrawDistanceChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getF32("FSAutoTuneRenderFarClipTarget");
FSPerfStats::tunables.userTargetDrawDistance = newval;
const auto newval = gSavedSettings.getF32("AutoTuneRenderFarClipTarget");
LLPerfStats::tunables.userTargetDrawDistance = newval;
}
void handleUserTargetReflectionsChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getS32("FSUserTargetReflections");
FSPerfStats::tunables.userTargetReflections = newval;
const auto newval = gSavedSettings.getS32("UserTargetReflections");
LLPerfStats::tunables.userTargetReflections = newval;
}
void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled");
FSPerfStats::StatsRecorder::setEnabled(newval);
const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled");
LLPerfStats::StatsRecorder::setEnabled(newval);
}
void handleUserImpostorByDistEnabledChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("FSAutoTuneImpostorByDistEnabled");
FSPerfStats::tunables.userImpostorDistanceTuningEnabled = newval;
const auto newval = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled");
LLPerfStats::tunables.userImpostorDistanceTuningEnabled = newval;
}
void handleUserImpostorDistanceChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getF32("FSAutoTuneImpostorFarAwayDistance");
FSPerfStats::tunables.userImpostorDistance = newval;
const auto newval = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance");
LLPerfStats::tunables.userImpostorDistance = newval;
}
void handleFPSTuningStrategyChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getU32("FSTuningFPSStrategy");
FSPerfStats::tunables.userFPSTuningStrategy = newval;
const auto newval = gSavedSettings.getU32("TuningFPSStrategy");
LLPerfStats::tunables.userFPSTuningStrategy = newval;
}
// </FS:Beq>
// <FS:Ansariel> FIRE-6809: Quickly moving the bandwidth slider has no effect
void handleBandwidthChanged(const LLSD& newValue)
@ -1188,146 +1209,147 @@ void setting_setup_signal_listener(LLControlGroup& group, const std::string& set
void settings_setup_listeners()
{
setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
// [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4
setting_setup_signal_listener(gSavedSettings, "RenderResolutionMultiplier", handleRenderResolutionDivisorChanged);
// [/SL:KB]
setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged);
setting_setup_signal_listener(gSavedSettings, "ChatConsoleFontSize", handleChatFontSizeChanged);
setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged);
setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged);
setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged);
setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged);
setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus);
setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause);
setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleShadowDetailChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
setting_setup_signal_listener(gSavedSettings, "RenderHiDPI", handleRenderHiDPIChanged);
setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged);
setting_setup_signal_listener(gSavedSettings, "ChatConsoleFontSize", handleChatFontSizeChanged);
setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged);
setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged);
setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged);
setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged);
setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus);
setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause);
// <FS:Zi> Is done inside XUI now, using visibility_control
// setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel);
// </FS:Zi>
@ -1335,16 +1357,27 @@ void settings_setup_listeners()
// setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel);
// </FS: Zi>
setting_setup_signal_listener(gSavedSettings, "ShowMenuBarLocation", toggle_show_menubar_location_panel);
setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost);
setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid);
setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost);
setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid);
// <FS:Ansariel> Show start location setting has no effect on login
setting_setup_signal_listener(gSavedSettings, "ShowStartLocation", handleForceShowGrid);
setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged);
setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged);
setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged);
setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged);
setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged);
setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged);
setting_setup_signal_listener(gSavedSettings, "TargetFPS", handleTargetFPSChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneFPS", handleAutoTuneFPSChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneLock", handleAutoTuneLockChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarMaxART", handleRenderAvatarMaxARTChanged);
setting_setup_signal_listener(gSavedSettings, "PerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "UserTargetReflections", handleUserTargetReflectionsChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged);
setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
@ -1432,18 +1465,6 @@ void settings_setup_listeners()
// <FS:Ansariel> Better asset cache size control
setting_setup_signal_listener(gSavedSettings, "FSDiskCacheSize", handleDiskCacheSizeChanged);
// <FS:Beq> perf floater controls
setting_setup_signal_listener(gSavedSettings, "FSTargetFPS", handleTargetFPSChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneFPS", handleAutoTuneFPSChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneLock", handleAutoTuneLockChanged);
setting_setup_signal_listener(gSavedSettings, "FSRenderAvatarMaxART", handleRenderAvatarMaxARTChanged);
setting_setup_signal_listener(gSavedSettings, "FSPerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "FSUserTargetReflections", handleUserTargetReflectionsChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "FSAutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "FSTuningFPSStrategy", handleFPSTuningStrategyChanged);
// </FS:Beq>
// <FS:Zi> Handle IME text input getting enabled or disabled
#if LL_SDL2

View File

@ -78,6 +78,7 @@
#include "llscenemonitor.h"
#include "llenvironment.h"
#include "llperfstats.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "llvisualeffect.h"
#include "rlvactions.h"
@ -85,7 +86,6 @@
// [/RLVa:KB]
#include "llpresetsmanager.h"
#include "fsdata.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
extern LLPointer<LLViewerTexture> gStartTexture;
extern bool gShiftFrame;
@ -462,8 +462,8 @@ static LLTrace::BlockTimerStatHandle FTM_EEP_UPDATE("Env Update");
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_DISPLAY); // <FS:Beq/> render time capture - This is the main stat for overall rendering.
LL_RECORD_BLOCK_TIME(FTM_RENDER);
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering.
LL_RECORD_BLOCK_TIME(FTM_RENDER);
LLViewerCamera& camera = LLViewerCamera::instance(); // <FS:Ansariel> Factor out calls to getInstance
@ -1240,8 +1240,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
void render_hud_attachments()
{
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_HUDS); // <FS:Beq/> render time capture - Primary contributor to HUDs (though these end up in render batches)
gGL.matrixMode(LLRender::MM_PROJECTION);
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_HUDS); // render time capture - Primary contributor to HUDs (though these end up in render batches)
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
@ -1448,8 +1448,8 @@ bool setup_hud_matrices(const LLRect& screen_region)
void render_ui(F32 zoom_factor, int subfield)
{
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_UI ); // <FS:Beq/> render time capture - Primary UI stat can have HUD time overlap (TODO)
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_UI ); // render time capture - Primary UI stat can have HUD time overlap (TODO)
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
LLGLState::checkStates();
@ -1538,8 +1538,8 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
void swap()
{
FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_SWAP ); // <FS:Beq/> render time capture - Swap buffer time - can signify excessive data transfer to/from GPU
LL_RECORD_BLOCK_TIME(FTM_SWAP);
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SWAP ); // render time capture - Swap buffer time - can signify excessive data transfer to/from GPU
LL_RECORD_BLOCK_TIME(FTM_SWAP);
if (gDisplaySwapBuffers)
{

View File

@ -108,7 +108,7 @@
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindinglinksets.h"
#include "llfloaterpay.h"
// #include "llfloaterperformance.h" <FS:Beq/> rename to fs as ll version no released
// #include "llfloaterperformance.h" <FS:Beq/> restore fsperf floater
#include "fsfloaterperformance.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
@ -622,7 +622,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("media_lists", "floater_media_lists.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterMediaLists>);
LLFloaterReg::add("money_tracker", "floater_fs_money_tracker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSMoneyTracker>);
LLFloaterReg::add("particle_editor","floater_particle_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ParticleEditor>);
LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPerformance>);
LLFloaterReg::add("performance", "floater_fs_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPerformance>);
LLFloaterReg::add(PHOTOTOOLS_FLOATER, "floater_phototools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterQuickPrefs>);
LLFloaterReg::add("phototools_camera", "floater_phototools_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
LLFloaterReg::add("quickprefs", "floater_quickprefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FloaterQuickPrefs>);

View File

@ -55,7 +55,7 @@
#include "m3math.h"
#include "m4math.h"
#include "llmatrix4a.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
#include "llperfstats.h"
#if !LL_DARWIN && !LL_LINUX
extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
@ -232,15 +232,16 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
return 0;
}
// <FS:Beq> render time capture
// TODO(Beq) This path does not appear to have attachments. Prove this then remove.
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
auto vobj = mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr );
}
// </FS:Beq>
// render time capture
// This path does not appear to have attachments. Prove this then remove.
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
auto vobj = mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
{
trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr );
LL_WARNS("trackAttachments") << "Attachment render time is captuted." << LL_ENDL;
}
U32 triangle_count = 0;
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;

View File

@ -718,7 +718,7 @@ void LLViewerPartSim::updateSimulation()
if (upd && vobj && (vobj->getPCode() == LL_PCODE_VOLUME))
{
if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex())
if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex() && vobj->getAvatar()->isTooSlow())
{
upd = FALSE;
}

View File

@ -58,6 +58,7 @@
#include "llfeaturemanager.h"
#include "llviewernetwork.h"
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
#include "llperfstats.h"
#include "llsdserialize.h"
#include "llsdutil.h"
#include "llcorehttputil.h"
@ -215,6 +216,13 @@ LLTrace::EventStatHandle<F64Seconds > AVATAR_EDIT_TIME("avataredittime", "Second
LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE("object_cache_hits");
LLTrace::EventStatHandle<F64Seconds > TEXTURE_FETCH_TIME("texture_fetch_time");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > SCENERY_FRAME_PCT("scenery_frame_pct");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > AVATAR_FRAME_PCT("avatar_frame_pct");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > HUDS_FRAME_PCT("huds_frame_pct");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > UI_FRAME_PCT("ui_frame_pct");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > SWAP_FRAME_PCT("swap_frame_pct");
LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > IDLE_FRAME_PCT("idle_frame_pct");
}
LLViewerStats::LLViewerStats()
@ -421,6 +429,89 @@ void update_statistics()
texture_stats_timer.reset();
}
}
if (LLFloaterReg::instanceVisible("scene_load_stats"))
{
static const F32 perf_stats_freq = 1;
static LLFrameTimer perf_stats_timer;
if (perf_stats_timer.getElapsedTimeF32() >= perf_stats_freq)
{
LLStringUtil::format_map_t args;
LLPerfStats::bufferToggleLock.lock(); // prevent toggle for a moment
auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
// cumulative avatar time (includes idle processing, attachments and base av)
auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(LLPerfStats::ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
// cumulative avatar render specific time (a bit arbitrary as the processing is too.)
// auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE);
// auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw;
// the time spent this frame on the "display()" call. Treated as "tot time rendering"
auto tot_render_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_DISPLAY);
// sleep time is basically forced sleep when window out of focus
auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP);
// time spent on UI
auto tot_ui_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_UI);
// cumulative time spent rendering HUDS
auto tot_huds_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_HUDS);
// "idle" time. This is the time spent in the idle poll section of the main loop
auto tot_idle_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_IDLE);
// similar to sleep time, induced by FPS limit
//auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT);
// swap time is time spent in swap buffer
auto tot_swap_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SWAP);
LLPerfStats::bufferToggleLock.unlock();
auto tot_frame_time_ns = LLPerfStats::raw_to_ns(tot_frame_time_raw);
auto tot_avatar_time_ns = LLPerfStats::raw_to_ns(tot_avatar_time_raw);
auto tot_huds_time_ns = LLPerfStats::raw_to_ns(tot_huds_time_raw);
// UI time includes HUD time so dedut that before we calc percentages
auto tot_ui_time_ns = LLPerfStats::raw_to_ns(tot_ui_time_raw - tot_huds_time_raw);
// auto tot_sleep_time_ns = LLPerfStats::raw_to_ns( tot_sleep_time_raw );
// auto tot_limit_time_ns = LLPerfStats::raw_to_ns( tot_limit_time_raw );
// auto tot_render_time_ns = LLPerfStats::raw_to_ns( tot_render_time_raw );
auto tot_idle_time_ns = LLPerfStats::raw_to_ns(tot_idle_time_raw);
auto tot_swap_time_ns = LLPerfStats::raw_to_ns(tot_swap_time_raw);
auto tot_scene_time_ns = LLPerfStats::raw_to_ns(tot_render_time_raw - tot_avatar_time_raw - tot_swap_time_raw - tot_ui_time_raw);
// auto tot_overhead_time_ns = LLPerfStats::raw_to_ns( tot_frame_time_raw - tot_render_time_raw - tot_idle_time_raw );
// // remove time spent sleeping for fps limit or out of focus.
// tot_frame_time_ns -= tot_limit_time_ns;
// tot_frame_time_ns -= tot_sleep_time_ns;
if (tot_frame_time_ns != 0)
{
auto pct_avatar_time = (tot_avatar_time_ns * 100) / tot_frame_time_ns;
auto pct_huds_time = (tot_huds_time_ns * 100) / tot_frame_time_ns;
auto pct_ui_time = (tot_ui_time_ns * 100) / tot_frame_time_ns;
auto pct_idle_time = (tot_idle_time_ns * 100) / tot_frame_time_ns;
auto pct_swap_time = (tot_swap_time_ns * 100) / tot_frame_time_ns;
auto pct_scene_render_time = (tot_scene_time_ns * 100) / tot_frame_time_ns;
pct_avatar_time = llclamp(pct_avatar_time, 0., 100.);
pct_huds_time = llclamp(pct_huds_time, 0., 100.);
pct_ui_time = llclamp(pct_ui_time, 0., 100.);
pct_idle_time = llclamp(pct_idle_time, 0., 100.);
pct_swap_time = llclamp(pct_swap_time, 0., 100.);
pct_scene_render_time = llclamp(pct_scene_render_time, 0., 100.);
if (tot_sleep_time_raw == 0)
{
sample(LLStatViewer::SCENERY_FRAME_PCT, (U32)llround(pct_scene_render_time));
sample(LLStatViewer::AVATAR_FRAME_PCT, (U32)llround(pct_avatar_time));
sample(LLStatViewer::HUDS_FRAME_PCT, (U32)llround(pct_huds_time));
sample(LLStatViewer::UI_FRAME_PCT, (U32)llround(pct_ui_time));
sample(LLStatViewer::SWAP_FRAME_PCT, (U32)llround(pct_swap_time));
sample(LLStatViewer::IDLE_FRAME_PCT, (U32)llround(pct_idle_time));
}
}
else
{
LL_WARNS("performance") << "Scene time 0. Skipping til we have data." << LL_ENDL;
}
perf_stats_timer.reset();
}
}
}
void update_texture_time()
@ -533,6 +624,7 @@ void send_viewer_stats(bool include_preferences)
system["gpu"] = gpu_desc;
system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
system["gpu_memory_bandwidth"] = LLFeatureManager::getInstance()->getGPUMemoryBandwidth();
system["gpu_vendor"] = gGLManager.mGLVendorShort;
system["gpu_version"] = gGLManager.mDriverVersionVendorString;
system["opengl_version"] = gGLManager.mGLVersionString;

View File

@ -214,8 +214,8 @@ static std::string get_texture_list_name()
void LLViewerTextureList::doPrefetchImages()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
gTextureTimer.start();
gTextureTimer.pause();
gTextureTimer.start();
gTextureTimer.pause();
// todo: do not load without getViewerAssetUrl()
// either fail login without caps or provide this

View File

@ -119,6 +119,8 @@
#include "llrendersphere.h"
#include "llskinningutil.h"
#include "llperfstats.h"
#include <boost/lexical_cast.hpp>
#include "fscommon.h"
@ -135,7 +137,6 @@
#include "fslslbridge.h" // <FS:PP> Movelock position refresh
#include "fsdiscordconnect.h" // <FS:LO> tapping a place that happens on landing in world to start up discord
#include "fsperfstats.h" // <FS:Beq> performance stats support
extern F32 SPEED_ADJUST_MAX;
extern F32 SPEED_ADJUST_MAX_SEC;
@ -226,6 +227,8 @@ const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;
const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60.f;
const S32 MIN_NONTUNED_AVS = 5;
enum ERenderName
{
RENDER_NAME_NEVER,
@ -636,6 +639,8 @@ F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;
F32 LLVOAvatar::sGreyTime = 0.f;
F32 LLVOAvatar::sGreyUpdateTime = 0.f;
LLPointer<LLViewerTexture> LLVOAvatar::sCloudTexture = NULL;
std::vector<LLUUID> LLVOAvatar::sAVsIgnoringARTLimit;
S32 LLVOAvatar::sAvatarsNearby = 0;
//-----------------------------------------------------------------------------
// Helper functions
@ -890,12 +895,17 @@ LLVOAvatar::~LLVOAvatar()
debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
}
// <FS:ND> only call logPendingPhases if we're still alive. Otherwise this can lead to shutdown crashes
if(mTuned)
{
LLPerfStats::tunedAvatars--;
mTuned = false;
}
sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID), sAVsIgnoringARTLimit.end());
// <FS:ND> only call logPendingPhases if we're still alive. Otherwise this can lead to shutdown crashes
// logPendingPhases();
if (isAgentAvatarValid())
logPendingPhases();
// </FS:ND>
LL_DEBUGS("Avatar") << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << LL_ENDL;
@ -2702,10 +2712,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
LL_INFOS() << "Warning! Idle on dead avatar" << LL_ENDL;
return;
}
// <FS:Beq> record time and refresh "tooSlow" status
FSPerfStats::RecordAvatarTime T(getID(), FSPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time.
updateTooSlow();
// </FS:Beq>;
// record time and refresh "tooSlow" status
LLPerfStats::RecordAvatarTime T(getID(), LLPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time.
updateTooSlow();
static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
&& !disable_all_render_types && !isSelf())
@ -3358,7 +3368,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
// Firestorm Clouds
// do not generate particles for dummy or overly-complex avatars
if (!mIsDummy && !isTooComplex())
if (!mIsDummy && !isTooComplex() && !isTooSlow())
{
setParticleSource(sCloud, getID());
}
@ -4307,7 +4317,7 @@ bool LLVOAvatar::isVisuallyMuted()
// </FS:Ansariel>
else
{
muted = isTooComplex();
muted = isTooComplex(); // <FS:Beq/> this should not trigger based on perfstats
}
}
@ -9196,95 +9206,6 @@ BOOL LLVOAvatar::isFullyLoaded() const
// return (mRenderUnloadedAvatar || mFullyLoaded);
}
// <FS:Beq> use Avatar Render Time as complexity metric
// markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number.
void LLVOAvatar::markARTStale()
{
mARTStale=true;
mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
}
// Udpate Avatar state based on render time
void LLVOAvatar::updateTooSlow()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
static LLCachedControl<bool> alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends");
static LLCachedControl<bool> allowSelfImpostor(gSavedSettings, "FSAllowSelfImpostor");
const auto id = getID();
// mTooSlow - Is the avatar flagged as being slow (includes shadow time)
// mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed.
// mARTStale - the rendertime we have is stale because of an update. We need to force a re-render to re-assess slowness
if( mARTStale )
{
if ( LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 5 )
{
// LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL;
// we've not had a chance to update yet (allow a few to be certain a full frame has passed)
return;
}
mARTStale = false;
mTooSlow = false;
mTooSlowWithoutShadows = false;
// LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL;
}
// Either we're not stale or we've updated.
U64 render_time_raw;
U64 render_geom_time_raw;
if( !mTooSlow )
{
// we are fully rendered, so we use the live values
std::lock_guard<std::mutex> lock{FSPerfStats::bufferToggleLock};
render_time_raw = FSPerfStats::StatsRecorder::get(FSPerfStats::ObjType_t::OT_AVATAR, id, FSPerfStats::StatType_t::RENDER_COMBINED);
render_geom_time_raw = FSPerfStats::StatsRecorder::get(FSPerfStats::ObjType_t::OT_AVATAR, id, FSPerfStats::StatType_t::RENDER_GEOMETRY);
}
else
{
// use the cached values.
render_time_raw = mRenderTime;
render_geom_time_raw = mGeomTime;
}
if( (FSPerfStats::renderAvatarMaxART_ns > 0) &&
(FSPerfStats::raw_to_ns(render_time_raw) >= FSPerfStats::renderAvatarMaxART_ns) )
{
if( !mTooSlow ) // if we were previously not slow (with or without shadows.)
{
// if we weren't capped, we are now
mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
mRenderTime = render_time_raw;
mGeomTime = render_geom_time_raw;
mARTStale = false;
mTooSlow = true;
}
if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap
{
bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) ||
( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER );
if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception )
{
// Note: slow rendering Friends still get their shadows zapped.
mTooSlowWithoutShadows = (FSPerfStats::raw_to_ns(render_geom_time_raw) >= FSPerfStats::renderAvatarMaxART_ns);
}
}
}
else
{
// LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << FSPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
mTooSlow = false;
mTooSlowWithoutShadows = false;
}
if(mTooSlow)
{
FSPerfStats::tunedAvatars++; // <FS:Beq> increment the number of avatars that have been tweaked.
}
}
// </FS:Beq>
bool LLVOAvatar::isTooComplex() const
{
bool too_complex;
@ -9312,6 +9233,182 @@ bool LLVOAvatar::isTooComplex() const
return too_complex;
}
bool LLVOAvatar::isTooSlow() const
{
static LLCachedControl<bool> always_render_friends(gSavedSettings, "AlwaysRenderFriends");
bool render_friend = (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends);
if (render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
{
return false;
}
return mTooSlow;
}
// use Avatar Render Time as complexity metric
// <FS:Beq> refactor for clarity post LL merge
void LLVOAvatar::clearSlowARTCache()
{
mARTStale = false;
mTooSlow = false;
mTooSlowWithoutShadows = false;
}
void LLVOAvatar::setSlowARTCache(U64 full_render_time, U64 non_shadow_render_time)
{
mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
mRenderTime = full_render_time;
mRenderTimeNoShadows = non_shadow_render_time;
mARTStale = false;
mTooSlow = true;
}
// </FS:Beq>
// markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number.
void LLVOAvatar::markARTStale()
{
mARTStale=true;
mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
}
// Udpate Avatar state based on render time
void LLVOAvatar::updateTooSlow()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
static LLCachedControl<bool> alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends");
static LLCachedControl<bool> allowSelfImpostor(gSavedSettings, "AllowSelfImpostor");
const auto id = getID();
bool changed_slow_state{false}; // <FS:Beq> Post LL merge, force dirty when slowness state changes
// mTooSlow - Is the avatar flagged as being slow (includes shadow time)
// mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed.
// mARTStale - the rendertime we have is stale because of an update. We need to force a re-render to re-assess slowness
if( mARTStale )
{
if ( LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 5 )
{
// LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL;
// we've not had a chance to update yet (allow a few to be certain a full frame has passed)
return;
}
// <FS:Beq> refactor and work out why shadow derendering is no longer working
// mARTStale = false;
// mTooSlow = false;
// mTooSlowWithoutShadows = false;
// LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL;
clearSlowARTCache();
changed_slow_state = true;
// </FS:Beq>
}
// Either we're not stale or we've updated.
U64 render_time_raw;
U64 render_time_no_shadows_raw; // <FS:Beq/> rename as we now include idle time
if( !mTooSlow )
{
// we are fully rendered, so we use the live values
std::lock_guard<std::mutex> lock{LLPerfStats::bufferToggleLock};
render_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_COMBINED);
// <FS:Beq> include idle time in total render time
// render_geom_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_GEOMETRY);
render_time_no_shadows_raw = render_time_raw - LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_SHADOWS);
// </FS:Beq>
}
else
{
// use the cached values.
render_time_raw = mRenderTime;
render_time_no_shadows_raw = mRenderTimeNoShadows; // <FS:Beq/> variable name updated to refelect different meaning.
}
bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
bool ignore_tune = false;
if (autotune && sAVsIgnoringARTLimit.size() > 0)
{
auto it = std::find(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID);
if (it != sAVsIgnoringARTLimit.end())
{
S32 index = it - sAVsIgnoringARTLimit.begin();
ignore_tune = (index < (MIN_NONTUNED_AVS - sAvatarsNearby + 1 + LLPerfStats::tunedAvatars));
}
}
bool exceeds_max_ART =
((LLPerfStats::renderAvatarMaxART_ns > 0) && (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns));
if (exceeds_max_ART && !ignore_tune)
{
if( !mTooSlow ) // if we were previously not slow (with or without shadows.)
{
// if we weren't capped, we are now
// <FS:Beq> refactored "geom" becomes "no shadow"
// mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
// mRenderTime = render_time_raw;
// mGeomTime = render_geom_time_raw;
// mARTStale = false;
// mTooSlow = true;
setSlowARTCache(render_time_raw, render_time_no_shadows_raw);
changed_slow_state = true;
// </FS:Beq>
}
if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap
{
bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) ||
( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER );
if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception )
{
// Note: slow rendering Friends still get their shadows zapped.
// <FS:Beq> changes to support idel and geom in non shadow rendering cost + improved dirty marking
// mTooSlowWithoutShadows = (LLPerfStats::raw_to_ns(render_geom_time_raw) >= LLPerfStats::renderAvatarMaxART_ns);
mTooSlowWithoutShadows = (LLPerfStats::raw_to_ns(render_time_no_shadows_raw) >= LLPerfStats::renderAvatarMaxART_ns);
}
if(mTooSlowWithoutShadows)
{
changed_slow_state = true;
// </FS:Beq>
}
}
}
else
{
// <FS:Beq> better state change flagging
// LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << LLPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
// LL_INFOS() << this->getFullname() << " good render time = " << render_time_ns << " vs ("<< LLPerfStats::renderAvatarMaxART_ns << " set @ " << mLastARTUpdateFrame << ")" << LL_ENDL;
if( mTooSlow || mTooSlowWithoutShadows )
{
changed_slow_state = true;
}
// </FS:Beq>
mTooSlow = false;
mTooSlowWithoutShadows = false;
if (ignore_tune)
{
return;
}
}
if(mTooSlow && !mTuned)
{
LLPerfStats::tunedAvatars++; // increment the number of avatars that have been tweaked.
mTuned = true;
}
else if(!mTooSlow && mTuned)
{
LLPerfStats::tunedAvatars--;
mTuned = false;
}
// <FS:Beq> better state change flagging
if( changed_slow_state )
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, true);
}
// </FS:Beq>
}
//-----------------------------------------------------------------------------
// findMotion()
//-----------------------------------------------------------------------------
@ -11722,6 +11819,64 @@ void LLVOAvatar::idleUpdateRenderComplexity()
// Render Complexity
calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed
bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
if (autotune && !isDead())
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
F32 radius = render_far_clip * render_far_clip;
bool is_nearby = true;
if ((dist_vec_squared(getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
(dist_vec_squared(getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
{
is_nearby = false;
}
if (is_nearby && (sAVsIgnoringARTLimit.size() < MIN_NONTUNED_AVS))
{
if (std::count(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID) == 0)
{
sAVsIgnoringARTLimit.push_back(mID);
}
}
else if (!is_nearby)
{
sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID),
sAVsIgnoringARTLimit.end());
}
updateNearbyAvatarCount();
}
}
void LLVOAvatar::updateNearbyAvatarCount()
{
static LLFrameTimer agent_update_timer;
if (agent_update_timer.getElapsedTimeF32() > 1.0f)
{
S32 avs_nearby = 0;
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
F32 radius = render_far_clip * render_far_clip;
std::vector<LLCharacter *>::iterator char_iter = LLCharacter::sInstances.begin();
while (char_iter != LLCharacter::sInstances.end())
{
LLVOAvatar *avatar = dynamic_cast<LLVOAvatar *>(*char_iter);
if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
{
if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
(dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
{
char_iter++;
continue;
}
avs_nearby++;
}
char_iter++;
}
sAvatarsNearby = avs_nearby;
agent_update_timer.reset();
}
}
void LLVOAvatar::idleUpdateDebugInfo()
@ -12151,13 +12306,13 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
mVisualComplexity = cost;
mVisualComplexityStale = false;
if (isSelf())
static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
if (isSelf() && show_my_complexity_changes)
{
// Avatar complexity
LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
LLAvatarRenderNotifier::getInstance()->setObjectComplexityList(object_complexity_list);
// HUD complexity
LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
}
@ -12342,7 +12497,7 @@ LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
{ // Always want to see this AV as an impostor
result = AOA_JELLYDOLL;
}
else if (isTooComplex())
else if (isTooComplex() || isTooSlowWithoutShadows()) // <FS:Beq/> correct for misplaced check
{
result = AOA_JELLYDOLL;
}
@ -12377,7 +12532,10 @@ void LLVOAvatar::calcMutedAVColor()
new_color = LLColor4::grey4;
change_msg = " blocked: color is grey4";
}
// <FS:Beq> we don't want jelly dolls
// else if (!isTooComplex() && !isTooSlow())
else if (!isTooComplex())
// </FS:Beq>
{
new_color = LLColor4::white;
change_msg = " simple imposter ";

View File

@ -330,6 +330,8 @@ public:
void idleUpdateBelowWater();
static void updateNearbyAvatarCount();
//--------------------------------------------------------------------
// Static preferences (controlled by user settings/menus)
//--------------------------------------------------------------------
@ -351,11 +353,13 @@ public:
static F32 sLODFactor; // user-settable LOD factor
static F32 sPhysicsLODFactor; // user-settable physics LOD factor
static BOOL sJointDebug; // output total number of joints being touched for each avatar
static U64 sRenderTimeLimit_ns; // <FS:Beq/> nanosecond time limit for avatar rendering 0 is unlimited.
static LLPartSysData sCloud;
static LLPointer<LLViewerTexture> sCloudTexture;
static std::vector<LLUUID> sAVsIgnoringARTLimit;
static S32 sAvatarsNearby;
//--------------------------------------------------------------------
// Region state
//--------------------------------------------------------------------
@ -367,17 +371,16 @@ public:
//--------------------------------------------------------------------
public:
BOOL isFullyLoaded() const;
// <FS:Beq> check and return current state relative to limits
// default will test only the geometry (combined=false).
// this allows us to disable shadows separately on complex avatars.
inline bool isTooSlowWithShadows() const {return mTooSlow;};
inline bool isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;};
inline bool isTooSlow(bool combined = false) const
{
return(combined?mTooSlow:mTooSlowWithoutShadows);
}
void updateTooSlow();
// </FS:Beq>
// check and return current state relative to limits
// default will test only the geometry (combined=false).
// this allows us to disable shadows separately on complex avatars.
inline bool isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;};
bool isTooSlow() const;
void updateTooSlow();
virtual bool isTooComplex() const; // <FS:Ansariel> FIRE-29012: Standalone animesh avatars get affected by complexity limit; changed to virtual
bool visualParamWeightsAreDefault();
virtual bool getIsCloud() const;
@ -399,7 +402,11 @@ public:
void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
void calcMutedAVColor();
void markARTStale();
void markARTStale();
// <FS:Beq> refactoring post LL merge
void clearSlowARTCache();
void setSlowARTCache(U64 full_render_time, U64 geometry_render_time);
// </FS:Beq>
protected:
LLViewerStats::PhaseMap& getPhases() { return mPhases; }
@ -420,15 +427,17 @@ private:
LLColor4 mMutedAVColor;
LLFrameTimer mFullyLoadedTimer;
LLFrameTimer mRuthTimer;
U32 mLastARTUpdateFrame{0};
U64 mRenderTime{0};
U64 mGeomTime{0};
bool mARTStale{true};
bool mARTCapped{false};
// <FS:Beq> variables to hold "slowness" status
bool mTooSlow{false};
bool mTooSlowWithoutShadows{false};
// </FS:Beq>
U32 mLastARTUpdateFrame{0};
U64 mRenderTime{0};
U64 mRenderTimeNoShadows{0};
bool mARTStale{true};
bool mARTCapped{false};
// variables to hold "slowness" status
bool mTooSlow{false};
bool mTooSlowWithoutShadows{false};
bool mTuned{false};
private:
LLViewerStats::PhaseMap mPhases;
@ -1233,7 +1242,7 @@ public:
// COF version of last appearance message received for this av.
S32 mLastUpdateReceivedCOFVersion;
U64 getLastART() const { return mRenderTime; }
U64 getLastART() const { return mRenderTime; }
/** Diagnostics
** **

View File

@ -88,12 +88,12 @@
#include "llcallstack.h"
#include "llsculptidsize.h"
#include "llavatarappearancedefines.h"
#include "llperfstats.h"
// [RLVa:KB] - Checked: RLVa-2.0.0
#include "rlvactions.h"
#include "rlvlocks.h"
// [/RLVa:KB]
#include "llviewernetwork.h"
#include "fsperfstats.h" // <FS:Beq> performance stats support
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
@ -5727,7 +5727,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
// if (type == LLRenderPass::PASS_ALPHA) // <FS:Beq/> always populate the draw_info ptr
// if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr
{ //for alpha sorting
facep->setDrawInfo(draw_info);
}
@ -5932,7 +5932,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("rebuildGeom - face list");
//get all the faces into a list
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
drawable_iter != group->getDataEnd(); ++drawable_iter)
{
@ -5975,6 +5975,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
// </FS:Beq>
if(vobj->isAttachment())
{
trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr);
}
LLVolume* volume = vobj->getVolume();
if (volume)
{
@ -6404,7 +6409,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
U32 buffer_count = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> capture render times
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
@ -6416,8 +6421,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if (!vobj) continue;
// <FS:Beq> capture render times
if (vobj->isAttachment())
if (vobj->isAttachment())
{
trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr );
}
@ -6865,18 +6869,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 indices_index = 0;
U16 index_offset = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr; // <FS:Beq/> capture render times
while (face_iter < i)
std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr;
while (face_iter < i)
{
//update face indices for new buffer
facep = *face_iter;
LLViewerObject* vobj = facep->getViewerObject();
// <FS:Beq> capture render times
if(vobj && vobj->isAttachment())
{
trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
}
// </FS:Beq>
LLViewerObject* vobj = facep->getViewerObject();
if(vobj && vobj->isAttachment())
{
trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
}
if (buffer.isNull())
{
// Bulk allocation failed

View File

@ -33,6 +33,7 @@
#include "llstl.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewercontrol.h"
#include "lldrawpool.h"
#include "llglheaders.h"
@ -1935,6 +1936,34 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
}
}
// <FS:Ansariel> [FS performance floater]
//S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs)
//{
// static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
// S32 nearby_max_complexity = 0;
// F32 radius = render_far_clip * render_far_clip;
// std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
// while (char_iter != LLCharacter::sInstances.end())
// {
// LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
// if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
// {
// if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
// (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
// {
// char_iter++;
// continue;
// }
// avatar->calculateUpdateRenderComplexity();
// nearby_max_complexity = llmax(nearby_max_complexity, (S32)avatar->getVisualComplexity());
// valid_nearby_avs.push_back(*char_iter);
// }
// char_iter++;
// }
// return nearby_max_complexity;
//}
// </FS:Ansariel> [FS performance floater]
// [RLVa:KB] - Checked: RLVa-2.0.1
bool LLWorld::getAvatar(const LLUUID& idAvatar, LLVector3d& posAvatar) const
{

View File

@ -51,6 +51,7 @@ class LLHost;
class LLViewerObject;
class LLSurfacePatch;
class LLCharacter;
class LLCloudPuff;
class LLCloudGroup;
class LLVOAvatar;
@ -243,6 +244,9 @@ public:
// or if the circuit to this simulator had been lost.
bool isRegionListed(const LLViewerRegion* region) const;
// <FS:Ansariel> [FS performance floater]
//S32 getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs);
private:
void clearHoleWaterObjects();
void clearEdgeWaterObjects();

View File

@ -43,6 +43,7 @@
#include "llui.h"
#include "llglheaders.h"
#include "llrender.h"
#include "llstartup.h"
#include "llwindow.h" // swapBuffers()
// newview includes
@ -160,6 +161,7 @@ F32 LLPipeline::RenderResolutionMultiplier;
// [/SL:KB]
bool LLPipeline::RenderUIBuffer;
S32 LLPipeline::RenderShadowDetail;
S32 LLPipeline::RenderShadowSplits;
bool LLPipeline::RenderDeferredSSAO;
F32 LLPipeline::RenderShadowResolutionScale;
bool LLPipeline::RenderLocalLights;
@ -596,6 +598,7 @@ void LLPipeline::init()
// [/SL:KB]
connectRefreshCachedSettingsSafe("RenderUIBuffer");
connectRefreshCachedSettingsSafe("RenderShadowDetail");
connectRefreshCachedSettingsSafe("RenderShadowSplits");
connectRefreshCachedSettingsSafe("RenderDeferredSSAO");
connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");
connectRefreshCachedSettingsSafe("RenderLocalLights");
@ -672,14 +675,13 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderAttachedParticles");
// </FS:Ansariel>
// <FS:Beq> FIRE-16728 Add free aim mouse and focus lock
connectRefreshCachedSettingsSafe("FSFocusPointLocked");
connectRefreshCachedSettingsSafe("FSFocusPointFollowsPointer");
connectRefreshCachedSettingsSafe("FSFocusPointLocked");
// </FS:Beq>
}
LLPipeline::~LLPipeline()
{
}
void LLPipeline::cleanup()
@ -1218,6 +1220,7 @@ void LLPipeline::refreshCachedSettings()
// [/SL:KB]
RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits");
RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights");
@ -6222,7 +6225,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
LLDrawable* drawable = light->drawable;
const LLViewerObject *vobj = light->drawable->getVObj();
if(vobj && vobj->getAvatar()
&& (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList())
&& (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlow())
)
{
drawable->clearState(LLDrawable::NEARBY_LIGHT);
@ -6301,7 +6304,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
continue;
}
LLVOAvatar * av = light->getAvatar();
if (av && (av->isTooComplex() || av->isInMuteList()))
if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlow()))
{
// avatars that are already in the list will be removed by removeMutedAVsLights
continue;
@ -10593,14 +10596,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (mSunDiffuse == LLColor4::black)
{ //sun diffuse is totally black, shadows don't matter
LLGLDepthTest depth(GL_TRUE);
for (S32 j = 0; j < 4; j++)
{
mShadow[j].bindTarget();
mShadow[j].clear();
mShadow[j].flush();
}
skipRenderingShadows();
}
else
{
@ -10655,7 +10651,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
std::vector<LLVector3> fp;
if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)
|| j > RenderShadowSplits)
{
//no possible shadow receivers
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
@ -11217,12 +11214,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
<< " is " << ( too_complex ? "" : "not ") << "too complex"
<< LL_ENDL;
bool too_slow = avatar->isTooSlowWithoutShadows(); // <FS:Beq/> only if we really have to do we imposter.
pushRenderTypeMask();
pushRenderTypeMask();
if ( !too_slow && ( visually_muted || too_complex ) )
{
if (visually_muted || too_complex)
{
// only show jelly doll geometry
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV,
@ -11937,6 +11932,31 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
void LLPipeline::skipRenderingShadows()
{
LLGLDepthTest depth(GL_TRUE);
for (S32 j = 0; j < 4; j++)
{
mShadow[j].bindTarget();
mShadow[j].clear();
mShadow[j].flush();
}
}
void LLPipeline::handleShadowDetailChanged()
{
if (RenderShadowDetail > gSavedSettings.getS32("RenderShadowDetail"))
{
skipRenderingShadows();
}
else
{
LLViewerShaderMgr::instance()->setShaders();
}
}
// <FS:Ansariel> Reset VB during TP
void LLPipeline::initDeferredVB()
{

View File

@ -425,6 +425,7 @@ public:
void skipRenderingOfTerrain( bool flag );
void hideObject( const LLUUID& id );
void restoreHiddenObject( const LLUUID& id );
void handleShadowDetailChanged();
private:
void unloadShaders();
@ -436,6 +437,7 @@ private:
void connectRefreshCachedSettingsSafe(const std::string name);
void hideDrawable( LLDrawable *pDrawable );
void unhideDrawable( LLDrawable *pDrawable );
void skipRenderingShadows();
// <FS:Ansariel> Reset VB during TP
void initDeferredVB();
@ -748,7 +750,6 @@ protected:
U64 mOldRenderDebugMask;
std::stack<U32> mRenderDebugFeatureStack;
/////////////////////////////////////////////
//
//
@ -949,6 +950,7 @@ public:
// [/SL:KB]
static bool RenderUIBuffer;
static S32 RenderShadowDetail;
static S32 RenderShadowSplits;
static bool RenderDeferredSSAO;
static F32 RenderShadowResolutionScale;
static bool RenderLocalLights;

View File

@ -1276,15 +1276,15 @@
<color
name="PanelGray"
value="0.27 0.27 0.27 1" />
<color
name="PerformanceMid"
value="1 0.8 0 1" />
<color
name="OutfitSnapshotMacMask"
value="0.115 0.115 0.115 1"/>
<color
name="OutfitSnapshotMacMask2"
value="0.1 0.1 0.1 1"/>
<color
name="PerformanceMid"
value="1 0.8 0 1" />
<!-- <FS:CR> Script Editor Colors -->
<color

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="performance" title="Grafik-Performance-Verbesserung (experimentell)">
<floater name="performance" title="Grafik-Performance-Verbesserung">
<floater.string name="frame_stats">
Frame: [TOT_FRAME_TIME]ms - Szenerie:[SCENERY_FRAME_PCT]% Avatare:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% HUDs:[HUDS_FRAME_PCT]% Swap:[SWAP_FRAME_PCT]% Tasks:[IDLE_FRAME_PCT]%
</floater.string>

View File

@ -19,10 +19,12 @@
</text>
<name_list name="nearby_list">
<name_list.columns tool_tip="Balkendiagram der benötigten Renderzeit (inkl. Auto-Anpassung) in Prozent, basierend auf dem Langsamsten." name="art_visual" />
<name_list.columns tool_tip="Avatar-Renderzeit (ART). Tatsächlich benötigte Zeit in Mikrosekunden für die Darstellung des Avatars vor Auto-Anpassung." name="art_value" />
<name_list.columns label="Zeit (μs)" tool_tip="Avatar-Renderzeit (ART). Tatsächlich benötigte Zeit in Mikrosekunden für die Darstellung des Avatars vor Auto-Anpassung." name="art_value" />
<name_list.columns label="Ang. Zeit (μs)" tool_tip="Avatar-Renderzeit (ART). Tatsächlich benötigte Zeit in Mikrosekunden für die Darstellung des Avatars nach Anpassungen." name="adj_art_value" />
<name_list.columns tool_tip="Avatar-Komplexität (ARC) basierend auf Standard-Berechnung." name="complex_value" />
<name_list.columns tool_tip="Zeigt Auto-Anpassung: I = Impostor, S = Kein Schatten." name="state" />
<name_list.columns label="Name" name="name"/>
<name_list.columns label="Übersicht" tool_tip="Wo die Renderzeit anfällt (Geometrie/Shader/Übriges)" name="breakdown"/>
</name_list>
<text name="av_nearby_desc2">
Per Rechts-Klick auf einen Avatar kann auch die Darstellung angepasst werden.

View File

@ -3,5 +3,6 @@
<text name="Graphic Presets">
Grafikvoreinstellungen
</text>
<button label="Grafikeinstellungen öffnen" name="open_prefs_btn" tool_tip="Grafikeinstellungen anzeigen"/>
<button label="Grafikeinstellungen" name="open_prefs_btn" tool_tip="Grafikeinstellungen anzeigen"/>
<button label="Grafikeinstellungen" name="open_autofps_btn" tool_tip="Performance-Fenster anzeigen"/>
</panel>

View File

@ -0,0 +1,606 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater
height="652"
layout="topleft"
name="performance"
help_topic="fs_performance_floater"
save_rect="true"
title="Improve Graphics Speed"
can_resize="false"
min_width="580"
width="580">
<floater.string name="frame_stats">
Frame: [TOT_FRAME_TIME]ms - Scenery:[SCENERY_FRAME_PCT]% Avatars:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% HUDs:[HUDS_FRAME_PCT]% Swap:[SWAP_FRAME_PCT]% Tasks:[IDLE_FRAME_PCT]%
</floater.string>
<floater.string name="limit_fps">
User Limited @ [FPSCAP] FPS
</floater.string>
<floater.string name="tuning_fps">
Target [FPSTARGET] FPS
</floater.string>
<floater.string name="av_frame_pct">
[AV_FRAME_PCT]%
</floater.string>
<floater.string name="huds_frame_pct">
[HUDS_FRAME_PCT]%
</floater.string>
<floater.string name="focus_fps">
In Background
</floater.string>
<floater.string name="info_waitforit">
Allow 5-10 seconds for changes to take effect.
</floater.string>
<floater.string name="info_frozen">
Stats pause when FPS is limited or in background.
</floater.string>
<floater.string name="tot_av_template">
Total: [TOT_AV] ([TOT_AV_TIME]μs)
</floater.string>
<floater.string name="tot_att_template">
Total: [TOT_ATT] ([TOT_ATT_TIME]μs)
</floater.string>
<flaoter.string
name="fps_text"
value="frames per second"/>
<floater.string
name="max_fps"
value="VSync @ [VSYNCFREQ] FPS"/>
<panel
bevel_style="none"
follows="left|top|right"
height="600"
width="580"
name="panel_top"
visible="true"
layout="topleft"
left="0"
top="0">
<panel
bg_alpha_color="black"
background_visible="true"
background_opaque="false"
border="false"
bevel_style="none"
follows="left|top|right"
height="55"
width="560"
name="fps_subpanel"
layout="topleft"
left="10"
top="5">
<text
follows="left|top"
font="SansSerifHuge"
text_color="White"
height="20"
layout="topleft"
left="10"
top="8"
name="fps_value"
width="42">
167
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left_pad="3"
top="13"
name="fps_lbl"
width="150">
frames per second
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="DrYellow"
height="28"
layout="topleft"
left_pad="10"
name="fps_warning"
top="13"
width="200"> User Limited @ 000 FPS
</text>
<text
follows="top|right"
text_color="White"
height="40"
layout="topleft"
left="420"
top="5"
name="fps_desc1_lbl"
width="140"
wrap="true">
Stats pause when FPS is limited or in background.
</text>
<text
follows="left|top|right"
font="MonospaceMedium"
text_color="White"
height="20"
layout="topleft"
halign="center"
left="5"
top="38"
name="frame_breakdown"
width="550">
[--------------------Frame breakdown will appear here.---------------------]
</text>
</panel>
<panel
bg_alpha_color="black"
background_visible="true"
background_opaque="false"
border="false"
bevel_style="none"
follows="left|top|right"
height="55"
width="560"
name="target_subpanel"
layout="topleft"
left="10"
top_pad="0">
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="10"
name="settings_lbl"
top="7"
tool_tip="Automatically adjust settings to maintain FPS. Set the Target to the desired frame rate and the viewer will attempt to match this by dynamically altering your settings."
width="75">
Auto Tune:
</text>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left_pad="10"
name="targetfps_desc"
wrap="true"
width="140"
halign="right"
top_delta="3">
Target Frame Rate (fps)
</text>
<spinner
name="target_fps"
control_name="TargetFPS"
font="SansSerifLarge"
tool_tip="Target FPS - The desired FPS level. The viewer will attempt to achieve this by adjusting your graphics settings."
layout="topleft"
follows="right|top"
left_pad="10"
top_delta="0"
height="25"
visible="true"
decimal_digits="0"
increment="1"
initial_value="25"
max_val="300"
min_val="1"
width="48"
label_width="0" />
<button
control_name="AutoTuneFPS"
follows="top|right"
height="20"
initial_value="false"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
label="Start"
label_selected="Stop"
layout="topleft"
left_pad="5"
name="AutoTuneFPS"
top_delta="0"
tool_tip="The viewer will attempt to adjust settings to meet the target FPS."
width="72">
</button>
<check_box
control_name="AutoTuneLock"
follows="top|right"
height="20"
initial_value="true"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
label="Continuous"
layout="topleft"
left_pad="5"
name="AutoTuneContinuous"
top_delta="0"
tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed. When disabled clicking the Auto Tune button will adjust for the current settings then stop."
width="64">
</check_box>
<button
follows="left|top"
height="24"
image_overlay="Script_Disk_Save"
layout="topleft"
right="-62"
name="PrefSaveButton"
top_delta="0"
tool_tip="Save the current settings to a default for future use."
width="24">
<button.commit_callback
function="Performance.PrefSave"
parameter="graphic" />
</button>
<button
follows="left|top"
height="24"
image_overlay="Script_Disk_Load"
layout="topleft"
right="-34"
name="PrefLoadButton"
top_delta="0"
tool_tip="Load an existing preset."
width="24">
<button.commit_callback
function="Performance.PrefLoad"
parameter="graphic" />
</button>
<!--Reset Button-->
<button
follows="left|top"
height="24"
image_overlay="Refresh_Off"
tool_tip="Reload default graphics settings for your hardware."
layout="topleft"
right="-6"
name="Defaults"
top_delta="0"
width="24">
<button.commit_callback
function="Performance.HardwareDefaults" />
</button>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="20"
name="settings_desc"
top_pad="0"
wrap="true"
width="215"
halign="right"
top_delta="5">
Tuning Strategy
</text>
<combo_box
follows="top|right"
font="SansSerif"
height="20"
layout="topleft"
left_pad="10"
control_name="TuningFPSStrategy"
name="FSTuningFPSStrategy"
top_delta="0"
width="125">
<combo_box.item
label="Avatars Only"
name="av_only"
value="0" />
<combo_box.item
label="Avatars and Scene"
name="av_and_scene"
value="1" />
</combo_box>
<button
height="16"
width="16"
scale_image="true"
layout="topleft"
mouse_opaque="true"
follows="right|top"
name="target_btn"
top_delta="2"
tool_tip="Change the Tuning Strategy behavior."
image_selected="Icon_Gear"
image_pressed="Icon_Gear"
image_unselected="Icon_Gear"
left_pad="8"
is_toggle="true"></button>
</panel>
</panel>
<panel
bevel_style="none"
follows="left|top|right"
height="540"
width="580"
name="panel_performance_main"
visible="true"
layout="topleft"
left="0"
top="115">
<panel
bg_alpha_color="PanelGray"
background_visible="true"
background_opaque="false"
border="true"
bevel_style="none"
follows="left|top|right"
height="50"
width="560"
name="settings_subpanel"
layout="topleft"
left="10"
top_pad="10">
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="10"
name="settings_lbl"
top="7"
width="180">
Graphics settings
</text>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="10"
name="settings_desc"
top_pad="0"
width="395">
Choose settings for distance, water, lighting and more.
</text>
<icon
height="16"
width="16"
image_name="Arrow_Right_Off"
mouse_opaque="true"
name="icon_arrow3"
follows="right|top"
top="19"
right="-20" />
</panel>
<panel
bg_alpha_color="PanelGray"
background_visible="true"
background_opaque="false"
border="true"
bevel_style="none"
follows="left|top|right"
height="50"
width="560"
name="nearby_subpanel"
layout="topleft"
top_pad="10">
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="10"
name="avatars_nearby_lbl"
top="7"
width="205">
Avatars nearby
</text>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="10"
name="avatars_nearby_desc"
top_pad="0"
width="345">
Manage which nearby avatars are fully displayed.
</text>
<text
follows="top|right"
font="SansSerifSmall"
text_color="White"
height="28"
layout="topleft"
left_pad="10"
name="avatars_frme_pct_lbl"
top="8"
width="75">
Time spent
drawing
avatars
</text>
<text
follows="top|right"
font="SansSerifHuge"
text_color="White"
height="20"
layout="topleft"
left_pad="10"
top="14"
name="av_frame_stats"
width="62">
00%
</text>
<icon
height="16"
width="16"
image_name="Arrow_Right_Off"
mouse_opaque="true"
name="icon_arrow2"
follows="right|top"
top="19"
right="-20" />
</panel>
<panel
bg_alpha_color="PanelGray"
background_visible="true"
background_opaque="false"
border="true"
bevel_style="none"
follows="left|top|right"
height="50"
width="560"
name="complexity_subpanel"
layout="topleft"
top_pad="10">
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="10"
name="complexity_lbl"
top="7"
width="180">
Your avatar complexity
</text>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="10"
name="complexity_info"
top_pad="0"
width="455">
Be a good citizen. Manage the impact of your avatar
</text>
<icon
height="16"
width="16"
image_name="Arrow_Right_Off"
mouse_opaque="true"
name="icon_arrow4"
follows="right|top"
top="19"
right="-20" />
</panel>
<panel
bg_alpha_color="PanelGray"
background_visible="true"
background_opaque="false"
border="true"
bevel_style="none"
follows="left|top|right"
height="50"
width="560"
name="huds_subpanel"
layout="topleft"
top_pad="10">
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="10"
name="huds_lbl"
top="7"
width="135">
Your active HUDs
</text>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="10"
name="huds_desc"
top_pad="0"
width="345">
Removing unnecessary HUDs may improve speed.
</text>
<text
follows="top|right"
font="SansSerifSmall"
text_color="White"
height="28"
layout="topleft"
left_pad="10"
name="huds_frme_pct_lbl"
top="8"
width="75">
Time spent
drawing
HUDs
</text>
<text
follows="top|right"
font="SansSerifHuge"
text_color="White"
height="20"
layout="topleft"
left_pad="10"
top="14"
name="huds_frame_stats"
width="62">
00%
</text>
<icon
height="16"
width="16"
image_name="Arrow_Right_Off"
mouse_opaque="true"
name="icon_arrow4"
follows="right|top"
top="19"
right="-20" />
</panel>
</panel>
<panel
filename="panel_fs_performance_nearby.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_nearby"
visible="false"
top="115" />
<panel
filename="panel_fs_performance_complexity.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_complexity"
visible="false"
top="115" />
<panel
filename="panel_fs_performance_preferences.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_preferences"
visible="false"
top="115" />
<panel
filename="panel_fs_performance_huds.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_huds"
visible="false"
top="115" />
<panel
filename="panel_fs_performance_autotune.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_autotune"
visible="false"
top="115" />
</floater>

View File

@ -556,6 +556,52 @@ HUDs
top="19"
right="-20" />
</panel>
<panel
bg_alpha_color="PanelGray"
background_visible="true"
background_opaque="false"
border="true"
bevel_style="none"
follows="left|top"
height="50"
width="560"
name="autoadjustments_subpanel"
layout="topleft"
top_pad="10">
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="10"
name="auto_adj_lbl"
top="7"
width="175">
Preferred frame rate
</text>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="10"
name="auto_adj_desc"
top_pad="0"
width="485">
Allow automatic adjustments to reach your preferred frame rate (advanced).
</text>
<icon
height="16"
width="16"
image_name="Arrow_Right_Off"
mouse_opaque="true"
name="icon_arrow4"
follows="right|top"
top="19"
right="-20"/>
</panel>
</panel>
<panel
filename="panel_performance_nearby.xml"
@ -582,19 +628,19 @@ HUDs
visible="false"
top="115" />
<panel
filename="panel_performance_huds.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_huds"
visible="false"
top="115" />
filename="panel_performance_huds.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_huds"
visible="false"
top="55" />
<panel
filename="panel_performance_autotune.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_autotune"
visible="false"
top="115" />
filename="panel_performance_autoadjustments.xml"
follows="all"
layout="topleft"
left="0"
name="panel_performance_autoadjustments"
visible="false"
top="55" />
</floater>

View File

@ -39,7 +39,8 @@
max_val="512"
name="DrawDistance"
top_delta="16"
width="330" />
width="330">
</slider>
<text
type="string"
length="1"
@ -521,8 +522,8 @@
label_width="185"
layout="topleft"
left="420"
min_val="1"
max_val="2"
min_val="0"
max_val="4"
name="ObjectMeshDetail"
show_text="false"
top_delta="16"

View File

@ -409,6 +409,59 @@
</stat_view>
</stat_view>
</stat_view>
<stat_view
name="frame_stats"
label="Frame breakdown"
show_label="true">
<stat_bar name="packet_loss"
label="Scenery"
orientation="horizontal"
unit_label=" %"
stat="scenery_frame_pct"
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
<stat_bar name="packet_loss"
label="Avatar"
orientation="horizontal"
unit_label=" %"
stat="avatar_frame_pct"
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
<stat_bar name="packet_loss"
label="UI"
orientation="horizontal"
unit_label=" %"
stat="ui_frame_pct"
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
<stat_bar name="packet_loss"
label="HUDs"
orientation="horizontal"
unit_label=" %"
stat="huds_frame_pct"
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
<stat_bar name="packet_loss"
label="Swap"
orientation="horizontal"
unit_label=" %"
stat="swap_frame_pct"
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
<stat_bar name="packet_loss"
label="Tasks"
orientation="horizontal"
unit_label=" %"
stat="idle_frame_pct"
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
</stat_view>
</container_view>
</scroll_container>
</floater>

View File

@ -1950,6 +1950,41 @@ Graphics Quality can be raised in Preferences &gt; Graphics.
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="AutoFPSConfirmDisable"
type="alertmodal">
Changing this setting will disable automatic adjustment and turn off 'Automatic settings'.
Are you sure you want to continue?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
notext="Cancel"
yestext="Continue"/>
</notification>
<notification
icon="alertmodal.tga"
name="AdvancedLightingConfirm"
type="alertmodal">
To turn on advanced lighting, we need to increase quality to level 4.
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="ShadowsConfirm"
type="alertmodal">
To enable shadows, we need to increase quality to level 4.
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="RegionNoTerraforming"
@ -13868,6 +13903,20 @@ If you want to see this object, remove it and re-attach it to an avatar attachme
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="EnableAutoFPSWarning"
type="alertmodal">
You are about to enable AutoFPS. All unsaved graphics settings will be lost.
Would you like to save them first?
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
notext="No"
yestext="Yes"/>
</notification>
<notification
icon="notify.tga"
name="NoValidEnvSettingFound"

View File

@ -0,0 +1,229 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
bevel_style="none"
follows="left|top"
height="530"
width="580"
name="panel_performance_autotune"
layout="topleft"
left="0"
top="0">
<button
height="16"
width="16"
layout="topleft"
mouse_opaque="true"
follows="left|top"
name="back_btn"
top="7"
image_selected="Arrow_Left_Off"
image_pressed="Arrow_Left_Off"
image_unselected="Arrow_Left_Off"
left="15"
is_toggle="true">
</button>
<text
follows="left|top"
height="20"
layout="topleft"
left_pad="3"
top="10"
name="back_lbl"
width="40">
Back
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="white"
height="20"
layout="topleft"
left="20"
top_pad="10"
name="settings_title"
width="300">
Auto Tune Preferences
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border1"
left="20"
top_pad="8"
width="540" />
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="40"
layout="topleft"
top_pad="20"
left="20"
name="quality_lbl"
width="100"
wrap="true">
Distant Avatars
</text>
<check_box
control_name="AutoTuneImpostorByDistEnabled"
height="19"
label="Enable distance-based optimization"
layout="topleft"
follows="top|left"
left_pad="40"
name="FSAutoTuneImpostorByDistEnabled"
tool_tip="When enabled the viewer will adjust the MaxNonImpostors setting to limit fully rendered avatars to those within the defined radius."
top_delta="0"
width="190" />
<spinner
control_name="AutoTuneImpostorFarAwayDistance"
height="20"
layout="topleft"
label="Farthest full avatar"
label_width="80"
label_wrap="true"
follows="top|left"
name="ffa_autotune"
left_pad="40"
decimal_digits="2"
min_val="16"
max_val="256"
width="140" >
</spinner>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="46"
layout="topleft"
top_pad="15"
left="160"
name="distant_av_advice"
width="450"
wrap="true">
Distant avatars can be automatically optimized regardless of their render cost.
Set the distance from camera beyond which an avatar will be optimized.
Note: This setting will force MaxNonImpostors to 1 if nobody is nearby.
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border2"
top_pad="8"
left="20"
width="540" />
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="36"
layout="topleft"
top_pad="20"
left="20"
name="distance_lbl"
width="100"
wrap="true">
Visibility distance tuning limits
</text>
<spinner
control_name="AutoTuneRenderFarClipMin"
height="20"
layout="topleft"
label="Minimum Distance"
label_width="80"
label_wrap="true"
top_delta="0"
follows="top|left"
name="min_dd_autotune"
decimal_digits="2"
left_pad="40"
min_val="32"
max_val="256"
width="140">
</spinner>
<spinner
control_name="AutoTuneRenderFarClipTarget"
height="20"
layout="topleft"
label="Preferred distance"
label_width="80"
label_wrap="true"
follows="top|left"
name="pref_dd_autotune"
left_pad="20"
min_val="32"
max_val="256"
width="140">
</spinner>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="38"
layout="topleft"
top_pad="15"
left="160"
name="distance_desc1"
wrap="true"
width="400">
When adjusting scene parameters, autotune will choose values between the minimum and the preferred draw distances.
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border2"
top_pad="8"
left="20"
width="540" />
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="36"
layout="topleft"
top_pad="20"
left="20"
name="sundry_lbl"
width="100"
wrap="true">
Sundry Settings
</text>
<check_box
control_name="AllowSelfImpostor"
height="19"
label="Allow your own avatar to be optimized"
layout="topleft"
follows="top|left"
left_pad="40"
name="alow_self_impostor"
tool_tip="When enabled the viewer may render your own avatar as an impostor."
top_delta="0"
width="190" />
<check_box
control_name="ShowTunedART"
height="19"
label="Show optimized render time"
layout="topleft"
follows="top|left"
left_delta="0"
name="show_tuned_art"
tool_tip="When enabled the Time column shows the current render time not the pre-tuning render time."
top_pad="0"
width="190" />
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="38"
layout="topleft"
top_pad="15"
left="160"
name="sundry_desc1"
wrap="true"
width="400">
These options control more subtle settings. Use the online help page to get more information on what these do.
</text>
</panel>

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel bevel_style="none"
follows="left|top"
height="530"
width="580"
name="panel_performance_complexity"
layout="topleft"
left="0"
top="0">
<button height="16"
width="16"
layout="topleft"
mouse_opaque="true"
follows="left|top"
name="back_btn"
top="7"
image_selected="Arrow_Left_Off"
image_pressed="Arrow_Left_Off"
image_unselected="Arrow_Left_Off"
left="15"
is_toggle="true">
</button>
<text follows="left|top"
height="20"
layout="topleft"
left_pad="3"
top="10"
name="back_lbl"
width="40">
Back
</text>
<text follows="left|top"
font="SansSerifLarge"
text_color="white"
height="20"
layout="topleft"
left="20"
top_pad="10"
name="attachments_title"
width="250">
Avatar attachment complexity
</text>
<text follows="right|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
right="-40"
top_delta="0"
name="tot_att_count"
halign="right"
width="200">
Total: 50 (120000.10μs)
</text>
<text follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="5"
left="20"
name="attachments_desc1"
width="580">
Attachments make your avatar more complex and slower to render.
</text>
<text follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="3"
left="20"
name="attachments_desc2"
width="580">
This screen allows you to view the attachments of your own avatar.
</text>
<text follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="3"
left="20"
name="attachments_desc3"
width="580">
You may remove your own attachments quickly and easily by hitting the 'X'.
</text>
<name_list left="20"
column_padding="1"
draw_stripes="true"
draw_heading="true"
height="379"
follows="left|top"
sort_column="1"
sort_ascending="false"
multi_select="false"
layout="topleft"
name="obj_list"
top_pad="10"
width="540">
<name_list.columns label=""
name="art_visual"
width="90" />
<name_list.columns label="Time (μs)"
name="art_value"
tool_tip="Time taken to render this attachment (microseconds)"
width="80" />
<name_list.columns label="ARC"
name="complex_value"
tool_tip="Item complexity (ARC)"
width="40" />
<name_list.columns label="Attachment name"
tool_tip="Click the 'X' to detach"
name="name" />
</name_list>
</panel>

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel bevel_style="none"
follows="left|top"
height="530"
width="580"
name="panel_performance_huds"
layout="topleft"
left="0"
top="0">
<button height="16"
width="16"
layout="topleft"
mouse_opaque="true"
follows="left|top"
name="back_btn"
top="7"
image_selected="Arrow_Left_Off"
image_pressed="Arrow_Left_Off"
image_unselected="Arrow_Left_Off"
left="15"
is_toggle="true">
</button>
<text follows="left|top"
height="20"
layout="topleft"
left_pad="3"
top="10"
name="back_lbl"
width="40">
Back
</text>
<text follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="20"
top_pad="10"
name="huds_title"
width="135">
Your active HUDs
</text>
<text follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="5"
left="20"
name="huds_desc1"
width="540">
Detaching HUDs you aren't using saves memory and can make the viewer run faster.
</text>
<text follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="3"
left="20"
name="huds_desc2"
width="540">
HUDs are often heavily scripted and also contribute to server-side lag.
</text>
<text follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="3"
left="20"
name="huds_desc3"
width="540">
Note: Using a HUD's minimize button does not detach it. Use the X to remove it.
</text>
<name_list
column_padding="1"
draw_stripes="true"
draw_heading="true"
height="380"
follows="left|top"
layout="topleft"
name="hud_list"
top_pad="10"
width="540">
<name_list.columns
label=""
name="art_visual"
width="90" />
<name_list.columns
label="Time (μs)"
name="art_value"
tool_tip="Time taken to render this HUD (microseconds)"
width="80" />
<name_list.columns
label="Name"
tool_tip="Click the 'X' to detach"
name="name" />
</name_list>
</panel>

View File

@ -0,0 +1,294 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
bevel_style="none"
follows="left|top|right"
height="530"
width="580"
name="panel_performance_nearby"
layout="topleft"
left="0"
top="0">
<button
height="16"
width="16"
layout="topleft"
mouse_opaque="true"
follows="left|top"
name="back_btn"
top="7"
image_selected="Arrow_Left_Off"
image_pressed="Arrow_Left_Off"
image_unselected="Arrow_Left_Off"
left="15"
is_toggle="true">
</button>
<text
follows="left|top"
height="20"
layout="topleft"
left_pad="3"
top="10"
name="back_lbl"
width="40">
Back
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
left="20"
top_pad="10"
name="av_nearby_title"
width="205">
Avatars nearby</text>
<text
follows="right|top"
font="SansSerifLarge"
text_color="White"
height="20"
layout="topleft"
right="-40"
top_delta="0"
name="tot_av_count"
halign="right"
width="200">
Total: 50 (120000.10μs)
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left="20"
top_pad="5"
name="av_nearby_desc"
width="580">
Hide the most complex avatars to boost speed.
</text>
<slider
control_name="IndirectMaxComplexity"
visible="false"
tool_tip="Controls at what point a visually complex avatar is drawn as a Impostor"
follows="left|top"
height="16"
initial_value="101"
increment="1"
label="Maximum complexity (K)"
text_color="White"
label_width="165"
layout="topleft"
min_val="1"
max_val="101"
name="IndirectMaxComplexity"
show_text="false"
top_pad="10"
width="300">
</slider>
<text
type="string"
visible="false"
length="1"
follows="left|top"
height="16"
layout="topleft"
top_delta="0"
left_delta="304"
text_color="White"
name="IndirectMaxComplexityText"
width="65">
0
</text>
<slider
control_name="RenderAvatarMaxART"
tool_tip="Controls when a visually complex avatar is considered to be taking too long to render (unit: microseconds)"
follows="left|top"
height="16"
initial_value="4.7"
increment="0.01"
label="Maximum render time (μs)"
text_color="White"
label_width="165"
layout="topleft"
min_val="2"
max_val="4.7"
name="FSRenderAvatarMaxART"
show_text="false"
left_delta="-304"
top_delta="-16"
width="490">
</slider>
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
top_delta="0"
left_pad="5"
text_color="White"
name="FSRenderAvatarMaxARTText"
width="65">
no limit
</text>
<name_list
column_padding="1"
draw_stripes="true"
draw_heading="true"
height="280"
left="20"
follows="left|top|right"
layout="topleft"
sort_column="art_value"
short_names="false"
name="nearby_list"
name_column="name"
top_pad="10"
width="540">
<name_list.columns
label=""
tool_tip="Bar graph showing current render time (includes auto-tuning) as % of slowest."
name="art_visual"
width="90" />
<name_list.columns
label="Time (μs)"
tool_tip="Avatar Render Time. Actual time taken to render this avatar before any auto-tuning (in microseconds)."
name="art_value"
width="80" />
<name_list.columns
label="Adj. Time (μs)"
tool_tip="Avatar Render Time. Actual time taken to render this avatar after adjustments (in microseconds)."
name="adj_art_value"
width="80" />
<name_list.columns
label="ARC"
tool_tip="Complexity (ARC) based on standard rules."
name="complex_value"
width="40" />
<name_list.columns
label=""
tool_tip="Shows any tuning. I=Impostor, S=no shadow."
name="state"
width="15" />
<name_list.columns
label="Name"
name="name"/>
<name_list.columns
label="Breakdown"
tool_tip="Where the rendering time is spent (Geom/Shad/Other)"
name="breakdown"/>
</name_list>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left="20"
top_pad="10"
name="av_nearby_desc2"
width="580">
You can also right-click on an avatar in-world to control display.
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left="20"
top_pad="0"
name="av_nearby_desc3"
width="580">
Note: Your own avatar includes viewer overheads. Use the attachment tab to see how you affect others.
</text>
<check_box
control_name="AlwaysRenderFriends"
height="16"
initial_value="true"
label="Always display friends in full detail"
label_text.text_color="White"
layout="topleft"
name="display_friends"
top_pad="2"
left="18"
width="256">
</check_box>
<button
height="23"
label="Exceptions..."
layout="topleft"
left="460"
top_delta="0"
name="exceptions_btn"
width="100">
</button>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border"
top_pad="10"
left="20"
width="540"/>
<check_box
height="16"
initial_value="true"
label="Hide avatars completely."
layout="topleft"
name="hide_avatars"
top_delta="15"
left="18"
width="280">
</check_box>
<text
type="string"
length="1"
follows="left|top"
height="15"
layout="topleft"
left="20"
name="name_tags_textbox"
top_pad="10"
width="400">
Name tags:
</text>
<radio_group
control_name="AvatarNameTagMode"
height="20"
layout="topleft"
left="120"
top_delta="0"
name="name_tag_mode">
<radio_item
label="Off"
name="radio"
top_delta="20"
layout="topleft"
height="16"
left="0"
value="0"
width="75" />
<radio_item
label="On"
left_pad="0"
layout="topleft"
top_delta="0"
height="16"
name="radio2"
value="1"
width="75" />
<radio_item
label="Show briefly"
left_pad="0"
name="radio3"
height="16"
layout="topleft"
top_delta="0"
value="2"
width="160" />
</radio_group>
</panel>

View File

@ -0,0 +1,516 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
bevel_style="none"
follows="left|top"
height="530"
width="580"
name="panel_performance_preferences"
layout="topleft"
left="0"
top="0">
<button
height="16"
width="16"
layout="topleft"
mouse_opaque="true"
follows="left|top"
name="back_btn"
top="7"
image_selected="Arrow_Left_Off"
image_pressed="Arrow_Left_Off"
image_unselected="Arrow_Left_Off"
left="15"
is_toggle="true">
</button>
<text
follows="left|top"
height="20"
layout="topleft"
left_pad="3"
top="10"
name="back_lbl"
width="40">
Back
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="white"
height="20"
layout="topleft"
left="20"
top_pad="10"
name="settings_title"
width="300">
Graphics settings
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border1"
left="20"
top_pad="8"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="36"
layout="topleft"
top_pad="20"
left="20"
name="quality_lbl"
width="100"
wrap="true">
Quality vs speed
</text>
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
left_pad="40"
name="FasterText"
top_delta="0"
width="40">
Faster
</text>
<icon
color="Slidermark"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_delta="48"
name="LowGraphicsDivet"
top_delta="-2"
width="2" />
<icon
color="Slidermark"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="LowMidGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="Slidermark"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="MidGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="Slidermark"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="MidHighGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="Slidermark"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="HighGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="Slidermark"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="HighUltraGraphicsDivet"
top_delta="0"
width="2" />
<icon
color="Slidermark"
height="14"
image_name="Rounded_Square"
layout="topleft"
left_pad="41"
name="UltraGraphicsDivet"
top_delta="0"
width="2" />
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
left_delta="20"
name="BetterText"
top_delta="0"
width="100">
Better Quality
</text>
<slider
control_name="RenderQualityPerformance"
decimal_digits="0"
follows="left|top"
height="16"
increment="1"
initial_value="0"
layout="topleft"
left_delta="-285"
max_val="6"
name="quality_vs_perf_selection"
show_text="false"
top_delta="-1"
width="275">
</slider>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left="190"
name="ShadersPrefText"
top_delta="20"
width="80">
Low
</text>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left_delta="87"
name="ShadersPrefText2"
top_delta="0"
width="80">
Mid
</text>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left_delta="87"
name="ShadersPrefText3"
top_delta="0"
width="80">
High
</text>
<text
type="string"
length="1"
follows="left|top"
halign="center"
height="12"
layout="topleft"
left_delta="85"
name="ShadersPrefText4"
top_delta="0"
width="80">
Ultra
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="15"
left="160"
name="quality_desc"
width="450">
Choosing a preset will reset all manual changes you have made.
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border2"
top_pad="5"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="36"
layout="topleft"
top_pad="20"
left="20"
name="distance_lbl"
width="100"
wrap="true">
Visibility distance
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left_pad="40"
name="faster_lbl"
width="40"
top_delta="0">
Faster
</text>
<slider
control_name="RenderFarClip"
decimal_digits="0"
follows="left|top"
top_delta="-1"
height="16"
increment="8"
initial_value="160"
label_width="90"
slider_label.halign="right"
layout="topleft"
min_val="32"
max_val="1024"
name="draw_distance"
left_pad="5"
width="310" />
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
left_pad="-8"
top_delta="0"
name="draw_distance_m"
width="20">
m
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left_pad="0"
top_delta="1"
name="farther_lbl"
width="40">
Farther
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="15"
left="160"
name="distance_desc1"
width="450">
Keep this low for better performance, increase it to see further afield.
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border3"
top_pad="5"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="20"
left="20"
name="environment_lbl"
width="100">
Environment
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_delta="0"
left="160"
name="enhancements_desc"
width="450">
Reducing / eliminating shadows can be a boost to FPS but impacts
the ambience and appearance of the scene.
</text>
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
left="160"
name="RenderShadowDetailText"
text_readonly_color="LabelDisabledColor"
top_pad="20"
width="128">
Shadow sources:
</text>
<combo_box
control_name="RenderShadowDetail"
height="18"
layout="topleft"
right="-20"
top_delta="0"
name="ShadowDetail"
width="150">
<combo_box.item
label="None"
name="0"
value="0"/>
<combo_box.item
label="Sun/Moon"
name="1"
value="1"/>
<combo_box.item
label="Sun/Moon + Projectors"
name="2"
value="2"/>
</combo_box>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border3"
top_pad="7"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="20"
left="20"
name="water_lbl"
width="100">
Water
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_delta="0"
left="160"
name="water_desc"
width="450">
Reducing water effects quality can greatly improve frame rate.
</text>
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
name="ReflectionsText"
text_readonly_color="LabelDisabledColor"
top_pad="16"
left="160"
width="128">
Water Reflections:
</text>
<combo_box
control_name="RenderReflectionDetail"
height="18"
layout="topleft"
right="-20"
top_delta="0"
name="Reflections"
width="150">
<combo_box.item
label="None; opaque"
name="-2"
value="-2"/>
<combo_box.item
label="None; transparent"
name="-1"
value="-1"/>
<combo_box.item
label="Minimal"
name="0"
value="0"/>
<combo_box.item
label="Terrain and trees"
name="1"
value="1"/>
<combo_box.item
label="All static objects"
name="2"
value="2"/>
<combo_box.item
label="All avatars and objects"
name="3"
value="3"/>
<combo_box.item
label="Everything"
name="4"
value="4"/>
</combo_box>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border4"
top_pad="7"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="20"
left="20"
name="photo_lbl"
width="100">
Photography
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="48"
layout="topleft"
top_delta="0"
left="160"
name="photo_desc"
width="350">
Photographers need high quality, but this is often
at the cost of frame rate. [APP_NAME] phototools can
help you find the right balance.
</text>
<button
name="open_phototools"
label="Phototools"
tool_tip="Open the dedicated photo tools for advanced photo settings."
top_delta="0"
right="-20"
height="23"
width="120"
follows="bottom|right"
layout="topleft">
<button.init_callback
function="Button.SetFloaterToggle"
parameter="phototools"/>
</button>
</panel>

View File

@ -0,0 +1,319 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
bevel_style="none"
follows="left|top"
height="580"
width="580"
name="panel_performance_autoadjustments"
layout="topleft"
left="0"
top="0">
<button
height="16"
width="16"
layout="topleft"
mouse_opaque="true"
follows="left|top"
name="back_btn"
top="7"
image_selected="Arrow_Left_Off"
image_pressed="Arrow_Left_Off"
image_unselected="Arrow_Left_Off"
left="15"
is_toggle="true">
</button>
<text
follows="left|top"
height="20"
layout="topleft"
left_pad="3"
top="10"
name="back_lbl"
width="40">
Back
</text>
<text
follows="left|top"
font="SansSerifLarge"
text_color="white"
height="20"
layout="topleft"
left="20"
top_pad="10"
name="settings_title"
width="300">
Preferred frame rate
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border0"
top_pad="15"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="20"
name="targetfps_desc"
wrap="true"
width="140"
top_pad="20">
Desired frame rate
</text>
<spinner
name="target_fps"
control_name="TargetFPS"
font="SansSerifLarge"
tool_tip="The viewer will attempt to achieve this by adjusting your graphics settings."
layout="topleft"
follows="right|top"
left_pad="5"
top_delta="0"
height="25"
visible="true"
decimal_digits="0"
increment="1"
initial_value="25"
max_val="300"
min_val="1"
width="48"
label_width="0" />
<button
control_name="AutoTuneFPS"
follows="top|right"
height="24"
initial_value="false"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
label="Start"
label_selected="Stop"
layout="topleft"
left_pad="10"
name="AutoTuneFPS"
top_delta="-1"
tool_tip="The viewer will attempt to adjust settings to meet the target FPS."
width="72">
</button>
<check_box
control_name="AutoTuneLock"
follows="top|right"
height="20"
initial_value="true"
image_pressed="PushButton_Press"
image_pressed_selected="PushButton_Selected_Press"
image_selected="PushButton_Selected_Press"
is_toggle="true"
label="Continuous"
layout="topleft"
left_pad="10"
name="AutoTuneContinuous"
top_delta="0"
tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed. When disabled clicking the Start button will adjust for the current settings then stop."
width="64">
</check_box>
<text
follows="left|top"
font="SansSerif"
text_color="White"
height="20"
layout="topleft"
left="20"
name="settings_desc"
top_pad="20"
wrap="true"
width="150">
Settings affect
</text>
<combo_box
follows="top|left"
font="SansSerif"
height="20"
layout="topleft"
left_pad="15"
control_name="TuningFPSStrategy"
name="TuningFPSStrategy"
width="130">
<combo_box.item
label="Avatars Only"
name="av_only"
value="0" />
<combo_box.item
label="Avatars and Scene"
name="av_and_scene"
value="1" />
<combo_box.item
label="World Only"
name="scene_only"
value="2" />
</combo_box>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border_vsync"
top_pad="20"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left="20"
top_pad="20"
name="vsync_desc"
width="580">
Synchronize the refresh rate and frame rate of a monitor,
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="3"
left="20"
name="vsync_desc2"
width="580">
which can result in smoother performance.
</text>
<check_box
control_name="RenderVSyncEnable"
height="16"
initial_value="true"
label="Enable VSync"
label_text.text_color="White"
layout="topleft"
top_pad="15"
name="vsync"
tool_tip="Enable Vertical synchronization to reduce screen tearing and stuttering."
width="315" />
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border1"
top_pad="20"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left="20"
top_pad="15"
name="simplify_dist_desc"
width="580">
Reducing detail shown on avatars that are far away will improve graphics speed.
</text>
<check_box
control_name="AutoTuneImpostorByDistEnabled"
height="19"
label="Simplify avatars beyond"
label_text.text_color="White"
layout="topleft"
follows="top|left"
name="AutoTuneImpostorByDistEnabled"
tool_tip="When enabled the viewer will adjust the MaxNonImpostors setting to limit fully rendered avatars to those within the defined radius."
top_pad="15"
width="190" />
<spinner
control_name="AutoTuneImpostorFarAwayDistance"
height="20"
layout="topleft"
follows="top|left"
name="ffa_autotune"
left_pad="20"
decimal_digits="2"
min_val="16"
max_val="256"
width="60" >
</spinner>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left_pad="10"
name="dist_meters"
width="70">
meters
</text>
<view_border
bevel_style="in"
height="0"
layout="topleft"
name="border2"
top_pad="20"
left="20"
width="540"/>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left="20"
top_pad="20"
name="dist_limits_desc"
width="580">
Choose the distance range that automatic settings will affect.
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="15"
name="min_dist_lbl"
width="120">
Minimum distance
</text>
<spinner
control_name="AutoTuneRenderFarClipMin"
height="20"
layout="topleft"
left_pad="15"
follows="top|left"
name="min_dd_autotune"
decimal_digits="2"
min_val="32"
max_val="256"
width="60">
</spinner>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="15"
left="20"
name="pref_dist_lbl"
width="120">
Maximum distance
</text>
<spinner
control_name="AutoTuneRenderFarClipTarget"
height="20"
layout="topleft"
follows="top|left"
name="pref_dd_autotune"
left_pad="15"
min_val="32"
max_val="256"
width="60">
</spinner>
</panel>

View File

@ -69,23 +69,22 @@ top="0">
Hide the most complex avatars to boost speed.
</text>
<slider
control_name="IndirectMaxComplexity"
visible="false"
tool_tip="Controls at what point a visually complex avatar is drawn as a Impostor"
control_name="RenderAvatarMaxART"
tool_tip="Controls when a visually complex avatar is considered to be taking too long to render (unit: microseconds)"
follows="left|top"
height="16"
initial_value="101"
increment="1"
label="Maximum complexity (K)"
initial_value="4.7"
increment="0.01"
label="Maximum render time (μs)"
text_color="White"
label_width="165"
layout="topleft"
min_val="1"
max_val="101"
name="IndirectMaxComplexity"
min_val="2"
max_val="4.7"
name="RenderAvatarMaxART"
show_text="false"
top_pad="10"
width="300">
width="490">
</slider>
<text
type="string"
@ -95,11 +94,11 @@ top="0">
height="16"
layout="topleft"
top_delta="0"
left_delta="304"
left_pad="5"
text_color="White"
name="IndirectMaxComplexityText"
name="RenderAvatarMaxARTText"
width="65">
0
no limit
</text>
<slider
control_name="FSRenderAvatarMaxART"

View File

@ -220,6 +220,94 @@ Faster
Ultra
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
top_pad="30"
name="quality_lbl"
width="100">
Quality &amp; Speed
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left_pad="40"
name="fastest_lbl"
width="40">
Fastest
</text>
<radio_group
control_name="RenderQualityPerformance"
follows="top|left"
draw_border="false"
height="25"
layout="topleft"
left_pad="5"
name="graphics_quality"
top_delta="0"
width="243">
<radio_item
height="16"
layout="topleft"
left="3"
name="0"
top="0"
width="7" />
<radio_item
height="16"
layout="topleft"
left_pad="30"
name="1"
width="7" />
<radio_item
height="16"
layout="topleft"
left_pad="30"
name="2"
width="7" />
<radio_item
height="16"
layout="topleft"
left_pad="30"
name="3"
width="7" />
<radio_item
height="16"
layout="topleft"
left_pad="30"
name="4"
width="7" />
<radio_item
height="16"
layout="topleft"
left_pad="30"
name="5"
width="7" />
<radio_item
height="16"
layout="topleft"
left_pad="30"
name="6"
width="7" />
</radio_group>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
height="18"
layout="topleft"
left_pad="10"
top_delta="1"
name="quality_lbl"
width="70">
Best quality
</text>
<text
follows="left|top"
font="SansSerifSmall"
text_color="White"
@ -279,7 +367,8 @@ Faster
max_val="1024"
name="draw_distance"
left_pad="5"
width="310" />
width="250">
</slider>
<text
type="string"
length="1"
@ -513,4 +602,99 @@ help you find the right balance.
function="Button.SetFloaterToggle"
parameter="phototools"/>
</button>
<spinner
control_name="RenderVolumeLODFactor"
follows="left|top"
height="23"
increment="0.125"
label="Distance detail:"
label_width="95"
layout="topleft"
max_val="4"
min_val="0"
name="render_volume_lod"
top_pad="10"
width="150" />
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
top_delta="3"
left_pad="10"
name="photo_desc"
width="180">
(Enter value between 0.0 and 4.0)
</text>
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
top="80"
left="213"
name="1_lbl"
width="7">
1
</text>
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
left_pad="31"
name="2_lbl"
width="7">
2
</text>
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
left_pad="30"
name="3_lbl"
width="7">
3
</text>
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
left_pad="30"
name="4_lbl"
width="7">
4
</text>
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
left_pad="30"
name="5_lbl"
width="7">
5
</text>
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
left_pad="30"
name="6_lbl"
width="7">
6
</text>
<text
follows="left|top"
font="SansSerifSmall"
height="18"
layout="topleft"
left_pad="30"
name="7_lbl"
width="7">
7
</text>
</panel>

View File

@ -57,13 +57,24 @@
width="215" />
<button
name="open_prefs_btn"
label="Open Graphics Preferences"
tool_tip = "Bring up graphics prefs"
label="Graphics Preferences"
tool_tip="Open graphics preferences"
top_delta="3"
left="15"
left="4"
height="22"
width="200">
width="132">
<button.commit_callback
function="Presets.GoGraphicsPrefs" />
</button>
<button
name="open_autofps_btn"
label="Performance"
tool_tip="Open performance window"
top_delta="0"
left_pad="5"
height="22"
width="80">
<button.commit_callback
function="Presets.GoAutofpsPrefs" />
</button>
</panel>

View File

@ -26,7 +26,7 @@
/>
<texture_picker
name="real_world_pic"
image_name="Generic_Person_Large"
fallback_image="Generic_Person_Large"
follows="top|left"
layout="topleft"
show_caption="false"

View File

@ -353,6 +353,7 @@
user_resize="false">
<texture_picker
name="2nd_life_pic"
fallback_image="Generic_Person_Large"
top="0"
left="0"
width="158"

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="performance" title="Améliorer les performances graphiques (expérimental)">
<floater name="performance" title="Améliorer les performances graphiques">
<floater.string name="frame_stats">
Images: [TOT_FRAME_TIME]ms - Scène:[SCENERY_FRAME_PCT]% Avatars:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% Huds:[HUDS_FRAME_PCT]% Swap:[SWAP_FRAME_PCT]% Tâches:[IDLE_FRAME_PCT]%
</floater.string>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater name="performance" title="Migliora Velocità Grafica (sperimentale)">
<floater name="performance" title="Migliora Velocità Grafica">
<floater.string name="frame_stats">
Frame: [TOT_FRAME_TIME]ms - Scenario:[SCENERY_FRAME_PCT]% Avatar:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% HUD:[HUDS_FRAME_PCT]% Swap:[SWAP_FRAME_PCT]% Tasks:[IDLE_FRAME_PCT]%
</floater.string>

Some files were not shown because too many files have changed in this diff Show More