diff --git a/.github/workflows/build_viewer.yml b/.github/workflows/build_viewer.yml index 08872166db..8adec3ef10 100644 --- a/.github/workflows/build_viewer.yml +++ b/.github/workflows/build_viewer.yml @@ -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 }} + diff --git a/doc/contributions.txt b/doc/contributions.txt index 814a323994..5a80916084 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -284,9 +284,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 diff --git a/fsutils/download_list.py b/fsutils/download_list.py index 0747ae7e4c..b8534efeff 100644 --- a/fsutils/download_list.py +++ b/fsutils/download_list.py @@ -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) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 66e272ded5..7c3e7aa128 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -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() diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index eab7c17b71..8b13789179 100644 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1,4 +1 @@ -euclid 5/29/2020 -euclid 7/23/2020 -euclid 4/29/2021 -euclid 10/5/2021 DRTVWR-546 + diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 999d432079..81449b4a42 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -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(); diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp index 90f99e8198..29c6bf0000 100644 --- a/indra/llinventory/llsettingswater.cpp +++ b/indra/llinventory/llsettingswater.cpp @@ -290,6 +290,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); + // 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; + } + // fog_density = pow(fog_density, underwater_fog_mod); } return fog_density; diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index ef7d18ddaf..1390c7ff6b 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -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) { } diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index d8ac4aad43..2bc9842b05 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -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, diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 31a295b34b..c3382e06c5 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -53,6 +53,8 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card); const char* cursorIDToName(int id); // +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); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 66f53f861e..5a3cd6bfbb 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -586,7 +586,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 @@ -1065,6 +1065,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO { current_refresh = 60; } + mRefreshRate = current_refresh; gGLManager.shutdownGL(); //destroy gl context diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5852dd6feb..265eedee5b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -365,8 +365,8 @@ set(viewer_SOURCE_FILES llfloaterpathfindinglinksets.cpp llfloaterpathfindingobjects.cpp llfloaterpay.cpp - # llfloaterperformance.cpp replaced with fs version due to large changes and likelihood that LL version will not release. - fsfloaterperformance.cpp + # llfloaterperformance.cpp + fsfloaterperformance.cpp # 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) + # 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) # - # Performance stast support - list(APPEND viewer_SOURCE_FILES fsperfstats.cpp) - list(APPEND viewer_HEADER_FILES fsperfstats.h) - # source_group("CMake Rules" FILES ViewerInstall.cmake) #build_data.json creation moved to viewer_manifest.py MAINT-6413 diff --git a/indra/newview/NACLantispam.cpp b/indra/newview/NACLantispam.cpp index a72bbbffc8..9b5e709f10 100644 --- a/indra/newview/NACLantispam.cpp +++ b/indra/newview/NACLantispam.cpp @@ -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::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(); } } diff --git a/indra/newview/NACLantispam.h b/indra/newview/NACLantispam.h index d5cf7889a6..cf85aa3dca 100644 --- a/indra/newview/NACLantispam.h +++ b/indra/newview/NACLantispam.h @@ -1,8 +1,8 @@ #ifndef NACL_ANTISPAM_H #define NACL_ANTISPAM_H -#include -#include +#include +#include #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 spam_queue_entry_map_t; -typedef boost::unordered_set collision_sound_set_t; +typedef std::unordered_map spam_queue_entry_map_t; +typedef std::unordered_set 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(); diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 8a68577213..5ea36a044a 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.11 +6.6.12 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b60de07a27..b590a571b4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11706,6 +11706,28 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 + RenderClass0MemoryBandwidth + + Comment + Memory bandwidth at which to default to Class 0 in gigabytes per second. Used as basis for other classes. + Persist + 1 + Type + F32 + Value + 16.0 + + RenderCPUBasis + + Comment + Reference CPU clockspeed to use to bias GPU class (in MHz). + Persist + 1 + Type + F32 + Value + 3000.0 + RenderComplexityColorMin Comment @@ -11981,6 +12003,17 @@ Change of this parameter will affect the layout of buttons in notification toast Backup 0 + RenderShadowSplits + + Comment + Amount of shadow map splits to render (0 - 3). + Persist + 1 + Type + S32 + Value + 3 + RenderSSAOScale Comment @@ -21979,6 +22012,160 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + TargetFPS + + Comment + Desired minimum FPS + Persist + 1 + Type + U32 + Value + 15 + + AutoTuneFPS + + Comment + Allow the viewer to adjust your settings to achieve target FPS + Persist + 1 + Type + Boolean + Value + 0 + + AutoTuneLock + + Comment + When enabled the viewer will dynamically change settings until auto tune is explicitly turned off. + Persist + 1 + Type + Boolean + Value + 0 + + KeepAutoTuneLock + + Comment + When enabled the AutoTuneLock will be maintainted all following sessions. + Persist + 1 + Type + U32 + Value + 1 + + AllowSelfImpostor + + Comment + Allow own render time to impostor your avatar. + Persist + 1 + Type + Boolean + Value + 0 + + ShowTunedART + + Comment + Show the current render time not the pre-tuning render time in the avatar display. + Persist + 1 + Type + Boolean + Value + 1 + + RenderAvatarMaxART + + Comment + Render Time Limit in microseconds (0.0 = no limit) + Persist + 0 + Type + F32 + Value + 4.699 + + AutoTuneRenderFarClipMin + + Comment + The lowest draw distance that auto tune is allowed to use + Persist + 0 + Type + F32 + Value + 32.0 + + AutoTuneRenderFarClipTarget + + Comment + The draw distance that auto tune will try to achieve + Persist + 0 + Type + F32 + Value + 256.0 + + UserTargetReflections + + Comment + Set by auto tune floater on build + Persist + 0 + Type + S32 + Value + 4 + + PerfStatsCaptureEnabled + + Comment + Enable/disable render time data to support autotune. + Persist + 1 + Type + Boolean + Value + 1 + + AutoTuneImpostorByDistEnabled + + Comment + Enable/disable using MaxNonImpostor to limit avatar rendering by distance. + Persist + 1 + Type + Boolean + Value + 0 + + AutoTuneImpostorFarAwayDistance + + Comment + Avatars beyond this range will automatically be optimized + Persist + 0 + Type + F32 + Value + 64.0 + + TuningFPSStrategy + + Comment + Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings, 2=Tune only global scene. + Persist + 1 + Type + U32 + Value + 1 + CameraOpacity Comment @@ -26030,28 +26217,6 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 - FSTargetFPS - - Comment - Desired minimum FPS - Persist - 1 - Type - U32 - Value - 25 - - FSAutoTuneFPS - - Comment - Allow the viewer to adjust your settings to achieve target FPS - Persist - 0 - Type - Boolean - Value - 0 - FSPerfFloaterSmoothingPeriods Comment @@ -26096,127 +26261,6 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 - FSPerfStatsCaptureEnabled - - Comment - Enable/disable render time data to support autotune. - Persist - 1 - Type - Boolean - Value - 1 - - FSAutoTuneImpostorByDistEnabled - - Comment - Enable/disable using MaxNonImpostor to limit avatar rendering by distance. - Persist - 1 - Type - Boolean - Value - 0 - - FSAutoTuneLock - - Comment - When enabled the viewer will dynamically change settings until auto tune is explicitly turned off. - Persist - 1 - Type - Boolean - Value - 1 - - FSAllowSelfImpostor - - Comment - Allow own render time to impostor your avatar. - Persist - 1 - Type - Boolean - Value - 0 - - FSShowTunedART - - Comment - Show the tuned render time in the avatar display. - Persist - 1 - Type - Boolean - Value - 0 - - FSRenderAvatarMaxART - - Comment - Render Time Limit in microseconds (0.0 = no limit) - Persist - 0 - Type - F32 - Value - 4.699 - - FSAutoTuneRenderFarClipMin - - Comment - The lowest draw distance that auto tune is allowed to use - Persist - 0 - Type - F32 - Value - 32.0 - - FSAutoTuneRenderFarClipTarget - - Comment - The draw distance that auto tune will try to achieve - Persist - 0 - Type - F32 - Value - 256.0 - - FSAutoTuneImpostorFarAwayDistance - - Comment - Avatars beyond this range will automatically be optimized - Persist - 0 - Type - F32 - Value - 64.0 - - FSTuningFPSStrategy - - Comment - Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings. - Persist - 1 - Type - U32 - Value - 0 - - FSUserTargetReflections - - Comment - Set by auto tune floater on build - Persist - 0 - Type - S32 - Value - 4 - FSReportRegionRestartToChat Comment @@ -26239,17 +26283,6 @@ Change of this parameter will affect the layout of buttons in notification toast Value 473405 - FSUseCoRoFor360Capture - - Comment - Use co-routine to extract 360 photos. - Persist - 1 - Type - Boolean - Value - 0 - SDL2IMEDefaultVerticalOffset Comment diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 310c0af25d..8113755d78 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -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 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index fb16e7005d..3867a8e8f7 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -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 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index bffbbec13b..f63f65bf3b 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -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 diff --git a/indra/newview/fsfloaterperformance.cpp b/indra/newview/fsfloaterperformance.cpp index 0979553e30..23da5a884c 100644 --- a/indra/newview/fsfloaterperformance.cpp +++ b/indra/newview/fsfloaterperformance.cpp @@ -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" // performance stats support +#include "llwindow.h" #include "fslslbridge.h" #include @@ -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("target_btn")->setCommitCallback(boost::bind(&FSFloaterPerformance::showSelectedPanel, this, mAutoTunePanel)); - tgt_panel->getChild("FSTuningFPSStrategy")->setCurrentByIndex(gSavedSettings.getU32("FSTuningFPSStrategy")); + tgt_panel->getChild("FSTuningFPSStrategy")->setCurrentByIndex(gSavedSettings.getU32("TuningFPSStrategy")); tgt_panel->getChild("PrefSaveButton")->setCommitCallback(boost::bind(&FSFloaterPerformance::savePreset, this)); tgt_panel->getChild("PrefLoadButton")->setCommitCallback(boost::bind(&FSFloaterPerformance::loadPreset, this)); tgt_panel->getChild("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("IndirectMaxComplexity")->setCommitCallback(boost::bind(&FSFloaterPerformance::updateMaxComplexity, this)); - mMaxARTChangedSignal = gSavedSettings.getControl("FSRenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this)); - mNearbyPanel->getChild("FSRenderAvatarMaxART")->setCommitCallback(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this)); + mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&FSFloaterPerformance::updateMaxRenderTime, this)); + mNearbyPanel->getChild("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 fpsCap(gSavedSettings, "FramePerSecondLimit"); // user limited FPS - static LLCachedControl targetFPS(gSavedSettings, "FSTargetFPS"); // desired FPS - static LLCachedControl tuningStrategy(gSavedSettings, "FSTuningFPSStrategy"); + static LLCachedControl targetFPS(gSavedSettings, "TargetFPS"); // desired FPS + static LLCachedControl tuningStrategy(gSavedSettings, "TuningFPSStrategy"); + static LLCachedControl 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("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("frame_breakdown")->setText(getString("frame_stats", args)); auto button = getChild("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 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 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("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 showTunedART(gSavedSettings, "FSShowTunedART"); + static LLCachedControl 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::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(av_item->getColumn(1)); + int colno{1}; + LLScrollListText* art_text = dynamic_cast(av_item->getColumn(colno)); if (art_text) { art_text->setAlignment(LLFontGL::RIGHT); } - LLScrollListText* value_text = dynamic_cast(av_item->getColumn(2)); + colno++; + LLScrollListText* value_text = dynamic_cast(av_item->getColumn(colno)); if (value_text) { value_text->setAlignment(LLFontGL::RIGHT); } - LLScrollListText* state_text = dynamic_cast(av_item->getColumn(3)); + colno++; + if (showTunedART) + { + LLScrollListText* value_text = dynamic_cast(av_item->getColumn(colno)); + if (value_text) + { + value_text->setAlignment(LLFontGL::RIGHT); + } + colno++; + } + LLScrollListText* state_text = dynamic_cast(av_item->getColumn(colno)); if (state_text) { state_text->setAlignment(LLFontGL::HCENTER); } - LLScrollListText* name_text = dynamic_cast(av_item->getColumn(4)); + colno++; + LLScrollListText* name_text = dynamic_cast(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("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("FSRenderAvatarMaxARTText", true), + gSavedSettings.getF32("RenderAvatarMaxART"), + mNearbyPanel->getChild("RenderAvatarMaxARTText", true), true); } diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 5b306eb584..2d820e226d 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -69,6 +69,7 @@ // 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*/ diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a93365820f..6a92e991f1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -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" // Tracy profiler support -#include "fsperfstats.h" // 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); - - // 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; // relocated - FIRE-22297: FPS limiter not working properly on Mac/Linux + { + LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); // perf stats // 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 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 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 // - // FIRE-22297: FPS limiter not working properly on Mac/Linux - LLTimer frameTimer; - {FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // perf stats - nd::etw::logFrame(); // 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(); - } // perf stats (close NonRender/IDLE tracking starting at event pump) - { - {FSPerfStats::RecordSceneTime T (FSPerfStats::StatType_t::RENDER_IDLE); // 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); // 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("mem_leaking"); - if (mem_leak_instance) - { - mem_leak_instance->idle(); - } - } + //memory leaking simulation + if (gSimulateMemLeak) + { + LLFloaterMemLeak* mem_leak_instance = + LLFloaterReg::findTypedInstance("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(); - } - }// 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() // instrument image decodes { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("updateTextureThreads"); - // FSPlot("max_time_ms",max_time); - // work_pending += updateTextureThreads(max_time); } // 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(); @@ -3587,15 +3579,9 @@ void LLAppViewer::initStrings() // } -// -// 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; } @@ -5856,7 +5842,7 @@ void LLAppViewer::idle() if (!(logoutRequestSent() && hasSavedFinalSnapshot())) { - FSPerfStats::tunedAvatars=0; // reset the number of avatars that have been tweaked. + LLPerfStats::tunedAvatars=0; // reset the number of avatars that have been tweaked. gObjectList.update(gAgent); } } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index b71f322060..594cfe513d 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -52,7 +52,7 @@ #include "llglcommonfunc.h" #include "llvoavatar.h" #include "llviewershadermgr.h" -#include "fsperfstats.h" // 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 ratPtr{}; // Perf stats + + std::unique_ptr ratPtr{}; // Perf stats for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo *pparams = *k; if (pparams) { - // Capture render times - if(pparams->mFace) - { - LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) - { - trackAttachments( vobj, false,&ratPtr); - } - } - // - 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 ratPtr{}; // Perf stats + std::unique_ptr ratPtr{}; // Perf stats for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo* pparams = *k; if (pparams) { - // Capture render times - if(pparams->mFace) - { - LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) - { - trackAttachments( vobj, true ,&ratPtr); - } - } - // + 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 ratPtr{}; + std::unique_ptr ratPtr{}; for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) { - // Capture render times - if(pparams->mFace) - { - LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) - { - trackAttachments( vobj, false, &ratPtr); - } - } - // - 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 ratPtr{}; // Perf stats + std::unique_ptr ratPtr{}; // Perf stats for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) { - // Capture render times - if(pparams->mFace) - { - LLViewerObject* vobj = pparams->mFace->getViewerObject(); - if(vobj->isAttachment()) - { - trackAttachments( vobj, true, &ratPtr); - } - } - // + 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 ratPtr{}; + std::unique_ptr ratPtr{}; for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) { - // Capture render times - if((*pparams).mFace) - { - LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); - if(vobj->isAttachment()) - { - trackAttachments( vobj, false, &ratPtr); - } - } - // + 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 ratPtr{}; + std::unique_ptr ratPtr{}; for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) { - // Capture render times - if((*pparams).mFace) - { - LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); - if(vobj->isAttachment()) - { - trackAttachments( vobj, true, &ratPtr); - } - } - // + if((*pparams).mFace) + { + LLViewerObject* vobj = (*pparams).mFace->getViewerObject(); + if(vobj->isAttachment()) + { + trackAttachments( vobj, true, &ratPtr); + } + } if (LLGLSLShader::sCurBoundShaderPtr) { LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 3c215b0b6f..7fc8a43b73 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -49,7 +49,7 @@ #include "llspatialpartition.h" #include "llglcommonfunc.h" #include "llvoavatar.h" -#include "fsperfstats.h" // performance stats support +#include "llperfstats.h" BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; BOOL LLDrawPoolAlpha::sShowDebugAlphaRigged = FALSE; @@ -348,11 +348,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 ratPtr{}; // Render time Stats collection + std::unique_ptr 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; @@ -545,17 +554,15 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector& mask |= LLVertexBuffer::MAP_WEIGHT4; - std::unique_ptr ratPtr{}; // Render time Stats collection + std::unique_ptr ratPtr{}; // Render time Stats collection for (LLDrawInfo* draw : emissives) { - // 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 ); - } - // + 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) @@ -630,8 +637,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 ratPtr{}; // Render time Stats collection - for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + std::unique_ptr 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) @@ -653,17 +660,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) continue; } - // Capture render times - if(params.mFace) - { - LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - - if(vobj->isAttachment()) - { - trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); - } - } - // + if(params.mFace) + { + LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); + + if(vobj->isAttachment()) + { + trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); + } + } if(depth_only) { @@ -856,6 +861,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 // + 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) { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 5aa172e0c1..13bb10cc4e 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -52,6 +52,7 @@ #include "llviewerpartsim.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewertexturelist.h" +#include "llperfstats.h" // Add avatar hitbox debug #include "llviewercontrol.h" @@ -59,7 +60,6 @@ // void drawBoxOutline(const LLVector3& pos,const LLVector3& size); // llspatialpartition.cpp // #include "llnetmap.h" -#include "fsperfstats.h" // 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(); - // 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)) - // + 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); // Add avatar hitbox debug static LLCachedControl render_hitbox(gSavedSettings, "DebugRenderHitboxes", false); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 7231381667..65de49dd16 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -49,7 +49,7 @@ #include "llspatialpartition.h" #include "llviewershadermgr.h" #include "llmodel.h" -#include "fsperfstats.h" // 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 ratPtr{}; // render time capture - for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) + std::unique_ptr ratPtr{}; + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; - // Capture render times - LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - if( vobj && vobj->isAttachment() ) - { - trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); - } - // + 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 ratPtr{}; // render time capture + std::unique_ptr ratPtr{}; for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; - // 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 ); } } - // 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 ratPtr{}; // render time capture + std::unique_ptr ratPtr{}; for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; @@ -1390,6 +1388,16 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask) } // + 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) diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index d4539c6916..f2408a3294 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -32,7 +32,7 @@ #include "pipeline.h" #include "llglcommonfunc.h" #include "llvoavatar.h" -#include "fsperfstats.h" // 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 ratPtr{}; // render time capture - for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) + std::unique_ptr ratPtr{}; + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; - // Capture render times - if(params.mFace) - { - LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - - if( vobj && vobj->isAttachment() ) - { - trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); - } - } - // + 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); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 29e321cb3c..e52500ce3f 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -60,7 +60,7 @@ // [RLVa:KB] - Checked: RLVa-2.0.0 #include "rlvhandler.h" // [/RLVa:KB] -#include "fsperfstats.h" // performance stats support +#include "llperfstats.h" #if LL_LINUX // Work-around spurious used before init warning on Vector4a diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 0e0cf3c1a1..ba6fbf35ac 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -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; } diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h index 42a226cd18..651404d890 100644 --- a/indra/newview/llfeaturemanager.h +++ b/indra/newview/llfeaturemanager.h @@ -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; diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index 8cdf3f7bf6..0648d651d1 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -323,25 +323,7 @@ const std::string LLFloater360Capture::getHTMLBaseFolder() // triggered when the 'capture' button in the UI is pressed void LLFloater360Capture::onCapture360ImagesBtn() { - // 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")) - { - // - // 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(); - }); - // FIRE-31942 Avoid CoRo that appears to never usefully yield - } - else - { - capture360Images(); - } - // + 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")) // 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 diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp index 866f5c7638..d3b549258b 100644 --- a/indra/newview/llfloateravatarrendersettings.cpp +++ b/indra/newview/llfloateravatarrendersettings.cpp @@ -91,8 +91,6 @@ BOOL LLFloaterAvatarRenderSettings::postBuild() LLFloater::postBuild(); mAvatarSettingsList = getChild("render_settings_list"); mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3)); - mAvatarSettingsList->setAlternateSort(); - getChild("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)); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index bedfd6a9f7..244e47b706 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -164,6 +164,49 @@ BOOL LLFloaterImagePreview::postBuild() } getChild("temp_check")->setVisible(enable_temp_uploads); // + + // detect and strip empty alpha layers from images on upload + getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnUpload, this)); + + getChild("uploaded_size_text")->setTextArg("[X_RES]", llformat("%d", mRawImagep->getWidth())); + getChild("uploaded_size_text")->setTextArg("[Y_RES]", llformat("%d", mRawImagep->getHeight())); + + mEmptyAlphaCheck = getChild("strip_alpha_check"); + + if (mRawImagep->getComponents() != 4) + { + getChild("image_alpha_warning")->setVisible(false); + getChild("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("image_alpha_warning")->setVisible(true); + + mEmptyAlphaCheck->setCommitCallback(boost::bind(&LLFloaterImagePreview::emptyAlphaCheckboxCallback, this)); + mEmptyAlphaCheck->setValue(true); + } + else + { + getChild("image_alpha_warning")->setVisible(false); + mEmptyAlphaCheck->setValue(false); + } + + getChild("uploaded_size_text")->setTextArg("[ALPHA]", getString(mEmptyAlphaCheck->getValue() ? "no_alpha" : "with_alpha")); + // } else { @@ -181,47 +224,6 @@ BOOL LLFloaterImagePreview::postBuild() // detect and strip empty alpha layers from images on upload // getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); - getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnUpload, this)); - - getChild("uploaded_size_text")->setTextArg("[X_RES]", llformat("%d", mRawImagep->getWidth())); - getChild("uploaded_size_text")->setTextArg("[Y_RES]", llformat("%d", mRawImagep->getHeight())); - - mEmptyAlphaCheck = getChild("strip_alpha_check"); - - if (mRawImagep->getComponents() != 4) - { - getChild("image_alpha_warning")->setVisible(false); - getChild("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("image_alpha_warning")->setVisible(true); - - mEmptyAlphaCheck->setCommitCallback(boost::bind(&LLFloaterImagePreview::emptyAlphaCheckboxCallback, this)); - mEmptyAlphaCheck->setValue(true); - } - else - { - getChild("image_alpha_warning")->setVisible(false); - mEmptyAlphaCheck->setValue(false); - } - - getChild("uploaded_size_text")->setTextArg("[ALPHA]", getString(mEmptyAlphaCheck->getValue() ? "no_alpha" : "with_alpha")); - // return TRUE; } diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp new file mode 100644 index 0000000000..e35fa55564 --- /dev/null +++ b/indra/newview/llfloaterperformance.cpp @@ -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("panel_performance_main"); + mNearbyPanel = getChild("panel_performance_nearby"); + mComplexityPanel = getChild("panel_performance_complexity"); + mSettingsPanel = getChild("panel_performance_preferences"); + mHUDsPanel = getChild("panel_performance_huds"); + mAutoadjustmentsPanel = getChild("panel_performance_autoadjustments"); + + getChild("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel)); + getChild("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel)); + getChild("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel)); + getChild("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel)); + getChild("autoadjustments_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mAutoadjustmentsPanel)); + + initBackBtn(mNearbyPanel); + initBackBtn(mComplexityPanel); + initBackBtn(mSettingsPanel); + initBackBtn(mHUDsPanel); + initBackBtn(mAutoadjustmentsPanel); + + mHUDList = mHUDsPanel->getChild("hud_list"); + mHUDList->setNameListType(LLNameListCtrl::SPECIAL); + mHUDList->setHoverIconName("StopReload_Off"); + mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + + mObjectList = mComplexityPanel->getChild("obj_list"); + mObjectList->setNameListType(LLNameListCtrl::SPECIAL); + mObjectList->setHoverIconName("StopReload_Off"); + mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + + mSettingsPanel->getChild("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); + mSettingsPanel->getChild("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this)); + mSettingsPanel->getChild("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2)); + mSettingsPanel->getChild("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this)); + mSettingsPanel->getChild("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this)); + + mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); + mNearbyPanel->getChild("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this)); + mNearbyPanel->getChild("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); + mNearbyList = mNearbyPanel->getChild("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("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("vsync_desc_limit")->setTextArg("[FPS_LIMIT]", fps_limit); + mAutoadjustmentsPanel->getChild("display_desc")->setTextArg("[FPS_LIMIT]", fps_limit); + mAutoadjustmentsPanel->getChild("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this)); + + mStartAutotuneBtn = mAutoadjustmentsPanel->getChild("start_autotune"); + mStopAutotuneBtn = mAutoadjustmentsPanel->getChild("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("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("back_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this)); + + panel->getChild("back_lbl")->setShowCursorHand(false); + panel->getChild("back_lbl")->setSoundFlags(LLView::MOUSE_UP); + panel->getChild("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(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 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(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 showTunedART(gSavedSettings, "ShowTunedART"); + S32 prev_pos = mNearbyList->getScrollPos(); + LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem(); + mNearbyList->clearRows(); + mNearbyList->updateColumns(true); + + static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); + std::vector valid_nearby_avs; + mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs); + + std::vector::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(*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(av_item->getColumn(1)); + if (value_text) + { + value_text->setAlignment(LLFontGL::HCENTER); + } + LLScrollListText* name_text = dynamic_cast(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(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("fps_value")->setValue(current_fps); + + std::string fps_text = getString("fps_text"); + static LLCachedControl 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("fps_lbl")->setValue(fps_text); +} + +void LLFloaterPerformance::detachItem(const LLUUID& item_id) +{ + LLAppearanceMgr::instance().removeItemFromAvatar(item_id); +} + +void LLFloaterPerformance::onClickAdvanced() +{ + LLFloaterPreference* instance = LLFloaterReg::getTypedInstance("preferences"); + if (instance) + { + instance->saveSettings(); + } + LLFloaterReg::showInstance("prefs_graphics_advanced"); +} + +void LLFloaterPerformance::onClickDefaults() +{ + LLFloaterPreference* instance = LLFloaterReg::getTypedInstance("preferences"); + if (instance) + { + instance->setRecommendedSettings(); + } +} + +void LLFloaterPerformance::onChangeQuality(const LLSD& data) +{ + LLFloaterPreference* instance = LLFloaterReg::getTypedInstance("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("RenderAvatarMaxART"), + mNearbyPanel->getChild("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(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¬if, const LLSD&resp) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); + if (opt == 0) + { + LLFloaterPreference* instance = LLFloaterReg::getTypedInstance("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 auto_tune_locked(gSavedSettings, "AutoTuneLock"); + mStartAutotuneBtn->setEnabled(!autotune_enabled && !auto_tune_locked); + mStopAutotuneBtn->setEnabled(autotune_enabled && !auto_tune_locked); + getChild("AutoTuneContinuous")->setEnabled(!autotune_enabled || (autotune_enabled && auto_tune_locked)); + + getChild("wip_desc")->setVisible(autotune_enabled && !auto_tune_locked); + getChild("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 diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h new file mode 100644 index 0000000000..00f904f6d6 --- /dev/null +++ b/indra/newview/llfloaterperformance.h @@ -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 diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 13e5e45068..aef117941e 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -54,6 +54,7 @@ #include "llfloaterabout.h" #include "llfavoritesbar.h" #include "llfloaterpreferencesgraphicsadvanced.h" +#include "llfloaterperformance.h" #include "llfloatersidepanelcontainer.h" // [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 // -#include "fsperfstats.h"// perfstats - // 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) // 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)); // 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) // FIRE-19810: Make presets global since PresetGraphicActive setting is global as well //bool started = (LLStartUp::getStartupState() == STATE_STARTED); - - //LLButton* load_btn = findChild("PrefLoadButton"); + //LLButton* load_btn = findChild("PrefLoadButton"); //LLButton* save_btn = findChild("PrefSaveButton"); //LLButton* delete_btn = findChild("PrefDeleteButton"); //LLButton* exceptions_btn = findChild("RenderExceptionsButton"); - //if (load_btn && save_btn && delete_btn && exceptions_btn) + // LLButton* auto_adjustments_btn = findChild("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); //} // collectSearchableItems(); @@ -1257,6 +1260,7 @@ void LLFloaterPreference::onOpen(const LLSD& key) if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) tabcontainer->selectFirstTab(); // + } // 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 //} // + 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& names) { LLView* view = findChild("display"); @@ -2853,24 +2886,23 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool sh } } -// 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)); + } } -// + void LLFloaterPreference::updateMaxComplexity() { // Called when the IndirectMaxComplexity control changes @@ -3034,6 +3066,17 @@ void LLFloaterPreference::onClickRenderExceptions() LLFloaterReg::showInstance("avatar_render_settings"); } +// Not currently used in FS +// void LLFloaterPreference::onClickAutoAdjustments() +// { +// LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance("performance"); +// if (performance_floater) +// { +// performance_floater->showAutoadjustmentsPanel(); +// } +// } +// + void LLFloaterPreference::onClickAdvanced() { LLFloaterReg::showInstance("prefs_graphics_advanced"); @@ -3056,6 +3099,22 @@ void LLFloaterPreference::onClickActionChange() updateClickActionControls(); } +void LLFloaterPreference::onAtmosShaderChange() +{ + LLCheckBoxCtrl* ctrl_alm = getChild("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"); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 6aeaeb7af3..726ee89daa 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -158,6 +158,8 @@ protected: // updates click/double-click action keybindngs depending on view values void updateClickActionControls(); + void onAtmosShaderChange(); + // 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: // 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); - // 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); - // + static void setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val = false); static void setIndirectControls(); static void setIndirectMaxNonImpostors(); static void setIndirectMaxArc(); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp index 653d26ff30..ad5edf0862 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -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("IndirectMaxComplexityText", true)); } +void LLFloaterPreferenceGraphicsAdvanced::updateObjectMeshDetailText() +{ + updateSliderText(getChild("ObjectMeshDetail", true), getChild("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("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("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("TransparentWater"); - // Bump & Shiny LLCheckBoxCtrl* bumpshiny_ctrl = getChild("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); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h index c5d21ba35b..2c92f3dbf1 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h @@ -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 diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index fd01c4bf4d..8290b9614e 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1134,6 +1134,7 @@ private: //----------------------------------------------------------------------------- // gpu_benchmark() +// returns measured memory bandwidth of GPU in gigabytes per second //----------------------------------------------------------------------------- F32 gpu_benchmark() { diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 5d88f356db..5051c8b324 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -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); } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 3632d7c631..30c879f8ed 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -86,15 +86,18 @@ void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id) mSelfProfile = (getAvatarId() == gAgentID); // FIRE-32179: Make drag-n-drop sharing of items possible again - LLProfileDropTarget* target = getChild("drop_target"); - if (avatar_id == gAgentID) + LLProfileDropTarget* target = findChild("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); + } } // } diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 8f9bb63522..39eb6d82eb 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -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("LOD_swap_ll_default"); tb->setToolTip(getString("ll_lod_tooltip_msg",args)); diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp index e59ec12529..64580b8490 100644 --- a/indra/newview/llpanelpresetspulldown.cpp +++ b/indra/newview/llpanelpresetspulldown.cpp @@ -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("performance"); + FSFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance("performance"); + if (performance_floater) + { + //performance_floater->showAutoadjustmentsPanel(); + performance_floater->showMainPanel(); + } +} diff --git a/indra/newview/llpanelpresetspulldown.h b/indra/newview/llpanelpresetspulldown.h index c0d32b9b21..79bd6886b1 100644 --- a/indra/newview/llpanelpresetspulldown.h +++ b/indra/newview/llpanelpresetspulldown.h @@ -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 mPresetNames; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index d213e8e535..d9bc087e83 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1201,7 +1201,9 @@ void LLPanelProfileSecondLife::resetData() resetLoading(); // Set default image and 1:1 dimensions for it - mSecondLifePic->setValue("Generic_Person_Large"); + // Retain texture picker for profile images + //mSecondLifePic->setValue("Generic_Person_Large"); + mSecondLifePic->setImageAssetID(LLUUID::null); mImageId = LLUUID::null; // 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"); + // Retain texture picker for profile images + //mPicture->setValue("Generic_Person_Large"); + mPicture->setImageAssetID(LLUUID::null); mImageId = LLUUID::null; // remove the buttons and just have click image to update profile diff --git a/indra/newview/fsperfstats.cpp b/indra/newview/llperfstats.cpp similarity index 66% rename from indra/newview/fsperfstats.cpp rename to indra/newview/llperfstats.cpp index 9b283feb00..2aedaf7022 100644 --- a/indra/newview/fsperfstats.cpp +++ b/indra/newview/llperfstats.cpp @@ -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 extern LLControlGroup gSavedSettings; -namespace FSPerfStats +namespace LLPerfStats { +// extra profiling #ifdef USAGE_TRACKING std::atomic inUse{0}; std::atomic inUseAvatar{0}; @@ -46,20 +48,24 @@ namespace FSPerfStats std::atomic inUseAttachmentRigged{0}; std::atomic inUseAttachmentUnRigged{0}; #endif - +// std::atomic tunedAvatars{0}; std::atomic 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 StatsRecorder::writeBuffer{0}; bool StatsRecorder::collectionEnabled{true}; LLUUID StatsRecorder::focusAv{LLUUID::null}; + bool StatsRecorder::autotuneInit{false}; std::array StatsRecorder::statsDoubleBuffer{ {} }; std::array StatsRecorder::max{ {} }; std::array 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(ObjType_t::OT_GENERAL)][LLUUID::null]; auto& lastStats = statsDoubleBuffer[writeBuffer ^ 1][static_cast(ObjType_t::OT_GENERAL)][LLUUID::null]; @@ -170,11 +190,13 @@ namespace FSPerfStats StatType_t::RENDER_COMBINED, StatType_t::RENDER_IDLE }; - + // restore FPSLimit reporting + // if( /*sceneStats[static_cast(StatType_t::RENDER_FPSLIMIT)] != 0 ||*/ sceneStats[static_cast(StatType_t::RENDER_SLEEP)] != 0 ) if( sceneStats[static_cast(StatType_t::RENDER_FPSLIMIT)] != 0 || sceneStats[static_cast(StatType_t::RENDER_SLEEP)] != 0 ) + // { unreliable = true; - lastStats[static_cast(StatType_t::RENDER_FPSLIMIT)] = sceneStats[static_cast(StatType_t::RENDER_FPSLIMIT)]; + lastStats[static_cast(StatType_t::RENDER_FPSLIMIT)] = sceneStats[static_cast(StatType_t::RENDER_FPSLIMIT)];// restore FPSLimit reporting lastStats[static_cast(StatType_t::RENDER_SLEEP)] = sceneStats[static_cast(StatType_t::RENDER_SLEEP)]; lastStats[static_cast(StatType_t::RENDER_FRAME)] = sceneStats[static_cast(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 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 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);// 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)// restore FPSLimit reporting { // This could be problematic. tot_frame_time_raw -= tot_limit_time_raw; - } + }// 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) ); } } } } } -} \ No newline at end of file +} diff --git a/indra/newview/fsperfstats.h b/indra/newview/llperfstats.h similarity index 75% rename from indra/newview/fsperfstats.h rename to indra/newview/llperfstats.h index 2e610d08c0..706cc94516 100644 --- a/indra/newview/fsperfstats.h +++ b/indra/newview/llperfstats.h @@ -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 #include @@ -35,12 +34,12 @@ #include #include "lluuid.h" #include "llfasttimer.h" -#include "blockingconcurrentqueue.h" +#include "blockingconcurrentqueue.h" // 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 +// 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 - +// extern U32 gFrameCount; extern LLUUID gAgentID; -namespace FSPerfStats +namespace LLPerfStats { +// Additional logging options. These can skew inworld numbers so onyl use for debugging and tracking issues #ifdef USAGE_TRACKING extern std::atomic inUse; extern std::atomic inUseAvatar; @@ -63,10 +63,11 @@ namespace FSPerfStats extern std::atomic inUseAttachmentRigged; extern std::atomic inUseAttachmentUnRigged; #endif +// // 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 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,// 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{ + // we don't want to be using lock based queues + // using Queue = LLThreadSafeQueue; using Queue = moodycamel::BlockingConcurrentQueue; + // 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;}; + // 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});}; - + // 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(FSPerfStats::StatType_t::STATS_COUNT)>; - using StatsMap = std::unordered_map; - using StatsTypeMatrix = std::array(FSPerfStats::ObjType_t::OT_COUNT)>; - using StatsSummaryArray = std::array(FSPerfStats::ObjType_t::OT_COUNT)>; + using StatsArray = std::array(LLPerfStats::StatType_t::STATS_COUNT)>; + using StatsMap = std::unordered_map; // + using StatsTypeMatrix = std::array(LLPerfStats::ObjType_t::OT_COUNT)>; + using StatsSummaryArray = std::array(LLPerfStats::ObjType_t::OT_COUNT)>; static std::atomic writeBuffer; static LLUUID focusAv; + static bool autotuneInit; static std::array statsDoubleBuffer; static std::array max; static std::array sum; @@ -264,12 +281,13 @@ namespace FSPerfStats auto& avKey{upd.avID}; auto type {upd.statType}; auto val {upd.time}; - + // 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 + // if (ot == ObjType_t::OT_GENERAL) { @@ -346,8 +364,24 @@ namespace FSPerfStats while( enabled() && !LLApp::isExiting() ) { + // 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"); + // 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"); // } } @@ -384,29 +418,35 @@ namespace FSPerfStats start{LLTrace::BlockTimer::getCPUClockCount64()}, stat{type, ObjTypeDiscriminator, std::move(av), std::move(id), 0, isRiggedAtt, isHUDAtt} { + // 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 - + // }; template < ObjType_t OD = ObjTypeDiscriminator, @@ -414,71 +454,75 @@ namespace FSPerfStats explicit RecordTime( StatType_t type ):RecordTime(LLUUID::null, LLUUID::null, type ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + // 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 + // }; template < ObjType_t OD = ObjTypeDiscriminator, std::enable_if_t * = nullptr> RecordTime( const LLUUID & av, StatType_t type ):RecordTime(std::move(av), LLUUID::null, type) { + // 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 - + // }; ~RecordTime() { - if(!FSPerfStats::StatsRecorder::enabled()) + if(!LLPerfStats::StatsRecorder::enabled()) { return; } - LL_PROFILE_ZONE_COLOR(tracy::Color::Red); + //LL_PROFILE_ZONE_COLOR(tracy::Color::Red); + // 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 + // stat.time = LLTrace::BlockTimer::getCPUClockCount64() - start; - + // 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 - + // StatsRecorder::send(std::move(stat)); }; }; - - inline double raw_to_ns(U64 raw) { return (static_cast(raw) * 1000000000.0) / FSPerfStats::cpu_hertz; }; - inline double raw_to_us(U64 raw) { return (static_cast(raw) * 1000000.0) / FSPerfStats::cpu_hertz; }; - inline double raw_to_ms(U64 raw) { return (static_cast(raw) * 1000.0) / FSPerfStats::cpu_hertz; }; + inline double raw_to_ns(U64 raw) { return (static_cast(raw) * 1000000000.0) / LLPerfStats::cpu_hertz; }; + inline double raw_to_us(U64 raw) { return (static_cast(raw) * 1000000.0) / LLPerfStats::cpu_hertz; }; + inline double raw_to_ms(U64 raw) { return (static_cast(raw) * 1000.0) / LLPerfStats::cpu_hertz; }; using RecordSceneTime = RecordTime; using RecordAvatarTime = RecordTime; using RecordAttachmentTime = RecordTime; using RecordHudAttachmentTime = RecordTime; -};// namespace FSPerfStats +};// namespace LLPerfStats // helper functions -using RATptr = std::unique_ptr; -using RSTptr = std::unique_ptr; +using RATptr = std::unique_ptr; +using RSTptr = std::unique_ptr; template 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) { + // 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 + // if (*ratPtrp) { // deliberately reset to ensure destruction before construction of replacement. ratPtrp->reset(); }; - *ratPtrp = std::make_unique( + *ratPtrp = std::make_unique( 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 \ No newline at end of file +#endif diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp index 800b5b34db..1d21442d89 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -42,7 +42,7 @@ #include "llagentcamera.h" #include "llfile.h" #include "quickprefs.h" -#include "fsperfstats.h" // avoid triggering reloads while autotuning +#include "llperfstats.h" LLPresetsManager::LLPresetsManager() // 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; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index e24fd6b3dd..8e0f9eb8b4 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -212,8 +212,8 @@ #include "llenvironment.h" #include "llstacktrace.h" -#include "fsperfstats.h" #include "threadpool.h" +#include "llperfstats.h" #if LL_WINDOWS @@ -2223,9 +2223,8 @@ bool idle_startup() update_static_eyes(); // - // - gAgent.addRegionChangedCallback(boost::bind(&FSPerfStats::StatsRecorder::clearStats)); - // + + gAgent.addRegionChangedCallback(boost::bind(&LLPerfStats::StatsRecorder::clearStats)); // *Note: this is where gWorldMap used to be initialized. @@ -3093,7 +3092,7 @@ bool idle_startup() if (STATE_CLEANUP == LLStartUp::getStartupState()) { - set_startup_status(1.0, "", ""); + set_startup_status(1.0, "", ""); display_startup(); if (!mBenefitsSuccessfullyInit) @@ -3220,6 +3219,8 @@ bool idle_startup() LLUIUsage::instance().clear(); + LLPerfStats::StatsRecorder::setAutotuneInit(); + // FIRE-6643 Display MOTD when login screens are disabled if (gSavedSettings.getBOOL("FSDisableLoginScreens")) { @@ -4396,10 +4397,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); - // Performance floater initialisation - FSPerfStats::StatsRecorder::setEnabled(gSavedSettings.getBOOL("FSPerfStatsCaptureEnabled")); - FSPerfStats::StatsRecorder::setFocusAv(gAgentID); - // // 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")) @@ -4409,6 +4406,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); diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 3c73ed7857..bbeab246b6 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -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 @@ -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; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 5c00375a93..85203f2503 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -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" // 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) } // -// perrf floater stuffs void handleTargetFPSChanged(const LLSD& newValue) { - const auto targetFPS = gSavedSettings.getU32("FSTargetFPS"); - FSPerfStats::tunables.userTargetFPS = targetFPS; -} -// 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); } -// 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; } -// // 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); // Is done inside XUI now, using visibility_control // setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel); // @@ -1335,16 +1357,27 @@ void settings_setup_listeners() // setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel); // 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); // 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() // Better asset cache size control setting_setup_signal_listener(gSavedSettings, "FSDiskCacheSize", handleDiskCacheSizeChanged); - // 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); - // // Handle IME text input getting enabled or disabled #if LL_SDL2 diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index d46fbadd34..dcb4a34ccd 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -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" // performance stats support extern LLPointer gStartTexture; extern bool gShiftFrame; @@ -287,8 +287,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); // 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(); // Factor out calls to getInstance @@ -1194,8 +1194,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); // 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(); @@ -1402,8 +1402,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 ); // 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(); @@ -1492,8 +1492,8 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap"); void swap() { - FSPerfStats::RecordSceneTime T ( FSPerfStats::StatType_t::RENDER_SWAP ); // 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) { diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 86ed25b744..88c80444d9 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -108,7 +108,7 @@ #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" #include "llfloaterpay.h" -// #include "llfloaterperformance.h" rename to fs as ll version no released +// #include "llfloaterperformance.h" 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); LLFloaterReg::add("money_tracker", "floater_fs_money_tracker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("particle_editor","floater_particle_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("performance", "floater_fs_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add(PHOTOTOOLS_FLOATER, "floater_phototools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("phototools_camera", "floater_phototools_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("quickprefs", "floater_quickprefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index fcc770870f..3ec8b2a93b 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -55,7 +55,7 @@ #include "m3math.h" #include "m4math.h" #include "llmatrix4a.h" -#include "fsperfstats.h" // 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; } - // render time capture - // TODO(Beq) This path does not appear to have attachments. Prove this then remove. - std::unique_ptr ratPtr{}; - auto vobj = mFace->getViewerObject(); - if( vobj && vobj->isAttachment() ) - { - trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr ); - } -// + // render time capture + // This path does not appear to have attachments. Prove this then remove. + std::unique_ptr 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; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 47715e3708..f77ed8abaf 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -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; } diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 83ffc540ab..2f588b19ef 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -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 AVATAR_EDIT_TIME("avataredittime", "Second LLTrace::EventStatHandle > OBJECT_CACHE_HIT_RATE("object_cache_hits"); LLTrace::EventStatHandle TEXTURE_FETCH_TIME("texture_fetch_time"); + +LLTrace::SampleStatHandle > SCENERY_FRAME_PCT("scenery_frame_pct"); +LLTrace::SampleStatHandle > AVATAR_FRAME_PCT("avatar_frame_pct"); +LLTrace::SampleStatHandle > HUDS_FRAME_PCT("huds_frame_pct"); +LLTrace::SampleStatHandle > UI_FRAME_PCT("ui_frame_pct"); +LLTrace::SampleStatHandle > SWAP_FRAME_PCT("swap_frame_pct"); +LLTrace::SampleStatHandle > 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; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index eb1c3a3043..ffca088bc4 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -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 diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 04bf69c768..e76b1d073f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -119,6 +119,8 @@ #include "llrendersphere.h" #include "llskinningutil.h" +#include "llperfstats.h" + #include #include "fscommon.h" @@ -135,7 +137,6 @@ #include "fslslbridge.h" // Movelock position refresh #include "fsdiscordconnect.h" // tapping a place that happens on landing in world to start up discord -#include "fsperfstats.h" // 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 LLVOAvatar::sCloudTexture = NULL; +std::vector LLVOAvatar::sAVsIgnoringARTLimit; +S32 LLVOAvatar::sAvatarsNearby = 0; //----------------------------------------------------------------------------- // Helper functions @@ -890,12 +895,17 @@ LLVOAvatar::~LLVOAvatar() debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); } - // 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()); + // only call logPendingPhases if we're still alive. Otherwise this can lead to shutdown crashes // logPendingPhases(); if (isAgentAvatarValid()) logPendingPhases(); - // 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; } - // record time and refresh "tooSlow" status - FSPerfStats::RecordAvatarTime T(getID(), FSPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time. - updateTooSlow(); - // ; + // record time and refresh "tooSlow" status + LLPerfStats::RecordAvatarTime T(getID(), LLPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time. + updateTooSlow(); + static LLCachedControl 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() // else { - muted = isTooComplex(); + muted = isTooComplex(); // this should not trigger based on perfstats } } @@ -9196,95 +9206,6 @@ BOOL LLVOAvatar::isFullyLoaded() const // return (mRenderUnloadedAvatar || mFullyLoaded); } -// 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 alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends"); - static LLCachedControl 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 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++; // increment the number of avatars that have been tweaked. - } -} -// - bool LLVOAvatar::isTooComplex() const { bool too_complex; @@ -9312,6 +9233,182 @@ bool LLVOAvatar::isTooComplex() const return too_complex; } +bool LLVOAvatar::isTooSlow() const +{ + static LLCachedControl 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 +// 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; +} +// +// 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 alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends"); + static LLCachedControl allowSelfImpostor(gSavedSettings, "AllowSelfImpostor"); + const auto id = getID(); + bool changed_slow_state{false}; // 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; + } + // 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; + // + } + + // Either we're not stale or we've updated. + + U64 render_time_raw; + U64 render_time_no_shadows_raw; // rename as we now include idle time + + if( !mTooSlow ) + { + // we are fully rendered, so we use the live values + std::lock_guard lock{LLPerfStats::bufferToggleLock}; + render_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_COMBINED); + // 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); + // + } + else + { + // use the cached values. + render_time_raw = mRenderTime; + render_time_no_shadows_raw = mRenderTimeNoShadows; // 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 + // 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; + // + } + 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. + // 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; + // + } + + } + } + else + { + // 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; + } + // + 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; + } + // better state change flagging + if( changed_slow_state ) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, true); + } + // +} + //----------------------------------------------------------------------------- // 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 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 render_far_clip(gSavedSettings, "RenderFarClip", 64); + F32 radius = render_far_clip * render_far_clip; + std::vector::iterator char_iter = LLCharacter::sInstances.begin(); + while (char_iter != LLCharacter::sInstances.end()) + { + LLVOAvatar *avatar = dynamic_cast(*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 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()) // correct for misplaced check { result = AOA_JELLYDOLL; } @@ -12377,7 +12532,10 @@ void LLVOAvatar::calcMutedAVColor() new_color = LLColor4::grey4; change_msg = " blocked: color is grey4"; } + // we don't want jelly dolls + // else if (!isTooComplex() && !isTooSlow()) else if (!isTooComplex()) + // { new_color = LLColor4::white; change_msg = " simple imposter "; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index bb9278368c..ecc33c405c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -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; // nanosecond time limit for avatar rendering 0 is unlimited. static LLPartSysData sCloud; static LLPointer sCloudTexture; + static std::vector sAVsIgnoringARTLimit; + static S32 sAvatarsNearby; + //-------------------------------------------------------------------- // Region state //-------------------------------------------------------------------- @@ -367,17 +371,16 @@ public: //-------------------------------------------------------------------- public: BOOL isFullyLoaded() const; - // 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(); - // + + // 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; // 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(); + // refactoring post LL merge + void clearSlowARTCache(); + void setSlowARTCache(U64 full_render_time, U64 geometry_render_time); + // 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}; - // variables to hold "slowness" status - bool mTooSlow{false}; - bool mTooSlowWithoutShadows{false}; - // + + 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 ** ** diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 926d59fe44..2857d27d88 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -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" // performance stats support const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; @@ -5728,7 +5728,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } - // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr + // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr { //for alpha sorting facep->setDrawInfo(draw_info); } @@ -5933,7 +5933,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 ratPtr{}; // render time capture + std::unique_ptr ratPtr{}; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { @@ -5976,6 +5976,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } // + if(vobj->isAttachment()) + { + trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr); + } + LLVolume* volume = vobj->getVolume(); if (volume) { @@ -6408,7 +6413,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) U32 buffer_count = 0; - std::unique_ptr ratPtr{}; // capture render times + std::unique_ptr ratPtr{}; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); @@ -6420,8 +6425,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) if (!vobj) continue; - // capture render times - if (vobj->isAttachment()) + if (vobj->isAttachment()) { trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr ); } @@ -6869,18 +6873,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 indices_index = 0; U16 index_offset = 0; - std::unique_ptr ratPtr; // capture render times - while (face_iter < i) + std::unique_ptr ratPtr; + while (face_iter < i) { //update face indices for new buffer facep = *face_iter; - LLViewerObject* vobj = facep->getViewerObject(); - // capture render times - if(vobj && vobj->isAttachment()) - { - trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr); - } - // + LLViewerObject* vobj = facep->getViewerObject(); + if(vobj && vobj->isAttachment()) + { + trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr); + } if (buffer.isNull()) { // Bulk allocation failed diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 10373d043e..e554562239 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -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* positi } } +// [FS performance floater] +//S32 LLWorld::getNearbyAvatarsAndCompl(std::vector &valid_nearby_avs) +//{ +// static LLCachedControl render_far_clip(gSavedSettings, "RenderFarClip", 64); +// S32 nearby_max_complexity = 0; +// F32 radius = render_far_clip * render_far_clip; +// std::vector::iterator char_iter = LLCharacter::sInstances.begin(); +// while (char_iter != LLCharacter::sInstances.end()) +// { +// LLVOAvatar* avatar = dynamic_cast(*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 performance floater] + // [RLVa:KB] - Checked: RLVa-2.0.1 bool LLWorld::getAvatar(const LLUUID& idAvatar, LLVector3d& posAvatar) const { diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 743f792dec..08d8764dcc 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -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 performance floater] + //S32 getNearbyAvatarsAndCompl(std::vector &valid_nearby_avs); + private: void clearHoleWaterObjects(); void clearEdgeWaterObjects(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 894f2f67d2..a7a6915146 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -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"); // // FIRE-16728 Add free aim mouse and focus lock - connectRefreshCachedSettingsSafe("FSFocusPointLocked"); connectRefreshCachedSettingsSafe("FSFocusPointFollowsPointer"); + connectRefreshCachedSettingsSafe("FSFocusPointLocked"); // } 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 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(); // 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(); + } +} + + // Reset VB during TP void LLPipeline::initDeferredVB() { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index fd7128e7aa..a26d15a7b0 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -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(); // Reset VB during TP void initDeferredVB(); @@ -748,7 +750,6 @@ protected: U64 mOldRenderDebugMask; std::stack 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; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index ef0eeab305..a7bda69992 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -1276,15 +1276,15 @@ + - - + 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]% diff --git a/indra/newview/skins/default/xui/de/panel_performance_autotune.xml b/indra/newview/skins/default/xui/de/panel_fs_performance_autotune.xml similarity index 100% rename from indra/newview/skins/default/xui/de/panel_performance_autotune.xml rename to indra/newview/skins/default/xui/de/panel_fs_performance_autotune.xml diff --git a/indra/newview/skins/default/xui/de/panel_performance_complexity.xml b/indra/newview/skins/default/xui/de/panel_fs_performance_complexity.xml similarity index 100% rename from indra/newview/skins/default/xui/de/panel_performance_complexity.xml rename to indra/newview/skins/default/xui/de/panel_fs_performance_complexity.xml diff --git a/indra/newview/skins/default/xui/de/panel_performance_huds.xml b/indra/newview/skins/default/xui/de/panel_fs_performance_huds.xml similarity index 100% rename from indra/newview/skins/default/xui/de/panel_performance_huds.xml rename to indra/newview/skins/default/xui/de/panel_fs_performance_huds.xml diff --git a/indra/newview/skins/default/xui/de/panel_performance_nearby.xml b/indra/newview/skins/default/xui/de/panel_fs_performance_nearby.xml similarity index 79% rename from indra/newview/skins/default/xui/de/panel_performance_nearby.xml rename to indra/newview/skins/default/xui/de/panel_fs_performance_nearby.xml index 657db8f70d..9cab18bdf4 100644 --- a/indra/newview/skins/default/xui/de/panel_performance_nearby.xml +++ b/indra/newview/skins/default/xui/de/panel_fs_performance_nearby.xml @@ -19,10 +19,12 @@ - + + + Per Rechts-Klick auf einen Avatar kann auch die Darstellung angepasst werden. diff --git a/indra/newview/skins/default/xui/de/panel_performance_preferences.xml b/indra/newview/skins/default/xui/de/panel_fs_performance_preferences.xml similarity index 100% rename from indra/newview/skins/default/xui/de/panel_performance_preferences.xml rename to indra/newview/skins/default/xui/de/panel_fs_performance_preferences.xml diff --git a/indra/newview/skins/default/xui/de/panel_presets_pulldown.xml b/indra/newview/skins/default/xui/de/panel_presets_pulldown.xml index ad68087ecb..270f6f0676 100644 --- a/indra/newview/skins/default/xui/de/panel_presets_pulldown.xml +++ b/indra/newview/skins/default/xui/de/panel_presets_pulldown.xml @@ -3,5 +3,6 @@ Grafikvoreinstellungen - + + + + + + + + Tuning Strategy + + + + + + + + + + + + Graphics settings + + + Choose settings for distance, water, lighting and more. + + + + + + Avatars nearby + + + Manage which nearby avatars are fully displayed. + + +Time spent +drawing +avatars + + + 00% + + + + + + Your avatar complexity + + + Be a good citizen. Manage the impact of your avatar + + + + + + Your active HUDs + + + Removing unnecessary HUDs may improve speed. + + +Time spent +drawing +HUDs + + + 00% + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml index deca1fca31..30234a16a2 100644 --- a/indra/newview/skins/default/xui/en/floater_performance.xml +++ b/indra/newview/skins/default/xui/en/floater_performance.xml @@ -556,6 +556,52 @@ HUDs top="19" right="-20" /> + + + Preferred frame rate + + + Allow automatic adjustments to reach your preferred frame rate (advanced). + + + + filename="panel_performance_huds.xml" + follows="all" + layout="topleft" + left="0" + name="panel_performance_huds" + visible="false" + top="55" /> + filename="panel_performance_autoadjustments.xml" + follows="all" + layout="topleft" + left="0" + name="panel_performance_autoadjustments" + visible="false" + top="55" /> diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 98c1261a6a..4eb9165b05 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -39,7 +39,8 @@ max_val="512" name="DrawDistance" top_delta="16" - width="330" /> + width="330"> + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 6cbb95dcc1..9ff50b8b6f 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1950,6 +1950,41 @@ Graphics Quality can be raised in Preferences > Graphics. fail + +Changing this setting will disable automatic adjustment and turn off 'Automatic settings'. +Are you sure you want to continue? + confirm + + + +To turn on advanced lighting, we need to increase quality to level 4. + confirm + + + +To enable shadows, we need to increase quality to level 4. + confirm + + + + +You are about to enable AutoFPS. All unsaved graphics settings will be lost. + +Would you like to save them first? + confirm + + + + + + + Back + + +Auto Tune Preferences + + + +Distant Avatars + + + + + +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. + + + +Visibility distance tuning limits + + + + + + +When adjusting scene parameters, autotune will choose values between the minimum and the preferred draw distances. + + + +Sundry Settings + + + + +These options control more subtle settings. Use the online help page to get more information on what these do. + + diff --git a/indra/newview/skins/default/xui/en/panel_fs_performance_complexity.xml b/indra/newview/skins/default/xui/en/panel_fs_performance_complexity.xml new file mode 100644 index 0000000000..7518328a35 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_performance_complexity.xml @@ -0,0 +1,116 @@ + + + + + Back + + + Avatar attachment complexity + + + Total: 50 (120000.10μs) + + + Attachments make your avatar more complex and slower to render. + + +This screen allows you to view the attachments of your own avatar. + + +You may remove your own attachments quickly and easily by hitting the 'X'. + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_fs_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_fs_performance_huds.xml new file mode 100644 index 0000000000..c6a5c025ae --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_performance_huds.xml @@ -0,0 +1,100 @@ + + + + + Back + + + Your active HUDs + + + Detaching HUDs you aren't using saves memory and can make the viewer run faster. + + + HUDs are often heavily scripted and also contribute to server-side lag. + + + Note: Using a HUD's minimize button does not detach it. Use the X to remove it. + + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_fs_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_fs_performance_nearby.xml new file mode 100644 index 0000000000..18dc8ca0a8 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_performance_nearby.xml @@ -0,0 +1,294 @@ + + + + + Back + + + Avatars nearby + + Total: 50 (120000.10μs) + + + Hide the most complex avatars to boost speed. + + + + + 0 + + + + + no limit + + + + + + + + + + + + You can also right-click on an avatar in-world to control display. + + + Note: Your own avatar includes viewer overheads. Use the attachment tab to see how you affect others. + + + + + + + + + Name tags: + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_fs_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_fs_performance_preferences.xml new file mode 100644 index 0000000000..1fd23144c0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_fs_performance_preferences.xml @@ -0,0 +1,516 @@ + + + + + Back + + + Graphics settings + + + + Quality vs speed + + +Faster + + + + + + + + + + Better Quality + + + + + Low + + + Mid + + + High + + + Ultra + + + Choosing a preset will reset all manual changes you have made. + + + + Visibility distance + + + Faster + + + + m + + + Farther + + + Keep this low for better performance, increase it to see further afield. + + + + Environment + + +Reducing / eliminating shadows can be a boost to FPS but impacts +the ambience and appearance of the scene. + + + Shadow sources: + + + + + + + + + Water + + + Reducing water effects quality can greatly improve frame rate. + + + Water Reflections: + + + + + + + + + + + + + Photography + + +Photographers need high quality, but this is often +at the cost of frame rate. [APP_NAME] phototools can +help you find the right balance. + + + diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml new file mode 100644 index 0000000000..28365595cc --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml @@ -0,0 +1,319 @@ + + + + + Back + + + Preferred frame rate + + + + Desired frame rate + + + + + + + Settings affect + + + + + + + + + Synchronize the refresh rate and frame rate of a monitor, + + + which can result in smoother performance. + + + + + Reducing detail shown on avatars that are far away will improve graphics speed. + + + + + + meters + + + + Choose the distance range that automatic settings will affect. + + + Minimum distance + + + + + Maximum distance + + + + diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml index 4e4c0fc5b7..083d5c6497 100644 --- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml +++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml @@ -69,23 +69,22 @@ top="0"> Hide the most complex avatars to boost speed. + width="490"> 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 + Quality & Speed + + + Fastest + + + + + + + + + + + + Best quality + + + width="250"> + + + + (Enter value between 0.0 and 4.0) + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + diff --git a/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml b/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml index 9ae8c7a0a8..735ab59881 100644 --- a/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml +++ b/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml @@ -57,13 +57,24 @@ width="215" /> + diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml index dcb39241a9..a8076b8550 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml @@ -26,7 +26,7 @@ /> - + 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]% diff --git a/indra/newview/skins/default/xui/fr/panel_performance_autotune.xml b/indra/newview/skins/default/xui/fr/panel_fs_performance_autotune.xml similarity index 100% rename from indra/newview/skins/default/xui/fr/panel_performance_autotune.xml rename to indra/newview/skins/default/xui/fr/panel_fs_performance_autotune.xml diff --git a/indra/newview/skins/default/xui/fr/panel_performance_complexity.xml b/indra/newview/skins/default/xui/fr/panel_fs_performance_complexity.xml similarity index 100% rename from indra/newview/skins/default/xui/fr/panel_performance_complexity.xml rename to indra/newview/skins/default/xui/fr/panel_fs_performance_complexity.xml diff --git a/indra/newview/skins/default/xui/fr/panel_performance_huds.xml b/indra/newview/skins/default/xui/fr/panel_fs_performance_huds.xml similarity index 100% rename from indra/newview/skins/default/xui/fr/panel_performance_huds.xml rename to indra/newview/skins/default/xui/fr/panel_fs_performance_huds.xml diff --git a/indra/newview/skins/default/xui/fr/panel_performance_nearby.xml b/indra/newview/skins/default/xui/fr/panel_fs_performance_nearby.xml similarity index 100% rename from indra/newview/skins/default/xui/fr/panel_performance_nearby.xml rename to indra/newview/skins/default/xui/fr/panel_fs_performance_nearby.xml diff --git a/indra/newview/skins/default/xui/fr/panel_performance_preferences.xml b/indra/newview/skins/default/xui/fr/panel_fs_performance_preferences.xml similarity index 100% rename from indra/newview/skins/default/xui/fr/panel_performance_preferences.xml rename to indra/newview/skins/default/xui/fr/panel_fs_performance_preferences.xml diff --git a/indra/newview/skins/default/xui/it/floater_performance.xml b/indra/newview/skins/default/xui/it/floater_fs_performance.xml similarity index 98% rename from indra/newview/skins/default/xui/it/floater_performance.xml rename to indra/newview/skins/default/xui/it/floater_fs_performance.xml index b692865ed6..76cd6ec442 100644 --- a/indra/newview/skins/default/xui/it/floater_performance.xml +++ b/indra/newview/skins/default/xui/it/floater_fs_performance.xml @@ -1,5 +1,5 @@ - + 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]% diff --git a/indra/newview/skins/default/xui/it/panel_performance_autotune.xml b/indra/newview/skins/default/xui/it/panel_fs_performance_autotune.xml similarity index 100% rename from indra/newview/skins/default/xui/it/panel_performance_autotune.xml rename to indra/newview/skins/default/xui/it/panel_fs_performance_autotune.xml diff --git a/indra/newview/skins/default/xui/it/panel_performance_complexity.xml b/indra/newview/skins/default/xui/it/panel_fs_performance_complexity.xml similarity index 100% rename from indra/newview/skins/default/xui/it/panel_performance_complexity.xml rename to indra/newview/skins/default/xui/it/panel_fs_performance_complexity.xml diff --git a/indra/newview/skins/default/xui/it/panel_performance_huds.xml b/indra/newview/skins/default/xui/it/panel_fs_performance_huds.xml similarity index 100% rename from indra/newview/skins/default/xui/it/panel_performance_huds.xml rename to indra/newview/skins/default/xui/it/panel_fs_performance_huds.xml diff --git a/indra/newview/skins/default/xui/it/panel_performance_nearby.xml b/indra/newview/skins/default/xui/it/panel_fs_performance_nearby.xml similarity index 100% rename from indra/newview/skins/default/xui/it/panel_performance_nearby.xml rename to indra/newview/skins/default/xui/it/panel_fs_performance_nearby.xml diff --git a/indra/newview/skins/default/xui/it/panel_performance_preferences.xml b/indra/newview/skins/default/xui/it/panel_fs_performance_preferences.xml similarity index 100% rename from indra/newview/skins/default/xui/it/panel_performance_preferences.xml rename to indra/newview/skins/default/xui/it/panel_fs_performance_preferences.xml diff --git a/indra/newview/skins/default/xui/pl/floater_performance.xml b/indra/newview/skins/default/xui/pl/floater_fs_performance.xml similarity index 98% rename from indra/newview/skins/default/xui/pl/floater_performance.xml rename to indra/newview/skins/default/xui/pl/floater_fs_performance.xml index cff8bd0151..80e1ba09b1 100644 --- a/indra/newview/skins/default/xui/pl/floater_performance.xml +++ b/indra/newview/skins/default/xui/pl/floater_fs_performance.xml @@ -1,5 +1,5 @@ - + Klatki: [TOT_FRAME_TIME]ms - Scena:[SCENERY_FRAME_PCT]% Awatary:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% HUDy:[HUDS_FRAME_PCT]% Swap:[SWAP_FRAME_PCT]% Zadania:[IDLE_FRAME_PCT]% diff --git a/indra/newview/skins/default/xui/pl/panel_performance_autotune.xml b/indra/newview/skins/default/xui/pl/panel_fs_performance_autotune.xml similarity index 100% rename from indra/newview/skins/default/xui/pl/panel_performance_autotune.xml rename to indra/newview/skins/default/xui/pl/panel_fs_performance_autotune.xml diff --git a/indra/newview/skins/default/xui/pl/panel_performance_complexity.xml b/indra/newview/skins/default/xui/pl/panel_fs_performance_complexity.xml similarity index 100% rename from indra/newview/skins/default/xui/pl/panel_performance_complexity.xml rename to indra/newview/skins/default/xui/pl/panel_fs_performance_complexity.xml diff --git a/indra/newview/skins/default/xui/pl/panel_performance_huds.xml b/indra/newview/skins/default/xui/pl/panel_fs_performance_huds.xml similarity index 100% rename from indra/newview/skins/default/xui/pl/panel_performance_huds.xml rename to indra/newview/skins/default/xui/pl/panel_fs_performance_huds.xml diff --git a/indra/newview/skins/default/xui/pl/panel_performance_nearby.xml b/indra/newview/skins/default/xui/pl/panel_fs_performance_nearby.xml similarity index 100% rename from indra/newview/skins/default/xui/pl/panel_performance_nearby.xml rename to indra/newview/skins/default/xui/pl/panel_fs_performance_nearby.xml diff --git a/indra/newview/skins/default/xui/pl/panel_performance_preferences.xml b/indra/newview/skins/default/xui/pl/panel_fs_performance_preferences.xml similarity index 100% rename from indra/newview/skins/default/xui/pl/panel_performance_preferences.xml rename to indra/newview/skins/default/xui/pl/panel_fs_performance_preferences.xml diff --git a/indra/newview/skins/default/xui/ru/floater_performance.xml b/indra/newview/skins/default/xui/ru/floater_fs_performance.xml similarity index 98% rename from indra/newview/skins/default/xui/ru/floater_performance.xml rename to indra/newview/skins/default/xui/ru/floater_fs_performance.xml index a82a6ba329..c75a25196c 100644 --- a/indra/newview/skins/default/xui/ru/floater_performance.xml +++ b/indra/newview/skins/default/xui/ru/floater_fs_performance.xml @@ -1,5 +1,5 @@ - + Кадр:[TOT_FRAME_TIME]ms Сцена:[SCENERY_FRAME_PCT]% Аватары:[AV_FRAME_PCT]% UI:[UI_FRAME_PCT]% HUDS:[HUDS_FRAME_PCT]% Swap:[SWAP_FRAME_PCT]% Задачи:[IDLE_FRAME_PCT]% diff --git a/indra/newview/skins/default/xui/ru/panel_performance_autotune.xml b/indra/newview/skins/default/xui/ru/panel_fs_performance_autotune.xml similarity index 100% rename from indra/newview/skins/default/xui/ru/panel_performance_autotune.xml rename to indra/newview/skins/default/xui/ru/panel_fs_performance_autotune.xml diff --git a/indra/newview/skins/default/xui/ru/panel_performance_complexity.xml b/indra/newview/skins/default/xui/ru/panel_fs_performance_complexity.xml similarity index 100% rename from indra/newview/skins/default/xui/ru/panel_performance_complexity.xml rename to indra/newview/skins/default/xui/ru/panel_fs_performance_complexity.xml diff --git a/indra/newview/skins/default/xui/ru/panel_performance_huds.xml b/indra/newview/skins/default/xui/ru/panel_fs_performance_huds.xml similarity index 100% rename from indra/newview/skins/default/xui/ru/panel_performance_huds.xml rename to indra/newview/skins/default/xui/ru/panel_fs_performance_huds.xml diff --git a/indra/newview/skins/default/xui/ru/panel_performance_nearby.xml b/indra/newview/skins/default/xui/ru/panel_fs_performance_nearby.xml similarity index 100% rename from indra/newview/skins/default/xui/ru/panel_performance_nearby.xml rename to indra/newview/skins/default/xui/ru/panel_fs_performance_nearby.xml diff --git a/indra/newview/skins/default/xui/ru/panel_performance_preferences.xml b/indra/newview/skins/default/xui/ru/panel_fs_performance_preferences.xml similarity index 100% rename from indra/newview/skins/default/xui/ru/panel_performance_preferences.xml rename to indra/newview/skins/default/xui/ru/panel_fs_performance_preferences.xml diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml b/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml index b4f81dc6a8..7883f66aa6 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_sound.xml @@ -18,6 +18,13 @@ + + Слышать мультимедиа и звуки из: + + + + + Автоматически включать звук после телепортации: @@ -51,7 +58,7 @@ -Автовоспроизведение + Автовоспроизведение diff --git a/indra/newview/skins/starlight/xui/en/panel_fs_profile_secondlife.xml b/indra/newview/skins/starlight/xui/en/panel_fs_profile_secondlife.xml deleted file mode 100644 index a8468bc0e1..0000000000 --- a/indra/newview/skins/starlight/xui/en/panel_fs_profile_secondlife.xml +++ /dev/null @@ -1,574 +0,0 @@ - - - -Online - - -Offline - - -[ACCTTYPE] -[PAYMENTINFO] -[FIRESTORM][FSDEV][FSSUPP][FSQA][FSGW] - - - -http://www.secondlife.com/account/billing.php?lang=en - - -http://www.secondlife.com/account/partners.php?lang=en - - - - - -[REG_DATE] -([AGE]) - - -[NAME] - - -[DISPLAY_NAME] - - - - - - - - - - - - - - - -