diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index cb070b0881..0851d20be0 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -1,5 +1,6 @@
# Replace tabs with spaces
1b68f71348ecf3983b76b40d7940da8377f049b7
+33418a77b716e122da9778869cdbabe97c83ff37
# Trim trailing whitespace
a0b3021bdcf76859054fda8e30abb3ed47749e83
8444cd9562a6a7b755fcb075864e205122354192
diff --git a/.github/ISSUE_TEMPLATE/10-bug.yaml b/.github/ISSUE_TEMPLATE/10-bug.yaml
index 41208e8bf5..612f71ace6 100644
--- a/.github/ISSUE_TEMPLATE/10-bug.yaml
+++ b/.github/ISSUE_TEMPLATE/10-bug.yaml
@@ -11,8 +11,8 @@ body:
- type: textarea
attributes:
label: Environment
- description: About Second Life Text
- placeholder: ex. Second Life Test 7.1.3.240191747 (64bit) ...
+ description: "Please copy the info from the viewer's 'About Second Life' window and paste it here:"
+ placeholder: 'ex. Second Life Release 7.1.8.9375512768 (64bit) ...'
validations:
required: true
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 01a915d499..00b9ccd2c9 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -7,14 +7,14 @@ on:
tags: ["Second_Life*"]
jobs:
- # The whole point of the setvar job is that we want to set a variable once
- # that will be consumed by multiple subsequent jobs. We tried setting it in
- # the global env, but a job.env can't directly reference the global env
- # context.
- setvar:
+ # The whole point of the setup job is that we want to set variables once
+ # that will be consumed by multiple subsequent jobs.
+ setup:
runs-on: ubuntu-latest
outputs:
release_run: ${{ steps.setvar.outputs.release_run }}
+ configurations: ${{ steps.setvar.outputs.configurations }}
+ bugsplat_db: ${{ steps.setvar.outputs.bugsplat_db }}
env:
# Build with a tag like "Second_Life#abcdef0" to generate a release page
# (used for builds we are planning to deploy).
@@ -22,33 +22,36 @@ jobs:
# important to ensure it's the empty string when false. If you omit || '',
# its value when false is "false", which is interpreted as true.
RELEASE_RUN: ${{ (github.event.inputs.release_run || github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life')) && 'Y' || '' }}
+ FROM_FORK: ${{ github.event.pull_request.head.repo.fork }}
steps:
- - name: Set Variable
+ - name: Set Variables
id: setvar
shell: bash
run: |
echo "release_run=$RELEASE_RUN" >> "$GITHUB_OUTPUT"
+ if [[ "$FROM_FORK" == "true" ]]; then
+ # PR from fork; don't build with Bugsplat, proprietary libs
+ echo 'configurations=["ReleaseOS"]' >> $GITHUB_OUTPUT
+ echo "bugsplat_db=" >> $GITHUB_OUTPUT
+ else
+ echo 'configurations=["Release"]' >> $GITHUB_OUTPUT
+ echo "bugsplat_db=SecondLife_Viewer_2018" >> $GITHUB_OUTPUT
+ fi
build:
- needs: setvar
+ needs: setup
strategy:
matrix:
runner: [windows-large, macos-12-xl]
- configuration: [Release]
- Linden: [true]
- include:
- - runner: macos-12-xl
- developer_dir: "/Applications/Xcode_14.0.1.app/Contents/Developer"
- - runner: windows-large
- configuration: ReleaseOS
- Linden: false
+ configuration: ${{ fromJSON(needs.setup.outputs.configurations) }}
runs-on: ${{ matrix.runner }}
outputs:
viewer_channel: ${{ steps.build.outputs.viewer_channel }}
viewer_version: ${{ steps.build.outputs.viewer_version }}
viewer_branch: ${{ steps.which-branch.outputs.branch }}
relnotes: ${{ steps.which-branch.outputs.relnotes }}
- imagename: ${{ steps.build.outputs.imagename }}
+ imagename: ${{ steps.build.outputs.imagename }}
+ configuration: ${{ matrix.configuration }}
env:
AUTOBUILD_ADDRSIZE: 64
AUTOBUILD_BUILD_ID: ${{ github.run_id }}
@@ -61,12 +64,9 @@ jobs:
# autobuild-package.xml.
AUTOBUILD_VCS_INFO: "true"
AUTOBUILD_VSVER: "170"
- DEVELOPER_DIR: ${{ matrix.developer_dir }}
+ DEVELOPER_DIR: "/Applications/Xcode_14.0.1.app/Contents/Developer"
# Ensure that Linden viewer builds engage Bugsplat.
- BUGSPLAT_DB: ${{ matrix.Linden && 'SecondLife_Viewer_2018' || '' }}
- # Run BUILD steps for Release configuration.
- # Run BUILD steps for ReleaseOS configuration only for release runs.
- BUILD: ${{ (matrix.Linden || needs.setvar.outputs.release_run) && 'Y' || '' }}
+ BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }}
build_coverity: false
build_log_dir: ${{ github.workspace }}/.logs
build_viewer: true
@@ -85,19 +85,16 @@ jobs:
variants: ${{ matrix.configuration }}
steps:
- name: Checkout code
- if: env.BUILD
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup python
- if: env.BUILD
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Checkout build variables
- if: env.BUILD
uses: actions/checkout@v4
with:
repository: secondlife/build-variables
@@ -105,19 +102,16 @@ jobs:
path: .build-variables
- name: Checkout master-message-template
- if: env.BUILD
uses: actions/checkout@v4
with:
repository: secondlife/master-message-template
path: .master-message-template
- name: Install autobuild and python dependencies
- if: env.BUILD
run: pip3 install autobuild llsd
- name: Cache autobuild packages
id: cache-installables
- if: env.BUILD
uses: actions/cache@v4
with:
path: .autobuild-installables
@@ -127,19 +121,17 @@ jobs:
${{ runner.os }}-64-
- name: Install windows dependencies
- if: env.BUILD && runner.os == 'Windows'
+ if: runner.os == 'Windows'
run: choco install nsis-unicode
- name: Determine source branch
id: which-branch
- if: env.BUILD
uses: secondlife/viewer-build-util/which-branch@v2
with:
token: ${{ github.token }}
- name: Build
id: build
- if: env.BUILD
shell: bash
env:
AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }}
@@ -265,7 +257,7 @@ jobs:
echo "artifact=$RUNNER_OS$cfg_suffix" >> $GITHUB_OUTPUT
- name: Upload executable
- if: matrix.Linden && steps.build.outputs.viewer_app
+ if: matrix.configuration == 'Release' && steps.build.outputs.viewer_app
uses: actions/upload-artifact@v4
with:
name: "${{ steps.build.outputs.artifact }}-app"
@@ -275,15 +267,13 @@ jobs:
# The other upload of nontrivial size is the symbol file. Use a distinct
# artifact for that too.
- name: Upload symbol file
- if: matrix.Linden
uses: actions/upload-artifact@v4
+ if: matrix.configuration == 'Release'
with:
name: "${{ steps.build.outputs.artifact }}-symbols"
- path: |
- ${{ steps.build.outputs.symbolfile }}
+ path: ${{ steps.build.outputs.symbolfile }}
- name: Upload metadata
- if: matrix.Linden
uses: actions/upload-artifact@v4
with:
name: "${{ steps.build.outputs.artifact }}-metadata"
@@ -294,7 +284,7 @@ jobs:
- name: Upload physics package
uses: actions/upload-artifact@v4
# should only be set for viewer-private
- if: matrix.Linden && steps.build.outputs.physicstpv
+ if: matrix.configuration == 'Release' && steps.build.outputs.physicstpv
with:
name: "${{ steps.build.outputs.artifact }}-physics"
# emitted by build.sh, zero or one lines
@@ -402,6 +392,7 @@ jobs:
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
needs: build
+ if: needs.build.outputs.configuration == 'Release'
runs-on: ubuntu-latest
steps:
- name: Download Mac Symbols
@@ -422,9 +413,9 @@ jobs:
files: "**/*.xcarchive.zip"
release:
- needs: [setvar, build, sign-and-package-windows, sign-and-package-mac]
+ needs: [setup, build, sign-and-package-windows, sign-and-package-mac]
runs-on: ubuntu-latest
- if: needs.setvar.outputs.release_run
+ if: needs.setup.outputs.release_run
steps:
- uses: actions/download-artifact@v4
with:
diff --git a/.github/workflows/tag-release.yaml b/.github/workflows/tag-release.yaml
index b73ec502f1..65d1d43a83 100644
--- a/.github/workflows/tag-release.yaml
+++ b/.github/workflows/tag-release.yaml
@@ -26,23 +26,22 @@ on:
jobs:
tag-release:
runs-on: ubuntu-latest
- env:
- GITHUB_TAG_TOKEN: ${{ secrets.GITHUB_TAG_TOKEN }}
steps:
- name: Setup Env Vars
run: |
CHANNEL="${{ inputs.channel }}"
echo VIEWER_CHANNEL="Second_Life_${CHANNEL:-Develop}" >> ${GITHUB_ENV}
- echo NIGHTLY_DATE=$(date --rfc-3339=date) >> ${GITHUB_ENV}
+ NIGHTLY_DATE=$(date --rfc-3339=date)
+ echo NIGHTLY_DATE=${NIGHTLY_DATE} >> ${GITHUB_ENV}
+ echo TAG_ID="$(echo ${{ github.sha }} | cut -c1-8)-${{ inputs.project || '${NIGHTLY_DATE}' }}" >> ${GITHUB_ENV}
- name: Update Tag
uses: actions/github-script@v7.0.1
- if: env.GITHUB_TAG_TOKEN
with:
- github-token: ${{ env.GITHUB_TAG_TOKEN }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
- github.rest.git.createRef(
+ github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
- ref: "refs/tags/${{ env.VIEWER_CHANNEL }}#${{ env.NIGHTLY_DATE }}",
+ ref: "refs/tags/${{ env.VIEWER_CHANNEL }}#${{ env.TAG_ID }}",
sha: context.sha
- )
+ })
diff --git a/autobuild.xml b/autobuild.xml
index 33a07a3b73..61a9d85d1a 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -46,11 +46,11 @@
archive
name
darwin64
@@ -60,9 +60,11 @@
archive
name
linux64
@@ -72,11 +74,11 @@
archive
name
windows64
@@ -89,7 +91,7 @@
copyright
Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
version
- 1.7.2-e935465
+ 1.7.4-10278668642
name
apr_suite
description
@@ -104,11 +106,11 @@
archive
name
darwin64
@@ -118,11 +120,11 @@
archive
name
linux64
@@ -132,11 +134,11 @@
archive
name
windows64
@@ -149,7 +151,7 @@
copyright
(see individual source files)
version
- 1.81-09d25a7
+ 1.85
name
boost
description
@@ -210,11 +212,11 @@
archive
name
darwin64
@@ -224,11 +226,11 @@
archive
name
linux64
@@ -238,11 +240,11 @@
archive
name
windows64
@@ -255,7 +257,7 @@
copyright
Copyright 2006 Sony Computer Entertainment Inc.
version
- 2.3.ab0c124
+ 2.3.10129939866
name
colladadom
@@ -437,6 +439,16 @@
dullahan
- license
- MPL
- license_file
- LICENSES/LICENSE.txt
- copyright
- Copyright (c) 2017, Linden Research, Inc.
version
- 1.14.0.202310131404_118.4.1_g3dd6078_chromium-118.0.5993.54
- name
- dullahan
- description
- A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies.
+ 1.14.0.202408091639_118.4.1_g3dd6078_chromium-118.0.5993.54
emoji_shortcodes
platforms
- darwin64
+ common
archive
hash
- 52c41a4547d2d9aceb4a9a1e9e1680c71e5ffa79
+ 9c58108270fbad15a321f75501cdfb9c6b78a6f2
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-emoji-shortcodes/releases/download/v6.1.0.5413f58/emoji_shortcodes-6.1.0.5413f58-darwin64-5413f58.tar.zst
+ https://github.com/secondlife/3p-emoji-shortcodes/releases/download/v15.3.2-r1/emoji_shortcodes-15.3.2.10207138275-common-10207138275.tar.zst
name
- darwin64
-
- windows64
-
- archive
-
- hash
- 3137e06d376767a631bc9626832d558c4d5e5aa9
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-emoji-shortcodes/releases/download/v6.1.0.5413f58/emoji_shortcodes-6.1.0.5413f58-windows64-5413f58.tar.zst
-
- name
- windows64
+ common
license
@@ -521,7 +523,7 @@
copyright
Copyright 2017-2019 Miles Johnson.
version
- 6.1.0.5413f58
+ 15.3.2.10207138275
name
emoji_shortcodes
canonical_repo
@@ -538,11 +540,11 @@
archive
hash
- b85526ca80b6a7e73c7870285cf68d568f742095
+ bd61ec7787ea96d11f735afa5a6296ed175472b6
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-expat/releases/download/v2.1.1.1f36d02/expat-2.1.1.1f36d02-darwin64-1f36d02.tar.zst
+ https://github.com/secondlife/3p-expat/releases/download/v2.6.2-r4/expat-2.6.2-r4-darwin64-10278332617.tar.zst
name
darwin64
@@ -552,11 +554,11 @@
archive
hash
- 4cd82e2dec06ddff19e9b3dc0254f2593ec80452
+ acf891bda4125a92f6347e69f0e7867f32cebd20
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-expat/releases/download/v2.1.1.1f36d02/expat-2.1.1.1f36d02-linux64-1f36d02.tar.zst
+ https://github.com/secondlife/3p-expat/releases/download/v2.6.2-r4/expat-2.6.2-r4-linux64-10278332617.tar.zst
name
linux64
@@ -566,11 +568,11 @@
archive
hash
- 47c01a89bc32c5740efe51be43e459ffd9b7cd34
+ 1b9c198626fca0f30fb2770856e65767a9951683
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-expat/releases/download/v2.1.1.1f36d02/expat-2.1.1.1f36d02-windows64-1f36d02.tar.zst
+ https://github.com/secondlife/3p-expat/releases/download/v2.6.2-r4/expat-2.6.2-r4-windows64-10278332617.tar.zst
name
windows64
@@ -581,9 +583,9 @@
license_file
LICENSES/expat.txt
copyright
- Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.
+ Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001-2022 Expat maintainers.
version
- 2.1.1.1f36d02
+ 2.6.2-r4
name
expat
description
@@ -959,63 +961,65 @@
name
jpegencoderbasic
- jpeglib
+ libjpeg-turbo
platforms
- darwin64
+ windows64
archive
hash
- 776d114aa1e3455bb13deaacd756deb07b53ecbe
+ 36144272e381952a7c11f1d593c2916c5c7387d0
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-jpeglib/releases/download/v8c.7846234/jpeglib-8c.7846234-darwin64-7846234.tar.zst
+ https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.3-r1/libjpeg_turbo-3.0.3-windows64-10204037839.tar.zst
name
- darwin64
+ windows64
linux64
archive
hash
- b4b2278bd2fcae85619e2145a243cca388d760d7
+ f853a7d4fe842e7a661dd71a56a51f65b2ec25c7
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-jpeglib/releases/download/v8c.7846234/jpeglib-8c.7846234-linux64-7846234.tar.zst
+ https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.3-r1/libjpeg_turbo-3.0.3-linux64-10204037839.tar.zst
name
linux64
- windows64
+ darwin64
archive
hash
- d50fcac69eeb9404638da07db96ee3e1191ecf93
+ 6fcbc2c3c91b5e9bfbbc57ddf27d2f3698fe7d99
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-jpeglib/releases/download/v8c.7846234/jpeglib-8c.7846234-windows64-7846234.tar.zst
+ https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.3-r1/libjpeg_turbo-3.0.3-darwin64-10204037839.tar.zst
name
- windows64
+ darwin64
license
- jpeglib
+ libjpeg-turbo
license_file
- LICENSES/jpeglib.txt
+ LICENSES/libjpeg-turbo.txt
copyright
- Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding.
+ Copyright (C)2009-2024 D. R. Commander. All Rights Reserved. Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
version
- 8c.7846234
+ 3.0.3
name
- jpeglib
+ libjpeg-turbo
+ canonical_repo
+ https://github.com/secondlife/3p-libjpeg-turbo
description
JPEG encoding, decoding library
@@ -1110,11 +1114,11 @@
archive
hash
- d5757ab84d934fa358f299ab91e2e297beaa3dac
+ e71ae7a645603fe967a69aa5beb5b3009185e177
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-libhunspell/releases/download/v1.3.2.650fb94/libhunspell-1.3.2.650fb94-darwin64-650fb94.tar.zst
+ https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r1/libhunspell-1.7.2.10207243663-darwin64-10207243663.tar.zst
name
darwin64
@@ -1124,11 +1128,11 @@
archive
hash
- 6413d3bd4cd50c2a6b7f949eb4bd6f0c94feb984
+ 275ffb7f60064d8008aed8406f80f34229f651fc
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-libhunspell/releases/download/v1.3.2.650fb94/libhunspell-1.3.2.650fb94-linux64-650fb94.tar.zst
+ https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r1/libhunspell-1.7.2.10207243663-linux64-10207243663.tar.zst
name
linux64
@@ -1138,11 +1142,11 @@
archive
hash
- c1be4a79b20435030b2e0e01b582c61b462c8376
+ 89ff24e93eaeca7949ccdb5cc368f938f5b1f307
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-libhunspell/releases/download/v1.3.2.650fb94/libhunspell-1.3.2.650fb94-windows64-650fb94.tar.zst
+ https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r1/libhunspell-1.7.2.10207243663-windows64-10207243663.tar.zst
name
windows64
@@ -1153,9 +1157,9 @@
license_file
LICENSES/hunspell.txt
copyright
- See hunspell.txt
+ LGPL 2.1
version
- 1.3.2.650fb94
+ 1.7.2.10207243663
name
libhunspell
description
@@ -1387,6 +1391,15 @@
llca
+ copyright
+ Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project.
+
+ license
+ mit
+ license_file
+ LICENSES/ca-license.txt
+ name
+ llca
platforms
common
@@ -1394,27 +1407,18 @@
archive
hash
- a9503e1b4e1d9790cf29d18a3d9ab39e6a515679
+ 6d6771706a5b70caa24893ff62afc925f8d035f6
hash_algorithm
sha1
url
- https://github.com/secondlife/llca/releases/download/v202402012004.0-0f5d9c3/llca-202402012004.0-common-0f5d9c3.tar.zst
+ https://github.com/secondlife/llca/releases/download/v202407221723.0-a0fd5b9/llca-202407221423.0-common-10042698865.tar.zst
name
common
- license
- mit
- license_file
- LICENSES/ca-license.txt
- copyright
- Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project.
-
version
- 202402012004.0
- name
- llca
+ 202407221423.0
llphysicsextensions_source
@@ -1435,11 +1439,11 @@
creds
github
hash
- 755a3de464149ae88b048f976828a8c0c46e3bdb
+ 9e59c93c7110e87b4ff3db330f11a23c50e5000f
hash_algorithm
sha1
url
- https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/172966323
+ https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910560
name
darwin64
@@ -1451,11 +1455,11 @@
creds
github
hash
- 813e7b5e294d7958e3d69e2252752ff346953b0c
+ 7ed994db5bafa9a7ad09a1b53da850a84715c65e
hash_algorithm
sha1
url
- https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/172966322
+ https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910561
name
linux64
@@ -1467,18 +1471,18 @@
creds
github
hash
- 67f647538b1b49d0152fd9d03cfb9bdf978e33d1
+ 66824c02e0e5eabbfbe37bfb173360195f89697c
hash_algorithm
sha1
url
- https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/172966328
+ https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910562
name
windows64
version
- 1.0.b8b1f73
+ 1.0.66e6919
llphysicsextensions_stub
@@ -1619,11 +1623,11 @@
archive
hash
- 3bf88febd23656327a4ee2a3ebe99cae4b15573e
+ 3d173e176e9777f1b10f54fe0bd1c735a65b56e5
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-meshoptimizer/releases/download/v160-032f20a/meshoptimizer-160-darwin64-032f20a.tar.zst
+ https://github.com/secondlife/3p-meshoptimizer/releases/download/v210-r1/meshoptimizer-210-darwin64-9846246058.tar.zst
name
darwin64
@@ -1633,15 +1637,29 @@
archive
hash
- 13c0a33d9c49cc07b354527c7ef992d33f854c59
+ 6777467d1d06064351c27f70d556fdcba8420c52
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-meshoptimizer/releases/download/v160-032f20a/meshoptimizer-160-windows64-032f20a.tar.zst
+ https://github.com/secondlife/3p-meshoptimizer/releases/download/v210-r1/meshoptimizer-210-windows64-9846246058.tar.zst
name
windows64
+ linux64
+
+ archive
+
+ hash
+ 17eb4a03f94d363e9ad8b096ac590e0649cf91fa
+ hash_algorithm
+ sha1
+ url
+ https://github.com/secondlife/3p-meshoptimizer/releases/download/v210-r1/meshoptimizer-210-linux64-9846246058.tar.zst
+
+ name
+ linux64
+
license
meshoptimizer
@@ -1650,7 +1668,7 @@
copyright
Copyright (c) 2016-2021 Arseny Kapoulkine
version
- 160
+ 210
name
meshoptimizer
canonical_repo
@@ -1942,11 +1960,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
archive
hash
- ad0dd0f608b868cc44c225ee48e114239fca2807
+ 1e694e5562b8d844bc44d5f7ae4dce243ee70d23
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.3-1.3.6.e4101b6/ogg_vorbis-1.3.3-1.3.6.e4101b6-darwin64-e4101b6.tar.zst
+ https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7/ogg_vorbis-1.3.5-1.3.7.10218872737-darwin64-10218872737.tar.zst
name
darwin64
@@ -1956,9 +1974,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
archive
hash
- 45ebd074053dc9cae8c5c74b52085d4b
+ ce0c6adb6d684eb2f4b2ad8838c67186c59e151a
+ hash_algorithm
+ sha1
url
- http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/465/990/ogg_vorbis-1.2.2-1.3.2.500397-linux64-500397.tar.bz2
+ https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7/ogg_vorbis-1.3.5-1.3.7.10218872737-linux64-10218872737.tar.zst
name
linux64
@@ -1968,11 +1988,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
archive
hash
- 2e73a0a5659c9a09eba2f94619aa5c23c7cc3937
+ 9434b592c5d748c5deb64ad548fd1484638e3172
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.3-1.3.6.e4101b6/ogg_vorbis-1.3.3-1.3.6.e4101b6-windows64-e4101b6.tar.zst
+ https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7/ogg_vorbis-1.3.5-1.3.7.10218872737-windows64-10218872737.tar.zst
name
windows64
@@ -1985,7 +2005,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
copyright
Copyright (c) 2002, Xiph.org Foundation
version
- 1.3.3-1.3.6.e4101b6
+ 1.3.5-1.3.7.10218872737
name
ogg_vorbis
description
@@ -2186,64 +2206,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
description
Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) Library
- pcre
-
- platforms
-
- darwin64
-
- archive
-
- hash
- b372d37596474043a62568e569b0ce155192f484
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-pcre/releases/download/v8.35.979fd86/pcre-8.35.979fd86-darwin64-979fd86.tar.zst
-
- name
- darwin64
-
- linux64
-
- archive
-
- hash
- 0f058ca2176e7d02d51e54c66a96f336
- url
- http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/908/2010/pcre-8.35.500898-linux64-500898.tar.bz2
-
- name
- linux64
-
- windows64
-
- archive
-
- hash
- 166564afb60a7536a038fae80e2fc9a41d6dbccb
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-pcre/releases/download/v8.35.979fd86/pcre-8.35.979fd86-windows64-979fd86.tar.zst
-
- name
- windows64
-
-
- license
- bsd
- license_file
- LICENSES/pcre-license.txt
- copyright
- Copyright (c) 1997-2014 University of Cambridge; Copyright(c) 2009-2014 Zoltan Herczeg; Copyright (c) 2007-2012, Google Inc.
- version
- 8.35.979fd86
- name
- pcre
- description
- PCRE Perl-compatible regular expression library
-
slvoice
platforms
@@ -2405,11 +2367,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
archive
hash
- 49650353442698c3e05102676fe427d0ebe02f0b
+ a901a14066daf8c8796c8d2914917129427fd80b
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-darwin64-eecbf72.tar.zst
+ https://github.com/secondlife/3p-tracy/releases/download/v0.10.0%2Br1/tracy-v0.10.0.9845715133-darwin64-9845715133.tar.zst
name
darwin64
@@ -2419,15 +2381,29 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
archive
hash
- 2b80e7407e4f3e82eff3879add0e9ad63e7fcace
+ ca5fc66e3431278f20286261ffe85192bbd9a2ca
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-windows64-eecbf72.tar.zst
+ https://github.com/secondlife/3p-tracy/releases/download/v0.10.0%2Br1/tracy-v0.10.0.9845715133-windows64-9845715133.tar.zst
name
windows64
+ linux64
+
+ archive
+
+ hash
+ e6f53d513c238ad599b75a8b5f94b8b0d1315438
+ hash_algorithm
+ sha1
+ url
+ https://github.com/secondlife/3p-tracy/releases/download/v0.10.0%2Br1/tracy-v0.10.0.9845715133-linux64-9845715133.tar.zst
+
+ name
+ linux64
+
license
bsd
@@ -2436,7 +2412,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
copyright
Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl)
version
- v0.8.1-eecbf72
+ v0.10.0.9845715133
name
tracy
canonical_repo
@@ -2480,93 +2456,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
description
TUT is a small and portable unit test framework for C++.
- uriparser
-
- platforms
-
- darwin64
-
- archive
-
- hash
- 4b6ee5113b1368ec9ff5b59e195adde370b9f585
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-uriparser/releases/download/v0.9.4-8fff38a/uriparser-0.9.4-darwin64-8fff38a.tar.zst
-
- name
- darwin64
-
- linux64
-
- archive
-
- hash
- 44dc74ec73e37c56bef6317d12a29d0435cb4bbb
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-uriparser/releases/download/v0.9.4-8fff38a/uriparser-0.9.4-linux64-8fff38a.tar.zst
-
- name
- linux64
-
- windows64
-
- archive
-
- hash
- e8b20edfc624f1d09bc83480932a9c844d47fc13
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-uriparser/releases/download/v0.9.4-8fff38a/uriparser-0.9.4-windows64-8fff38a.tar.zst
-
- name
- windows64
-
-
- license
- New BSD license
- license_file
- LICENSES/uriparser.txt
- copyright
- Copyright (C) 2007, Weijia Song <songweijia@gmail.com>, Sebastian Pipping <webmaster@hartwork.org>
- version
- 0.9.4
- name
- uriparser
- description
- uriparser is a strictly RFC 3986 compliant URI parsing and handling library written in C. uriparser is cross-platform, fast, supports Unicode and is licensed under the New BSD license.
-
viewer-fonts
platforms
- darwin64
+ common
archive
hash
- 6041bbd4001e3951f96ac3456c7906da
+ e88a7c97a6843d43e0093388f211299ec2892790
+ hash_algorithm
+ sha1
url
- https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113314/980656/viewer_fonts-1.579464-darwin64-579464.tar.bz2
+ https://github.com/secondlife/3p-viewer-fonts/releases/download/v1.1.0-r1/viewer_fonts-1.0.0.10204976553-common-10204976553.tar.zst
name
- darwin64
-
- windows64
-
- archive
-
- hash
- 1745ba6eec0108250446fe01d4aa065c
- url
- https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/113307/980631/viewer_fonts-1.579464-windows64-579464.tar.bz2
-
- name
- windows64
+ common
license
@@ -2576,7 +2482,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
copyright
Copyright 2016-2022 Brad Erickson CC-BY-4.0/MIT, Copyright 2016-2022 Twitter, Inc. CC-BY-4.0, Copyright 2013 Joe Loughry and Terence Eden MIT
version
- 1.579464
+ 1.0.0.10204976553
name
viewer-fonts
description
@@ -2648,50 +2554,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
vlc-bin
- platforms
-
- darwin64
-
- archive
-
- hash
- a26b47ab01a7e2c0add4c236886162c1135b3b79
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.16.c219a5d/vlc_bin-3.0.16.c219a5d-darwin64-c219a5d.tar.zst
-
- name
- darwin64
-
- windows64
-
- archive
-
- hash
- d56002da7435bab166c88d59eeaf69fd87cd897d
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.16.c219a5d/vlc_bin-3.0.16.c219a5d-windows64-c219a5d.tar.zst
-
- name
- windows64
-
-
+ copyright
+ Copyright (C) 1998-2016 VLC authors and VideoLAN
license
GPL2
license_file
LICENSES/vlc.txt
- copyright
- Copyright (C) 1998-2016 VLC authors and VideoLAN
- version
- 3.0.16.c219a5d
name
vlc-bin
-
- xmlrpc-epi
-
platforms
darwin64
@@ -2699,56 +2569,32 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
archive
hash
- aa12611374876196b3ebb6bda8d419a697217b8b
+ f13c82042ef8311e57dd75a3b2bda02d70f711b5
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-darwin64-8a05acf.tar.zst
+ https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.21.e60ee26/vlc_bin-3.0.21.10218721728-darwin64-10218721728.tar.zst
name
darwin64
- linux64
-
- archive
-
- hash
- ad0c8b41ee4b4de216382bec46ee1c25962a3f12
- hash_algorithm
- sha1
- url
- https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-linux64-8a05acf.tar.zst
-
- name
- linux64
-
windows64
archive
hash
- e53fd38c14b8c47c7c84dead8a1b211bb8be170c
+ bd995441c1a229ed1432ddd837d7d1663b8c5548
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-windows64-8a05acf.tar.zst
+ https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.21.e60ee26/vlc_bin-3.0.21.10218721728-windows64-10218721728.tar.zst
name
windows64
- license
- xmlrpc-epi
- license_file
- LICENSES/xmlrpc-epi.txt
- copyright
- Copyright: (C) 2000 Epinions, Inc.
version
- 0.54.1.8a05acf
- name
- xmlrpc-epi
- description
- XMLRPC Library
+ 3.0.21.10218721728
vulkan_gltf
@@ -2859,11 +2705,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
archive
hash
- 1a73c476b371b62066d1c3eced249660e9467e53
+ fc9362865e33391d55c64d6101726da0a25d924e
hash_algorithm
sha1
url
- https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-69ff69a/xxhash-0.8.1-69ff69a-common-69ff69a.tar.zst
+ https://github.com/secondlife/3p-xxhash/releases/download/v0.8.2-r1/xxhash-0.8.2-10285735820-common-10285735820.tar.zst
name
common
@@ -2876,7 +2722,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
copyright
Copyright (c) 2012-2021 Yann Collet
version
- 0.8.1-69ff69a
+ 0.8.2-10285735820
name
xxhash
description
diff --git a/build.sh b/build.sh
index 5dfb4b6a74..dd85fde7d6 100755
--- a/build.sh
+++ b/build.sh
@@ -146,12 +146,21 @@ pre_build()
&& [ -r "$master_message_template_checkout/message_template.msg" ] \
&& template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
- RELEASE_CRASH_REPORTING=ON
- HAVOK=ON
+ RELEASE_CRASH_REPORTING=OFF
+ HAVOK=OFF
SIGNING=()
- if [[ "$arch" == "Darwin" && "$variant" == "Release" ]]
- then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
- "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
+ if [[ "$variant" != *OS ]]
+ then
+ # Proprietary builds
+
+ RELEASE_CRASH_REPORTING=ON
+ HAVOK=ON
+
+ if [[ "$arch" == "Darwin" ]]
+ then
+ SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
+ "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
+ fi
fi
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 5a4d276a20..54817ca52d 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1436,6 +1436,30 @@ Sovereign Engineer
SL-18534
SL-19690
SL-19336
+ secondlife/viewer/pull/1283
+ secondlife/viewer/pull/1287
+ secondlife/viewer/pull/1906
+ secondlife/viewer/pull/1930
+ secondlife/viewer/pull/1941
+ secondlife/viewer/pull/1946
+ secondlife/viewer/pull/1948
+ secondlife/viewer/pull/1950
+ secondlife/viewer/pull/1951
+ secondlife/viewer/pull/2066
+ secondlife/viewer/pull/2077
+ secondlife/viewer/pull/2078
+ secondlife/viewer/pull/2080
+ secondlife/viewer/pull/2085
+ secondlife/viewer/pull/2098
+ secondlife/viewer/pull/2099
+ secondlife/viewer/pull/2105
+ secondlife/viewer/pull/2115
+ secondlife/viewer/pull/2116
+ secondlife/viewer/pull/2124
+ secondlife/viewer/pull/2125
+ secondlife/viewer/pull/2135
+ secondlife/viewer/pull/2136
+ secondlife/viewer/pull/2149
SpacedOut Frye
VWR-34
VWR-45
diff --git a/doc/testplans/pbr_materials.md b/doc/testplans/pbr_materials.md
new file mode 100644
index 0000000000..1ef7945b94
--- /dev/null
+++ b/doc/testplans/pbr_materials.md
@@ -0,0 +1,12 @@
+# PBR Materials
+
+## KHR Texture Transforms
+
+Texture repeats for PBR materials on prims are based on the [KHR\_texture\_transform](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform) spec, and thus should be expected to behave according to the spec. We currently suport offset, rotation, and scale from the spec. texCoord is not currently supported.
+
+PBR materials should have approximately correct lighting based on the normal texture:
+
+- With default texture transforms, assuming the prim or model has correct normals and tangents
+- With a texture transform applied, especially rotation or negative scale
+- With a texture animation applied via `llSetTextureAnim`, especially a rotation animation
+ - Note: Texture animations are not guaranteed to loop when a PBR texture transform is applied
diff --git a/doc/testplans/pbr_terrain_appearance.md b/doc/testplans/pbr_terrain_appearance.md
index 11b501be3a..eab5b8bf44 100644
--- a/doc/testplans/pbr_terrain_appearance.md
+++ b/doc/testplans/pbr_terrain_appearance.md
@@ -39,7 +39,7 @@ PBR terrain does not support materials with alpha blend or double-sided. In addi
## PBR Terrain Texture Transforms
-Like PBR materials on prims, PBR terrain repeats are based on the [KHR\_texture\_transform](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform) spec, and thus should be expected to behave the same way.
+Like PBR materials on prims, PBR terrain repeats are based on the [KHR\_texture\_transform](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform) spec, and thus should be expected to behave the same way. We currently suport offset, rotation, and scale from the spec. texCoord is not currently supported.
The southwest corner of a region, at z=0, is the UV origin for all texture coordinates of the whole region. Unless an offset is also applied, scale and rotation of the terrain texture transforms are relative to that point.
@@ -50,3 +50,14 @@ If triplanar mapping is enabled, and an avatar faces an axially-aligned wall, th
Textures of materials should not appear mirrored.
When triplanar mapping is enabled, rotations on the axially aligned walls should apply in the same direction as they would on flat ground.
+
+## PBR Terrain Normal Textures
+
+This section assumes terrain normal maps are enabled at the current graphics setting.
+
+PBR terrain should have approximately correct lighting based on the normal texture:
+
+- When on flat ground
+- On cliffs, when triplanar mapping is enabled. Lighting will be somewhat less accurate when the cliff face is not axially aligned.
+- If no Terrain Texture Transform is applied.
+- If a Terrain Texture Transform is applied, especially for rotation or negative scale.
diff --git a/doc/testplans/pbr_terrain_composition.md b/doc/testplans/pbr_terrain_composition.md
index 731da90aba..bac0e8662e 100644
--- a/doc/testplans/pbr_terrain_composition.md
+++ b/doc/testplans/pbr_terrain_composition.md
@@ -44,6 +44,8 @@ The PBR terrain texture transform flag should be set automatically when logging
When the PBR terrain texture transform feature is enabled, the UI of the Terrain tab should be overhauled. Availability of features depends on the type of terrain.
+**Known issue:** The Region/Estate floater may have to be closed/reopened a second time in order for the UI overhaul to take effect, after teleporting between regions that do and do not have the feature flag set.
+
When "PBR Metallic Roughness" is checked:
- There should be a way for the user to change the texture transforms for the terrain in the current region
@@ -87,6 +89,12 @@ If saving the terrain fails for any reason, the terrain should not be updated.
Unlike a viewer without PBR terrain support, the new viewer will no longer treat textures with alpha channels as invalid.
+### Saving PBR Terrain Texture Transforms
+
+If "PBR Metallic Roughness" checkbox is checked, a user with saving composition permissions should also be allowed to edit and save PBR texture transforms.
+
+One texture transform may be set for each material swatch. Setting texture transforms for each individual texture on the material is not currently supported.
+
## Graphics Features
Texture terrain with transparency is not permitted to be applied in the viewer.
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 07deaa56b0..f1fa7761c3 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -32,6 +32,10 @@ add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE})
# -- which we do. Without one or the other, we get a ton of Boost warnings.
add_compile_definitions(BOOST_BIND_GLOBAL_PLACEHOLDERS)
+# Force enable SSE2 instructions in GLM per the manual
+# https://github.com/g-truc/glm/blob/master/manual.md#section2_10
+add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1)
+
# Configure crash reporting
set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
set(NON_RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in developer builds")
@@ -104,11 +108,6 @@ if (WINDOWS)
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif()
- # workaround for github runner image breakage:
- # https://github.com/actions/runner-images/issues/10004#issuecomment-2153445161
- # can be removed after the above issue is resolved and deployed across GHA
- add_compile_definitions(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)
-
# Allow use of sprintf etc
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif (WINDOWS)
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index 21139319c3..97b316c4c7 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -18,6 +18,7 @@ if (WINDOWS)
${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib
${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib
)
+ target_compile_definitions( ll::apr INTERFACE APR_DECLARE_STATIC=1 APU_DECLARE_STATIC=1 API_DECLARE_STATIC=1)
elseif (DARWIN)
if (LLCOMMON_LINK_SHARED)
set(APR_selector "0.dylib")
@@ -28,16 +29,15 @@ elseif (DARWIN)
endif (LLCOMMON_LINK_SHARED)
target_link_libraries( ll::apr INTERFACE
- libapr-1.${APR_selector}
- libaprutil-1.${APRUTIL_selector}
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.${APR_selector}
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.${APR_selector}
iconv
)
-else (WINDOWS)
+else()
target_link_libraries( ll::apr INTERFACE
- apr-1
- aprutil-1
- uuid
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.a
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.a
rt
)
-endif (WINDOWS)
+endif ()
target_include_directories( ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1 )
diff --git a/indra/cmake/Audio.cmake b/indra/cmake/Audio.cmake
index 38547bb017..8c82749cab 100644
--- a/indra/cmake/Audio.cmake
+++ b/indra/cmake/Audio.cmake
@@ -1,4 +1,5 @@
# -*- cmake -*-
+include(Linking)
include(Prebuilt)
include_guard()
@@ -9,8 +10,22 @@ use_prebuilt_binary(ogg_vorbis)
target_include_directories( ll::vorbis SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include )
if (WINDOWS)
- target_link_libraries(ll::vorbis INTERFACE ogg_static vorbis_static vorbisenc_static vorbisfile_static )
+ target_link_libraries(ll::vorbis INTERFACE
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libogg.lib
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/libogg.lib
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisenc.lib
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbisenc.lib
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisfile.lib
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbisfile.lib
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbis.lib
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbis.lib
+ )
else (WINDOWS)
- target_link_libraries(ll::vorbis INTERFACE ogg vorbis vorbisenc vorbisfile )
+ target_link_libraries(ll::vorbis INTERFACE
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libogg.a
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisenc.a
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisfile.a
+ ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbis.a
+ )
endif (WINDOWS)
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index 601a23a86d..8c5b946753 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -24,7 +24,8 @@ if (WINDOWS)
libboost_program_options-mt${addrsfx}
libboost_regex-mt${addrsfx}
libboost_system-mt${addrsfx}
- libboost_thread-mt${addrsfx})
+ libboost_thread-mt${addrsfx}
+ libboost_url-mt${addrsfx})
elseif (LINUX)
target_link_libraries( ll::boost INTERFACE
boost_context-mt${addrsfx}
@@ -34,7 +35,8 @@ elseif (LINUX)
boost_regex-mt${addrsfx}
boost_signals-mt${addrsfx}
boost_system-mt${addrsfx}
- boost_thread-mt${addrsfx})
+ boost_thread-mt${addrsfx}
+ boost_url-mt${addrsfx})
elseif (DARWIN)
target_link_libraries( ll::boost INTERFACE
boost_context-mt${addrsfx}
@@ -43,7 +45,8 @@ elseif (DARWIN)
boost_program_options-mt${addrsfx}
boost_regex-mt${addrsfx}
boost_system-mt${addrsfx}
- boost_thread-mt${addrsfx})
+ boost_thread-mt${addrsfx}
+ boost_url-mt${addrsfx})
endif (WINDOWS)
if (LINUX)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 0f338931c0..73b614e0af 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -57,13 +57,11 @@ set(cmake_SOURCE_FILES
Tut.cmake
UI.cmake
UnixInstall.cmake
- URIPARSER.cmake
Variables.cmake
ViewerMiscLibs.cmake
VisualLeakDetector.cmake
LibVLCPlugin.cmake
WebRTC.cmake
- XmlRpcEpi.cmake
xxHash.cmake
ZLIBNG.cmake
)
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 30dee3c6c1..86c5b80fad 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -54,13 +54,14 @@ if(WINDOWS)
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(release_files
openjp2.dll
- libapr-1.dll
- libaprutil-1.dll
nghttp2.dll
- libhunspell.dll
- uriparser.dll
)
+ if(LLCOMMON_LINK_SHARED)
+ set(release_files ${release_files} libapr-1.dll)
+ set(release_files ${release_files} libaprutil-1.dll)
+ endif()
+
# OpenSSL
if(ADDRESS_SIZE EQUAL 64)
set(release_files ${release_files} libcrypto-1_1-x64.dll)
@@ -137,9 +138,14 @@ if(WINDOWS)
# Check each of them.
foreach(release_msvc_file
msvcp${MSVC_VER}.dll
+ msvcp${MSVC_VER}_1.dll
+ msvcp${MSVC_VER}_2.dll
+ msvcp${MSVC_VER}_atomic_wait.dll
+ msvcp${MSVC_VER}_codecvt_ids.dll
msvcr${MSVC_VER}.dll
vcruntime${MSVC_VER}.dll
vcruntime${MSVC_VER}_1.dll
+ vcruntime${MSVC_VER}_threads.dll
)
if(redist_path AND EXISTS "${redist_path}/${release_msvc_file}")
MESSAGE(STATUS "Copying redist file from ${redist_path}/${release_msvc_file}")
@@ -176,20 +182,20 @@ elseif(DARWIN)
)
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(release_files
- libapr-1.0.dylib
- libapr-1.dylib
- libaprutil-1.0.dylib
- libaprutil-1.dylib
- ${EXPAT_COPY}
- libhunspell-1.3.0.dylib
libndofdev.dylib
libnghttp2.dylib
libnghttp2.14.dylib
- liburiparser.dylib
- liburiparser.1.dylib
- liburiparser.1.0.27.dylib
)
+ if(LLCOMMON_LINK_SHARED)
+ set(release_files ${release_files}
+ libapr-1.0.dylib
+ libapr-1.dylib
+ libaprutil-1.0.dylib
+ libaprutil-1.dylib
+ )
+ endif()
+
if (TARGET ll::openal)
list(APPEND release_files libalut.dylib libopenal.dylib)
endif ()
@@ -225,12 +231,9 @@ elseif(LINUX)
if( USE_AUTOBUILD_3P )
list( APPEND release_files
- libapr-1.so.0
- libaprutil-1.so.0
libatk-1.0.so
libfreetype.so.6.6.2
libfreetype.so.6
- libhunspell-1.3.so.0.0.0
libopenjp2.so
libuuid.so.16
libuuid.so.16.0.22
@@ -239,6 +242,13 @@ elseif(LINUX)
libgmodule-2.0.so
libgobject-2.0.so
)
+
+ if(LLCOMMON_LINK_SHARED)
+ set(release_files ${release_files}
+ libapr-1.so.0
+ libaprutil-1.so.0
+ )
+ endif()
endif()
else(WINDOWS)
diff --git a/indra/cmake/EXPAT.cmake b/indra/cmake/EXPAT.cmake
index 327fe8aa72..1a0b8789dc 100644
--- a/indra/cmake/EXPAT.cmake
+++ b/indra/cmake/EXPAT.cmake
@@ -7,14 +7,13 @@ add_library( ll::expat INTERFACE IMPORTED )
use_system_binary(expat)
use_prebuilt_binary(expat)
if (WINDOWS)
- target_link_libraries( ll::expat INTERFACE libexpatMT )
- set(EXPAT_COPY libexpatMT.dll)
-else (WINDOWS)
- target_link_libraries( ll::expat INTERFACE expat )
- if (DARWIN)
- set(EXPAT_COPY libexpat.1.dylib libexpat.dylib)
- else ()
- set(EXPAT_COPY libexpat.so.1 libexpat.so)
- endif ()
-endif (WINDOWS)
+ target_compile_definitions( ll::expat INTERFACE XML_STATIC=1)
+ target_link_libraries( ll::expat INTERFACE
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/libexpatd.lib
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.lib)
+else ()
+ target_link_libraries( ll::expat INTERFACE
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/libexpat.a
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.a)
+endif ()
target_include_directories( ll::expat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include )
diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake
index bb037c0237..129679febd 100644
--- a/indra/cmake/Hunspell.cmake
+++ b/indra/cmake/Hunspell.cmake
@@ -1,4 +1,5 @@
# -*- cmake -*-
+include(Linking)
include(Prebuilt)
include_guard()
@@ -8,10 +9,16 @@ add_library( ll::hunspell INTERFACE IMPORTED )
use_system_binary(hunspell)
use_prebuilt_binary(libhunspell)
if (WINDOWS)
- target_link_libraries( ll::hunspell INTERFACE libhunspell)
+ target_compile_definitions( ll::hunspell INTERFACE HUNSPELL_STATIC=1)
+ target_link_libraries( ll::hunspell INTERFACE
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/libhunspell.lib
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell.lib
+ )
elseif(DARWIN)
- target_link_libraries( ll::hunspell INTERFACE hunspell-1.3)
+ target_link_libraries( ll::hunspell INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell-1.7.a
+ )
elseif(LINUX)
- target_link_libraries( ll::hunspell INTERFACE hunspell-1.3)
+ target_link_libraries( ll::hunspell INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell-1.7.a
+ )
endif()
target_include_directories( ll::hunspell SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/hunspell)
diff --git a/indra/cmake/JPEG.cmake b/indra/cmake/JPEG.cmake
index 252d7852d4..ade5a070cc 100644
--- a/indra/cmake/JPEG.cmake
+++ b/indra/cmake/JPEG.cmake
@@ -7,12 +7,14 @@ include_guard()
add_library( ll::libjpeg INTERFACE IMPORTED )
use_system_binary(libjpeg)
-use_prebuilt_binary(jpeglib)
+use_prebuilt_binary(libjpeg-turbo)
if (LINUX)
- target_link_libraries( ll::libjpeg INTERFACE jpeg)
+ target_link_libraries( ll::libjpeg INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a)
elseif (DARWIN)
- target_link_libraries( ll::libjpeg INTERFACE jpeg)
+ target_link_libraries( ll::libjpeg INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a)
elseif (WINDOWS)
- target_link_libraries( ll::libjpeg INTERFACE jpeglib)
+ target_link_libraries( ll::libjpeg INTERFACE
+ debug ${ARCH_PREBUILT_DIRS_DEBUG}/jpeg.lib
+ optimized ${ARCH_PREBUILT_DIRS_RELEASE}/jpeg.lib)
endif (LINUX)
target_include_directories( ll::libjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 9e3707ff17..dd43ca4916 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -6,5 +6,3 @@ include(EXPAT)
include(Tracy)
include(xxHash)
include(ZLIBNG)
-
-include(XmlRpcEpi)
diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index 735f5e8052..1e81532551 100644
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -6,7 +6,6 @@ include(Boost)
include_guard()
-add_library( ll::pcre INTERFACE IMPORTED )
add_library( ll::minizip-ng INTERFACE IMPORTED )
add_library( ll::libxml INTERFACE IMPORTED )
add_library( ll::colladadom INTERFACE IMPORTED )
@@ -22,11 +21,8 @@ use_system_binary( colladadom )
use_prebuilt_binary(colladadom)
use_prebuilt_binary(minizip-ng) # needed for colladadom
-use_prebuilt_binary(pcre)
use_prebuilt_binary(libxml2)
-target_link_libraries( ll::pcre INTERFACE pcrecpp pcre )
-
if (WINDOWS)
target_link_libraries( ll::minizip-ng INTERFACE libminizip )
else()
diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake
deleted file mode 100644
index 6c33ff70e1..0000000000
--- a/indra/cmake/URIPARSER.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- cmake -*-
-
-include_guard()
-
-include(Prebuilt)
-
-add_library( ll::uriparser INTERFACE IMPORTED )
-
-use_system_binary( uriparser )
-
-use_prebuilt_binary(uriparser)
-if (WINDOWS)
- target_link_libraries( ll::uriparser INTERFACE uriparser)
-elseif (LINUX)
- target_link_libraries( ll::uriparser INTERFACE uriparser)
-elseif (DARWIN)
- target_link_libraries( ll::uriparser INTERFACE liburiparser.dylib)
-endif (WINDOWS)
-target_include_directories( ll::uriparser SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/uriparser)
diff --git a/indra/cmake/XmlRpcEpi.cmake b/indra/cmake/XmlRpcEpi.cmake
deleted file mode 100644
index 6409f9d6e2..0000000000
--- a/indra/cmake/XmlRpcEpi.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-
-include_guard()
-add_library( ll::xmlrpc-epi INTERFACE IMPORTED )
-
-use_system_binary( xmlrpc-epi )
-
-use_prebuilt_binary(xmlrpc-epi)
-target_link_libraries(ll::xmlrpc-epi INTERFACE xmlrpc-epi )
-target_include_directories( ll::xmlrpc-epi SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index 7ae760d312..8df8a9726f 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -557,7 +557,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
}
if (mLastWeight != mLastWeight)
{
- mLastWeight = mCurWeight+.001;
+ mLastWeight = mCurWeight+.001f;
}
// perform differential update of morph
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index d376c68c7f..aa48a2d621 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -106,7 +106,7 @@ void LLTexLayerSetBuffer::pushProjection() const
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadIdentity();
- gGL.ortho(0.0f, getCompositeWidth(), 0.0f, getCompositeHeight(), -1.0f, 1.0f);
+ gGL.ortho(0.0f, (F32)getCompositeWidth(), 0.0f, (F32)getCompositeHeight(), -1.0f, 1.0f);
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index a46f9acc63..d8a6fffea6 100755
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -790,9 +790,12 @@ bool LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
{
- // Just put it on the decode queue.
+ // Just put it on the decode queue it if it's not already in the queue
LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL;
- mImpl->mDecodeQueue.push_back(uuid);
+ if (std::find(mImpl->mDecodeQueue.begin(), mImpl->mDecodeQueue.end(), uuid) == mImpl->mDecodeQueue.end())
+ {
+ mImpl->mDecodeQueue.emplace_back(uuid);
+ }
return true;
}
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 3697422ac8..613c408157 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1827,7 +1827,17 @@ bool LLAudioData::load()
{
// Hrm. Right now, let's unset the buffer, since it's empty.
gAudiop->cleanupBuffer(mBufferp);
- mBufferp = NULL;
+ mBufferp = nullptr;
+
+ if (!gDirUtilp->fileExists(wav_path))
+ {
+ mHasLocalData = false;
+ mHasDecodedData = false;
+ mHasCompletedDecode = false;
+ mHasDecodeFailed = false;
+ mHasWAVLoadFailed = false;
+ gAudiop->preloadSound(mID);
+ }
return false;
}
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 264b9a0be1..ecbcdb3bf5 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -38,7 +38,7 @@
LLStringTable LLCharacter::sVisualParamNames(1024);
-std::vector< LLCharacter* > LLCharacter::sInstances;
+std::list< LLCharacter* > LLCharacter::sInstances;
bool LLCharacter::sAllowInstancesChange = true ;
//-----------------------------------------------------------------------------
@@ -53,7 +53,6 @@ LLCharacter::LLCharacter()
mSkeletonSerialNum( 0 )
{
llassert_always(sAllowInstancesChange) ;
- sInstances.push_back(this);
mMotionController.setCharacter( this );
mPauseRequest = new LLPauseRequestHandle();
@@ -66,28 +65,12 @@ LLCharacter::LLCharacter()
//-----------------------------------------------------------------------------
LLCharacter::~LLCharacter()
{
- for (LLVisualParam *param = getFirstVisualParam();
- param;
- param = getNextVisualParam())
+ for (const auto& it : mVisualParamIndexMap)
{
- delete param;
+ delete it.second;
}
- size_t i ;
- size_t size = sInstances.size() ;
- for(i = 0 ; i < size ; i++)
- {
- if(sInstances[i] == this)
- {
- break ;
- }
- }
-
- llassert_always(i < size) ;
-
llassert_always(sAllowInstancesChange) ;
- sInstances[i] = sInstances[size - 1] ;
- sInstances.pop_back() ;
}
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index b390960a75..6143ec8cd1 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -245,6 +245,24 @@ public:
S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); }
LLVisualParam* getVisualParam(const char *name);
+ void animateTweakableVisualParams(F32 delta)
+ {
+ for (auto& it : mVisualParamIndexMap)
+ {
+ if (it.second->isTweakable())
+ {
+ it.second->animate(delta);
+ }
+ }
+ }
+
+ void applyAllVisualParams(ESex avatar_sex)
+ {
+ for (auto& it : mVisualParamIndexMap)
+ {
+ it.second->apply(avatar_sex);
+ }
+ }
ESex getSex() const { return mSex; }
void setSex( ESex sex ) { mSex = sex; }
@@ -255,7 +273,7 @@ public:
U32 getSkeletonSerialNum() const { return mSkeletonSerialNum; }
void setSkeletonSerialNum( U32 num ) { mSkeletonSerialNum = num; }
- static std::vector< LLCharacter* > sInstances;
+ static std::list< LLCharacter* > sInstances;
static bool sAllowInstancesChange ; //debug use
virtual void setHoverOffset(const LLVector3& hover_offset, bool send_update=true) { mHoverOffset = hover_offset; }
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index 12212efb66..6790f1ad56 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -2227,7 +2227,12 @@ bool LLKeyframeMotion::dumpToFile(const std::string& name)
}
S32 file_size = getFileSize();
- U8* buffer = new U8[file_size];
+ U8* buffer = new(std::nothrow) U8[file_size];
+ if (!buffer)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Bad memory allocation for buffer, file: " << name << " " << file_size << LL_ENDL;
+ }
LL_DEBUGS("BVH") << "Dumping " << outfilename << LL_ENDL;
LLDataPackerBinaryBuffer dp(buffer, file_size);
@@ -2407,13 +2412,10 @@ void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid,
{
LLUUID* id = (LLUUID*)user_data;
- std::vector::iterator char_iter = LLCharacter::sInstances.begin();
-
- while(char_iter != LLCharacter::sInstances.end() &&
- (*char_iter)->getID() != *id)
- {
- ++char_iter;
- }
+ auto char_iter = std::find_if(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), [&](LLCharacter* c)
+ {
+ return c->getID() == *id;
+ });
delete id;
@@ -2438,7 +2440,12 @@ void LLKeyframeMotion::onLoadComplete(const LLUUID& asset_uuid,
LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
S32 size = file.getSize();
- U8* buffer = new U8[size];
+ U8* buffer = new(std::nothrow) U8[size];
+ if (!buffer)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Bad memory allocation for buffer of size: " << size << LL_ENDL;
+ }
file.read((U8*)buffer, size); /*Flawfinder: ignore*/
LL_DEBUGS("Animation") << "Loading keyframe data for: " << motionp->getName() << ":" << motionp->getID() << " (" << size << " bytes)" << LL_ENDL;
diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp
index 605e15f442..f8691b5f59 100644
--- a/indra/llcharacter/llkeyframewalkmotion.cpp
+++ b/indra/llcharacter/llkeyframewalkmotion.cpp
@@ -383,7 +383,7 @@ bool LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask)
F32 target_roll = llclamp(ang_vel.mV[VZ], -4.f, 4.f) * roll_factor;
// roll is critically damped interpolation between current roll and angular velocity-derived target roll
- mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, U32Milliseconds(100));
+ mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, F32Milliseconds(100.f));
LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f));
mPelvisState->setRotation(roll);
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 95e991c246..8e43627a5f 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -10,7 +10,6 @@ include(Boost)
include(LLSharedLibs)
include(Copy3rdPartyLibs)
include(ZLIBNG)
-include(URIPARSER)
include(Tracy)
@@ -278,7 +277,6 @@ target_link_libraries(
ll::expat
ll::zlib-ng
ll::boost
- ll::uriparser
ll::oslibraries
ll::tracy
)
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index b85bd2573b..6da764f94c 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -90,7 +90,7 @@ bool LLApp::sDisableCrashlogger = false;
// Local flag for whether or not to do logging in signal handlers.
//static
-bool LLApp::sLogInSignal = false;
+bool LLApp::sLogInSignal = true;
// static
// Keeps track of application status
@@ -373,6 +373,9 @@ static std::map statusDesc
// static
void LLApp::setStatus(EAppStatus status)
{
+ auto status_it = statusDesc.find(status);
+ std::string status_text = status_it != statusDesc.end() ? std::string(status_it->second) : std::to_string(status);
+ LL_INFOS() << "status: " << status_text << LL_ENDL;
// notify everyone waiting on sStatus any time its value changes
sStatus.set_all(status);
@@ -381,18 +384,7 @@ void LLApp::setStatus(EAppStatus status)
if (! LLEventPumps::wasDeleted())
{
// notify interested parties of status change
- LLSD statsd;
- auto found = statusDesc.find(status);
- if (found != statusDesc.end())
- {
- statsd = found->second;
- }
- else
- {
- // unknown status? at least report value
- statsd = LLSD::Integer(status);
- }
- LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", statsd));
+ LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", status_text));
}
}
@@ -487,6 +479,33 @@ int LLApp::getPid()
#endif
}
+// static
+void LLApp::notifyOutOfDiskSpace()
+{
+ static const U32Seconds min_interval = U32Seconds(60);
+ static U32Seconds min_time_to_send = U32Seconds(0);
+ U32Seconds now = LLTimer::getTotalTime();
+ if (now < min_time_to_send)
+ return;
+
+ min_time_to_send = now + min_interval;
+
+ if (LLApp* app = instance())
+ {
+ app->sendOutOfDiskSpaceNotification();
+ }
+ else
+ {
+ LL_WARNS() << "No app instance" << LL_ENDL;
+ }
+}
+
+// virtual
+void LLApp::sendOutOfDiskSpaceNotification()
+{
+ LL_WARNS() << "Should never be called" << LL_ENDL; // Should be overridden
+}
+
#ifndef LL_WINDOWS
void setup_signals()
{
@@ -654,6 +673,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
{
LL_WARNS() << "Signal handler - Handling fatal signal!" << LL_ENDL;
}
+
if (LLApp::isError())
{
// Received second fatal signal while handling first, just die right now
@@ -691,11 +711,11 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
clear_signals();
raise(signum);
return;
- } else {
- if (LLApp::sLogInSignal)
- {
- LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;
- }
+ }
+
+ if (LLApp::sLogInSignal)
+ {
+ LL_INFOS() << "Signal handler - Unhandled signal " << signum << ", ignoring!" << LL_ENDL;
}
}
}
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index ad8912ca88..d90ecdf661 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -202,6 +202,8 @@ public:
static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
static int getPid();
+ static void notifyOutOfDiskSpace();
+
//
// Sleep for specified time while still running
//
@@ -301,6 +303,8 @@ protected:
*/
void stepFrame();
+ virtual void sendOutOfDiskSpaceNotification();
+
private:
// Contains the filename of the minidump file after a crash.
char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH];
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index b085f8f5dc..01763c49aa 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -28,6 +28,7 @@
#include "linden_common.h"
#include "llapr.h"
+#include "llapp.h"
#include "llmutex.h"
#include "apr_dso.h"
@@ -606,7 +607,11 @@ S32 LLAPRFile::writeEx(const std::string& filename, const void *buf, S32 offset,
apr_status_t s = apr_file_write(file_handle, buf, &bytes_written);
if (s != APR_SUCCESS)
{
- LL_WARNS("APR") << " Attempting to write filename: " << filename << LL_ENDL;
+ LL_WARNS("APR") << "Attempting to write filename: " << filename << LL_ENDL;
+ if (APR_STATUS_IS_ENOSPC(s))
+ {
+ LLApp::notifyOutOfDiskSpace();
+ }
ll_apr_warn_status(s);
bytes_written = 0;
}
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 369d65407e..c3820ae987 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -31,8 +31,9 @@
#include "llexception.h"
#include
-#include
#include
+#include
+#include
#include "mutex.h"
#include "llsingleton.h"
#include "llinstancetracker.h"
@@ -307,6 +308,12 @@ public:
// use mutex, lock, condition_variable suitable for coroutines
using Mutex = boost::fibers::mutex;
+ using RMutex = boost::fibers::recursive_mutex;
+ // With C++17, LockType is deprecated: at this point we can directly
+ // declare 'std::unique_lock lk(some_mutex)' without explicitly stating
+ // the mutex type. Sadly, making LockType an alias template for
+ // std::unique_lock doesn't work the same way: Class Template Argument
+ // Deduction only works for class templates, not alias templates.
using LockType = std::unique_lock;
using cv_status = boost::fibers::cv_status;
using ConditionVariable = boost::fibers::condition_variable;
diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index c63c7012d1..b38864688d 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -41,20 +41,11 @@
#include "llstring.h"
#include "llfasttimer.h"
-static const F64 DATE_EPOCH = 0.0;
-
static const F64 LL_APR_USEC_PER_SEC = 1000000.0;
// should be APR_USEC_PER_SEC, but that relies on INT64_C which
// isn't defined in glib under our build set up for some reason
-LLDate::LLDate() : mSecondsSinceEpoch(DATE_EPOCH)
-{}
-
-LLDate::LLDate(const LLDate& date) :
- mSecondsSinceEpoch(date.mSecondsSinceEpoch)
-{}
-
LLDate::LLDate(F64SecondsImplicit seconds_since_epoch) :
mSecondsSinceEpoch(seconds_since_epoch.value())
{}
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 81f2dd0d1c..1a69a04232 100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -43,16 +43,13 @@
*/
class LL_COMMON_API LLDate
{
+ static constexpr F64 DATE_EPOCH = 0.0;
public:
/**
* @brief Construct a date equal to epoch.
*/
- LLDate();
-
- /**
- * @brief Construct a date equal to the source date.
- */
- LLDate(const LLDate& date);
+ constexpr LLDate() : mSecondsSinceEpoch(DATE_EPOCH)
+ {}
/**
* @brief Construct a date from a seconds since epoch value.
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index fa24987d1c..6c3b9c9542 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -55,7 +55,6 @@
#include "llsingleton.h"
#include "llstl.h"
#include "lltimer.h"
-#include
// On Mac, got:
// #error "Boost.Stacktrace requires `_Unwind_Backtrace` function. Define
@@ -168,7 +167,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
if (LLError::getAlwaysFlush())
{
mFile << message << std::endl;
@@ -235,7 +234,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
// The default colors for error, warn and debug are now a bit more pastel
// and easier to read on the default (black) terminal background but you
// now have the option to set the color of each via an environment variables:
@@ -275,7 +274,7 @@ namespace {
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
static std::string s_ansi_bold = createBoldANSI(); // bold text
static std::string s_ansi_reset = createResetANSI(); // reset
// ANSI color code escape sequence, message, and reset in one fprintf call
@@ -312,7 +311,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
mBuffer->addLine(message);
}
@@ -339,7 +338,7 @@ namespace {
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
debugger_print(message);
}
};
@@ -507,7 +506,7 @@ namespace
LLError::TimeFunction mTimeFunction;
Recorders mRecorders;
- boost::fibers::recursive_mutex mRecorderMutex;
+ LLCoros::RMutex mRecorderMutex;
int mShouldLogCallCounter;
@@ -1216,7 +1215,7 @@ namespace
void writeToRecorders(const LLError::CallSite& site, const std::string& message)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
LLError::ELevel level = site.mLevel;
SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
@@ -1347,7 +1346,7 @@ namespace LLError
bool Log::shouldLog(CallSite& site)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
LLMutexTrylock lock(getMutex(), 5);
if (!lock.isLocked())
{
@@ -1392,7 +1391,7 @@ namespace LLError
void Log::flush(const std::ostringstream& out, const CallSite& site)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
LLMutexTrylock lock(getMutex(),5);
if (!lock.isLocked())
{
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index cbb703e9e7..1845fc42db 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -190,7 +190,7 @@ namespace LLError
{}
void recordMessage(LLError::ELevel level, const std::string& message) override
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
mCallable(level, message);
}
private:
diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h
index 5c45144fad..d8c7e15a27 100644
--- a/indra/llcommon/lleventfilter.h
+++ b/indra/llcommon/lleventfilter.h
@@ -429,7 +429,7 @@ public:
// path, then stores it to mTarget.
virtual bool post(const LLSD& event)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// Extract the element specified by 'mPath' from 'event'. To perform a
// generic type-appropriate store through mTarget, construct an
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index ddf239f306..9045324bf2 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -248,6 +248,24 @@ int LLFile::close(LLFILE * file)
return ret_value;
}
+std::string LLFile::getContents(const std::string& filename)
+{
+ LLFILE* fp = fopen(filename, "rb"); /* Flawfinder: ignore */
+ if (fp)
+ {
+ fseek(fp, 0, SEEK_END);
+ U32 length = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector buffer(length);
+ size_t nread = fread(buffer.data(), 1, length, fp);
+ fclose(fp);
+
+ return std::string(buffer.data(), nread);
+ }
+
+ return LLStringUtil::null;
+}
int LLFile::remove(const std::string& filename, int supress_error)
{
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index 2564671b13..74110343fc 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -67,6 +67,8 @@ public:
static int close(LLFILE * file);
+ static std::string getContents(const std::string& filename);
+
// perms is a permissions mask like 0777 or 0700. In most cases it will
// be overridden by the user's umask. It is ignored on Windows.
// mkdir() considers "directory already exists" to be SUCCESS.
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 4b7d60d654..99c803e46f 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -39,6 +39,7 @@
#elif LL_LINUX
# include
# include
+# include
#endif
#include "llmemory.h"
@@ -50,13 +51,28 @@
//----------------------------------------------------------------------------
//static
+
+// most important memory metric for texture streaming
+// On Windows, this should agree with resource monitor -> performance -> memory -> available
+// On OS X, this should be activity monitor -> memory -> (physical memory - memory used)
+// NOTE: this number MAY be less than the actual available memory on systems with more than MaxHeapSize64 GB of physical memory (default 16GB)
+// In that case, should report min(available, sMaxHeapSizeInKB-sAllocateMemInKB)
U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
+
+// Installed physical memory
U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0);
+
+// Maximimum heap size according to the user's settings (default 16GB)
+U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
+
+// Current memory usage
+U32Kilobytes LLMemory::sAllocatedMemInKB(0);
+
+U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
+
+
static LLTrace::SampleStatHandle sAllocatedMem("allocated_mem", "active memory in use by application");
static LLTrace::SampleStatHandle sVirtualMem("virtual_mem", "virtual memory assigned to application");
-U32Kilobytes LLMemory::sAllocatedMemInKB(0);
-U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
-U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
{
@@ -84,7 +100,14 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size)
//static
void LLMemory::updateMemoryInfo()
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
+
+ sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB();
+
+ U32Kilobytes avail_mem;
+ LLMemoryInfo::getAvailableMemoryKB(avail_mem);
+ sAvailPhysicalMemInKB = avail_mem;
+
#if LL_WINDOWS
PROCESS_MEMORY_COUNTERS counters;
@@ -95,23 +118,9 @@ void LLMemory::updateMemoryInfo()
}
sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(counters.WorkingSetSize));
- sample(sAllocatedMem, sAllocatedMemInKB);
sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(counters.PagefileUsage));
sample(sVirtualMem, sAllocatedPageSizeInKB);
- U32Kilobytes avail_phys, avail_virtual;
- LLMemoryInfo::getAvailableMemoryKB(avail_phys, avail_virtual) ;
- sMaxPhysicalMemInKB = llmin(avail_phys + sAllocatedMemInKB, sMaxHeapSizeInKB);
-
- if(sMaxPhysicalMemInKB > sAllocatedMemInKB)
- {
- sAvailPhysicalMemInKB = sMaxPhysicalMemInKB - sAllocatedMemInKB ;
- }
- else
- {
- sAvailPhysicalMemInKB = U32Kilobytes(0);
- }
-
#elif defined(LL_DARWIN)
task_vm_info info;
mach_msg_type_number_t infoCount = TASK_VM_INFO_COUNT;
@@ -136,31 +145,19 @@ void LLMemory::updateMemoryInfo()
{
LL_WARNS() << "task_info failed" << LL_ENDL;
}
-
- // Total installed and available physical memory are properties of the host, not just our process.
- vm_statistics64_data_t vmstat;
- mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
- mach_port_t host = mach_host_self();
- vm_size_t page_size;
- host_page_size(host, &page_size);
- kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast(&vmstat), &count);
- if (result == KERN_SUCCESS) {
- // This is what Chrome reports as 'the "Physical Memory Free" value reported by the Memory Monitor in Instruments.'
- // Note though that inactive pages are not included here and not yet free, but could become so under memory pressure.
- sAvailPhysicalMemInKB = U32Bytes(vmstat.free_count * page_size);
- sMaxPhysicalMemInKB = LLMemoryInfo::getHardwareMemSize();
- }
- else
- {
- LL_WARNS() << "task_info failed" << LL_ENDL;
- }
-
+#elif defined(LL_LINUX)
+ // Use sysinfo() to get the total physical memory.
+ struct sysinfo info;
+ sysinfo(&info);
+ sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(LLMemory::getCurrentRSS())); // represents the RAM allocated by this process only (in line with the windows implementation)
#else
//not valid for other systems for now.
+ LL_WARNS() << "LLMemory::updateMemoryInfo() not implemented for this platform." << LL_ENDL;
sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS());
- sMaxPhysicalMemInKB = U64Bytes(U32_MAX);
- sAvailPhysicalMemInKB = U64Bytes(U32_MAX);
#endif
+ sample(sAllocatedMem, sAllocatedMemInKB);
+
+ sAvailPhysicalMemInKB = llmin(sAvailPhysicalMemInKB, sMaxHeapSizeInKB - sAllocatedMemInKB);
return ;
}
@@ -192,16 +189,16 @@ void* LLMemory::tryToAlloc(void* address, U32 size)
//static
void LLMemory::logMemoryInfo(bool update)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
if(update)
{
updateMemoryInfo() ;
}
- LL_INFOS() << "Current allocated physical memory(KB): " << sAllocatedMemInKB << LL_ENDL ;
- LL_INFOS() << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << LL_ENDL ;
- LL_INFOS() << "Current available physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
- LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ;
+ LL_INFOS() << llformat("Current allocated physical memory: %.2f MB", sAllocatedMemInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current allocated page size: %.2f MB", sAllocatedPageSizeInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current available physical memory: %.2f MB", sAvailPhysicalMemInKB / 1024.0) << LL_ENDL;
+ LL_INFOS() << llformat("Current max usable memory: %.2f MB", sMaxPhysicalMemInKB / 1024.0) << LL_ENDL;
}
//static
diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp
index 40c651d9c1..be1ae89a25 100644
--- a/indra/llcommon/llmutex.cpp
+++ b/indra/llcommon/llmutex.cpp
@@ -100,7 +100,7 @@ void LLMutex::unlock()
bool LLMutex::isLocked()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (!mMutex.try_lock())
{
return true;
@@ -124,7 +124,7 @@ LLThread::id_t LLMutex::lockingThread() const
bool LLMutex::trylock()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (isSelfLocked())
{ //redundant lock
mCount++;
@@ -161,7 +161,7 @@ LLSharedMutex::LLSharedMutex()
bool LLSharedMutex::isLocked() const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
std::lock_guard lock(mLockMutex);
return !mLockingThreads.empty();
@@ -169,7 +169,7 @@ bool LLSharedMutex::isLocked() const
bool LLSharedMutex::isThreadLocked() const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard lock(mLockMutex);
@@ -179,7 +179,7 @@ bool LLSharedMutex::isThreadLocked() const
void LLSharedMutex::lockShared()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
mLockMutex.lock();
@@ -204,7 +204,7 @@ void LLSharedMutex::lockShared()
void LLSharedMutex::lockExclusive()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
mLockMutex.lock();
@@ -237,7 +237,7 @@ void LLSharedMutex::lockExclusive()
bool LLSharedMutex::trylockShared()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard lock(mLockMutex);
@@ -260,7 +260,7 @@ bool LLSharedMutex::trylockShared()
bool LLSharedMutex::trylockExclusive()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard lock(mLockMutex);
@@ -282,7 +282,7 @@ bool LLSharedMutex::trylockExclusive()
void LLSharedMutex::unlockShared()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard lock(mLockMutex);
@@ -303,7 +303,7 @@ void LLSharedMutex::unlockShared()
void LLSharedMutex::unlockExclusive()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
LLThread::id_t current_thread = LLThread::currentID();
std::lock_guard lock(mLockMutex);
@@ -338,20 +338,20 @@ LLCondition::~LLCondition()
void LLCondition::wait()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
std::unique_lock< std::mutex > lock(mMutex);
mCond.wait(lock);
}
void LLCondition::signal()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mCond.notify_one();
}
void LLCondition::broadcast()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mCond.notify_all();
}
@@ -364,7 +364,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex)
: mMutex(mutex),
mLocked(false)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (mMutex)
mLocked = mMutex->trylock();
}
@@ -373,7 +373,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
: mMutex(mutex),
mLocked(false)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (!mMutex)
return;
@@ -388,7 +388,7 @@ LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms)
LLMutexTrylock::~LLMutexTrylock()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (mMutex && mLocked)
mMutex->unlock();
}
@@ -400,7 +400,7 @@ LLMutexTrylock::~LLMutexTrylock()
//
LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if(mutex)
{
mutex->lock();
@@ -419,7 +419,7 @@ LLScopedLock::~LLScopedLock()
void LLScopedLock::unlock()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if(mLocked)
{
mMutex->unlock();
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index f5916f9d58..6edff9fa5e 100644
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -46,8 +46,11 @@
template class LLPointer
{
public:
+ template
+ friend class LLPointer;
+
LLPointer() :
- mPointer(NULL)
+ mPointer(nullptr)
{
}
@@ -63,6 +66,12 @@ public:
ref();
}
+ LLPointer(LLPointer&& ptr) noexcept
+ {
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+
// Support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template
LLPointer(const LLPointer& ptr) :
@@ -71,6 +80,13 @@ public:
ref();
}
+ template
+ LLPointer(LLPointer&& ptr) noexcept :
+ mPointer(ptr.get())
+ {
+ ptr.mPointer = nullptr;
+ }
+
~LLPointer()
{
unref();
@@ -82,11 +98,11 @@ public:
const Type& operator*() const { return *mPointer; }
Type& operator*() { return *mPointer; }
- operator BOOL() const { return (mPointer != NULL); }
- operator bool() const { return (mPointer != NULL); }
- bool operator!() const { return (mPointer == NULL); }
- bool isNull() const { return (mPointer == NULL); }
- bool notNull() const { return (mPointer != NULL); }
+ operator BOOL() const { return (mPointer != nullptr); }
+ operator bool() const { return (mPointer != nullptr); }
+ bool operator!() const { return (mPointer == nullptr); }
+ bool isNull() const { return (mPointer == nullptr); }
+ bool notNull() const { return (mPointer != nullptr); }
operator Type*() const { return mPointer; }
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
@@ -107,6 +123,17 @@ public:
return *this;
}
+ LLPointer& operator =(LLPointer&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template
LLPointer& operator =(const LLPointer& ptr)
@@ -115,6 +142,18 @@ public:
return *this;
}
+ template
+ LLPointer& operator =(LLPointer&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// Just exchange the pointers, which will not change the reference counts.
static void swap(LLPointer& a, LLPointer& b)
{
@@ -141,9 +180,9 @@ protected:
if (mPointer)
{
Type *temp = mPointer;
- mPointer = NULL;
+ mPointer = nullptr;
temp->unref();
- if (mPointer != NULL)
+ if (mPointer != nullptr)
{
LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
unref();
@@ -168,9 +207,11 @@ protected:
template class LLConstPointer
{
+ template
+ friend class LLConstPointer;
public:
LLConstPointer() :
- mPointer(NULL)
+ mPointer(nullptr)
{
}
@@ -186,6 +227,12 @@ public:
ref();
}
+ LLConstPointer(LLConstPointer&& ptr) noexcept
+ {
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template
LLConstPointer(const LLConstPointer& ptr) :
@@ -194,6 +241,13 @@ public:
ref();
}
+ template
+ LLConstPointer(LLConstPointer&& ptr) noexcept :
+ mPointer(ptr.get())
+ {
+ ptr.mPointer = nullptr;
+ }
+
~LLConstPointer()
{
unref();
@@ -203,11 +257,11 @@ public:
const Type* operator->() const { return mPointer; }
const Type& operator*() const { return *mPointer; }
- operator BOOL() const { return (mPointer != NULL); }
- operator bool() const { return (mPointer != NULL); }
- bool operator!() const { return (mPointer == NULL); }
- bool isNull() const { return (mPointer == NULL); }
- bool notNull() const { return (mPointer != NULL); }
+ operator BOOL() const { return (mPointer != nullptr); }
+ operator bool() const { return (mPointer != nullptr); }
+ bool operator!() const { return (mPointer == nullptr); }
+ bool isNull() const { return (mPointer == nullptr); }
+ bool notNull() const { return (mPointer != nullptr); }
operator const Type*() const { return mPointer; }
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
@@ -239,6 +293,17 @@ public:
return *this;
}
+ LLConstPointer& operator =(LLConstPointer&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
template
LLConstPointer& operator =(const LLConstPointer& ptr)
@@ -252,6 +317,18 @@ public:
return *this;
}
+ template
+ LLConstPointer& operator =(LLConstPointer&& ptr)
+ {
+ if (mPointer != ptr.mPointer)
+ {
+ unref();
+ mPointer = ptr.mPointer;
+ ptr.mPointer = nullptr;
+ }
+ return *this;
+ }
+
// Just exchange the pointers, which will not change the reference counts.
static void swap(LLConstPointer& a, LLConstPointer& b)
{
@@ -278,9 +355,9 @@ protected:
if (mPointer)
{
const Type *temp = mPointer;
- mPointer = NULL;
+ mPointer = nullptr;
temp->unref();
- if (mPointer != NULL)
+ if (mPointer != nullptr)
{
LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
unref();
@@ -313,7 +390,7 @@ public:
: LLPointer(ptr),
mStayUnique(false)
{
- if (ptr.mForceUnique)
+ if (ptr.mStayUnique)
{
makeUnique();
}
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 0248e8f8b9..a528cc7fd8 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -74,9 +74,6 @@
#ifndef LL_MSVC
#define LL_MSVC 1
#endif
- #if _MSC_VER < 1400
- #define LL_MSVC7 //Visual C++ 2003 or earlier
- #endif
#endif
// Deal with minor differences on Unixy OSes.
@@ -130,8 +127,6 @@
#endif
// level 4 warnings that we need to disable:
-#pragma warning (disable : 4244) // possible loss of data on conversions
-#pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template
#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class
#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class
#endif // LL_MSVC
diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h
index 722d9afca2..732436cc4f 100644
--- a/indra/llcommon/llprofiler.h
+++ b/indra/llcommon/llprofiler.h
@@ -84,7 +84,7 @@ extern thread_local bool gProfilerEnabled;
// #define TRACY_NO_BROADCAST 1
// #define TRACY_ONLY_LOCALHOST 1
#define TRACY_ONLY_IPV4 1
- #include "Tracy.hpp"
+ #include "tracy/Tracy.hpp"
// Enable OpenGL profiling
#define LL_PROFILER_ENABLE_TRACY_OPENGL 0
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 7d77f6f6a9..1c4ac5a7bf 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -483,7 +483,7 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
if (sleep_time.count() > 0)
{
- ms_sleep(sleep_time.count());
+ ms_sleep((U32)sleep_time.count());
}
}
processRequest(req);
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
index 25d75af568..2c51e6f07f 100644
--- a/indra/llcommon/llrand.cpp
+++ b/indra/llcommon/llrand.cpp
@@ -85,7 +85,7 @@ inline F32 ll_internal_random()
// Per Monty, it's important to clamp using the correct fmodf() rather
// than expanding to F64 for fmod() and then truncating back to F32. Prior
// to this change, we were getting sporadic ll_frand() == 1.0 results.
- F32 rv{ narrow(gRandomGenerator()) };
+ F32 rv{ narrow(gRandomGenerator()) };
if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f);
return rv;
}
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 663ceac22b..77fe545c3f 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -30,6 +30,7 @@
#include "linden_common.h"
#include "llsd.h"
+#include "llbase64.h"
#include "llerror.h"
#include "../llmath/llmath.h"
#include "llformat.h"
@@ -105,6 +106,9 @@ public:
static void reset(Impl*& var, Impl* impl);
///< safely set var to refer to the new impl (possibly shared)
+ static void move(Impl*& var, Impl*& impl);
+ ///< safely move impl from one object to another
+
static Impl& safe( Impl*);
static const Impl& safe(const Impl*);
///< since a NULL Impl* is used for undefined, this ensures there is
@@ -122,11 +126,17 @@ public:
virtual void assign(Impl*& var, LLSD::Boolean);
virtual void assign(Impl*& var, LLSD::Integer);
virtual void assign(Impl*& var, LLSD::Real);
+ virtual void assign(Impl*& var, const char*);
virtual void assign(Impl*& var, const LLSD::String&);
virtual void assign(Impl*& var, const LLSD::UUID&);
virtual void assign(Impl*& var, const LLSD::Date&);
virtual void assign(Impl*& var, const LLSD::URI&);
virtual void assign(Impl*& var, const LLSD::Binary&);
+ virtual void assign(Impl*& var, LLSD::String&&);
+ virtual void assign(Impl*& var, LLSD::UUID&&);
+ virtual void assign(Impl*& var, LLSD::Date&&);
+ virtual void assign(Impl*& var, LLSD::URI&&);
+ virtual void assign(Impl*& var, LLSD::Binary&&);
///< If the receiver is the right type and unshared, these are simple
// data assignments, othewise the default implementation handless
// constructing the proper Impl subclass
@@ -142,11 +152,13 @@ public:
virtual const String& asStringRef() const { static const std::string empty; return empty; }
- virtual bool has(const String&) const { return false; }
- virtual LLSD get(const String&) const { return LLSD(); }
+ virtual String asXMLRPCValue() const { return ""; }
+
+ virtual bool has(std::string_view) const { return false; }
+ virtual LLSD get(std::string_view) const { return LLSD(); }
virtual LLSD getKeys() const { return LLSD::emptyArray(); }
virtual void erase(const String&) { }
- virtual const LLSD& ref(const String&) const{ return undef(); }
+ virtual const LLSD& ref(std::string_view) const{ return undef(); }
virtual size_t size() const { return 0; }
virtual LLSD get(size_t) const { return LLSD(); }
@@ -182,7 +194,7 @@ namespace LLSDUnnamedNamespace
namespace
#endif
{
- template
+ template
class ImplBase : public LLSD::Impl
///< This class handles most of the work for a subclass of Impl
// for a given simple data type. Subclasses of this provide the
@@ -195,6 +207,7 @@ namespace
public:
ImplBase(DataRef value) : mValue(value) { }
+ ImplBase(DataMove value) : mValue(std::move(value)) { }
virtual LLSD::Type type() const { return T; }
@@ -209,11 +222,21 @@ namespace
mValue = value;
}
}
+ virtual void assign(LLSD::Impl*& var, DataMove value) {
+ if (shared())
+ {
+ Impl::assign(var, std::move(value));
+ }
+ else
+ {
+ mValue = std::move(value);
+ }
+ }
};
- class ImplBoolean
- : public ImplBase
+ class ImplBoolean final
+ : public ImplBase
{
public:
ImplBoolean(LLSD::Boolean v) : Base(v) { }
@@ -222,6 +245,8 @@ namespace
virtual LLSD::Integer asInteger() const { return mValue ? 1 : 0; }
virtual LLSD::Real asReal() const { return mValue ? 1 : 0; }
virtual LLSD::String asString() const;
+
+ virtual LLSD::String asXMLRPCValue() const { return mValue ? "1" : "0"; }
};
LLSD::String ImplBoolean::asString() const
@@ -233,8 +258,8 @@ namespace
{ return mValue ? "true" : ""; }
- class ImplInteger
- : public ImplBase
+ class ImplInteger final
+ : public ImplBase
{
public:
ImplInteger(LLSD::Integer v) : Base(v) { }
@@ -243,14 +268,16 @@ namespace
virtual LLSD::Integer asInteger() const { return mValue; }
virtual LLSD::Real asReal() const { return mValue; }
virtual LLSD::String asString() const;
+
+ virtual LLSD::String asXMLRPCValue() const { return "" + std::to_string(mValue) + ""; }
};
LLSD::String ImplInteger::asString() const
{ return llformat("%d", mValue); }
- class ImplReal
- : public ImplBase
+ class ImplReal final
+ : public ImplBase
{
public:
ImplReal(LLSD::Real v) : Base(v) { }
@@ -259,6 +286,8 @@ namespace
virtual LLSD::Integer asInteger() const;
virtual LLSD::Real asReal() const { return mValue; }
virtual LLSD::String asString() const;
+
+ virtual LLSD::String asXMLRPCValue() const { return "" + std::to_string(mValue) + ""; }
};
LLSD::Boolean ImplReal::asBoolean() const
@@ -271,11 +300,12 @@ namespace
{ return llformat("%lg", mValue); }
- class ImplString
- : public ImplBase
+ class ImplString final
+ : public ImplBase
{
public:
ImplString(const LLSD::String& v) : Base(v) { }
+ ImplString(LLSD::String&& v) : Base(std::move(v)) {}
virtual LLSD::Boolean asBoolean() const { return !mValue.empty(); }
virtual LLSD::Integer asInteger() const;
@@ -286,9 +316,24 @@ namespace
virtual LLSD::URI asURI() const { return LLURI(mValue); }
virtual size_t size() const { return mValue.size(); }
virtual const LLSD::String& asStringRef() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "" + LLStringFn::xml_encode(mValue) + ""; }
+
+ using LLSD::Impl::assign; // Unhiding base class virtuals...
+ virtual void assign(LLSD::Impl*& var, const char* value)
+ {
+ if (shared())
+ {
+ Impl::assign(var, value);
+ }
+ else
+ {
+ mValue = value;
+ }
+ }
};
- LLSD::Integer ImplString::asInteger() const
+ LLSD::Integer ImplString::asInteger() const
{
// This must treat "1.23" not as an error, but as a number, which is
// then truncated down to an integer. Hence, this code doesn't call
@@ -298,7 +343,7 @@ namespace
return (int)asReal();
}
- LLSD::Real ImplString::asReal() const
+ LLSD::Real ImplString::asReal() const
{
F64 v = 0.0;
std::istringstream i_stream(mValue);
@@ -315,25 +360,32 @@ namespace
}
- class ImplUUID
- : public ImplBase
+ class ImplUUID final
+ : public ImplBase
{
public:
ImplUUID(const LLSD::UUID& v) : Base(v) { }
+ ImplUUID(LLSD::UUID&& v) : Base(std::move(v)) { }
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::UUID asUUID() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "" + mValue.asString() + ""; }
};
- class ImplDate
- : public ImplBase
+ class ImplDate final
+ : public ImplBase
{
public:
ImplDate(const LLSD::Date& v)
- : ImplBase(v)
+ : ImplBase(v)
{ }
+ ImplDate(LLSD::Date&& v)
+ : ImplBase(std::move(v))
+ { }
+
virtual LLSD::Integer asInteger() const
{
return (LLSD::Integer)(mValue.secondsSinceEpoch());
@@ -344,34 +396,42 @@ namespace
}
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::Date asDate() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "" + mValue.toHTTPDateString("%FT%T") + ""; }
};
- class ImplURI
- : public ImplBase
+ class ImplURI final
+ : public ImplBase
{
public:
ImplURI(const LLSD::URI& v) : Base(v) { }
+ ImplURI(LLSD::URI&& v) : Base(std::move(v)) { }
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::URI asURI() const { return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "" + LLStringFn::xml_encode(mValue.asString()) + ""; }
};
- class ImplBinary
- : public ImplBase
+ class ImplBinary final
+ : public ImplBase
{
public:
ImplBinary(const LLSD::Binary& v) : Base(v) { }
+ ImplBinary(LLSD::Binary&& v) : Base(std::move(v)) { }
virtual const LLSD::Binary& asBinary() const{ return mValue; }
+
+ virtual LLSD::String asXMLRPCValue() const { return "" + LLBase64::encode(mValue.data(), mValue.size()) + ""; }
};
- class ImplMap : public LLSD::Impl
+ class ImplMap final : public LLSD::Impl
{
private:
- typedef std::map DataMap;
+ typedef std::map> DataMap;
DataMap mData;
@@ -387,17 +447,30 @@ namespace
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
- virtual bool has(const LLSD::String&) const;
+ virtual LLSD::String asXMLRPCValue() const
+ {
+ std::ostringstream os;
+ os << "";
+ for (const auto& it : mData)
+ {
+ os << "" << LLStringFn::xml_encode(it.first) << ""
+ << it.second.asXMLRPCValue() << "";
+ }
+ os << "";
+ return os.str();
+ }
+
+ virtual bool has(std::string_view) const;
using LLSD::Impl::get; // Unhiding get(size_t)
using LLSD::Impl::erase; // Unhiding erase(size_t)
using LLSD::Impl::ref; // Unhiding ref(size_t)
- virtual LLSD get(const LLSD::String&) const;
+ virtual LLSD get(std::string_view) const;
virtual LLSD getKeys() const;
- void insert(const LLSD::String& k, const LLSD& v);
+ void insert(std::string_view k, const LLSD& v);
virtual void erase(const LLSD::String&);
- LLSD& ref(const LLSD::String&);
- virtual const LLSD& ref(const LLSD::String&) const;
+ LLSD& ref(std::string_view);
+ virtual const LLSD& ref(std::string_view) const;
virtual size_t size() const { return mData.size(); }
@@ -425,14 +498,14 @@ namespace
}
}
- bool ImplMap::has(const LLSD::String& k) const
+ bool ImplMap::has(const std::string_view k) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
DataMap::const_iterator i = mData.find(k);
return i != mData.end();
}
- LLSD ImplMap::get(const LLSD::String& k) const
+ LLSD ImplMap::get(const std::string_view k) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
DataMap::const_iterator i = mData.find(k);
@@ -452,10 +525,10 @@ namespace
return keys;
}
- void ImplMap::insert(const LLSD::String& k, const LLSD& v)
+ void ImplMap::insert(std::string_view k, const LLSD& v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
- mData.insert(DataMap::value_type(k, v));
+ mData.emplace(k, v);
}
void ImplMap::erase(const LLSD::String& k)
@@ -464,15 +537,21 @@ namespace
mData.erase(k);
}
- LLSD& ImplMap::ref(const LLSD::String& k)
+ LLSD& ImplMap::ref(std::string_view k)
{
- return mData[k];
+ DataMap::iterator i = mData.lower_bound(k);
+ if (i == mData.end() || mData.key_comp()(k, i->first))
+ {
+ return mData.emplace_hint(i, std::make_pair(k, LLSD()))->second;
+ }
+
+ return i->second;
}
- const LLSD& ImplMap::ref(const LLSD::String& k) const
+ const LLSD& ImplMap::ref(std::string_view k) const
{
DataMap::const_iterator i = mData.lower_bound(k);
- if (i == mData.end() || mData.key_comp()(k, i->first))
+ if (i == mData.end() || mData.key_comp()(k, i->first))
{
return undef();
}
@@ -500,7 +579,7 @@ namespace
{
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
Impl::calcStats((*iter).second, type_counts, share_counts);
- iter++;
+ ++iter;
}
// Add in the values for this map
@@ -511,7 +590,7 @@ namespace
class ImplArray : public LLSD::Impl
{
private:
- typedef std::vector DataVector;
+ typedef std::vector DataVector;
DataVector mData;
@@ -527,6 +606,18 @@ namespace
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
+ virtual LLSD::String asXMLRPCValue() const
+ {
+ std::ostringstream os;
+ os << "";
+ for (const auto& it : mData)
+ {
+ os << it.asXMLRPCValue();
+ }
+ os << "";
+ return os.str();
+ }
+
using LLSD::Impl::get; // Unhiding get(LLSD::String)
using LLSD::Impl::erase; // Unhiding erase(LLSD::String)
using LLSD::Impl::ref; // Unhiding ref(LLSD::String)
@@ -647,7 +738,7 @@ namespace
while (iter != endArray())
{ // Add values for all items held in the array
Impl::calcStats((*iter), type_counts, share_counts);
- iter++;
+ ++iter;
}
// Add in the values for this array
@@ -685,6 +776,16 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl)
var = impl;
}
+void LLSD::Impl::move(Impl*& var, Impl*& impl)
+{
+ if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0)
+ {
+ delete var; // destroy var if usage falls to 0 and not static
+ }
+ var = impl; // Steal impl to var without incrementing use since this is a move
+ impl = nullptr; // null out old-impl pointer
+}
+
LLSD::Impl& LLSD::Impl::safe(Impl* impl)
{
static Impl theUndefined(STATIC_USAGE_COUNT);
@@ -738,6 +839,11 @@ void LLSD::Impl::assign(Impl*& var, LLSD::Real v)
reset(var, new ImplReal(v));
}
+void LLSD::Impl::assign(Impl*& var, const char* v)
+{
+ reset(var, new ImplString(v));
+}
+
void LLSD::Impl::assign(Impl*& var, const LLSD::String& v)
{
reset(var, new ImplString(v));
@@ -763,6 +869,31 @@ void LLSD::Impl::assign(Impl*& var, const LLSD::Binary& v)
reset(var, new ImplBinary(v));
}
+void LLSD::Impl::assign(Impl*& var, LLSD::String&& v)
+{
+ reset(var, new ImplString(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::UUID&& v)
+{
+ reset(var, new ImplUUID(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::Date&& v)
+{
+ reset(var, new ImplDate(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::URI&& v)
+{
+ reset(var, new ImplURI(std::move(v)));
+}
+
+void LLSD::Impl::assign(Impl*& var, LLSD::Binary&& v)
+{
+ reset(var, new ImplBinary(std::move(v)));
+}
+
const LLSD& LLSD::Impl::undef()
{
@@ -835,6 +966,9 @@ LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0)
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
+LLSD::LLSD(LLSD&& other) noexcept : impl(nullptr) { ALLOC_LLSD_OBJECT; Impl::move(impl, other.impl); }
+void LLSD::assign(LLSD&& other) { Impl::move(impl, other.impl); }
+LLSD& LLSD::operator=(LLSD&& other) noexcept { Impl::move(impl, other.impl); return *this; }
void LLSD::clear() { Impl::assignUndefined(impl); }
@@ -849,6 +983,11 @@ LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(UUID&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(String&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(Date&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(URI&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
+LLSD::LLSD(Binary&& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(std::move(v)); }
// Scalar Assignment
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
@@ -859,6 +998,11 @@ void LLSD::assign(const UUID& v) { safe(impl).assign(impl, v); }
void LLSD::assign(const Date& v) { safe(impl).assign(impl, v); }
void LLSD::assign(const URI& v) { safe(impl).assign(impl, v); }
void LLSD::assign(const Binary& v) { safe(impl).assign(impl, v); }
+void LLSD::assign(String&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(UUID&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(Date&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(URI&& v) { safe(impl).assign(impl, std::move(v)); }
+void LLSD::assign(Binary&& v) { safe(impl).assign(impl, std::move(v)); }
// Scalar Accessors
LLSD::Boolean LLSD::asBoolean() const { return safe(impl).asBoolean(); }
@@ -872,11 +1016,13 @@ const LLSD::Binary& LLSD::asBinary() const { return safe(impl).asBinary(); }
const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
+LLSD::String LLSD::asXMLRPCValue() const { return "" + safe(impl).asXMLRPCValue() + ""; }
+
// const char * helpers
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
void LLSD::assign(const char* v)
{
- if(v) assign(std::string(v));
+ if(v) safe(impl).assign(impl, v);
else assign(std::string());
}
@@ -888,24 +1034,24 @@ LLSD LLSD::emptyMap()
return v;
}
-bool LLSD::has(const String& k) const { return safe(impl).has(k); }
-LLSD LLSD::get(const String& k) const { return safe(impl).get(k); }
+bool LLSD::has(const std::string_view k) const { return safe(impl).has(k); }
+LLSD LLSD::get(const std::string_view k) const { return safe(impl).get(k); }
LLSD LLSD::getKeys() const { return safe(impl).getKeys(); }
-void LLSD::insert(const String& k, const LLSD& v) { makeMap(impl).insert(k, v); }
+void LLSD::insert(std::string_view k, const LLSD& v) { makeMap(impl).insert(k, v); }
-LLSD& LLSD::with(const String& k, const LLSD& v)
+LLSD& LLSD::with(std::string_view k, const LLSD& v)
{
makeMap(impl).insert(k, v);
return *this;
}
void LLSD::erase(const String& k) { makeMap(impl).erase(k); }
-LLSD& LLSD::operator[](const String& k)
+LLSD& LLSD::operator[](const std::string_view k)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
return makeMap(impl).ref(k);
}
-const LLSD& LLSD::operator[](const String& k) const
+const LLSD& LLSD::operator[](const std::string_view k) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
return safe(impl).ref(k);
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index a5e735b561..d2b3548831 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -161,6 +161,13 @@ public:
//@}
+ /** @name Movable */
+ //@{
+ LLSD(LLSD&& other) noexcept;
+ void assign(LLSD&& other);
+ LLSD& operator=(LLSD&& other) noexcept;
+ //@}
+
void clear(); ///< resets to Undefined
@@ -188,6 +195,11 @@ public:
LLSD(const Date&);
LLSD(const URI&);
LLSD(const Binary&);
+ LLSD(String&&);
+ LLSD(UUID&&);
+ LLSD(Date&&);
+ LLSD(URI&&);
+ LLSD(Binary&&);
//@}
/** @name Convenience Constructors */
@@ -215,6 +227,11 @@ public:
void assign(const Date&);
void assign(const URI&);
void assign(const Binary&);
+ void assign(String&&);
+ void assign(UUID&&);
+ void assign(Date&&);
+ void assign(URI&&);
+ void assign(Binary&&);
LLSD& operator=(Boolean v) { assign(v); return *this; }
LLSD& operator=(Integer v) { assign(v); return *this; }
@@ -224,6 +241,11 @@ public:
LLSD& operator=(const Date& v) { assign(v); return *this; }
LLSD& operator=(const URI& v) { assign(v); return *this; }
LLSD& operator=(const Binary& v) { assign(v); return *this; }
+ LLSD& operator=(String&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(UUID&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(Date&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(URI&& v) { assign(std::move(v)); return *this; }
+ LLSD& operator=(Binary&& v) { assign(std::move(v)); return *this; }
//@}
/**
@@ -259,10 +281,14 @@ public:
UUID asUUID() const;
Date asDate() const;
URI asURI() const;
- const Binary& asBinary() const;
+ const Binary& asBinary() const;
// asStringRef on any non-string type will return a ref to an empty string.
- const String& asStringRef() const;
+ const String& asStringRef() const;
+
+ // Return "<((type))>((scalar value or recursive calls))((type))>"
+ // See http://xmlrpc.com/spec.md
+ String asXMLRPCValue() const;
operator Boolean() const { return asBoolean(); }
operator Integer() const { return asInteger(); }
@@ -275,7 +301,7 @@ public:
// This is needed because most platforms do not automatically
// convert the boolean negation as a bool in an if statement.
- bool operator!() const {return !asBoolean();}
+ bool operator!() const { return !asBoolean(); }
//@}
/** @name Character Pointer Helpers
@@ -292,24 +318,22 @@ public:
//@{
static LLSD emptyMap();
- bool has(const String&) const;
- LLSD get(const String&) const;
+ bool has(const std::string_view) const;
+ LLSD get(const std::string_view) const;
LLSD getKeys() const; // Return an LLSD array with keys as strings
- void insert(const String&, const LLSD&);
+ void insert(std::string_view, const LLSD&);
void erase(const String&);
- LLSD& with(const String&, const LLSD&);
+ LLSD& with(std::string_view, const LLSD&);
- LLSD& operator[](const String&);
+ LLSD& operator[](const std::string_view);
LLSD& operator[](const char* c)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
- return (*this)[String(c)];
+ return c ? (*this)[std::string_view(c)] : *this;
}
- const LLSD& operator[](const String&) const;
+ const LLSD& operator[](const std::string_view) const;
const LLSD& operator[](const char* c) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
- return (*this)[String(c)];
+ return c ? (*this)[std::string_view(c)] : *this;
}
//@}
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index b981be4d0a..3ae153a67c 100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -149,7 +149,7 @@ bool LLParamSDParser::readF32(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast(parser);
- *((F32*)val_ptr) = self.mCurReadSD->asReal();
+ *((F32*)val_ptr) = (F32)self.mCurReadSD->asReal();
return true;
}
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 15002580c9..37af366a20 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -231,7 +231,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, llssize max_bytes)
}
// Since we've already read 'inbuf' bytes into 'hdr_buf', prepend that
// data to whatever remains in 'str'.
- LLMemoryStreamBuf already(reinterpret_cast(hdr_buf), inbuf);
+ LLMemoryStreamBuf already(reinterpret_cast(hdr_buf), (S32)inbuf);
cat_streambuf prebuff(&already, str.rdbuf());
std::istream prepend(&prebuff);
#if 1
@@ -475,7 +475,7 @@ LLSDNotationParser::~LLSDNotationParser()
// virtual
S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// map: { string:object, string:object }
// array: [ object, object, object ]
// undef: !
@@ -566,7 +566,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
data,
NOTATION_FALSE_SERIAL,
false);
- if(PARSE_FAILURE == cnt) parse_count = cnt;
+ if(PARSE_FAILURE == cnt) parse_count = (S32)cnt;
else account(cnt);
}
else
@@ -592,7 +592,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
if(isalpha(c))
{
auto cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true);
- if(PARSE_FAILURE == cnt) parse_count = cnt;
+ if(PARSE_FAILURE == cnt) parse_count = (S32)cnt;
else account(cnt);
}
else
@@ -735,7 +735,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c
S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// map: { string:object, string:object }
map = LLSD::emptyMap();
S32 parse_count = 0;
@@ -796,7 +796,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) c
S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// array: [ object, object, object ]
array = LLSD::emptyArray();
S32 parse_count = 0;
@@ -836,7 +836,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_dept
bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
std::string value;
auto count = deserialize_string(istr, value, mMaxBytesLeft);
if(PARSE_FAILURE == count) return false;
@@ -847,7 +847,7 @@ bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
// binary: b##"ff3120ab1"
// or: b(len)"..."
@@ -950,7 +950,7 @@ LLSDBinaryParser::~LLSDBinaryParser()
// virtual
S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
/**
* Undefined: '!'
* Boolean: '1' for true '0' for false
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 88cbb3b984..6396caf8d5 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -554,7 +554,7 @@ void LLSDXMLParser::Impl::parsePart(const char* buf, llssize len)
if ( buf != NULL
&& len > 0 )
{
- XML_Status status = XML_Parse(mParser, buf, len, false);
+ XML_Status status = XML_Parse(mParser, buf, (int)len, 0);
if (status == XML_STATUS_ERROR)
{
LL_INFOS() << "Unexpected XML parsing error at start" << LL_ENDL;
@@ -930,7 +930,7 @@ void LLSDXMLParser::parsePart(const char *buf, llssize len)
// virtual
S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data, S32 max_depth) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD;
#ifdef XML_PARSER_PERFORMANCE_TESTS
XML_Timer timer( &parseTime );
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index dd3a58c26d..12f67208c1 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -51,7 +51,7 @@
// U32
LLSD ll_sd_from_U32(const U32 val)
{
- std::vector v;
+ LLSD::Binary v;
U32 net_order = htonl(val);
v.resize(4);
@@ -63,7 +63,7 @@ LLSD ll_sd_from_U32(const U32 val)
U32 ll_U32_from_sd(const LLSD& sd)
{
U32 ret;
- std::vector v = sd.asBinary();
+ const LLSD::Binary& v = sd.asBinary();
if (v.size() < 4)
{
return 0;
@@ -76,7 +76,7 @@ U32 ll_U32_from_sd(const LLSD& sd)
//U64
LLSD ll_sd_from_U64(const U64 val)
{
- std::vector v;
+ LLSD::Binary v;
U32 high, low;
high = (U32)(val >> 32);
@@ -94,7 +94,7 @@ LLSD ll_sd_from_U64(const U64 val)
U64 ll_U64_from_sd(const LLSD& sd)
{
U32 high, low;
- std::vector v = sd.asBinary();
+ const LLSD::Binary& v = sd.asBinary();
if (v.size() < 8)
{
@@ -112,7 +112,7 @@ U64 ll_U64_from_sd(const LLSD& sd)
// IP Address (stored in net order in a U32, so don't need swizzling)
LLSD ll_sd_from_ipaddr(const U32 val)
{
- std::vector v;
+ LLSD::Binary v;
v.resize(4);
memcpy(&(v[0]), &val, 4); /* Flawfinder: ignore */
@@ -123,7 +123,7 @@ LLSD ll_sd_from_ipaddr(const U32 val)
U32 ll_ipaddr_from_sd(const LLSD& sd)
{
U32 ret;
- std::vector v = sd.asBinary();
+ const LLSD::Binary& v = sd.asBinary();
if (v.size() < 4)
{
return 0;
@@ -135,17 +135,17 @@ U32 ll_ipaddr_from_sd(const LLSD& sd)
// Converts an LLSD binary to an LLSD string
LLSD ll_string_from_binary(const LLSD& sd)
{
- std::vector value = sd.asBinary();
+ const LLSD::Binary& value = sd.asBinary();
std::string str;
str.resize(value.size());
- memcpy(&str[0], &value[0], value.size());
+ memcpy(&str[0], value.data(), value.size());
return str;
}
// Converts an LLSD string to an LLSD binary
LLSD ll_binary_from_string(const LLSD& sd)
{
- std::vector binary_value;
+ LLSD::Binary binary_value;
std::string string_value = sd.asString();
for (const U8 c : string_value)
@@ -214,7 +214,7 @@ bool compare_llsd_with_template(
const LLSD& template_llsd,
LLSD& resultant_llsd)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
if (
llsd_to_test.isUndefined() &&
@@ -337,7 +337,7 @@ bool filter_llsd_with_template(
const LLSD & template_llsd,
LLSD & resultant_llsd)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
if (llsd_to_test.isUndefined() && template_llsd.isDefined())
{
@@ -533,7 +533,7 @@ class TypeLookup
public:
TypeLookup()
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
for (const Data *di(boost::begin(typedata)), *dend(boost::end(typedata)); di != dend; ++di)
{
@@ -543,7 +543,7 @@ public:
std::string lookup(LLSD::Type type) const
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
MapType::const_iterator found = mMap.find(type);
if (found != mMap.end())
@@ -595,7 +595,7 @@ static std::string match_types(LLSD::Type expect, // prototype.type()
LLSD::Type actual, // type we're checking
const std::string& pfx) // as for llsd_matches
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// Trivial case: if the actual type is exactly what we expect, we're good.
if (actual == expect)
@@ -634,7 +634,7 @@ static std::string match_types(LLSD::Type expect, // prototype.type()
// see docstring in .h file
std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::string& pfx)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// An undefined prototype means that any data is valid.
// An undefined slot in an array or map prototype means that any data
@@ -768,7 +768,7 @@ std::string llsd_matches(const LLSD& prototype, const LLSD& data, const std::str
bool llsd_equals(const LLSD& lhs, const LLSD& rhs, int bits)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// We're comparing strict equality of LLSD representation rather than
// performing any conversions. So if the types aren't equal, the LLSD
@@ -878,7 +878,7 @@ namespace llsd
LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// Treat rawPath uniformly as an array. If it's not already an array,
// store it as the only entry in one. (But let's say Undefined means an
@@ -905,7 +905,7 @@ LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
// path entry that's bad.
for (LLSD::Integer i = 0; i < path.size(); ++i)
{
- LL_PROFILE_ZONE_NUM( i )
+ LL_PROFILE_ZONE_NUM(i);
const LLSD& key{path[i]};
if (key.isString())
@@ -935,7 +935,7 @@ LLSD& drill_ref(LLSD& blob, const LLSD& rawPath)
LLSD drill(const LLSD& blob, const LLSD& path)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
// drill_ref() does exactly what we want. Temporarily cast away
// const-ness and use that.
@@ -949,7 +949,7 @@ LLSD drill(const LLSD& blob, const LLSD& path)
// filter may be include to exclude/include keys in a map.
LLSD llsd_clone(LLSD value, LLSD filter)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
LLSD clone;
bool has_filter(filter.isMap());
@@ -990,8 +990,7 @@ LLSD llsd_clone(LLSD value, LLSD filter)
case LLSD::TypeBinary:
{
- LLSD::Binary bin(value.asBinary().begin(), value.asBinary().end());
- clone = LLSD::Binary(bin);
+ clone = LLSD::Binary(value.asBinary().begin(), value.asBinary().end());
break;
}
default:
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 7c6be25309..316831cd74 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -37,7 +37,8 @@
#include "llmainthreadtask.h"
#ifdef LL_WINDOWS
-#pragma warning( disable : 4506 ) // no definition for inline function
+#pragma warning(push)
+#pragma warning(disable : 4506) // no definition for inline function
#endif
class LLSingletonBase: private boost::noncopyable
@@ -861,4 +862,8 @@ private:
template
T* LLSimpleton::sInstance{ nullptr };
+#ifdef LL_WINDOWS
+#pragma warning(pop)
+#endif
+
#endif
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index 1b52d94258..7d41c42ba7 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -226,11 +226,11 @@ void delete_and_clear_array(T*& ptr)
// foo[2] = "hello";
// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
-template
-inline T* get_ptr_in_map(const std::map& inmap, const K& key)
+template
+inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_type const& key)
{
// Typedef here avoids warnings because of new c++ naming rules.
- typedef typename std::map::const_iterator map_iter;
+ typedef typename T::const_iterator map_iter;
map_iter iter = inmap.find(key);
if(iter == inmap.end())
{
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 514d73b24b..c57f8b1e96 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -250,7 +250,7 @@ LLWString utf16str_to_wstring(const U16* utf16str, size_t len)
while (i < len)
{
llwchar cur_char;
- i += utf16chars_to_wchar(chars16+i, &cur_char);
+ i += (S32)utf16chars_to_wchar(chars16+i, &cur_char);
wout += cur_char;
}
return wout;
@@ -1208,6 +1208,75 @@ namespace LLStringFn
return output;
}
+ using literals_t = std::map;
+ static const literals_t xml_elem_literals =
+ {
+ { '<', "<" },
+ { '>', ">" },
+ { '&', "&" }
+ };
+ static const literals_t xml_attr_literals =
+ {
+ { '"', """ },
+ { '\'', "'" }
+ };
+
+ static void literals_encode(std::string& text, const literals_t& literals)
+ {
+ for (const std::pair it : literals)
+ {
+ std::string::size_type pos = 0;
+ while ((pos = text.find(it.first, pos)) != std::string::npos)
+ {
+ text.replace(pos, 1, it.second);
+ pos += it.second.size();
+ }
+ }
+ }
+
+ static void literals_decode(std::string& text, const literals_t& literals)
+ {
+ for (const std::pair it : literals)
+ {
+ std::string::size_type pos = 0;
+ while ((pos = text.find(it.second, pos)) != std::string::npos)
+ {
+ text[pos++] = it.first;
+ text.erase(pos, it.second.size() - 1);
+ }
+ }
+ }
+
+ /**
+ * @brief Replace all characters that are not allowed in XML 1.0
+ * with corresponding literals: [ < > & ] => [ < > & ]
+ */
+ std::string xml_encode(const std::string& input, bool for_attribute)
+ {
+ std::string result(input);
+ literals_encode(result, xml_elem_literals);
+ if (for_attribute)
+ {
+ literals_encode(result, xml_attr_literals);
+ }
+ return result;
+ }
+
+ /**
+ * @brief Replace some of XML literals that are defined in XML 1.0
+ * with corresponding characters: [ < > & ] => [ < > & ]
+ */
+ std::string xml_decode(const std::string& input, bool for_attribute)
+ {
+ std::string result(input);
+ literals_decode(result, xml_elem_literals);
+ if (for_attribute)
+ {
+ literals_decode(result, xml_attr_literals);
+ }
+ return result;
+ }
+
/**
* @brief Replace all control characters (c < 0x20) with replacement in
* string.
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 123f4184b5..b69a068830 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -889,6 +889,20 @@ namespace LLStringFn
LL_COMMON_API std::string strip_invalid_xml(const std::string& input);
+ /**
+ * @brief Replace all characters that are not allowed in XML 1.0
+ * with corresponding literals: [ < > & ] => [ < > & ]
+ */
+ LL_COMMON_API std::string xml_encode(const std::string& input, bool for_attribute = false);
+
+
+ /**
+ * @brief Replace some of XML literals that are defined in XML 1.0
+ * with corresponding characters: [ < > & ] => [ < > & ]
+ */
+ LL_COMMON_API std::string xml_decode(const std::string& input, bool for_attribute = false);
+
+
/**
* @brief Replace all control characters (0 <= c < 0x20) with replacement in
* string. This is safe for utf-8
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index cfb05873df..79625ad9f8 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -74,6 +74,8 @@ using namespace llsd;
# include
# include
# include
+# include
+# include
#elif LL_LINUX
# include
# include
@@ -85,6 +87,7 @@ const char MEMINFO_FILE[] = "/proc/meminfo";
#endif
LLCPUInfo gSysCPU;
+LLMemoryInfo gSysMemory;
// Don't log memory info any more often than this. It also serves as our
// framerate sample size.
@@ -797,33 +800,32 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
}
//static
-void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb)
+void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_mem_kb)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
#if LL_WINDOWS
// Sigh, this shouldn't be a static method, then we wouldn't have to
// reload this data separately from refresh()
LLSD statsMap(loadStatsMap());
- avail_physical_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
- avail_virtual_mem_kb = (U32Kilobytes)statsMap["Avail Virtual KB"].asInteger();
+ avail_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger();
#elif LL_DARWIN
- // mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
- // $ vm_stat
- // Mach Virtual Memory Statistics: (page size of 4096 bytes)
- // Pages free: 462078.
- // Pages active: 142010.
- // Pages inactive: 220007.
- // Pages wired down: 159552.
- // "Translation faults": 220825184.
- // Pages copy-on-write: 2104153.
- // Pages zero filled: 167034876.
- // Pages reactivated: 65153.
- // Pageins: 2097212.
- // Pageouts: 41759.
- // Object cache: 841598 hits of 7629869 lookups (11% hit rate)
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ // use host_statistics64 to get memory info
+ vm_statistics64_data_t vmstat;
+ mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
+ mach_port_t host = mach_host_self();
+ vm_size_t page_size;
+ host_page_size(host, &page_size);
+ kern_return_t result = host_statistics64(host, HOST_VM_INFO64, reinterpret_cast(&vmstat), &count);
+ if (result == KERN_SUCCESS)
+ {
+ avail_mem_kb = U64Bytes((vmstat.free_count + vmstat.inactive_count) * page_size);
+ }
+ else
+ {
+ avail_mem_kb = (U32Kilobytes)-1;
+ }
#elif LL_LINUX
// mStatsMap is derived from MEMINFO_FILE:
@@ -874,15 +876,14 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32
// DirectMap4k: 434168 kB
// DirectMap2M: 477184 kB
// (could also run 'free', but easier to read a file than run a program)
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ LLSD statsMap(loadStatsMap());
+ avail_mem_kb = (U32Kilobytes)statsMap["MemFree"].asInteger();
#else
//do not know how to collect available memory info for other systems.
//leave it blank here for now.
- avail_physical_mem_kb = (U32Kilobytes)-1 ;
- avail_virtual_mem_kb = (U32Kilobytes)-1 ;
+ avail_mem_kb = (U32Kilobytes)-1 ;
#endif
}
@@ -928,7 +929,7 @@ LLSD LLMemoryInfo::getStatsMap() const
LLMemoryInfo& LLMemoryInfo::refresh()
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
mStatsMap = loadStatsMap();
LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
@@ -977,7 +978,7 @@ LLSD LLMemoryInfo::loadStatsMap()
// specifically accepts PROCESS_MEMORY_COUNTERS*, and since this is a
// classic-C API, PROCESS_MEMORY_COUNTERS_EX isn't a subclass. Cast the
// pointer.
- GetProcessMemoryInfo(GetCurrentProcess(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));
+ GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmem, sizeof(pmem));
stats.add("Page Fault Count", pmem.PageFaultCount);
stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index f97d49eeb1..827b0dc048 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -134,8 +134,8 @@ public:
static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib.
#endif
- //get the available memory infomation in KiloBytes.
- static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
+ //get the available memory in KiloBytes.
+ static void getAvailableMemoryKB(U32Kilobytes& avail_mem_kb);
// Retrieve a map of memory statistics. The keys of the map are platform-
// dependent. The values are in kilobytes to try to avoid integer overflow.
@@ -169,6 +169,7 @@ bool LL_COMMON_API gunzip_file(const std::string& srcfile, const std::string& ds
// gzip srcfile into dstfile. Returns false on error.
bool LL_COMMON_API gzip_file(const std::string& srcfile, const std::string& dstfile);
+extern LL_COMMON_API LLMemoryInfo gSysMemory;
extern LL_COMMON_API LLCPUInfo gSysCPU;
#endif // LL_LLSYS_H
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index faaaefd561..e5d25b52f0 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -269,6 +269,7 @@ void LLThread::shutdown()
mStatus = STOPPED;
return;
}
+ delete mThreadp;
mThreadp = NULL;
}
@@ -299,6 +300,7 @@ void LLThread::start()
{
mThreadp = new std::thread(std::bind(&LLThread::threadRun, this));
mNativeHandle = mThreadp->native_handle();
+ mThreadp->detach();
}
catch (std::system_error& ex)
{
@@ -344,7 +346,7 @@ bool LLThread::runCondition(void)
// Stop thread execution if requested until unpaused.
void LLThread::checkPause()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->lock();
// This is in a while loop because the pthread API allows for spurious wakeups.
@@ -376,20 +378,20 @@ void LLThread::setQuitting()
// static
LLThread::id_t LLThread::currentID()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
return std::this_thread::get_id();
}
// static
void LLThread::yield()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
std::this_thread::yield();
}
void LLThread::wake()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->lock();
if(!shouldSleep())
{
@@ -400,7 +402,7 @@ void LLThread::wake()
void LLThread::wakeLocked()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if(!shouldSleep())
{
mRunCondition->signal();
@@ -409,13 +411,13 @@ void LLThread::wakeLocked()
void LLThread::lockData()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->lock();
}
void LLThread::unlockData()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
mDataLock->unlock();
}
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index a3e871661c..28d6e4e4cc 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -91,7 +91,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
U32 micro_sleep(U64 us, U32 max_yields)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
#if 0
LARGE_INTEGER ft;
ft.QuadPart = -static_cast(us * 10); // '-' using relative time
@@ -101,7 +101,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
#else
- Sleep(us / 1000);
+ Sleep((DWORD)(us / 1000));
#endif
return 0;
@@ -109,7 +109,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
void ms_sleep(U32 ms)
{
- LL_PROFILE_ZONE_SCOPED
+ LL_PROFILE_ZONE_SCOPED;
micro_sleep(ms * 1000, 0);
}
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index 8741087f3a..dc9a87eb80 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -100,7 +100,7 @@ bool AccumulatorBufferGroup::isCurrent() const
return mCounts.isCurrent();
}
-void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
+void AccumulatorBufferGroup::append(const AccumulatorBufferGroup& other)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
mCounts.addSamples(other.mCounts, SEQUENTIAL);
@@ -109,7 +109,7 @@ void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
mStackTimers.addSamples(other.mStackTimers, SEQUENTIAL);
}
-void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
+void AccumulatorBufferGroup::merge(const AccumulatorBufferGroup& other)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
mCounts.addSamples(other.mCounts, NON_SEQUENTIAL);
@@ -140,7 +140,7 @@ void AccumulatorBufferGroup::sync()
F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const SampleAccumulator& b)
{
- const F64 epsilon = 0.0000001;
+ constexpr F64 epsilon = 0.0000001;
if (a.getSamplingTime() > epsilon && b.getSamplingTime() > epsilon)
{
@@ -170,7 +170,7 @@ F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const Samp
return a.getSumOfSquares();
}
-void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type )
+void SampleAccumulator::addSamples(const SampleAccumulator& other, EBufferAppendType append_type)
{
if (append_type == NON_SEQUENTIAL)
{
@@ -205,7 +205,7 @@ void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppen
}
}
-void SampleAccumulator::reset( const SampleAccumulator* other )
+void SampleAccumulator::reset(const SampleAccumulator* other)
{
mLastValue = other ? other->mLastValue : NaN;
mHasValue = other ? other->mHasValue : false;
@@ -243,7 +243,7 @@ F64 EventAccumulator::mergeSumsOfSquares(const EventAccumulator& a, const EventA
return a.mSumOfSquares;
}
-void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendType append_type )
+void EventAccumulator::addSamples(const EventAccumulator& other, EBufferAppendType append_type)
{
if (other.mNumSamples)
{
@@ -269,12 +269,12 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT
}
}
-void EventAccumulator::reset( const EventAccumulator* other )
+void EventAccumulator::reset(const EventAccumulator* other)
{
mNumSamples = 0;
mSum = 0;
- mMin = F32(NaN);
- mMax = F32(NaN);
+ mMin = NaN;
+ mMax = NaN;
mMean = NaN;
mSumOfSquares = 0;
mLastValue = other ? other->mLastValue : NaN;
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index ba7acf9547..0a2e2bf997 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -39,7 +39,7 @@
namespace LLTrace
{
- const F64 NaN = std::numeric_limits::quiet_NaN();
+ constexpr F64 NaN = std::numeric_limits::quiet_NaN();
enum EBufferAppendType
{
@@ -251,8 +251,8 @@ namespace LLTrace
EventAccumulator()
: mSum(0),
- mMin(F32(NaN)),
- mMax(F32(NaN)),
+ mMin(NaN),
+ mMax(NaN),
mMean(NaN),
mSumOfSquares(0),
mNumSamples(0),
@@ -288,11 +288,11 @@ namespace LLTrace
void sync(F64SecondsImplicit) {}
F64 getSum() const { return mSum; }
- F32 getMin() const { return mMin; }
- F32 getMax() const { return mMax; }
+ F64 getMin() const { return mMin; }
+ F64 getMax() const { return mMax; }
F64 getLastValue() const { return mLastValue; }
F64 getMean() const { return mMean; }
- F64 getStandardDeviation() const { return sqrtf(mSumOfSquares / mNumSamples); }
+ F64 getStandardDeviation() const { return sqrt(mSumOfSquares / mNumSamples); }
F64 getSumOfSquares() const { return mSumOfSquares; }
S32 getSampleCount() const { return mNumSamples; }
bool hasValue() const { return mNumSamples > 0; }
@@ -307,7 +307,7 @@ namespace LLTrace
F64 mMean,
mSumOfSquares;
- F32 mMin,
+ F64 mMin,
mMax;
S32 mNumSamples;
@@ -322,8 +322,8 @@ namespace LLTrace
SampleAccumulator()
: mSum(0),
- mMin(F32(NaN)),
- mMax(F32(NaN)),
+ mMin(NaN),
+ mMax(NaN),
mMean(NaN),
mSumOfSquares(0),
mLastSampleTimeStamp(0),
@@ -378,11 +378,11 @@ namespace LLTrace
}
F64 getSum() const { return mSum; }
- F32 getMin() const { return mMin; }
- F32 getMax() const { return mMax; }
+ F64 getMin() const { return mMin; }
+ F64 getMax() const { return mMax; }
F64 getLastValue() const { return mLastValue; }
F64 getMean() const { return mMean; }
- F64 getStandardDeviation() const { return sqrtf(mSumOfSquares / mTotalSamplingTime); }
+ F64 getStandardDeviation() const { return sqrt(mSumOfSquares / mTotalSamplingTime); }
F64 getSumOfSquares() const { return mSumOfSquares; }
F64SecondsImplicit getSamplingTime() const { return mTotalSamplingTime; }
S32 getSampleCount() const { return mNumSamples; }
@@ -402,7 +402,7 @@ namespace LLTrace
mLastSampleTimeStamp,
mTotalSamplingTime;
- F32 mMin,
+ F64 mMin,
mMax;
S32 mNumSamples;
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 1ec83be7cb..c23adca7e8 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -229,7 +229,7 @@ F32 Recording::getPerSec(const StatType& s
update();
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL;
- return (F32)(accumulator.mCalls + (active_accumulator ? active_accumulator->mCalls : 0)) / mElapsedSeconds.value();
+ return (F32)(accumulator.mCalls + (active_accumulator ? active_accumulator->mCalls : 0)) / (F32)mElapsedSeconds.value();
}
bool Recording::hasValue(const StatType& stat)
@@ -296,11 +296,11 @@ F64 Recording::getMean( const StatType& stat )
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
if (active_accumulator && active_accumulator->hasValue())
{
- F32 t = 0.0f;
+ F64 t = 0.0;
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
if (div > 0)
{
- t = active_accumulator->getSampleCount() / div;
+ t = (F64)active_accumulator->getSampleCount() / (F64)div;
}
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
}
@@ -319,7 +319,7 @@ F64 Recording::getStandardDeviation( const StatType& stat )
if (active_accumulator && active_accumulator->hasValue())
{
F64 sum_of_squares = SampleAccumulator::mergeSumsOfSquares(accumulator, *active_accumulator);
- return sqrtf(sum_of_squares / (accumulator.getSamplingTime() + active_accumulator->getSamplingTime()));
+ return sqrt(sum_of_squares / (F64)(accumulator.getSamplingTime() + active_accumulator->getSamplingTime()));
}
else
{
@@ -382,11 +382,11 @@ F64 Recording::getMean( const StatType& stat )
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
if (active_accumulator && active_accumulator->hasValue())
{
- F32 t = 0.0f;
+ F64 t = 0.0;
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
if (div > 0)
{
- t = active_accumulator->getSampleCount() / div;
+ t = (F64)active_accumulator->getSampleCount() / (F64)div;
}
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
}
@@ -405,7 +405,7 @@ F64 Recording::getStandardDeviation( const StatType& stat )
if (active_accumulator && active_accumulator->hasValue())
{
F64 sum_of_squares = EventAccumulator::mergeSumsOfSquares(accumulator, *active_accumulator);
- return sqrtf(sum_of_squares / (accumulator.getSampleCount() + active_accumulator->getSampleCount()));
+ return sqrt(sum_of_squares / (F64)(accumulator.getSampleCount() + active_accumulator->getSampleCount()));
}
else
{
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 985f06cd59..ad4c91d85b 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -35,6 +35,11 @@
#include "llpointer.h"
#include
+#ifdef LL_WINDOWS
+#pragma warning(push)
+#pragma warning(disable : 4244) // possible loss of data on conversions
+#endif
+
class LLStopWatchControlsMixinCommon
{
public:
@@ -714,4 +719,8 @@ namespace LLTrace
};
}
+#ifdef LL_WINDOWS
+#pragma warning(pop)
+#endif
+
#endif // LL_LLTRACERECORDING_H
diff --git a/indra/llcommon/llunittype.h b/indra/llcommon/llunittype.h
index 83ce0d05a8..bb1408609a 100644
--- a/indra/llcommon/llunittype.h
+++ b/indra/llcommon/llunittype.h
@@ -31,6 +31,11 @@
#include "llpreprocessor.h"
#include "llerror.h"
+#ifdef LL_WINDOWS
+#pragma warning(push)
+#pragma warning(disable : 4244) // possible loss of data on conversions
+#endif
+
//lightweight replacement of type traits for simple type equality check
template
struct LLIsSameType
@@ -846,4 +851,8 @@ LL_FORCE_INLINE S2 ll_convert_units(LLUnit in, LLUnit U64##unit_name; \
typedef LLUnitImplicit U64##unit_name##Implicit
+#ifdef LL_WINDOWS
+#pragma warning(pop)
+#endif
+
#endif //LL_UNITTYPE_H
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index 2ebb7fc742..33a48d970d 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -29,12 +29,7 @@
#include "linden_common.h"
#include "lluriparser.h"
-#if LL_DARWIN
-#include
-#include
-#endif
-
-LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)
+LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(false)
{
if (u.find("://") == std::string::npos)
{
@@ -42,36 +37,52 @@ LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedT
mTmpScheme = true;
}
- mNormalizedUri += u.c_str();
+ mNormalizedUri.append(u);
mRes = parse();
}
LLUriParser::~LLUriParser()
{
- uriFreeUriMembersA(&mUri);
}
-S32 LLUriParser::parse()
+bool LLUriParser::parse()
{
- mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL);
+ try
+ {
+ auto res = boost::urls::parse_uri(mNormalizedUri);
+ if (res)
+ {
+ mUri = *res;
+ mRes = true;
+ }
+ else
+ {
+ mRes = false;
+ }
+ }
+ catch (const std::length_error&)
+ {
+ LL_WARNS() << "Failed to parse uri due to exceeding uri_view max_size" << LL_ENDL;
+ mRes = false;
+ }
return mRes;
}
-const char * LLUriParser::scheme() const
+const std::string& LLUriParser::scheme() const
{
- return mScheme.c_str();
+ return mScheme;
}
-void LLUriParser::sheme(const std::string& s)
+void LLUriParser::scheme(const std::string& s)
{
mTmpScheme = !s.size();
mScheme = s;
}
-const char * LLUriParser::port() const
+const std::string& LLUriParser::port() const
{
- return mPort.c_str();
+ return mPort;
}
void LLUriParser::port(const std::string& s)
@@ -79,9 +90,9 @@ void LLUriParser::port(const std::string& s)
mPort = s;
}
-const char * LLUriParser::host() const
+const std::string& LLUriParser::host() const
{
- return mHost.c_str();
+ return mHost;
}
void LLUriParser::host(const std::string& s)
@@ -89,9 +100,9 @@ void LLUriParser::host(const std::string& s)
mHost = s;
}
-const char * LLUriParser::path() const
+const std::string& LLUriParser::path() const
{
- return mPath.c_str();
+ return mPath;
}
void LLUriParser::path(const std::string& s)
@@ -99,9 +110,9 @@ void LLUriParser::path(const std::string& s)
mPath = s;
}
-const char * LLUriParser::query() const
+const std::string& LLUriParser::query() const
{
- return mQuery.c_str();
+ return mQuery;
}
void LLUriParser::query(const std::string& s)
@@ -109,9 +120,9 @@ void LLUriParser::query(const std::string& s)
mQuery = s;
}
-const char * LLUriParser::fragment() const
+const std::string& LLUriParser::fragment() const
{
- return mFragment.c_str();
+ return mFragment;
}
void LLUriParser::fragment(const std::string& s)
@@ -119,19 +130,6 @@ void LLUriParser::fragment(const std::string& s)
mFragment = s;
}
-void LLUriParser::textRangeToString(UriTextRangeA& textRange, std::string& str)
-{
- if (textRange.first != NULL && textRange.afterLast != NULL && textRange.first < textRange.afterLast)
- {
- const ptrdiff_t len = textRange.afterLast - textRange.first;
- str.assign(textRange.first, static_cast(len));
- }
- else
- {
- str = LLStringUtil::null;
- }
-}
-
void LLUriParser::extractParts()
{
if (mTmpScheme || mNormalizedTmp)
@@ -140,96 +138,24 @@ void LLUriParser::extractParts()
}
else
{
- textRangeToString(mUri.scheme, mScheme);
+ mScheme = mUri.scheme();
}
- textRangeToString(mUri.hostText, mHost);
- textRangeToString(mUri.portText, mPort);
- textRangeToString(mUri.query, mQuery);
- textRangeToString(mUri.fragment, mFragment);
-
- UriPathSegmentA * pathHead = mUri.pathHead;
- while (pathHead)
- {
- std::string partOfPath;
- textRangeToString(pathHead->text, partOfPath);
-
- mPath += '/';
- mPath += partOfPath;
-
- pathHead = pathHead->next;
- }
+ mHost = mUri.host();
+ mPort = mUri.port();
+ mQuery = mUri.query();
+ mFragment = mUri.fragment();
+ mPath = mUri.path();
}
-#if LL_DARWIN
-typedef void(*sighandler_t)(int);
-jmp_buf return_to_normalize;
-static int sLastSignal = 0;
-void uri_signal_handler(int signal)
-{
- sLastSignal = signal;
- // Apparently signal handler throwing an exception doesn't work.
- // This is ugly and unsafe due to not unwinding content of uriparser library,
- // but unless we have a way to catch this as NSexception, jump appears to be the only option.
- longjmp(return_to_normalize, 1 /*setjmp will return this value*/);
-}
-#endif
-
-S32 LLUriParser::normalize()
+bool LLUriParser::normalize()
{
mNormalizedTmp = mTmpScheme;
- if (!mRes)
+ if (mRes)
{
-#if LL_DARWIN
- sighandler_t last_sigill_handler, last_sigbus_handler;
- last_sigill_handler = signal(SIGILL, &uri_signal_handler); // illegal instruction
- last_sigbus_handler = signal(SIGBUS, &uri_signal_handler);
-
- if (setjmp(return_to_normalize))
- {
- // Issue: external library crashed via signal
- // If you encountered this, please try to figure out what's wrong:
- // 1. Verify that library's input is 'sane'
- // 2. Check if we have an NSexception to work with (unlikely)
- // 3. See if passing same string causes exception to repeat
- //
- // Crash happens at uriNormalizeSyntaxExA
- // Warning!!! This does not properly unwind stack,
- // if this can be handled by NSexception, it needs to be remade
- llassert(0);
-
- LL_WARNS() << "Uriparser crashed with " << sLastSignal << " , while processing: " << mNormalizedUri << LL_ENDL;
- signal(SIGILL, last_sigill_handler);
- signal(SIGBUS, last_sigbus_handler);
- return 1;
- }
-#endif
-
- mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
-
-#if LL_DARWIN
- signal(SIGILL, last_sigill_handler);
- signal(SIGBUS, last_sigbus_handler);
-#endif
-
- if (!mRes)
- {
- S32 chars_required;
- mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
-
- if (!mRes)
- {
- chars_required++;
- std::vector label_buf(chars_required);
- mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
-
- if (!mRes)
- {
- mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
- mTmpScheme = false;
- }
- }
- }
+ mUri.normalize_scheme().normalize_authority();
+ mNormalizedUri = mUri.buffer().substr(mTmpScheme ? 7 : 0);
+ mTmpScheme = false;
}
if(mTmpScheme && mNormalizedUri.size() > 7)
@@ -302,7 +228,7 @@ bool LLUriParser::test() const
return uri == mNormalizedUri;
}
-const char * LLUriParser::normalizedUri() const
+const std::string& LLUriParser::normalizedUri() const
{
- return mNormalizedUri.c_str();
+ return mNormalizedUri;
}
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index 77eb4031d5..61d613f399 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -30,7 +30,7 @@
#define LL_LLURIPARSER_H
#include
-#include "uriparser/Uri.h"
+#include "boost/url.hpp"
class LL_COMMON_API LLUriParser
{
@@ -38,36 +38,35 @@ public:
LLUriParser(const std::string& u);
~LLUriParser();
- const char * scheme() const;
- void sheme (const std::string& s);
+ const std::string& scheme() const;
+ void scheme (const std::string& s);
- const char * port() const;
+ const std::string& port() const;
void port (const std::string& s);
- const char * host() const;
+ const std::string& host() const;
void host (const std::string& s);
- const char * path() const;
+ const std::string& path() const;
void path (const std::string& s);
- const char * query() const;
+ const std::string& query() const;
void query (const std::string& s);
- const char * fragment() const;
+ const std::string& fragment() const;
void fragment (const std::string& s);
- const char * normalizedUri() const;
+ const std::string& normalizedUri() const;
void extractParts();
void glue(std::string& uri) const;
void glueFirst(std::string& uri, bool use_scheme = true) const;
void glueSecond(std::string& uri) const;
bool test() const;
- S32 normalize();
+ bool normalize();
private:
- S32 parse();
- void textRangeToString(UriTextRangeA& textRange, std::string& str);
+ bool parse();
std::string mScheme;
std::string mHost;
std::string mPort;
@@ -76,9 +75,9 @@ private:
std::string mFragment;
std::string mNormalizedUri;
- UriUriA mUri;
+ boost::url mUri;
- S32 mRes;
+ bool mRes;
bool mTmpScheme;
bool mNormalizedTmp;
};
diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp
index a01d7fe415..d7b80e2545 100644
--- a/indra/llcommon/tests/lleventfilter_test.cpp
+++ b/indra/llcommon/tests/lleventfilter_test.cpp
@@ -81,13 +81,13 @@ class TestEventThrottle: public LLEventThrottleBase
public:
TestEventThrottle(F32 interval):
LLEventThrottleBase(interval),
- mAlarmRemaining(-1),
- mTimerRemaining(-1)
+ mAlarmRemaining(-1.f),
+ mTimerRemaining(-1.f)
{}
TestEventThrottle(LLEventPump& source, F32 interval):
LLEventThrottleBase(source, interval),
- mAlarmRemaining(-1),
- mTimerRemaining(-1)
+ mAlarmRemaining(-1.f),
+ mTimerRemaining(-1.f)
{}
/*----- implementation of LLEventThrottleBase timing functionality -----*/
@@ -100,12 +100,12 @@ public:
virtual bool alarmRunning() const /*override*/
{
// decrementing to exactly 0 should mean the alarm fires
- return mAlarmRemaining > 0;
+ return mAlarmRemaining > 0.f;
}
virtual void alarmCancel() /*override*/
{
- mAlarmRemaining = -1;
+ mAlarmRemaining = -1.f;
}
virtual void timerSet(F32 interval) /*override*/
@@ -116,7 +116,7 @@ public:
virtual F32 timerGetRemaining() const /*override*/
{
// LLTimer.getRemainingTimeF32() never returns negative; 0.0 means expired
- return (mTimerRemaining > 0.0)? mTimerRemaining : 0.0;
+ return (mTimerRemaining > 0.0f)? mTimerRemaining : 0.0f;
}
/*------------------- methods for manipulating time --------------------*/
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index fb2af1d2db..fae9f7023f 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -1809,7 +1809,7 @@ namespace tut
std::string q("\"");
std::string qPYTHON(q + PYTHON + q);
std::string qscript(q + scriptfile.getName() + q);
- int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(),
+ int rc = (int)_spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(),
std::forward(args)..., NULL);
if (rc == -1)
{
diff --git a/indra/llcommon/tests/lltrace_test.cpp b/indra/llcommon/tests/lltrace_test.cpp
index 8851f87b91..923a67ac8e 100644
--- a/indra/llcommon/tests/lltrace_test.cpp
+++ b/indra/llcommon/tests/lltrace_test.cpp
@@ -32,6 +32,10 @@
#include "lltracerecording.h"
#include "../test/lltut.h"
+#ifdef LL_WINDOWS
+#pragma warning(disable : 4244) // possible loss of data on conversions
+#endif
+
namespace LLUnits
{
// using powers of 2 to allow strict floating point equality
diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp
index 49f2d3085a..98a58eb47e 100644
--- a/indra/llcommon/tests/llunits_test.cpp
+++ b/indra/llcommon/tests/llunits_test.cpp
@@ -262,7 +262,7 @@ namespace tut
F32 float_val = quatloos_implicit;
ensure("implicit units convert implicitly to regular values", float_val == 16);
- S32 int_val = quatloos_implicit;
+ S32 int_val = (S32)quatloos_implicit;
ensure("implicit units convert implicitly to regular values", int_val == 16);
// conversion of implicits
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 5650c4c8ba..d388883575 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -155,10 +155,7 @@ if (DARWIN)
# for portability. This operation is Darwin-specific. We can count on the
# 'cp' command.
set(copy_dylibs
- libapr-1.0.dylib
- libaprutil-1.0.dylib
libnghttp2*.dylib
- liburiparser*.dylib
${EXPAT_COPY}
)
diff --git a/indra/llcorehttp/_httpinternal.h b/indra/llcorehttp/_httpinternal.h
index 768ef98330..2a191fa550 100644
--- a/indra/llcorehttp/_httpinternal.h
+++ b/indra/llcorehttp/_httpinternal.h
@@ -106,17 +106,17 @@ namespace LLCore
// Maxium number of policy classes that can be defined.
// *TODO: Currently limited to the default class + 1, extend.
// (TSN: should this be more dynamically sized. Is there a reason to hard limit the number of policies?)
-const int HTTP_POLICY_CLASS_LIMIT = 32;
+constexpr int HTTP_POLICY_CLASS_LIMIT = 32;
// Debug/informational tracing. Used both
// as a global option and in per-request traces.
-const int HTTP_TRACE_OFF = 0;
-const int HTTP_TRACE_LOW = 1;
-const int HTTP_TRACE_CURL_HEADERS = 2;
-const int HTTP_TRACE_CURL_BODIES = 3;
+constexpr int HTTP_TRACE_OFF = 0;
+constexpr int HTTP_TRACE_LOW = 1;
+constexpr int HTTP_TRACE_CURL_HEADERS = 2;
+constexpr int HTTP_TRACE_CURL_BODIES = 3;
-const int HTTP_TRACE_MIN = HTTP_TRACE_OFF;
-const int HTTP_TRACE_MAX = HTTP_TRACE_CURL_BODIES;
+constexpr int HTTP_TRACE_MIN = HTTP_TRACE_OFF;
+constexpr int HTTP_TRACE_MAX = HTTP_TRACE_CURL_BODIES;
// Request retry limits
//
@@ -127,41 +127,41 @@ const int HTTP_TRACE_MAX = HTTP_TRACE_CURL_BODIES;
// We want to span a few windows to allow transport to slow
// after onset of the throttles and then recover without a final
// failure. Other systems may need other constants.
-const int HTTP_RETRY_COUNT_DEFAULT = 5;
-const int HTTP_RETRY_COUNT_MIN = 0;
-const int HTTP_RETRY_COUNT_MAX = 100;
-const HttpTime HTTP_RETRY_BACKOFF_MIN_DEFAULT = 1E6L; // 1 sec
-const HttpTime HTTP_RETRY_BACKOFF_MAX_DEFAULT = 5E6L; // 5 sec
-const HttpTime HTTP_RETRY_BACKOFF_MAX = 20E6L; // 20 sec
+constexpr int HTTP_RETRY_COUNT_DEFAULT = 5;
+constexpr int HTTP_RETRY_COUNT_MIN = 0;
+constexpr int HTTP_RETRY_COUNT_MAX = 100;
+constexpr HttpTime HTTP_RETRY_BACKOFF_MIN_DEFAULT = 1000000UL; // 1 sec
+constexpr HttpTime HTTP_RETRY_BACKOFF_MAX_DEFAULT = 50000006UL; // 5 sec
+constexpr HttpTime HTTP_RETRY_BACKOFF_MAX = 20000000UL; // 20 sec
-const int HTTP_REDIRECTS_DEFAULT = 10;
+constexpr int HTTP_REDIRECTS_DEFAULT = 10;
// Timeout value used for both connect and protocol exchange.
// Retries and time-on-queue are not included and aren't
// accounted for.
-const long HTTP_REQUEST_TIMEOUT_DEFAULT = 30L;
-const long HTTP_REQUEST_XFER_TIMEOUT_DEFAULT = 0L;
-const long HTTP_REQUEST_TIMEOUT_MIN = 0L;
-const long HTTP_REQUEST_TIMEOUT_MAX = 3600L;
+constexpr long HTTP_REQUEST_TIMEOUT_DEFAULT = 30L;
+constexpr long HTTP_REQUEST_XFER_TIMEOUT_DEFAULT = 0L;
+constexpr long HTTP_REQUEST_TIMEOUT_MIN = 0L;
+constexpr long HTTP_REQUEST_TIMEOUT_MAX = 3600L;
// Limits on connection counts
-const int HTTP_CONNECTION_LIMIT_DEFAULT = 8;
-const int HTTP_CONNECTION_LIMIT_MIN = 1;
-const int HTTP_CONNECTION_LIMIT_MAX = 256;
+constexpr int HTTP_CONNECTION_LIMIT_DEFAULT = 8;
+constexpr int HTTP_CONNECTION_LIMIT_MIN = 1;
+constexpr int HTTP_CONNECTION_LIMIT_MAX = 256;
// Pipelining limits
-const long HTTP_PIPELINING_DEFAULT = 0L;
-const long HTTP_PIPELINING_MAX = 20L;
+constexpr long HTTP_PIPELINING_DEFAULT = 0L;
+constexpr long HTTP_PIPELINING_MAX = 20L;
// Miscellaneous defaults
-const bool HTTP_USE_RETRY_AFTER_DEFAULT = true;
-const long HTTP_THROTTLE_RATE_DEFAULT = 0L;
+constexpr bool HTTP_USE_RETRY_AFTER_DEFAULT = true;
+constexpr long HTTP_THROTTLE_RATE_DEFAULT = 0L;
// Tuning parameters
// Time worker thread sleeps after a pass through the
// request, ready and active queues.
-const int HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS = 2;
+constexpr int HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS = 2;
// Block allocation size (a tuning parameter) is found
// in bufferarray.h.
diff --git a/indra/llcorehttp/httpstats.h b/indra/llcorehttp/httpstats.h
index e1387d9df5..f12e59da0c 100644
--- a/indra/llcorehttp/httpstats.h
+++ b/indra/llcorehttp/httpstats.h
@@ -47,12 +47,12 @@ namespace LLCore
void recordDataDown(size_t bytes)
{
- mDataDown.push(bytes);
+ mDataDown.push((F32)bytes);
}
void recordDataUp(size_t bytes)
{
- mDataUp.push(bytes);
+ mDataUp.push((F32)bytes);
}
void recordHTTPRequest() { ++mRequests; }
diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp
index 506232ab2a..ecd197b2c1 100644
--- a/indra/llcrashlogger/llcrashlock.cpp
+++ b/indra/llcrashlogger/llcrashlock.cpp
@@ -45,11 +45,10 @@
bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
{
- std::wstring wpname;
- wpname = std::wstring(pname.begin(), pname.end());
+ std::wstring wpname = ll_convert_string_to_wide(pname);
HANDLE snapshot;
- PROCESSENTRY32 pe32;
+ PROCESSENTRY32 pe32{};
bool matched = false;
@@ -65,7 +64,7 @@ bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
{
do {
std::wstring wexecname = pe32.szExeFile;
- std::string execname = std::string(wexecname.begin(), wexecname.end());
+ std::string execname = ll_convert_wide_to_string(wexecname);
if (!wpname.compare(pe32.szExeFile))
{
if (pid == (U32)pe32.th32ProcessID)
diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp
index 8ee2c309a5..a18dc0a4f1 100644
--- a/indra/llfilesystem/lldir.cpp
+++ b/indra/llfilesystem/lldir.cpp
@@ -201,15 +201,15 @@ U32 LLDir::deleteDirAndContents(const std::string& dir_name)
boost::filesystem::path dir_path(dir_name);
#endif
- if (boost::filesystem::exists (dir_path))
+ if (boost::filesystem::exists(dir_path))
{
- if (!boost::filesystem::is_empty (dir_path))
+ if (!boost::filesystem::is_empty(dir_path))
{ // Directory has content
- num_deleted = boost::filesystem::remove_all (dir_path);
+ num_deleted = (U32)boost::filesystem::remove_all(dir_path);
}
else
{ // Directory is empty
- boost::filesystem::remove (dir_path);
+ boost::filesystem::remove(dir_path);
}
}
}
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index da2e960ed3..86b1e2ac81 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -325,8 +325,8 @@ const std::string LLDiskCache::getCacheInfo()
{
std::ostringstream cache_info;
- F32 max_in_mb = (F32)mMaxSizeBytes / (1024.0 * 1024.0);
- F32 percent_used = ((F32)dirFileSize(mCacheDir) / (F32)mMaxSizeBytes) * 100.0;
+ F32 max_in_mb = (F32)mMaxSizeBytes / (1024.0f * 1024.0f);
+ F32 percent_used = ((F32)dirFileSize(mCacheDir) / (F32)mMaxSizeBytes) * 100.0f;
cache_info << std::fixed;
cache_info << std::setprecision(1);
diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp
index 235aae0be3..7d2a6bd6f5 100644
--- a/indra/llfilesystem/llfilesystem.cpp
+++ b/indra/llfilesystem/llfilesystem.cpp
@@ -79,6 +79,7 @@ LLFileSystem::~LLFileSystem()
// static
bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type)
{
+ LL_PROFILE_ZONE_SCOPED;
std::string id_str;
file_id.toString(id_str);
const std::string extra_info = "";
@@ -147,7 +148,7 @@ S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType fi
if (file.is_open())
{
file.seekg(0, std::ios::end);
- file_size = file.tellg();
+ file_size = (S32)file.tellg();
}
return file_size;
@@ -175,7 +176,7 @@ bool LLFileSystem::read(U8* buffer, S32 bytes)
}
else
{
- mBytesRead = file.gcount();
+ mBytesRead = (S32)file.gcount();
}
file.close();
@@ -216,7 +217,7 @@ bool LLFileSystem::write(const U8* buffer, S32 bytes)
{
ofs.write((const char*)buffer, bytes);
- mPosition = ofs.tellp(); // Fix asset caching
+ mPosition = (S32)ofs.tellp(); // Fix asset caching
success = true;
}
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 42eecbb97c..8b966b8ea3 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -32,37 +32,37 @@
#include "llpointer.h"
#include "lltrace.h"
-const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
-const S32 MAX_IMAGE_MIP = 12; // 4096x4096
+constexpr S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
+constexpr S32 MAX_IMAGE_MIP = 12; // 4096x4096
// *TODO : Use MAX_IMAGE_MIP as max discard level and modify j2c management so that the number
// of levels is read from the header's file, not inferred from its size.
-const S32 MAX_DISCARD_LEVEL = 5;
+constexpr S32 MAX_DISCARD_LEVEL = 5;
// JPEG2000 size constraints
// Those are declared here as they are germane to other image constraints used in the viewer
// and declared right here. Some come from the JPEG2000 spec, some conventions specific to SL.
-const S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec
-const S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is)
-const S32 MAX_PRECINCT_SIZE = 4096; // No reason to be bigger than MAX_IMAGE_SIZE
-const S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
-const S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
-const S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
-const S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!!
-const S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
+constexpr S32 MAX_DECOMPOSITION_LEVELS = 32; // Number of decomposition levels cannot exceed 32 according to jpeg2000 spec
+constexpr S32 MIN_DECOMPOSITION_LEVELS = 5; // the SL viewer will *crash* trying to decode images with fewer than 5 decomposition levels (unless image is small that is)
+constexpr S32 MAX_PRECINCT_SIZE = 4096; // No reason to be bigger than MAX_IMAGE_SIZE
+constexpr S32 MIN_PRECINCT_SIZE = 4; // Can't be smaller than MIN_BLOCK_SIZE
+constexpr S32 MAX_BLOCK_SIZE = 64; // Max total block size is 4096, hence 64x64 when using square blocks
+constexpr S32 MIN_BLOCK_SIZE = 4; // Min block dim is 4 according to jpeg2000 spec
+constexpr S32 MIN_LAYER_SIZE = 2000; // Size of the first quality layer (after header). Must be > to FIRST_PACKET_SIZE!!
+constexpr S32 MAX_NB_LAYERS = 64; // Max number of layers we'll entertain in SL (practical limit)
-const S32 MIN_IMAGE_SIZE = (1< raw_image)
bool abs_value = (mFilterData[i][index++].asReal() > 0.0);
for (S32 k = 0; k < NUM_VALUES_IN_MAT3; k++)
for (S32 j = 0; j < NUM_VALUES_IN_MAT3; j++)
- kernel.mMatrix[k][j] = mFilterData[i][index++].asReal();
+ kernel.mMatrix[k][j] = (F32)mFilterData[i][index++].asReal();
convolve(kernel,normalize,abs_value);
}
else if (filter_name == "colortransform")
@@ -262,7 +262,7 @@ void LLImageFilter::executeFilter(LLPointer raw_image)
S32 index = 1;
for (S32 k = 0; k < NUM_VALUES_IN_MAT3; k++)
for (S32 j = 0; j < NUM_VALUES_IN_MAT3; j++)
- transform.mMatrix[k][j] = mFilterData[i][index++].asReal();
+ transform.mMatrix[k][j] = (F32)mFilterData[i][index++].asReal();
transform.transpose();
colorTransform(transform);
}
@@ -279,32 +279,32 @@ void LLImageFilter::executeFilter(LLPointer raw_image)
void LLImageFilter::blendStencil(F32 alpha, U8* pixel, U8 red, U8 green, U8 blue)
{
- F32 inv_alpha = 1.0 - alpha;
+ F32 inv_alpha = 1.0f - alpha;
switch (mStencilBlendMode)
{
case STENCIL_BLEND_MODE_BLEND:
// Classic blend of incoming color with the background image
- pixel[VRED] = inv_alpha * pixel[VRED] + alpha * red;
- pixel[VGREEN] = inv_alpha * pixel[VGREEN] + alpha * green;
- pixel[VBLUE] = inv_alpha * pixel[VBLUE] + alpha * blue;
+ pixel[VRED] = (U8)(inv_alpha * pixel[VRED] + alpha * red);
+ pixel[VGREEN] = (U8)(inv_alpha * pixel[VGREEN] + alpha * green);
+ pixel[VBLUE] = (U8)(inv_alpha * pixel[VBLUE] + alpha * blue);
break;
case STENCIL_BLEND_MODE_ADD:
// Add incoming color to the background image
- pixel[VRED] = llclampb(pixel[VRED] + alpha * red);
- pixel[VGREEN] = llclampb(pixel[VGREEN] + alpha * green);
- pixel[VBLUE] = llclampb(pixel[VBLUE] + alpha * blue);
+ pixel[VRED] = (U8)llclampb(pixel[VRED] + alpha * red);
+ pixel[VGREEN] = (U8)llclampb(pixel[VGREEN] + alpha * green);
+ pixel[VBLUE] = (U8)llclampb(pixel[VBLUE] + alpha * blue);
break;
case STENCIL_BLEND_MODE_ABACK:
// Add back background image to the incoming color
- pixel[VRED] = llclampb(inv_alpha * pixel[VRED] + red);
- pixel[VGREEN] = llclampb(inv_alpha * pixel[VGREEN] + green);
- pixel[VBLUE] = llclampb(inv_alpha * pixel[VBLUE] + blue);
+ pixel[VRED] = (U8)llclampb(inv_alpha * pixel[VRED] + red);
+ pixel[VGREEN] = (U8)llclampb(inv_alpha * pixel[VGREEN] + green);
+ pixel[VBLUE] = (U8)llclampb(inv_alpha * pixel[VBLUE] + blue);
break;
case STENCIL_BLEND_MODE_FADE:
// Fade incoming color to black
- pixel[VRED] = alpha * red;
- pixel[VGREEN] = alpha * green;
- pixel[VBLUE] = alpha * blue;
+ pixel[VRED] = (U8)(alpha * red);
+ pixel[VGREEN] = (U8)(alpha * green);
+ pixel[VBLUE] = (U8)(alpha * blue);
break;
}
}
@@ -348,7 +348,7 @@ void LLImageFilter::colorTransform(const LLMatrix3 &transform)
dst.clamp(0.0f,255.0f);
// Blend result
- blendStencil(getStencilAlpha(i,j), dst_data, dst.mV[VRED], dst.mV[VGREEN], dst.mV[VBLUE]);
+ blendStencil(getStencilAlpha(i,j), dst_data, (U8)dst.mV[VRED], (U8)dst.mV[VGREEN], (U8)dst.mV[VBLUE]);
dst_data += components;
}
}
@@ -463,7 +463,7 @@ void LLImageFilter::convolve(const LLMatrix3 &kernel, bool normalize, bool abs_v
dst.clamp(0.0f,255.0f);
// Blend result
- blendStencil(getStencilAlpha(i,j), dst_data, dst.mV[VRED], dst.mV[VGREEN], dst.mV[VBLUE]);
+ blendStencil(getStencilAlpha(i,j), dst_data, (U8)dst.mV[VRED], (U8)dst.mV[VGREEN], (U8)dst.mV[VBLUE]);
// Next pixel
dst_data += components;
@@ -499,7 +499,7 @@ void LLImageFilter::filterScreen(EScreenMode mode, const F32 wave_length, const
S32 width = mImage->getWidth();
S32 height = mImage->getHeight();
- F32 wave_length_pixels = wave_length * (F32)(height) / 2.0;
+ F32 wave_length_pixels = wave_length * (F32)(height) / 2.0f;
F32 sin = sinf(angle*DEG_TO_RAD);
F32 cos = cosf(angle*DEG_TO_RAD);
@@ -507,7 +507,7 @@ void LLImageFilter::filterScreen(EScreenMode mode, const F32 wave_length, const
U8 gamma[256];
for (S32 i = 0; i < 256; i++)
{
- F32 gamma_i = llclampf((float)(powf((float)(i)/255.0,1.0/4.0)));
+ F32 gamma_i = llclampf((float)(powf((float)(i)/255.0f,1.0f/4.0f)));
gamma[i] = (U8)(255.0 * gamma_i);
}
@@ -525,11 +525,11 @@ void LLImageFilter::filterScreen(EScreenMode mode, const F32 wave_length, const
case SCREEN_MODE_2DSINE:
di = cos*i + sin*j;
dj = -sin*i + cos*j;
- value = (sinf(2*F_PI*di/wave_length_pixels)*sinf(2*F_PI*dj/wave_length_pixels)+1.0)*255.0/2.0;
+ value = (sinf(2*F_PI*di/wave_length_pixels)*sinf(2*F_PI*dj/wave_length_pixels)+1.0f)*255.0f/2.0f;
break;
case SCREEN_MODE_LINE:
dj = sin*i - cos*j;
- value = (sinf(2*F_PI*dj/wave_length_pixels)+1.0)*255.0/2.0;
+ value = (sinf(2*F_PI*dj/wave_length_pixels)+1.0f)*255.0f/2.0f;
break;
}
U8 dst_value = (dst_data[VRED] >= (U8)(value) ? gamma[dst_data[VRED] - (U8)(value)] : 0);
@@ -556,16 +556,16 @@ void LLImageFilter::setStencil(EStencilShape shape, EStencilBlendMode mode, F32
mStencilCenterX = (S32)(mImage->getWidth() + params[0] * (F32)(mImage->getHeight()))/2;
mStencilCenterY = (S32)(mImage->getHeight() + params[1] * (F32)(mImage->getHeight()))/2;
mStencilWidth = (S32)(params[2] * (F32)(mImage->getHeight()))/2;
- mStencilGamma = (params[3] <= 0.0 ? 1.0 : params[3]);
+ mStencilGamma = (params[3] <= 0.0f ? 1.0f : params[3]);
- mStencilWavelength = (params[0] <= 0.0 ? 10.0 : params[0] * (F32)(mImage->getHeight()) / 2.0);
+ mStencilWavelength = (params[0] <= 0.0f ? 10.0f : params[0] * (F32)(mImage->getHeight()) / 2.0f);
mStencilSine = sinf(params[1]*DEG_TO_RAD);
mStencilCosine = cosf(params[1]*DEG_TO_RAD);
- mStencilStartX = ((F32)(mImage->getWidth()) + params[0] * (F32)(mImage->getHeight()))/2.0;
- mStencilStartY = ((F32)(mImage->getHeight()) + params[1] * (F32)(mImage->getHeight()))/2.0;
- F32 end_x = ((F32)(mImage->getWidth()) + params[2] * (F32)(mImage->getHeight()))/2.0;
- F32 end_y = ((F32)(mImage->getHeight()) + params[3] * (F32)(mImage->getHeight()))/2.0;
+ mStencilStartX = ((F32)(mImage->getWidth()) + params[0] * (F32)(mImage->getHeight()))/2.0f;
+ mStencilStartY = ((F32)(mImage->getHeight()) + params[1] * (F32)(mImage->getHeight()))/2.0f;
+ F32 end_x = ((F32)(mImage->getWidth()) + params[2] * (F32)(mImage->getHeight()))/2.0f;
+ F32 end_y = ((F32)(mImage->getHeight()) + params[3] * (F32)(mImage->getHeight()))/2.0f;
mStencilGradX = end_x - mStencilStartX;
mStencilGradY = end_y - mStencilStartY;
mStencilGradN = mStencilGradX*mStencilGradX + mStencilGradY*mStencilGradY;
@@ -578,14 +578,14 @@ F32 LLImageFilter::getStencilAlpha(S32 i, S32 j)
{
// alpha is a modified gaussian value, with a center and fading in a circular pattern toward the edges
// The gamma parameter controls the intensity of the drop down from alpha 1.0 (center) to 0.0
- F32 d_center_square = (i - mStencilCenterX)*(i - mStencilCenterX) + (j - mStencilCenterY)*(j - mStencilCenterY);
+ F32 d_center_square = (F32)((i - mStencilCenterX)*(i - mStencilCenterX) + (j - mStencilCenterY)*(j - mStencilCenterY));
alpha = powf(F_E, -(powf((d_center_square/(mStencilWidth*mStencilWidth)),mStencilGamma)/2.0f));
}
else if (mStencilShape == STENCIL_SHAPE_SCAN_LINES)
{
// alpha varies according to a squared sine function.
F32 d = mStencilSine*i - mStencilCosine*j;
- alpha = (sinf(2*F_PI*d/mStencilWavelength) > 0.0 ? 1.0 : 0.0);
+ alpha = (sinf(2*F_PI*d/mStencilWavelength) > 0.0f ? 1.0f : 0.0f);
}
else if (mStencilShape == STENCIL_SHAPE_GRADIENT)
{
@@ -756,11 +756,11 @@ void LLImageFilter::filterGamma(F32 gamma, const LLColor3& alpha)
for (S32 i = 0; i < 256; i++)
{
- F32 gamma_i = llclampf((float)(powf((float)(i)/255.0,1.0/gamma)));
+ F32 gamma_i = llclampf((float)(powf((float)(i)/255.0f,1.0f/gamma)));
// Blend in with alpha values
- gamma_red_lut[i] = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * 255.0 * gamma_i);
- gamma_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * 255.0 * gamma_i);
- gamma_blue_lut[i] = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * 255.0 * gamma_i);
+ gamma_red_lut[i] = (U8)((1.0f - alpha.mV[0]) * (float)(i) + alpha.mV[0] * 255.0f * gamma_i);
+ gamma_green_lut[i] = (U8)((1.0f - alpha.mV[1]) * (float)(i) + alpha.mV[1] * 255.0f * gamma_i);
+ gamma_blue_lut[i] = (U8)((1.0f - alpha.mV[2]) * (float)(i) + alpha.mV[2] * 255.0f * gamma_i);
}
colorCorrect(gamma_red_lut,gamma_green_lut,gamma_blue_lut);
@@ -808,23 +808,23 @@ void LLImageFilter::filterLinearize(F32 tail, const LLColor3& alpha)
{
U8 value_i = (i < min_v ? 0 : 255);
// Blend in with alpha values
- linear_red_lut[i] = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
- linear_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
- linear_blue_lut[i] = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
+ linear_red_lut[i] = (U8)((1.0f - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
+ linear_green_lut[i] = (U8)((1.0f - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
+ linear_blue_lut[i] = (U8)((1.0f - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
}
}
else
{
// Linearize between min and max
- F32 slope = 255.0 / (F32)(max_v - min_v);
+ F32 slope = 255.0f / (F32)(max_v - min_v);
F32 translate = -min_v * slope;
for (S32 i = 0; i < 256; i++)
{
U8 value_i = (U8)(llclampb((S32)(slope*i + translate)));
// Blend in with alpha values
- linear_red_lut[i] = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
- linear_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
- linear_blue_lut[i] = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
+ linear_red_lut[i] = (U8)((1.0f - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
+ linear_green_lut[i] = (U8)((1.0f - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
+ linear_blue_lut[i] = (U8)((1.0f - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
}
}
@@ -863,9 +863,9 @@ void LLImageFilter::filterEqualize(S32 nb_classes, const LLColor3& alpha)
for (S32 i = 0; i < 256; i++)
{
// Blend in current_value with alpha values
- equalize_red_lut[i] = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * current_value);
- equalize_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * current_value);
- equalize_blue_lut[i] = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * current_value);
+ equalize_red_lut[i] = (U8)((1.0f - alpha.mV[0]) * (float)(i) + alpha.mV[0] * current_value);
+ equalize_green_lut[i] = (U8)((1.0f - alpha.mV[1]) * (float)(i) + alpha.mV[1] * current_value);
+ equalize_blue_lut[i] = (U8)((1.0f - alpha.mV[2]) * (float)(i) + alpha.mV[2] * current_value);
if (cumulated_histo[i] >= current_count)
{
current_count += delta_count;
@@ -884,15 +884,15 @@ void LLImageFilter::filterColorize(const LLColor3& color, const LLColor3& alpha)
U8 green_lut[256];
U8 blue_lut[256];
- F32 red_composite = 255.0 * alpha.mV[0] * color.mV[0];
- F32 green_composite = 255.0 * alpha.mV[1] * color.mV[1];
- F32 blue_composite = 255.0 * alpha.mV[2] * color.mV[2];
+ F32 red_composite = 255.0f * alpha.mV[0] * color.mV[0];
+ F32 green_composite = 255.0f * alpha.mV[1] * color.mV[1];
+ F32 blue_composite = 255.0f * alpha.mV[2] * color.mV[2];
for (S32 i = 0; i < 256; i++)
{
- red_lut[i] = (U8)(llclampb((S32)((1.0 - alpha.mV[0]) * (F32)(i) + red_composite)));
- green_lut[i] = (U8)(llclampb((S32)((1.0 - alpha.mV[1]) * (F32)(i) + green_composite)));
- blue_lut[i] = (U8)(llclampb((S32)((1.0 - alpha.mV[2]) * (F32)(i) + blue_composite)));
+ red_lut[i] = (U8)(llclampb((S32)((1.0f - alpha.mV[0]) * (F32)(i) + red_composite)));
+ green_lut[i] = (U8)(llclampb((S32)((1.0f - alpha.mV[1]) * (F32)(i) + green_composite)));
+ blue_lut[i] = (U8)(llclampb((S32)((1.0f - alpha.mV[2]) * (F32)(i) + blue_composite)));
}
colorCorrect(red_lut,green_lut,blue_lut);
@@ -904,15 +904,15 @@ void LLImageFilter::filterContrast(F32 slope, const LLColor3& alpha)
U8 contrast_green_lut[256];
U8 contrast_blue_lut[256];
- F32 translate = 128.0 * (1.0 - slope);
+ F32 translate = 128.0f * (1.0f - slope);
for (S32 i = 0; i < 256; i++)
{
U8 value_i = (U8)(llclampb((S32)(slope*i + translate)));
// Blend in with alpha values
- contrast_red_lut[i] = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
- contrast_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
- contrast_blue_lut[i] = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
+ contrast_red_lut[i] = (U8)((1.0f - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
+ contrast_green_lut[i] = (U8)((1.0f - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
+ contrast_blue_lut[i] = (U8)((1.0f - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
}
colorCorrect(contrast_red_lut,contrast_green_lut,contrast_blue_lut);
@@ -924,15 +924,15 @@ void LLImageFilter::filterBrightness(F32 add, const LLColor3& alpha)
U8 brightness_green_lut[256];
U8 brightness_blue_lut[256];
- S32 add_value = (S32)(add * 255.0);
+ S32 add_value = (S32)(add * 255.0f);
for (S32 i = 0; i < 256; i++)
{
U8 value_i = (U8)(llclampb(i + add_value));
// Blend in with alpha values
- brightness_red_lut[i] = (U8)((1.0 - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
- brightness_green_lut[i] = (U8)((1.0 - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
- brightness_blue_lut[i] = (U8)((1.0 - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
+ brightness_red_lut[i] = (U8)((1.0f - alpha.mV[0]) * (float)(i) + alpha.mV[0] * value_i);
+ brightness_green_lut[i] = (U8)((1.0f - alpha.mV[1]) * (float)(i) + alpha.mV[1] * value_i);
+ brightness_blue_lut[i] = (U8)((1.0f - alpha.mV[2]) * (float)(i) + alpha.mV[2] * value_i);
}
colorCorrect(brightness_red_lut,brightness_green_lut,brightness_blue_lut);
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 0058b91b0f..42f3e92257 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -275,30 +275,24 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r
// For details about the equation used here, see https://wiki.lindenlab.com/wiki/THX1138_KDU_Improvements#Byte_Range_Study
// Estimate the number of layers. This is consistent with what's done for j2c encoding in LLImageJ2CKDU::encodeImpl().
+ constexpr S32 precision = 8; // assumed bitrate per component channel, might change in future for HDR support
+ constexpr S32 max_components = 4; // assumed the file has four components; three color and alpha
S32 nb_layers = 1;
- S32 surface = w*h;
+ const S32 surface = w*h;
S32 s = 64*64;
+ S32 totalbytes = (S32)(s * max_components * precision * rate); // first level computed before loop
while (surface > s)
{
+ if (nb_layers <= (5 - discard_level))
+ totalbytes += (S32)(s * max_components * precision * rate);
nb_layers++;
s *= 4;
}
- F32 layer_factor = 3.0f * (7 - llclamp(nb_layers,1,6));
- // Compute w/pow(2,discard_level) and h/pow(2,discard_level)
- w >>= discard_level;
- h >>= discard_level;
- w = llmax(w, 1);
- h = llmax(h, 1);
+ totalbytes /= 8; // to bytes
+ totalbytes += calcHeaderSizeJ2C(); // header
- // Temporary: compute both new and old range and pick one according to the settings TextureNewByteRange
- // *TODO: Take the old code out once we have enough tests done
- S32 bytes;
- S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor);
- S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
- bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
- bytes = llmax(bytes, calcHeaderSizeJ2C());
- return bytes;
+ return totalbytes;
}
S32 LLImageJ2C::calcHeaderSize()
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 9a4e382183..f4bcb97a5d 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -431,23 +431,20 @@ public:
opj_set_default_encoder_parameters(¶meters);
parameters.cod_format = OPJ_CODEC_J2K;
parameters.cp_disto_alloc = 1;
- parameters.max_cs_size = (1 << 15);
if (reversible)
{
+ parameters.max_cs_size = 0; // do not limit size for reversible compression
+ parameters.irreversible = 0; // should be the default, but, just in case
parameters.tcp_numlayers = 1;
- parameters.tcp_rates[0] = 1.0f;
+ /* documentation seems to be wrong, should be 0.0f for lossless, not 1.0f
+ see https://github.com/uclouvain/openjpeg/blob/39e8c50a2f9bdcf36810ee3d41bcbf1cc78968ae/src/lib/openjp2/j2k.c#L7755
+ */
+ parameters.tcp_rates[0] = 0.0f;
}
else
{
- parameters.tcp_numlayers = 5;
- parameters.tcp_rates[0] = 1920.0f;
- parameters.tcp_rates[1] = 960.0f;
- parameters.tcp_rates[2] = 480.0f;
- parameters.tcp_rates[3] = 120.0f;
- parameters.tcp_rates[4] = 30.0f;
parameters.irreversible = 1;
- parameters.tcp_mct = 1;
}
if (comment_text)
@@ -501,6 +498,50 @@ public:
parameters.prog_order = OPJ_RLCP;
parameters.cp_disto_alloc = 1;
+ // if not lossless compression, computes tcp_numlayers and max_cs_size depending on the image dimensions
+ if( parameters.irreversible ) {
+
+ // computes a number of layers
+ U32 surface = rawImageIn.getWidth() * rawImageIn.getHeight();
+ U32 nb_layers = 1;
+ U32 s = 64*64;
+ while (surface > s)
+ {
+ nb_layers++;
+ s *= 4;
+ }
+ nb_layers = llclamp(nb_layers, 1, 6);
+
+ parameters.tcp_numlayers = nb_layers;
+ parameters.tcp_rates[nb_layers - 1] = (U32)(1.f / DEFAULT_COMPRESSION_RATE); // 1:8 by default
+
+ // for each subsequent layer, computes its rate and adds surface * numcomps * 1/rate to the max_cs_size
+ U32 max_cs_size = (U32)(surface * image->numcomps * DEFAULT_COMPRESSION_RATE);
+ U32 multiplier;
+ for (int i = nb_layers - 2; i >= 0; i--)
+ {
+ if( i == nb_layers - 2 )
+ {
+ multiplier = 15;
+ }
+ else if( i == nb_layers - 3 )
+ {
+ multiplier = 4;
+ }
+ else
+ {
+ multiplier = 2;
+ }
+ parameters.tcp_rates[i] = parameters.tcp_rates[i + 1] * multiplier;
+ max_cs_size += (U32)(surface * image->numcomps * (1 / parameters.tcp_rates[i]));
+ }
+
+ //ensure that we have at least a minimal size
+ max_cs_size = llmax(max_cs_size, (U32)FIRST_PACKET_SIZE);
+
+ parameters.max_cs_size = max_cs_size;
+ }
+
if (!opj_setup_encoder(encoder, ¶meters, image))
{
return false;
@@ -557,7 +598,7 @@ public:
{
// "append" (set) the data we "streamed" (memcopied) for writing to the formatted image
// with side-effect of setting the actually encoded size to same
- compressedImageOut.allocateData(offset);
+ compressedImageOut.allocateData((S32)offset);
memcpy(compressedImageOut.getData(), buffer, offset);
compressedImageOut.updateData(); // update width, height etc from header
}
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index ef6ddb3cab..71dc8cff34 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -1268,7 +1268,7 @@ void LLParcel::setExperienceKeyType( const LLUUID& experience_key, U32 type )
U32 LLParcel::countExperienceKeyType( U32 type )
{
- return std::count_if(
+ return (U32)std::count_if(
boost::begin(mExperienceKeys | boost::adaptors::map_values),
boost::end(mExperienceKeys | boost::adaptors::map_values),
[type](U32 key){ return (key == type); });
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index c1893eff41..7b55fbc9e8 100644
--- a/indra/llinventory/llsettingsbase.cpp
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -278,11 +278,11 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD
{
case LLSD::TypeInteger:
// lerp between the two values rounding the result to the nearest integer.
- new_value = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
+ new_value = LLSD::Integer(llroundf(lerp((F32)value.asReal(), (F32)other_value.asReal(), (F32)mix)));
break;
case LLSD::TypeReal:
// lerp between the two values.
- new_value = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
+ new_value = LLSD::Real(lerp((F32)value.asReal(), (F32)other_value.asReal(), (F32)mix));
break;
case LLSD::TypeMap:
// deep copy.
@@ -297,7 +297,7 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD
{
LLQuaternion a(value);
LLQuaternion b(other_value);
- LLQuaternion q = slerp(mix, a, b);
+ LLQuaternion q = slerp((F32)mix, a, b);
new_array = q.getValue();
}
else
@@ -308,7 +308,7 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD
for (size_t i = 0; i < len; ++i)
{
- new_array[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
+ new_array[i] = lerp((F32)value[i].asReal(), (F32)other_value[i].asReal(), (F32)mix);
}
}
@@ -693,7 +693,7 @@ void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)
F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_in)
{
- LLSettingsBase::TrackPosition blendf = blendf_in;
+ LLSettingsBase::TrackPosition blendf = (F32)blendf_in;
llassert(!isnan(blendf));
if (blendf >= 1.0)
{
@@ -744,7 +744,7 @@ bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& t
return false;
}
- LLSettingsBase::BlendFactor blendf = calculateBlend(mTimeSpent, mBlendSpan);
+ LLSettingsBase::BlendFactor blendf = calculateBlend((F32)mTimeSpent.value(), mBlendSpan);
if (fabs(mLastBlendF - blendf) < mBlendFMinDelta)
{
diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h
index a5499c4eb6..9d8d746b7e 100644
--- a/indra/llinventory/llsettingsbase.h
+++ b/indra/llinventory/llsettingsbase.h
@@ -475,7 +475,7 @@ public:
LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t &target,
const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::Seconds& blend_span) :
LLSettingsBlender(target, initsetting, endsetting),
- mBlendSpan(blend_span),
+ mBlendSpan((F32)blend_span.value()),
mLastUpdate(0.0f),
mTimeSpent(0.0f),
mBlendFMinDelta(MIN_BLEND_DELTA),
diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp
index 99f917d94b..1e7de94414 100644
--- a/indra/llinventory/llsettingsdaycycle.cpp
+++ b/indra/llinventory/llsettingsdaycycle.cpp
@@ -499,7 +499,7 @@ namespace
continue;
}
- LLSettingsBase::TrackPosition frame = elem[LLSettingsDay::SETTING_KEYKFRAME].asReal();
+ LLSettingsBase::TrackPosition frame = (F32)elem[LLSettingsDay::SETTING_KEYKFRAME].asReal();
if ((frame < 0.0) || (frame > 1.0))
{
frame = llclamp(frame, 0.0f, 1.0f);
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index e14b2f25ed..cbec2f4906 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -480,19 +480,19 @@ void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
// If there is no cloud texture in destination, reduce coverage to imitate disappearance
// See LLDrawPoolWLSky::renderSkyClouds... we don't blend present texture with null
// Note: Probably can be done by shader
- cloud_shadow = lerp(mSettings[SETTING_CLOUD_SHADOW].asReal(), (F64)0.f, blendf);
+ cloud_shadow = lerp((F32)mSettings[SETTING_CLOUD_SHADOW].asReal(), 0.f, (F32)blendf);
cloud_noise_id_next = cloud_noise_id;
}
else if (cloud_noise_id.isNull() && !cloud_noise_id_next.isNull())
{
// Source has no cloud texture, reduce initial coverage to imitate appearance
// use same texture as destination
- cloud_shadow = lerp((F64)0.f, other->mSettings[SETTING_CLOUD_SHADOW].asReal(), blendf);
+ cloud_shadow = lerp(0.f, (F32)other->mSettings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf);
setCloudNoiseTextureId(cloud_noise_id_next);
}
else
{
- cloud_shadow = lerp(mSettings[SETTING_CLOUD_SHADOW].asReal(), other->mSettings[SETTING_CLOUD_SHADOW].asReal(), blendf);
+ cloud_shadow = lerp((F32)mSettings[SETTING_CLOUD_SHADOW].asReal(), (F32)other->mSettings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf);
}
LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf);
@@ -923,8 +923,8 @@ LLSD LLSettingsSky::translateLegacySettings(const LLSD& legacy)
if (legacy.has(SETTING_LEGACY_EAST_ANGLE) && legacy.has(SETTING_LEGACY_SUN_ANGLE))
{
// get counter-clockwise radian angle from clockwise legacy WL east angle...
- F32 azimuth = -legacy[SETTING_LEGACY_EAST_ANGLE].asReal();
- F32 altitude = legacy[SETTING_LEGACY_SUN_ANGLE].asReal();
+ F32 azimuth = -(F32)legacy[SETTING_LEGACY_EAST_ANGLE].asReal();
+ F32 altitude = (F32)legacy[SETTING_LEGACY_SUN_ANGLE].asReal();
LLQuaternion sunquat = convert_azimuth_and_altitude_to_quat(azimuth, altitude);
// original WL moon dir was diametrically opposed to the sun dir
@@ -958,7 +958,7 @@ void LLSettingsSky::updateSettings()
F32 LLSettingsSky::getSunMoonGlowFactor() const
{
return getIsSunUp() ? 1.0f :
- getIsMoonUp() ? getMoonBrightness() * 0.25 : 0.0f;
+ getIsMoonUp() ? getMoonBrightness() * 0.25f : 0.0f;
}
bool LLSettingsSky::getIsSunUp() const
@@ -1043,11 +1043,11 @@ F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) const
LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT;
if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key))
{
- return mSettings[SETTING_LEGACY_HAZE][key].asReal();
+ return (F32)mSettings[SETTING_LEGACY_HAZE][key].asReal();
}
if (mSettings.has(key))
{
- return mSettings[key].asReal();
+ return (F32)mSettings[key].asReal();
}
return default_value;
}
@@ -1307,7 +1307,7 @@ void LLSettingsSky::clampColor(LLColor3& color, F32 gamma, F32 scale) const
color *= scale/max_color;
}
LLColor3 linear(color);
- linear *= 1.0 / scale;
+ linear *= 1.0f / scale;
linear = smear(1.0f) - linear;
linear = componentPow(linear, gamma);
linear *= scale;
@@ -1353,7 +1353,7 @@ void LLSettingsSky::calculateLightSettings() const
F32 haze_horizon = getHazeHorizon();
- sunlight *= 1.0 - cloud_shadow;
+ sunlight *= 1.0f - cloud_shadow;
sunlight += tmpAmbient;
mHazeColor = getBlueHorizon() * getBlueDensity() * sunlight;
@@ -1415,22 +1415,22 @@ LLUUID LLSettingsSky::GetDefaultHaloTextureId()
F32 LLSettingsSky::getPlanetRadius() const
{
- return mSettings[SETTING_PLANET_RADIUS].asReal();
+ return (F32)mSettings[SETTING_PLANET_RADIUS].asReal();
}
F32 LLSettingsSky::getSkyMoistureLevel() const
{
- return mSettings[SETTING_SKY_MOISTURE_LEVEL].asReal();
+ return (F32)mSettings[SETTING_SKY_MOISTURE_LEVEL].asReal();
}
F32 LLSettingsSky::getSkyDropletRadius() const
{
- return mSettings[SETTING_SKY_DROPLET_RADIUS].asReal();
+ return (F32)mSettings[SETTING_SKY_DROPLET_RADIUS].asReal();
}
F32 LLSettingsSky::getSkyIceLevel() const
{
- return mSettings[SETTING_SKY_ICE_LEVEL].asReal();
+ return (F32)mSettings[SETTING_SKY_ICE_LEVEL].asReal();
}
F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const
@@ -1440,27 +1440,27 @@ F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const
return sAutoAdjustProbeAmbiance;
}
- return mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal();
+ return (F32)mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal();
}
F32 LLSettingsSky::getSkyBottomRadius() const
{
- return mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
+ return (F32)mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal();
}
F32 LLSettingsSky::getSkyTopRadius() const
{
- return mSettings[SETTING_SKY_TOP_RADIUS].asReal();
+ return (F32)mSettings[SETTING_SKY_TOP_RADIUS].asReal();
}
F32 LLSettingsSky::getSunArcRadians() const
{
- return mSettings[SETTING_SUN_ARC_RADIANS].asReal();
+ return (F32)mSettings[SETTING_SUN_ARC_RADIANS].asReal();
}
F32 LLSettingsSky::getMieAnisotropy() const
{
- return getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR].asReal();
+ return (F32)getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR].asReal();
}
LLSD LLSettingsSky::getRayleighConfig() const
@@ -1569,7 +1569,7 @@ void LLSettingsSky::setCloudPosDensity2(const LLColor3 &val)
F32 LLSettingsSky::getCloudScale() const
{
- return mSettings[SETTING_CLOUD_SCALE].asReal();
+ return (F32)mSettings[SETTING_CLOUD_SCALE].asReal();
}
void LLSettingsSky::setCloudScale(F32 val)
@@ -1601,7 +1601,7 @@ void LLSettingsSky::setCloudScrollRateY(F32 val)
F32 LLSettingsSky::getCloudShadow() const
{
- return mSettings[SETTING_CLOUD_SHADOW].asReal();
+ return (F32)mSettings[SETTING_CLOUD_SHADOW].asReal();
}
void LLSettingsSky::setCloudShadow(F32 val)
@@ -1611,7 +1611,7 @@ void LLSettingsSky::setCloudShadow(F32 val)
F32 LLSettingsSky::getCloudVariance() const
{
- return mSettings[SETTING_CLOUD_VARIANCE].asReal();
+ return (F32)mSettings[SETTING_CLOUD_VARIANCE].asReal();
}
void LLSettingsSky::setCloudVariance(F32 val)
@@ -1621,7 +1621,7 @@ void LLSettingsSky::setCloudVariance(F32 val)
F32 LLSettingsSky::getDomeOffset() const
{
- //return mSettings[SETTING_DOME_OFFSET].asReal();
+ //return (F32)mSettings[SETTING_DOME_OFFSET].asReal();
return DOME_OFFSET;
}
@@ -1633,7 +1633,7 @@ F32 LLSettingsSky::getDomeRadius() const
F32 LLSettingsSky::getGamma() const
{
- return mSettings[SETTING_GAMMA].asReal();
+ return (F32)mSettings[SETTING_GAMMA].asReal();
}
void LLSettingsSky::setGamma(F32 val)
@@ -1654,7 +1654,7 @@ void LLSettingsSky::setGlow(const LLColor3 &val)
F32 LLSettingsSky::getMaxY() const
{
- return mSettings[SETTING_MAX_Y].asReal();
+ return (F32)mSettings[SETTING_MAX_Y].asReal();
}
void LLSettingsSky::setMaxY(F32 val)
@@ -1674,7 +1674,7 @@ void LLSettingsSky::setMoonRotation(const LLQuaternion &val)
F32 LLSettingsSky::getMoonScale() const
{
- return mSettings[SETTING_MOON_SCALE].asReal();
+ return (F32)mSettings[SETTING_MOON_SCALE].asReal();
}
void LLSettingsSky::setMoonScale(F32 val)
@@ -1692,9 +1692,9 @@ void LLSettingsSky::setMoonTextureId(LLUUID id)
setValue(SETTING_MOON_TEXTUREID, id);
}
-F32 LLSettingsSky::getMoonBrightness() const
+F32 LLSettingsSky::getMoonBrightness() const
{
- return mSettings[SETTING_MOON_BRIGHTNESS].asReal();
+ return (F32)mSettings[SETTING_MOON_BRIGHTNESS].asReal();
}
void LLSettingsSky::setMoonBrightness(F32 brightness_factor)
@@ -1704,7 +1704,7 @@ void LLSettingsSky::setMoonBrightness(F32 brightness_factor)
F32 LLSettingsSky::getStarBrightness() const
{
- return mSettings[SETTING_STAR_BRIGHTNESS].asReal();
+ return (F32)mSettings[SETTING_STAR_BRIGHTNESS].asReal();
}
void LLSettingsSky::setStarBrightness(F32 val)
@@ -1749,7 +1749,7 @@ void LLSettingsSky::setSunRotation(const LLQuaternion &val)
F32 LLSettingsSky::getSunScale() const
{
- return mSettings[SETTING_SUN_SCALE].asReal();
+ return (F32)mSettings[SETTING_SUN_SCALE].asReal();
}
void LLSettingsSky::setSunScale(F32 val)
diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h
index 0b29d8ca19..9e7ff61272 100644
--- a/indra/llinventory/llsettingswater.h
+++ b/indra/llinventory/llsettingswater.h
@@ -72,7 +72,7 @@ public:
//---------------------------------------------------------------------
F32 getBlurMultiplier() const
{
- return mSettings[SETTING_BLUR_MULTIPLIER].asReal();
+ return (F32)mSettings[SETTING_BLUR_MULTIPLIER].asReal();
}
void setBlurMultiplier(F32 val)
@@ -92,7 +92,7 @@ public:
F32 getWaterFogDensity() const
{
- return mSettings[SETTING_FOG_DENSITY].asReal();
+ return (F32)mSettings[SETTING_FOG_DENSITY].asReal();
}
F32 getModifiedWaterFogDensity(bool underwater) const;
@@ -104,7 +104,7 @@ public:
F32 getFogMod() const
{
- return mSettings[SETTING_FOG_MOD].asReal();
+ return (F32)mSettings[SETTING_FOG_MOD].asReal();
}
void setFogMod(F32 val)
@@ -114,7 +114,7 @@ public:
F32 getFresnelOffset() const
{
- return mSettings[SETTING_FRESNEL_OFFSET].asReal();
+ return (F32)mSettings[SETTING_FRESNEL_OFFSET].asReal();
}
void setFresnelOffset(F32 val)
@@ -124,7 +124,7 @@ public:
F32 getFresnelScale() const
{
- return mSettings[SETTING_FRESNEL_SCALE].asReal();
+ return (F32)mSettings[SETTING_FRESNEL_SCALE].asReal();
}
void setFresnelScale(F32 val)
@@ -164,7 +164,7 @@ public:
F32 getScaleAbove() const
{
- return mSettings[SETTING_SCALE_ABOVE].asReal();
+ return (F32)mSettings[SETTING_SCALE_ABOVE].asReal();
}
void setScaleAbove(F32 val)
@@ -174,7 +174,7 @@ public:
F32 getScaleBelow() const
{
- return mSettings[SETTING_SCALE_BELOW].asReal();
+ return (F32)mSettings[SETTING_SCALE_BELOW].asReal();
}
void setScaleBelow(F32 val)
diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp
index bcf6131bd8..9779cb8fbc 100644
--- a/indra/llinventory/tests/inventorymisc_test.cpp
+++ b/indra/llinventory/tests/inventorymisc_test.cpp
@@ -61,7 +61,7 @@ LLPointer create_random_inventory_item()
S32 price = rand();
LLSaleInfo sale_info(LLSaleInfo::FS_COPY, price);
U32 flags = rand();
- S32 creation = time(NULL);
+ S32 creation = (S32)time(NULL);
LLPointer item = new LLInventoryItem(
item_id,
@@ -195,7 +195,7 @@ namespace tut
src->setSaleInfo(new_sale_info);
U32 new_flags = rand();
- S32 new_creation = time(NULL);
+ S32 new_creation = (S32)time(NULL);
LLPermissions new_perm;
@@ -266,7 +266,7 @@ namespace tut
src->setSaleInfo(new_sale_info);
U32 new_flags = rand();
- S32 new_creation = time(NULL);
+ S32 new_creation = (S32)time(NULL);
LLPermissions new_perm;
diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h
index e8fdcc9ae3..ea71752ebc 100644
--- a/indra/llmath/llcalcparser.h
+++ b/indra/llmath/llcalcparser.h
@@ -175,7 +175,7 @@ private:
F32 _exp(const F32& a) const { return exp(a); }
F32 _fabs(const F32& a) const { return fabs(a); }
F32 _floor(const F32& a) const { return (F32)llfloor(a); }
- F32 _ceil(const F32& a) const { return llceil(a); }
+ F32 _ceil(const F32& a) const { return (F32)llceil(a); }
F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); }
LLCalc::calc_map_t* mConstants;
diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h
index 6136c59ed1..762d13eded 100644
--- a/indra/llmath/llquaternion.h
+++ b/indra/llmath/llquaternion.h
@@ -186,10 +186,10 @@ inline LLSD LLQuaternion::getValue() const
inline void LLQuaternion::setValue(const LLSD& sd)
{
- mQ[0] = sd[0].asReal();
- mQ[1] = sd[1].asReal();
- mQ[2] = sd[2].asReal();
- mQ[3] = sd[3].asReal();
+ mQ[0] = (F32)sd[0].asReal();
+ mQ[1] = (F32)sd[1].asReal();
+ mQ[2] = (F32)sd[2].asReal();
+ mQ[3] = (F32)sd[3].asReal();
}
// checker
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index f3db9424d9..56ac22ca18 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -734,7 +734,7 @@ S32 LLProfile::getNumPoints(const LLProfileParams& params, bool path_open,F32 de
bool LLProfile::generate(const LLProfileParams& params, bool path_open,F32 detail, S32 split,
bool is_sculpted, S32 sculpt_size)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if ((!mDirty) && (!is_sculpted))
{
@@ -1216,7 +1216,7 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
constexpr F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
@@ -1452,7 +1452,7 @@ S32 LLPath::getNumPoints(const LLPathParams& params, F32 detail)
bool LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
bool is_sculpted, S32 sculpt_size)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if ((!mDirty) && (!is_sculpted))
{
@@ -2029,7 +2029,7 @@ LLVolume::~LLVolume()
bool LLVolume::generate()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
LL_CHECK_MEMORY
llassert_always(mProfilep);
@@ -2289,7 +2289,7 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs
bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//input stream is now pointing at a zlib compressed block of LLSD
//decompress block
@@ -2345,11 +2345,11 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
continue;
}
- LLSD::Binary pos = mdl[i]["Position"];
- LLSD::Binary norm = mdl[i]["Normal"];
- LLSD::Binary tangent = mdl[i]["Tangent"];
- LLSD::Binary tc = mdl[i]["TexCoord0"];
- LLSD::Binary idx = mdl[i]["TriangleList"];
+ const LLSD::Binary& pos = mdl[i]["Position"].asBinary();
+ const LLSD::Binary& norm = mdl[i]["Normal"].asBinary();
+ const LLSD::Binary& tangent = mdl[i]["Tangent"].asBinary();
+ const LLSD::Binary& tc = mdl[i]["TexCoord0"].asBinary();
+ const LLSD::Binary& idx = mdl[i]["TriangleList"].asBinary();
//copy out indices
auto num_indices = idx.size() / 2;
@@ -2538,7 +2538,7 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
continue;
}
- LLSD::Binary weights = mdl[i]["Weights"];
+ const LLSD::Binary& weights = mdl[i]["Weights"].asBinary();
U32 idx = 0;
@@ -2776,7 +2776,7 @@ S32 LLVolume::getNumFaces() const
void LLVolume::createVolumeFaces()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if (mGenerateSingleFace)
{
@@ -3741,7 +3741,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices,
const LLMatrix3& norm_mat_in,
S32 face_mask)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
LLMatrix4a mat;
mat.loadu(mat_in);
@@ -4870,7 +4870,7 @@ void LLVolumeFace::freeData()
bool LLVolumeFace::create(LLVolume* volume, bool partial_build)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//tree for this face is no longer valid
destroyOctree();
@@ -5462,7 +5462,11 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
U32 stream_count = data.w.empty() ? 4 : 5;
- S32 vert_count = static_cast(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
+ S32 vert_count = 0;
+ if (!data.p.empty())
+ {
+ vert_count = static_cast(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
+ }
if (vert_count < 65535 && vert_count != 0)
{
@@ -5545,7 +5549,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if (getOctree())
{
@@ -6556,7 +6560,7 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v,
bool LLVolumeFace::createSide(LLVolume* volume, bool partial_build)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
LL_CHECK_MEMORY
bool flat = mTypeMask & FLAT_MASK;
@@ -7090,7 +7094,7 @@ bool LLVolumeFace::createSide(LLVolume* volume, bool partial_build)
void LLCalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index 05d45f7b5f..1d74644715 100644
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -143,7 +143,7 @@ public:
virtual void visit(const LLOctreeNode* branch)
{ //this is a depth first traversal, so it's safe to assum all children have complete
//bounding data
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*)branch->getListener(0);
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index 7b92f85a0c..f7af469e66 100644
--- a/indra/llmath/v3color.h
+++ b/indra/llmath/v3color.h
@@ -209,10 +209,6 @@ inline LLColor3::LLColor3(const F32 *vec)
mV[VBLUE] = vec[VBLUE];
}
-#if LL_WINDOWS
-# pragma warning( disable : 4996 ) // strncpy teh sux0r
-#endif
-
inline LLColor3::LLColor3(const char* color_string) // takes a string of format "RRGGBB" where RR is hex 00..FF
{
if (strlen(color_string) < 6) /* Flawfinder: ignore */
@@ -517,9 +513,9 @@ inline const LLVector3 linearColor3v(const T& a) {
template
const LLColor3& LLColor3::set(const std::vector& v)
{
- for (S32 i = 0; i < llmin((S32)v.size(), 3); ++i)
+ for (size_t i = 0; i < llmin(v.size(), 3); ++i)
{
- mV[i] = v[i];
+ mV[i] = (F32)v[i];
}
return *this;
@@ -530,9 +526,9 @@ const LLColor3& LLColor3::set(const std::vector& v)
template
void LLColor3::write(std::vector& v) const
{
- for (int i = 0; i < llmin((S32)v.size(), 3); ++i)
+ for (size_t i = 0; i < llmin(v.size(), 3); ++i)
{
- v[i] = mV[i];
+ v[i] = (T)mV[i];
}
}
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index e9bb6a07ba..cafdbd9d7c 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -702,9 +702,9 @@ inline const LLColor4 linearColor4(const LLColor4 &a)
template
const LLColor4& LLColor4::set(const std::vector& v)
{
- for (S32 i = 0; i < llmin((S32)v.size(), 4); ++i)
+ for (size_t i = 0; i < llmin(v.size(), 4); ++i)
{
- mV[i] = v[i];
+ mV[i] = (F32)v[i];
}
return *this;
@@ -713,9 +713,9 @@ const LLColor4& LLColor4::set(const std::vector& v)
template
void LLColor4::write(std::vector& v) const
{
- for (int i = 0; i < llmin((S32)v.size(), 4); ++i)
+ for (size_t i = 0; i < llmin(v.size(), 4); ++i)
{
- v[i] = mV[i];
+ v[i] = (T)mV[i];
}
}
diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h
index 7ed22212d3..a5b6f506d7 100644
--- a/indra/llmath/v4math.h
+++ b/indra/llmath/v4math.h
@@ -67,10 +67,10 @@ class LLVector4
void setValue(const LLSD& sd)
{
- mV[0] = sd[0].asReal();
- mV[1] = sd[1].asReal();
- mV[2] = sd[2].asReal();
- mV[3] = sd[3].asReal();
+ mV[0] = (F32)sd[0].asReal();
+ mV[1] = (F32)sd[1].asReal();
+ mV[2] = (F32)sd[2].asReal();
+ mV[3] = (F32)sd[3].asReal();
}
diff --git a/indra/llmeshoptimizer/llmeshoptimizer.cpp b/indra/llmeshoptimizer/llmeshoptimizer.cpp
index 52ed9b9526..7339454367 100644
--- a/indra/llmeshoptimizer/llmeshoptimizer.cpp
+++ b/indra/llmeshoptimizer/llmeshoptimizer.cpp
@@ -291,6 +291,7 @@ U64 LLMeshOptimizer::simplifyU32(U32 *destination,
vertex_positions_stride,
target_index_count,
target_error,
+ 0,
result_error
);
}
@@ -332,6 +333,7 @@ U64 LLMeshOptimizer::simplify(U16 *destination,
vertex_positions_stride,
target_index_count,
target_error,
+ 0,
result_error
);
}
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 5322139304..b2757a7306 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -27,7 +27,6 @@ set(llmessage_SOURCE_FILES
lldatapacker.cpp
lldispatcher.cpp
llexperiencecache.cpp
- llfiltersd2xmlrpc.cpp
llgenericstreamingmessage.cpp
llhost.cpp
llhttpnode.cpp
@@ -111,7 +110,6 @@ set(llmessage_HEADER_FILES
lleventflags.h
llexperiencecache.h
llextendedstatus.h
- llfiltersd2xmlrpc.h
llfollowcamparams.h
llgenericstreamingmessage.h
llhost.h
@@ -193,7 +191,6 @@ target_link_libraries(
llfilesystem
llmath
llcorehttp
- ll::xmlrpc-epi
)
target_include_directories( llmessage INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 70a7a34a70..2de59c1b6a 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -484,6 +484,8 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
void *user_data,
bool is_priority)
{
+ LL_PROFILE_ZONE_SCOPED;
+
LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << LL_ENDL;
LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << LL_ENDL;
@@ -529,6 +531,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
if (size > 0)
{
+ LL_PROFILE_ZONE_NAMED("gad - file in cache");
// we've already got the file
// theoretically, partial files w/o a pending request shouldn't happen
// unless there's a weird error
@@ -548,7 +551,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
}
bool duplicate = false;
-
+ LL_PROFILE_ZONE_NAMED("gad - check pending downloads");
// check to see if there's a pending download of this uuid already
for (request_list_t::iterator iter = mPendingDownloads.begin();
iter != mPendingDownloads.end(); ++iter )
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index dc7115b167..3a4b493b26 100644
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -142,7 +142,7 @@ LLHeapBuffer::~LLHeapBuffer()
S32 LLHeapBuffer::bytesLeft() const
{
- return (mSize - (mNextFree - mBuffer));
+ return (mSize - (S32)(mNextFree - mBuffer));
}
// virtual
@@ -371,11 +371,11 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
return it;
}
S32 channel = (*it).getChannel();
- LLSegment segment1(channel, base, (address - base) + 1);
+ LLSegment segment1(channel, base, (S32)((address - base) + 1));
*it = segment1;
segment_iterator_t rv = it;
++it;
- LLSegment segment2(channel, address + 1, size - (address - base) - 1);
+ LLSegment segment2(channel, address + 1, (S32)(size - (address - base) - 1));
mSegments.insert(it, segment2);
return rv;
}
@@ -424,7 +424,7 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
segment = LLSegment(
(*rv).getChannel(),
address,
- (*rv).size() - (address - (*rv).data()));
+ (*rv).size() - (S32)(address - (*rv).data()));
}
else
{
@@ -533,7 +533,7 @@ S32 LLBufferArray::countAfter(S32 channel, U8* start) const
if(++start < ((*it).data() + (*it).size()))
{
// it's in the same segment
- offset = start - (*it).data();
+ offset = (S32)(start - (*it).data());
}
else if(++it == end)
{
@@ -586,7 +586,7 @@ U8* LLBufferArray::readAfter(
&& (*it).isOnChannel(channel))
{
// copy the data out of this segment
- S32 bytes_in_segment = (*it).size() - (start - (*it).data());
+ S32 bytes_in_segment = (*it).size() - (S32)(start - (*it).data());
bytes_to_copy = llmin(bytes_left, bytes_in_segment);
memcpy(dest, start, bytes_to_copy); /*Flawfinder: ignore*/
len += bytes_to_copy;
@@ -681,7 +681,7 @@ U8* LLBufferArray::seek(
{
if(delta > 0)
{
- S32 bytes_in_segment = (*it).size() - (start - (*it).data());
+ S32 bytes_in_segment = (*it).size() - (S32)(start - (*it).data());
S32 local_delta = llmin(delta, bytes_in_segment);
rv += local_delta;
delta -= local_delta;
@@ -689,7 +689,7 @@ U8* LLBufferArray::seek(
}
else
{
- S32 bytes_in_segment = start - (*it).data();
+ S32 bytes_in_segment = (S32)(start - (*it).data());
S32 local_delta = llmin(llabs(delta), bytes_in_segment);
rv -= local_delta;
delta += local_delta;
diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp
index e51b489813..2c745f6fe4 100644
--- a/indra/llmessage/llbufferstream.cpp
+++ b/indra/llmessage/llbufferstream.cpp
@@ -273,7 +273,7 @@ streampos LLBufferStreamBuf::seekoff(
}
LLMutexLock lock(mBuffer->getMutex());
- address = mBuffer->seek(mChannels.in(), base_addr, off);
+ address = mBuffer->seek(mChannels.in(), base_addr, (S32)off);
if(address)
{
LLBufferArray::segment_iterator_t iter;
@@ -306,7 +306,7 @@ streampos LLBufferStreamBuf::seekoff(
}
LLMutexLock lock(mBuffer->getMutex());
- address = mBuffer->seek(mChannels.out(), base_addr, off);
+ address = mBuffer->seek(mChannels.out(), base_addr, (S32)off);
if(address)
{
LLBufferArray::segment_iterator_t iter;
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp
index bf22f3d3f0..8f9c02bdca 100644
--- a/indra/llmessage/llcircuit.cpp
+++ b/indra/llmessage/llcircuit.cpp
@@ -525,13 +525,13 @@ void LLCircuitData::checkPeriodTime()
F64Seconds period_length = mt_sec - mPeriodTime;
if ( period_length > TARGET_PERIOD_LENGTH)
{
- F32 bps_in = F32Bits(mBytesInThisPeriod).value() / period_length.value();
+ F32 bps_in = F32Bits(mBytesInThisPeriod).value() / (F32)period_length.value();
if (bps_in > mPeakBPSIn)
{
mPeakBPSIn = bps_in;
}
- F32 bps_out = F32Bits(mBytesOutThisPeriod).value() / period_length.value();
+ F32 bps_out = F32Bits(mBytesOutThisPeriod).value() / (F32)period_length.value();
if (bps_out > mPeakBPSOut)
{
mPeakBPSOut = bps_out;
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 684e96883f..918a69be6f 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -523,7 +523,7 @@ LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::
bas >> std::noskipws;
data.assign(std::istream_iterator(bas), std::istream_iterator());
- result[HttpCoroutineAdapter::HTTP_RESULTS_RAW] = data;
+ result[HttpCoroutineAdapter::HTTP_RESULTS_RAW] = std::move(data);
#else
// This is disabled because it's dangerous. See the other case for an
@@ -585,7 +585,7 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
LLCore::BufferArrayStream bas(body);
- boost::json::error_code ec;
+ boost::system::error_code ec;
boost::json::value jsonRoot = boost::json::parse(bas, ec);
if(ec.failed())
{ // deserialization failed. Record the reason and pass back an empty map for markup.
@@ -610,7 +610,7 @@ LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &succes
LLCore::BufferArrayStream bas(body);
- boost::json::error_code ec;
+ boost::system::error_code ec;
boost::json::value jsonRoot = boost::json::parse(bas, ec);
if (ec.failed())
{
diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp
deleted file mode 100644
index 84b56d54bf..0000000000
--- a/indra/llmessage/llfiltersd2xmlrpc.cpp
+++ /dev/null
@@ -1,778 +0,0 @@
-/**
- * @file llfiltersd2xmlrpc.cpp
- * @author Phoenix
- * @date 2005-04-26
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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$
- */
-
-/**
- * xml rpc request:
- *
- *
- * examples.getStateName
- * 41
- *
- *
- *
- * xml rpc response:
- *
- *
- *
- * South Dakota
- *
- *
- *
- * xml rpc fault:
- *
- *
- *
- *
- * faultCode4
- * faultString...
- *
- *
- *
- *
- * llsd rpc request:
- *
- * { 'method':'...', 'parameter':...]}
- *
- *
- * llsd rpc response:
- *
- * { 'response':... }
- *
- *
- * llsd rpc fault:
- *
- * { 'fault': {'code':i..., 'description':'...'} }
- *
- *
- */
-
-#include "linden_common.h"
-#include "llfiltersd2xmlrpc.h"
-
-#include
-#include
-
-#ifdef LL_USESYSTEMLIBS
-#include
-#else
-#include
-#endif
-
-#include "apr_base64.h"
-
-#include "llbuffer.h"
-#include "llbufferstream.h"
-#include "llfasttimer.h"
-#include "llmemorystream.h"
-#include "llsd.h"
-#include "llsdserialize.h"
-#include "lluuid.h"
-
-// spammy mode
-//#define LL_SPEW_STREAM_OUT_DEBUGGING 1
-
-/**
- * String constants
- */
-static const char XML_HEADER[] = "";
-static const char XMLRPC_REQUEST_HEADER_1[] = "";
-static const char XMLRPC_REQUEST_HEADER_2[] = "";
-static const char XMLRPC_REQUEST_FOOTER[] = "";
-static const char XMLRPC_METHOD_RESPONSE_HEADER[] = "";
-static const char XMLRPC_METHOD_RESPONSE_FOOTER[] = "";
-static const char XMLRPC_RESPONSE_HEADER[] = "";
-static const char XMLRPC_RESPONSE_FOOTER[] = "";
-static const char XMLRPC_FAULT_1[] = "faultCode";
-static const char XMLRPC_FAULT_2[] = "faultString";
-static const char XMLRPC_FAULT_3[] = "";
-static const char LLSDRPC_RESPONSE_HEADER[] = "{'response':";
-static const char LLSDRPC_RESPONSE_FOOTER[] = "}";
-const char LLSDRPC_REQUEST_HEADER_1[] = "{'method':'";
-const char LLSDRPC_REQUEST_HEADER_2[] = "', 'parameter': ";
-const char LLSDRPC_REQUEST_FOOTER[] = "}";
-static const char LLSDRPC_FAULT_HADER_1[] = "{ 'fault': {'code':i";
-static const char LLSDRPC_FAULT_HADER_2[] = ", 'description':";
-static const char LLSDRPC_FAULT_FOOTER[] = "} }";
-static const S32 DEFAULT_PRECISION = 20;
-
-/**
- * LLFilterSD2XMLRPC
- */
-LLFilterSD2XMLRPC::LLFilterSD2XMLRPC()
-{
-}
-
-LLFilterSD2XMLRPC::~LLFilterSD2XMLRPC()
-{
-}
-
-std::string xml_escape_string(const std::string& in)
-{
- std::ostringstream out;
- std::string::const_iterator it = in.begin();
- std::string::const_iterator end = in.end();
- for(; it != end; ++it)
- {
- switch((*it))
- {
- case '<':
- out << "<";
- break;
- case '>':
- out << ">";
- break;
- case '&':
- out << "&";
- break;
- case '\'':
- out << "'";
- break;
- case '"':
- out << """;
- break;
- default:
- out << (*it);
- break;
- }
- }
- return out.str();
-}
-
-void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd)
-{
- ostr << "";
- switch(sd.type())
- {
- case LLSD::TypeMap:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(map) BEGIN" << LL_ENDL;
-#endif
- ostr << "";
- if(ostr.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing struct" << LL_ENDL;
- }
- LLSD::map_const_iterator it = sd.beginMap();
- LLSD::map_const_iterator end = sd.endMap();
- for(; it != end; ++it)
- {
- ostr << "" << xml_escape_string((*it).first)
- << "";
- streamOut(ostr, (*it).second);
- if(ostr.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing '" << (*it).first
- << "' with sd type " << (*it).second.type() << LL_ENDL;
- }
- ostr << "";
- }
- ostr << "";
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(map) END" << LL_ENDL;
-#endif
- break;
- }
- case LLSD::TypeArray:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(array) BEGIN" << LL_ENDL;
-#endif
- ostr << "";
- LLSD::array_const_iterator it = sd.beginArray();
- LLSD::array_const_iterator end = sd.endArray();
- for(; it != end; ++it)
- {
- streamOut(ostr, *it);
- if(ostr.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing array element sd type "
- << (*it).type() << LL_ENDL;
- }
- }
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(array) END" << LL_ENDL;
-#endif
- ostr << "";
- break;
- }
- case LLSD::TypeUndefined:
- // treat undefined as a bool with a false value.
- case LLSD::TypeBoolean:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(bool)" << LL_ENDL;
-#endif
- ostr << "" << (sd.asBoolean() ? "1" : "0") << "";
- break;
- case LLSD::TypeInteger:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(int)" << LL_ENDL;
-#endif
- ostr << "" << sd.asInteger() << "";
- break;
- case LLSD::TypeReal:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(real)" << LL_ENDL;
-#endif
- ostr << "" << sd.asReal() << "";
- break;
- case LLSD::TypeString:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(string)" << LL_ENDL;
-#endif
- ostr << "" << xml_escape_string(sd.asString()) << "";
- break;
- case LLSD::TypeUUID:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(uuid)" << LL_ENDL;
-#endif
- // serialize it as a string
- ostr << "" << sd.asString() << "";
- break;
- case LLSD::TypeURI:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(uri)" << LL_ENDL;
-#endif
- // serialize it as a string
- ostr << "" << xml_escape_string(sd.asString()) << "";
- break;
- }
- case LLSD::TypeBinary:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(binary)" << LL_ENDL;
-#endif
- // this is pretty inefficient, but we'll deal with that
- // problem when it becomes one.
- ostr << "";
- LLSD::Binary buffer = sd.asBinary();
- if(!buffer.empty())
- {
- // *TODO: convert to LLBase64
- int b64_buffer_length = apr_base64_encode_len(static_cast(buffer.size()));
- char* b64_buffer = new char[b64_buffer_length];
- b64_buffer_length = apr_base64_encode_binary(
- b64_buffer,
- &buffer[0],
- static_cast(buffer.size()));
- ostr.write(b64_buffer, b64_buffer_length - 1);
- delete[] b64_buffer;
- }
- ostr << "";
- break;
- }
- case LLSD::TypeDate:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(date)" << LL_ENDL;
-#endif
- // no need to escape this since it will be alpha-numeric.
- ostr << "" << sd.asString() << "";
- break;
- default:
- // unhandled type
- LL_WARNS() << "Unhandled structured data type: " << sd.type()
- << LL_ENDL;
- break;
- }
- ostr << "";
-}
-
-/**
- * LLFilterSD2XMLRPCResponse
- */
-
-LLFilterSD2XMLRPCResponse::LLFilterSD2XMLRPCResponse()
-{
-}
-
-LLFilterSD2XMLRPCResponse::~LLFilterSD2XMLRPCResponse()
-{
-}
-
-
-// virtual
-LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump)
-{
- LL_PROFILE_ZONE_SCOPED;
-
- PUMP_DEBUG;
- // This pipe does not work if it does not have everyting. This
- // could be addressed by making a stream parser for llsd which
- // handled partial information.
- if(!eos)
- {
- return STATUS_BREAK;
- }
-
- PUMP_DEBUG;
- // we have everyting in the buffer, so turn the structure data rpc
- // response into an xml rpc response.
- LLBufferStream stream(channels, buffer.get());
- stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER;
- LLSD sd;
- LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in()));
-
- PUMP_DEBUG;
- LLIOPipe::EStatus rv = STATUS_ERROR;
- if(sd.has("response"))
- {
- PUMP_DEBUG;
- // it is a normal response. pack it up and ship it out.
- stream.precision(DEFAULT_PRECISION);
- stream << XMLRPC_RESPONSE_HEADER;
- streamOut(stream, sd["response"]);
- stream << XMLRPC_RESPONSE_FOOTER << XMLRPC_METHOD_RESPONSE_FOOTER;
- rv = STATUS_DONE;
- }
- else if(sd.has("fault"))
- {
- PUMP_DEBUG;
- // it is a fault.
- stream << XMLRPC_FAULT_1 << sd["fault"]["code"].asInteger()
- << XMLRPC_FAULT_2
- << xml_escape_string(sd["fault"]["description"].asString())
- << XMLRPC_FAULT_3 << XMLRPC_METHOD_RESPONSE_FOOTER;
- rv = STATUS_DONE;
- }
- else
- {
- LL_WARNS() << "Unable to determine the type of LLSD response." << LL_ENDL;
- }
- PUMP_DEBUG;
- return rv;
-}
-
-/**
- * LLFilterSD2XMLRPCRequest
- */
-LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest()
-{
-}
-
-LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest(const char* method)
-{
- if(method)
- {
- mMethod.assign(method);
- }
-}
-
-LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest()
-{
-}
-
-// virtual
-LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump)
-{
- LL_PROFILE_ZONE_SCOPED;
- // This pipe does not work if it does not have everyting. This
- // could be addressed by making a stream parser for llsd which
- // handled partial information.
- PUMP_DEBUG;
- if(!eos)
- {
- LL_INFOS() << "!eos" << LL_ENDL;
- return STATUS_BREAK;
- }
-
- // See if we can parse it
- LLBufferStream stream(channels, buffer.get());
- LLSD sd;
- LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in()));
- if(stream.fail())
- {
- LL_INFOS() << "STREAM FAILURE reading structure data." << LL_ENDL;
- }
-
- PUMP_DEBUG;
- // We can get the method and parameters from either the member
- // function or passed in via the buffer. We prefer the buffer if
- // we found a parameter and a method, or fall back to using
- // mMethod and putting everyting in the buffer into the parameter.
- std::string method;
- LLSD param_sd;
- if(sd.has("method") && sd.has("parameter"))
- {
- method = sd["method"].asString();
- param_sd = sd["parameter"];
- }
- else
- {
- method = mMethod;
- param_sd = sd;
- }
- if(method.empty())
- {
- LL_WARNS() << "SD -> XML Request no method found." << LL_ENDL;
- return STATUS_ERROR;
- }
-
- PUMP_DEBUG;
- // We have a method, and some kind of parameter, so package it up
- // and send it out.
- LLBufferStream ostream(channels, buffer.get());
- ostream.precision(DEFAULT_PRECISION);
- if(ostream.fail())
- {
- LL_INFOS() << "STREAM FAILURE setting precision" << LL_ENDL;
- }
- ostream << XML_HEADER << XMLRPC_REQUEST_HEADER_1
- << xml_escape_string(method) << XMLRPC_REQUEST_HEADER_2;
- if(ostream.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing method headers" << LL_ENDL;
- }
- switch(param_sd.type())
- {
- case LLSD::TypeMap:
- // If the params are a map, then we do not want to iterate
- // through them since the iterators returned will be map
- // ordered un-named values, which will lose the names, and
- // only stream the values, turning it into an array.
- ostream << "";
- streamOut(ostream, param_sd);
- ostream << "";
- break;
- case LLSD::TypeArray:
- {
-
- LLSD::array_iterator it = param_sd.beginArray();
- LLSD::array_iterator end = param_sd.endArray();
- for(; it != end; ++it)
- {
- ostream << "";
- streamOut(ostream, *it);
- ostream << "";
- }
- break;
- }
- default:
- ostream << "";
- streamOut(ostream, param_sd);
- ostream << "";
- break;
- }
-
- stream << XMLRPC_REQUEST_FOOTER;
- return STATUS_DONE;
-}
-
-/**
- * LLFilterXMLRPCResponse2LLSD
- */
-// this is a c function here since it's really an implementation
-// detail that requires a header file just get the definition of the
-// parameters.
-LLIOPipe::EStatus stream_out(std::ostream& ostr, XMLRPC_VALUE value)
-{
- XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(value);
- LLIOPipe::EStatus status = LLIOPipe::STATUS_OK;
- switch(type)
- {
- case xmlrpc_type_base64:
- {
- S32 len = XMLRPC_GetValueStringLen(value);
- const char* buf = XMLRPC_GetValueBase64(value);
- ostr << " b(";
- if((len > 0) && buf)
- {
- ostr << len << ")\"";
- ostr.write(buf, len);
- ostr << "\"";
- }
- else
- {
- ostr << "0)\"\"";
- }
- break;
- }
- case xmlrpc_type_boolean:
- //LL_DEBUGS() << "stream_out() bool" << LL_ENDL;
- ostr << " " << (XMLRPC_GetValueBoolean(value) ? "true" : "false");
- break;
- case xmlrpc_type_datetime:
- ostr << " d\"" << XMLRPC_GetValueDateTime_ISO8601(value) << "\"";
- break;
- case xmlrpc_type_double:
- ostr << " r" << XMLRPC_GetValueDouble(value);
- //LL_DEBUGS() << "stream_out() double" << XMLRPC_GetValueDouble(value)
- // << LL_ENDL;
- break;
- case xmlrpc_type_int:
- ostr << " i" << XMLRPC_GetValueInt(value);
- //LL_DEBUGS() << "stream_out() integer:" << XMLRPC_GetValueInt(value)
- // << LL_ENDL;
- break;
- case xmlrpc_type_string:
- //LL_DEBUGS() << "stream_out() string: " << str << LL_ENDL;
- ostr << " s(" << XMLRPC_GetValueStringLen(value) << ")'"
- << XMLRPC_GetValueString(value) << "'";
- break;
- case xmlrpc_type_array: // vector
- case xmlrpc_type_mixed: // vector
- {
- //LL_DEBUGS() << "stream_out() array" << LL_ENDL;
- ostr << " [";
- U32 needs_comma = 0;
- XMLRPC_VALUE current = XMLRPC_VectorRewind(value);
- while(current && (LLIOPipe::STATUS_OK == status))
- {
- if(needs_comma++) ostr << ",";
- status = stream_out(ostr, current);
- current = XMLRPC_VectorNext(value);
- }
- ostr << "]";
- break;
- }
- case xmlrpc_type_struct: // still vector
- {
- //LL_DEBUGS() << "stream_out() struct" << LL_ENDL;
- ostr << " {";
- std::string name;
- U32 needs_comma = 0;
- XMLRPC_VALUE current = XMLRPC_VectorRewind(value);
- while(current && (LLIOPipe::STATUS_OK == status))
- {
- if(needs_comma++) ostr << ",";
- name.assign(XMLRPC_GetValueID(current));
- ostr << "'" << LLSDNotationFormatter::escapeString(name) << "':";
- status = stream_out(ostr, current);
- current = XMLRPC_VectorNext(value);
- }
- ostr << "}";
- break;
- }
- case xmlrpc_type_empty:
- case xmlrpc_type_none:
- default:
- status = LLIOPipe::STATUS_ERROR;
- LL_WARNS() << "Found an empty xmlrpc type.." << LL_ENDL;
- // not much we can do here...
- break;
- };
- return status;
-}
-
-LLFilterXMLRPCResponse2LLSD::LLFilterXMLRPCResponse2LLSD()
-{
-}
-
-LLFilterXMLRPCResponse2LLSD::~LLFilterXMLRPCResponse2LLSD()
-{
-}
-
-LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump)
-{
- LL_PROFILE_ZONE_SCOPED;
-
- PUMP_DEBUG;
- if(!eos) return STATUS_BREAK;
- if(!buffer) return STATUS_ERROR;
-
- PUMP_DEBUG;
- // *FIX: This technique for reading data is far from optimal. We
- // need to have some kind of istream interface into the xml
- // parser...
- S32 bytes = buffer->countAfter(channels.in(), NULL);
- if(!bytes) return STATUS_ERROR;
- char* buf = new char[bytes + 1];
- buf[bytes] = '\0';
- buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes);
-
- //LL_DEBUGS() << "xmlrpc response: " << buf << LL_ENDL;
-
- PUMP_DEBUG;
- XMLRPC_REQUEST response = XMLRPC_REQUEST_FromXML(
- buf,
- bytes,
- NULL);
- if(!response)
- {
- LL_WARNS() << "XML -> SD Response unable to parse xml." << LL_ENDL;
- delete[] buf;
- return STATUS_ERROR;
- }
-
- PUMP_DEBUG;
- LLBufferStream stream(channels, buffer.get());
- stream.precision(DEFAULT_PRECISION);
- if(XMLRPC_ResponseIsFault(response))
- {
- PUMP_DEBUG;
- stream << LLSDRPC_FAULT_HADER_1
- << XMLRPC_GetResponseFaultCode(response)
- << LLSDRPC_FAULT_HADER_2;
- const char* fault_str = XMLRPC_GetResponseFaultString(response);
- std::string fault_string;
- if(fault_str)
- {
- fault_string.assign(fault_str);
- }
- stream << "'" << LLSDNotationFormatter::escapeString(fault_string)
- << "'" <countAfter(channels.in(), NULL);
- if(!bytes) return STATUS_ERROR;
- char* buf = new char[bytes + 1];
- buf[bytes] = '\0';
- buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes);
-
- //LL_DEBUGS() << "xmlrpc request: " << buf << LL_ENDL;
-
- // Check the value in the buffer. XMLRPC_REQUEST_FromXML will report a error code 4 if
- // values that are less than 0x20 are passed to it, except
- // 0x09: Horizontal tab; 0x0a: New Line; 0x0d: Carriage
- U8* cur_pBuf = (U8*)buf;
- U8 cur_char;
- for (S32 i=0; i SD Request process parse error." << LL_ENDL;
- delete[] buf;
- return STATUS_ERROR;
- }
-
- PUMP_DEBUG;
- LLBufferStream stream(channels, buffer.get());
- stream.precision(DEFAULT_PRECISION);
- const char* name = XMLRPC_RequestGetMethodName(request);
- stream << LLSDRPC_REQUEST_HEADER_1 << (name ? name : "")
- << LLSDRPC_REQUEST_HEADER_2;
- XMLRPC_VALUE param = XMLRPC_RequestGetData(request);
- if(param)
- {
- PUMP_DEBUG;
- S32 size = XMLRPC_VectorSize(param);
- if(size > 1)
- {
- // if there are multiple parameters, stuff the values into
- // an array so that the next step in the chain can read them.
- stream << "[";
- }
- XMLRPC_VALUE current = XMLRPC_VectorRewind(param);
- bool needs_comma = false;
- while(current)
- {
- if(needs_comma)
- {
- stream << ",";
- }
- needs_comma = true;
- stream_out(stream, current);
- current = XMLRPC_VectorNext(param);
- }
- if(size > 1)
- {
- // close the array
- stream << "]";
- }
- }
- stream << LLSDRPC_REQUEST_FOOTER;
- XMLRPC_RequestFree(request, 1);
- delete[] buf;
- PUMP_DEBUG;
- return STATUS_DONE;
-}
-
diff --git a/indra/llmessage/llfiltersd2xmlrpc.h b/indra/llmessage/llfiltersd2xmlrpc.h
deleted file mode 100644
index 55938d3e2b..0000000000
--- a/indra/llmessage/llfiltersd2xmlrpc.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * @file llfiltersd2xmlrpc.h
- * @author Phoenix
- * @date 2005-04-26
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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_LLFILTERSD2XMLRPC_H
-#define LL_LLFILTERSD2XMLRPC_H
-
-/**
- * These classes implement the necessary pipes for translating between
- * xmlrpc and llsd rpc. The llsd rpcs mechanism was developed as an
- * extensible and easy to parse serialization grammer which maintains
- * a time efficient in-memory representation.
- */
-
-#include
-#include "lliopipe.h"
-
-/**
- * @class LLFilterSD2XMLRPC
- * @brief Filter from serialized LLSD to an XMLRPC method call
- *
- * This clas provides common functionality for the LLFilterSD2XMLRPRC
- * request and response classes.
- */
-class LLFilterSD2XMLRPC : public LLIOPipe
-{
-public:
- LLFilterSD2XMLRPC();
- virtual ~LLFilterSD2XMLRPC();
-
-protected:
- /**
- * @brief helper method
- */
- void streamOut(std::ostream& ostr, const LLSD& sd);
-};
-
-/**
- * @class LLFilterSD2XMLRPCResponse
- * @brief Filter from serialized LLSD to an XMLRPC response
- *
- * This class filters a serialized LLSD object to an xmlrpc
- * repsonse. Since resonses are limited to a single param, the xmlrprc
- * response only serializes it as one object.
- * This class correctly handles normal llsd responses as well as llsd
- * rpc faults.
- *
- * For example, if given:
- * {'response':[ i200, r3.4, {"foo":"bar"} ]}
- * Would generate:
- *
- *
- *
- * 200
- * 3.4
- *
- * foobar
- *
- *
- *
- */
-class LLFilterSD2XMLRPCResponse : public LLFilterSD2XMLRPC
-{
-public:
- // constructor
- LLFilterSD2XMLRPCResponse();
-
- // destructor
- virtual ~LLFilterSD2XMLRPCResponse();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-};
-
-/**
- * @class LLFilterSD2XMLRPCRequest
- * @brief Filter from serialized LLSD to an XMLRPC method call
- *
- * This class will accept any kind of serialized LLSD object, but you
- * probably want to have an array on the outer boundary since this
- * object will interpret each element in the top level LLSD as a
- * parameter into the xmlrpc spec.
- *
- * For example, you would represent 3 params as:
- *
- * {'method'='foo', 'parameter':[i200, r3.4, {"foo":"bar"}]}
- *
- * To generate:
- *
- *
- *
- * 200
- * 3.4
- *
- * foobar
- *
- *
- *
- * This class will accept 2 different kinds of encodings. The first
- * just an array of params as long as you specify the method in the
- * constructor. It will also accept a structured data in the form:
- * {'method':'$method_name', 'parameter':[...] } In the latter form, the
- * encoded 'method' will be used regardless of the construction of the
- * object, and the 'parameter' will be used as parameter to the call.
- */
-class LLFilterSD2XMLRPCRequest : public LLFilterSD2XMLRPC
-{
-public:
- // constructor
- LLFilterSD2XMLRPCRequest();
-
- // constructor
- LLFilterSD2XMLRPCRequest(const char* method);
-
- // destructor
- virtual ~LLFilterSD2XMLRPCRequest();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-
-protected:
- // The method name of this request.
- std::string mMethod;
-};
-
-/**
- * @class LLFilterXMLRPCResponse2LLSD
- * @brief Filter from serialized XMLRPC method response to LLSD
- *
- * The xmlrpc spec states that responses can only have one element
- * which can be of any supported type.
- * This takes in xml of the form:
- *
- *
- * ok
- *
- * And processes it into:
- * 'ok'
- *
- */
-class LLFilterXMLRPCResponse2LLSD : public LLIOPipe
-{
-public:
- // constructor
- LLFilterXMLRPCResponse2LLSD();
-
- // destructor
- virtual ~LLFilterXMLRPCResponse2LLSD();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-
-protected:
-};
-
-/**
- * @class LLFilterXMLRPCRequest2LLSD
- * @brief Filter from serialized XMLRPC method call to LLSD
- *
- * This takes in xml of the form:
- *
- *
- * repeat
- *
- * 4
- * ok
- *
- *
- * And processes it into:
- * { 'method':'repeat', 'params':[i4, 'ok'] }
- */
-class LLFilterXMLRPCRequest2LLSD : public LLIOPipe
-{
-public:
- // constructor
- LLFilterXMLRPCRequest2LLSD();
-
- // destructor
- virtual ~LLFilterXMLRPCRequest2LLSD();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-
-protected:
-};
-
-/**
- * @brief This function takes string, and escapes it appropritately
- * for inclusion as xml data.
- */
-std::string xml_escape_string(const std::string& in);
-
-/**
- * @brief Externally available constants
- */
-extern const char LLSDRPC_REQUEST_HEADER_1[];
-extern const char LLSDRPC_REQUEST_HEADER_2[];
-extern const char LLSDRPC_REQUEST_FOOTER[];
-
-#endif // LL_LLFILTERSD2XMLRPC_H
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index e562f09844..edc431e538 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -625,7 +625,7 @@ bool LLHTTPResponder::readHeaderLine(
}
return false;
}
- S32 offset = -((len - 1) - (newline - dest));
+ S32 offset = -((len - 1) - (S32)(newline - dest));
++newline;
*newline = '\0';
mLastRead = buffer->seek(channels.in(), last, offset);
diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp
index 0e709d6c75..edbeb4acc1 100644
--- a/indra/llmessage/lltemplatemessagedispatcher.cpp
+++ b/indra/llmessage/lltemplatemessagedispatcher.cpp
@@ -43,7 +43,7 @@ void LLTemplateMessageDispatcher::dispatch(const std::string& msg_name,
const LLSD& message,
LLHTTPNode::ResponsePtr responsep)
{
- std::vector data = message["body"]["binary-template-data"].asBinary();
+ const LLSD::Binary& data = message["body"]["binary-template-data"].asBinary();
auto size = data.size();
if(size == 0)
{
@@ -53,11 +53,11 @@ void LLTemplateMessageDispatcher::dispatch(const std::string& msg_name,
LLHost host;
host = gMessageSystem->getSender();
- bool validate_message = mTemplateMessageReader.validateMessage(&(data[0]), static_cast(size), host, true);
+ bool validate_message = mTemplateMessageReader.validateMessage(data.data(), static_cast(size), host, true);
if (validate_message)
{
- mTemplateMessageReader.readMessage(&(data[0]),host);
+ mTemplateMessageReader.readMessage(data.data(),host);
}
else
{
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 00abcf740f..bd1e19c294 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -34,6 +34,9 @@
#include "llpluginmessageclasses.h"
#include "llsdserialize.h"
#include "stringize.h"
+#include "threadpool.h"
+#include "workqueue.h"
+
#include "llapr.h"
//virtual
@@ -79,29 +82,8 @@ protected:
};
-
-class LLPluginProcessCreationThread : public LLThread
-{
-public:
- LLPluginProcessCreationThread(LLPluginProcessParent *parent) :
- LLThread("LLPluginProcessCreationThread", gAPRPoolp),
- pParent(parent)
- {
- }
-protected:
- // Inherited from LLThread, should run once
- /*virtual*/ void run(void)
- {
- pParent->createPluginProcess();
- }
-private:
- LLPluginProcessParent *pParent;
-
-};
-
LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
- mIncomingQueueMutex(),
- pProcessCreationThread(NULL)
+ mIncomingQueueMutex()
{
if(!sInstancesMutex)
{
@@ -130,18 +112,6 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
LLPluginProcessParent::~LLPluginProcessParent()
{
LL_DEBUGS("Plugin") << "destructor" << LL_ENDL;
- if (pProcessCreationThread)
- {
- if (!pProcessCreationThread->isStopped())
- {
- // Shouldn't happen at this stage
- LL_WARNS("Plugin") << "Shutting down active pProcessCreationThread" << LL_ENDL;
- pProcessCreationThread->shutdown();
- ms_sleep(20);
- }
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- }
// Destroy any remaining shared memory regions
sharedMemoryRegionsType::iterator iter;
@@ -352,35 +322,6 @@ bool LLPluginProcessParent::accept()
return result;
}
-bool LLPluginProcessParent::createPluginProcess()
-{
- if (!mProcess)
- {
- // Only argument to the launcher is the port number we're listening on
- mProcessParams.args.add(stringize(mBoundPort));
- mProcess = LLProcess::create(mProcessParams);
- return mProcess != NULL;
- }
-
- return false;
-}
-
-void LLPluginProcessParent::clearProcessCreationThread()
-{
- if (pProcessCreationThread)
- {
- if (!pProcessCreationThread->isStopped())
- {
- pProcessCreationThread->shutdown();
- }
- else
- {
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- }
- }
-}
-
void LLPluginProcessParent::idle(void)
{
bool idle_again;
@@ -542,29 +483,71 @@ void LLPluginProcessParent::idle(void)
case STATE_LISTENING:
{
+ // Only argument to the launcher is the port number we're listening on
+ mProcessParams.args.add(stringize(mBoundPort));
+
// Launch the plugin process.
- if (mDebug && !pProcessCreationThread)
+ if (mDebug && !mProcess)
{
- createPluginProcess();
- if (!mProcess)
+ if (!(mProcess = LLProcess::create(mProcessParams)))
{
errorState();
}
}
- else if (pProcessCreationThread == NULL)
+ else if (!mProcess && !mProcessCreationRequested)
{
- // exe plugin process allocation can be hindered by a number
- // of factors, don't hold whole viewer because of it, use thread
- pProcessCreationThread = new LLPluginProcessCreationThread(this);
- pProcessCreationThread->start();
- }
- else if (!mProcess && pProcessCreationThread->isStopped())
- {
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- errorState();
- }
+ mProcessCreationRequested = true;
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak
+ // pointer
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+ auto process_params = mProcessParams;
+
+ bool posted = main_queue->postTo(
+ general_queue,
+ [process_params]() // Work done on general queue
+ {
+ return LLProcess::create(process_params);
+ },
+ [this](LLProcessPtr new_process) // Callback to main thread
+ mutable {
+ ptr_t that;
+ {
+ // this grabs a copy of the smart pointer to ourselves to ensure that we do not
+ // get destroyed until after this method returns.
+ LLCoros::LockType lock(*sInstancesMutex);
+ mapInstances_t::iterator it = sInstances.find(this);
+ if (it != sInstances.end())
+ that = (*it).second;
+ }
+
+ if (that)
+ {
+ if (new_process)
+ {
+ that->mProcess = new_process;
+ }
+ else
+ {
+ that->mProcessCreationRequested = false;
+ that->errorState();
+ }
+ }
+
+ });
+ if (!posted)
+ {
+ LL_WARNS("Plugin") << "Failed to dispath process creation to threadpool" << LL_ENDL;
+ if (!(mProcess = LLProcess::create(mProcessParams)))
+ {
+ mProcessCreationRequested = false;
+ errorState();
+ }
+ }
+ }
if (mProcess)
{
@@ -595,15 +578,6 @@ void LLPluginProcessParent::idle(void)
// This will allow us to time out if the process never starts.
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout);
-
- // pProcessCreationThread should have stopped by this point,
- // but check just in case it paused on statistics sync
- if (pProcessCreationThread && pProcessCreationThread->isStopped())
- {
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- }
-
setState(STATE_LAUNCHED);
}
}
@@ -706,7 +680,6 @@ void LLPluginProcessParent::idle(void)
killSockets();
setState(STATE_DONE);
dirtyPollSet();
- clearProcessCreationThread();
break;
case STATE_DONE:
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index d1c4933d81..334f1411af 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -69,11 +69,6 @@ public:
const std::string &plugin_filename,
bool debug);
- // Creates a process
- // returns true if process already exists or if created,
- // false if failed to create
- bool createPluginProcess();
-
void idle(void);
// returns true if the plugin is on its way to steady state
@@ -168,15 +163,13 @@ private:
bool accept();
- void clearProcessCreationThread();
-
LLSocket::ptr_t mListenSocket;
LLSocket::ptr_t mSocket;
U32 mBoundPort;
LLProcess::Params mProcessParams;
LLProcessPtr mProcess;
- LLThread *pProcessCreationThread;
+ bool mProcessCreationRequested = false;
std::string mPluginFile;
std::string mPluginDir;
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 972f502aa9..19a43839af 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -70,7 +70,6 @@ target_link_libraries(llprimitive
llrender
llphysicsextensions_impl
ll::colladadom
- ll::pcre
ll::glh_linear
)
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 1480322935..3e84eeffc2 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -107,7 +107,7 @@ bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S
{
if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0)
{
- pos_offset = inputs[j]->getOffset();
+ pos_offset = (S32)inputs[j]->getOffset();
const domURIFragmentType& uri = v_inp[k]->getSource();
daeElementRef elem = uri.getElement();
@@ -116,7 +116,7 @@ bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S
if (strcmp(COMMON_PROFILE_INPUT_NORMAL, v_inp[k]->getSemantic()) == 0)
{
- norm_offset = inputs[j]->getOffset();
+ norm_offset = (S32)inputs[j]->getOffset();
const domURIFragmentType& uri = v_inp[k]->getSource();
daeElementRef elem = uri.getElement();
@@ -128,14 +128,14 @@ bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S
if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0)
{
//found normal array for this triangle list
- norm_offset = inputs[j]->getOffset();
+ norm_offset = (S32)inputs[j]->getOffset();
const domURIFragmentType& uri = inputs[j]->getSource();
daeElementRef elem = uri.getElement();
norm_source = (domSource*) elem.cast();
}
else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0)
{ //found texCoords
- tc_offset = inputs[j]->getOffset();
+ tc_offset = (S32)inputs[j]->getOffset();
const domURIFragmentType& uri = inputs[j]->getSource();
daeElementRef elem = uri.getElement();
tc_source = (domSource*) elem.cast();
@@ -201,8 +201,8 @@ LLModel::EModelStatus load_face_from_dom_triangles(
return LLModel::BAD_ELEMENT;
}
// VFExtents change
- face.mExtents[0].set(v[0], v[1], v[2]);
- face.mExtents[1].set(v[0], v[1], v[2]);
+ face.mExtents[0].set((F32)v[0], (F32)v[1], (F32)v[2]);
+ face.mExtents[1].set((F32)v[0], (F32)v[1], (F32)v[2]);
}
LLVolumeFace::VertexMapData::PointMap point_map;
@@ -223,22 +223,22 @@ LLModel::EModelStatus load_face_from_dom_triangles(
LLVolumeFace::VertexData cv;
if (pos_source)
{
- cv.setPosition(LLVector4a(v[idx[i+pos_offset]*3+0],
- v[idx[i+pos_offset]*3+1],
- v[idx[i+pos_offset]*3+2]));
+ cv.setPosition(LLVector4a((F32)v[idx[i+pos_offset]*3+0],
+ (F32)v[idx[i+pos_offset]*3+1],
+ (F32)v[idx[i+pos_offset]*3+2]));
}
if (tc_source)
{
- cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0],
- tc[idx[i+tc_offset]*2+1]);
+ cv.mTexCoord.setVec((F32)tc[idx[i+tc_offset]*2+0],
+ (F32)tc[idx[i+tc_offset]*2+1]);
}
if (norm_source)
{
- cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0],
- n[idx[i+norm_offset]*3+1],
- n[idx[i+norm_offset]*3+2]));
+ cv.setNormal(LLVector4a((F32)n[idx[i+norm_offset]*3+0],
+ (F32)n[idx[i+norm_offset]*3+1],
+ (F32)n[idx[i+norm_offset]*3+2]));
}
bool found = false;
@@ -326,8 +326,8 @@ LLModel::EModelStatus load_face_from_dom_triangles(
face = LLVolumeFace();
// VFExtents change
- face.mExtents[0].set(v[0], v[1], v[2]);
- face.mExtents[1].set(v[0], v[1], v[2]);
+ face.mExtents[0].set((F32)v[0], (F32)v[1], (F32)v[2]);
+ face.mExtents[1].set((F32)v[0], (F32)v[1], (F32)v[2]);
verts.clear();
indices.clear();
@@ -416,8 +416,8 @@ LLModel::EModelStatus load_face_from_dom_polylist(
{
v = pos_source->getFloat_array()->getValue();
// VFExtents change
- face.mExtents[0].set(v[0], v[1], v[2]);
- face.mExtents[1].set(v[0], v[1], v[2]);
+ face.mExtents[0].set((F32)v[0], (F32)v[1], (F32)v[2]);
+ face.mExtents[1].set((F32)v[0], (F32)v[1], (F32)v[2]);
}
if (tc_source)
@@ -445,9 +445,9 @@ LLModel::EModelStatus load_face_from_dom_polylist(
if (pos_source)
{
- cv.getPosition().set(v[idx[cur_idx+pos_offset]*3+0],
- v[idx[cur_idx+pos_offset]*3+1],
- v[idx[cur_idx+pos_offset]*3+2]);
+ cv.getPosition().set((F32)v[idx[cur_idx+pos_offset]*3+0],
+ (F32)v[idx[cur_idx+pos_offset]*3+1],
+ (F32)v[idx[cur_idx+pos_offset]*3+2]);
if (!cv.getPosition().isFinite3())
{
LL_WARNS() << "Found NaN while loading position data from DAE-Model, invalid model." << LL_ENDL;
@@ -465,7 +465,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(
if (idx_y < tc.getCount())
{
- cv.mTexCoord.setVec(tc[idx_x], tc[idx_y]);
+ cv.mTexCoord.setVec((F32)tc[idx_x], (F32)tc[idx_y]);
}
else if (log_tc_msg)
{
@@ -479,9 +479,9 @@ LLModel::EModelStatus load_face_from_dom_polylist(
if (norm_source)
{
- cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0],
- n[idx[cur_idx+norm_offset]*3+1],
- n[idx[cur_idx+norm_offset]*3+2]);
+ cv.getNormal().set((F32)n[idx[cur_idx+norm_offset]*3+0],
+ (F32)n[idx[cur_idx+norm_offset]*3+1],
+ (F32)n[idx[cur_idx+norm_offset]*3+2]);
if (!cv.getNormal().isFinite3())
{
@@ -607,8 +607,8 @@ LLModel::EModelStatus load_face_from_dom_polylist(
face = LLVolumeFace();
// VFExtents change
- face.mExtents[0].set(v[0], v[1], v[2]);
- face.mExtents[1].set(v[0], v[1], v[2]);
+ face.mExtents[0].set((F32)v[0], (F32)v[1], (F32)v[2]);
+ face.mExtents[1].set((F32)v[0], (F32)v[1], (F32)v[2]);
verts.clear();
indices.clear();
point_map.clear();
@@ -669,7 +669,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac
if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0)
{ //found vertex array
- v_offset = inputs[i]->getOffset();
+ v_offset = (S32)inputs[i]->getOffset();
const domURIFragmentType& uri = inputs[i]->getSource();
daeElementRef elem = uri.getElement();
@@ -697,7 +697,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac
}
else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[i]->getSemantic()) == 0)
{
- n_offset = inputs[i]->getOffset();
+ n_offset = (S32)inputs[i]->getOffset();
//found normal array for this triangle list
const domURIFragmentType& uri = inputs[i]->getSource();
daeElementRef elem = uri.getElement();
@@ -710,7 +710,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac
}
else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0)
{ //found texCoords
- t_offset = inputs[i]->getOffset();
+ t_offset = (S32)inputs[i]->getOffset();
const domURIFragmentType& uri = inputs[i]->getSource();
daeElementRef elem = uri.getElement();
domSource* src = (domSource*) elem.cast();
@@ -745,11 +745,11 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac
if (v)
{
- U32 v_idx = idx[j*stride+v_offset]*3;
+ U32 v_idx = (U32)idx[j*stride+v_offset]*3;
v_idx = llclamp(v_idx, (U32) 0, (U32) v->getCount());
- vert.getPosition().set(v->get(v_idx),
- v->get(v_idx+1),
- v->get(v_idx+2));
+ vert.getPosition().set((F32)v->get(v_idx),
+ (F32)v->get(v_idx+1),
+ (F32)v->get(v_idx+2));
}
//bounds check n and t lookups because some FBX to DAE converters
@@ -757,11 +757,11 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac
//for a particular channel
if (n && n->getCount() > 0)
{
- U32 n_idx = idx[j*stride+n_offset]*3;
+ U32 n_idx = (U32)idx[j*stride+n_offset]*3;
n_idx = llclamp(n_idx, (U32) 0, (U32) n->getCount());
- vert.getNormal().set(n->get(n_idx),
- n->get(n_idx+1),
- n->get(n_idx+2));
+ vert.getNormal().set((F32)n->get(n_idx),
+ (F32)n->get(n_idx+1),
+ (F32)n->get(n_idx+2));
}
else
{
@@ -771,10 +771,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac
if (t && t->getCount() > 0)
{
- U32 t_idx = idx[j*stride+t_offset]*2;
+ U32 t_idx = (U32)idx[j*stride+t_offset]*2;
t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount());
- vert.mTexCoord.setVec(t->get(t_idx),
- t->get(t_idx+1));
+ vert.mTexCoord.setVec((F32)t->get(t_idx),
+ (F32)t->get(t_idx+1));
}
else
{
@@ -1026,7 +1026,7 @@ bool LLDAELoader::OpenFile(const std::string& filename)
if (unit)
{
- F32 meter = unit->getMeter();
+ F32 meter = (F32)unit->getMeter();
mTransform.mMatrix[0][0] = meter;
mTransform.mMatrix[1][1] = meter;
mTransform.mMatrix[2][2] = meter;
@@ -1241,7 +1241,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
{
for(int j = 0; j < 4; j++)
{
- mat.mMatrix[i][j] = dom_value[i + j*4];
+ mat.mMatrix[i][j] = (F32)dom_value[i + j*4];
}
}
@@ -1463,7 +1463,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
{
for(int j = 0; j < 4; j++)
{
- mat.mMatrix[i][j] = transform[k*16 + i + j*4];
+ mat.mMatrix[i][j] = (F32)transform[k*16 + i + j*4];
}
}
model->mSkinInfo.mInvBindMatrix.push_back(LLMatrix4a(mat));
@@ -1581,7 +1581,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
LL_ERRS() << "Invalid position array size." << LL_ENDL;
}
- LLVector3 v(pos[j], pos[j+1], pos[j+2]);
+ LLVector3 v((F32)pos[j], (F32)pos[j+1], (F32)pos[j+2]);
//transform from COLLADA space to volume space
v = v * inverse_normalized_transformation;
@@ -1621,15 +1621,15 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
U32 c_idx = 0;
for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx)
{ //for each vertex
- daeUInt count = vcount[vc_idx];
+ daeUInt count = (daeUInt)vcount[vc_idx];
//create list of weights that influence this vertex
LLModel::weight_list weight_list;
for (daeUInt i = 0; i < count; ++i)
{ //for each weight
- daeInt joint_idx = v[c_idx++];
- daeInt weight_idx = v[c_idx++];
+ daeInt joint_idx = (daeInt)v[c_idx++];
+ daeInt weight_idx = (daeInt)v[c_idx++];
if (joint_idx == -1)
{
@@ -1637,7 +1637,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
continue;
}
- F32 weight_value = w[weight_idx];
+ F32 weight_value = (F32)w[weight_idx];
weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value));
}
@@ -1807,7 +1807,7 @@ bool LLDAELoader::verifyController( domController* pController )
{
//Skin is reference directly by geometry and get the vertex count from skin
domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights();
- U32 vertexWeightsCount = pVertexWeights->getCount();
+ U32 vertexWeightsCount = (U32)pVertexWeights->getCount();
domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement();
domMesh* pMesh = pGeometry->getMesh();
@@ -1825,7 +1825,7 @@ bool LLDAELoader::verifyController( domController* pController )
{
xsAnyURI src = pVertices->getInput_array()[0]->getSource();
domSource* pSource = (domSource*) (domElement*) src.getElement();
- U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount();
+ U32 verticesCount = (U32)pSource->getTechnique_common()->getAccessor()->getCount();
result = verifyCount( verticesCount, vertexWeightsCount );
if ( !result )
{
@@ -1845,7 +1845,7 @@ bool LLDAELoader::verifyController( domController* pController )
U32 sum = 0;
for (size_t i=0; igetVcount()->getValue()[i];
+ sum += (U32)pVertexWeights->getVcount()->getValue()[i];
}
result = verifyCount( sum * static_cast(inputs.getCount()), (domInt) static_cast(pVertexWeights->getV()->getValue().getCount()) );
}
@@ -1860,7 +1860,7 @@ bool LLDAELoader::verifyController( domController* pController )
void LLDAELoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& transform )
{
domFloat3 jointTrans = pTranslate->getValue();
- LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] );
+ LLVector3 singleJointTranslation((F32)jointTrans[0], (F32)jointTrans[1], (F32)jointTrans[2]);
transform.setTranslation( singleJointTranslation );
}
//-----------------------------------------------------------------------------
@@ -1872,7 +1872,7 @@ void LLDAELoader::extractTranslationViaElement( daeElement* pTranslateElement, L
{
domTranslate* pTranslateChild = static_cast( pTranslateElement );
domFloat3 translateChild = pTranslateChild->getValue();
- LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] );
+ LLVector3 singleJointTranslation((F32)translateChild[0], (F32)translateChild[1], (F32)translateChild[2]);
transform.setTranslation( singleJointTranslation );
}
}
@@ -1894,7 +1894,7 @@ void LLDAELoader::extractTranslationViaSID( daeElement* pElement, LLMatrix4& tra
{
for( int j = 0; j < 4; j++ )
{
- workingTransform.mMatrix[i][j] = domArray[i + j*4];
+ workingTransform.mMatrix[i][j] = (F32)domArray[i + j*4];
}
}
LLVector3 trans = workingTransform.getTranslation();
@@ -1957,7 +1957,7 @@ void LLDAELoader::processJointNode( domNode* pNode, JointTransformMap& jointTran
{
for (int j = 0; j < 4; j++)
{
- workingTransform.mMatrix[i][j] = domArray[i + j * 4];
+ workingTransform.mMatrix[i][j] = (F32)domArray[i + j * 4];
}
}
}
@@ -2023,7 +2023,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da
domFloat3 dom_value = translate->getValue();
LLMatrix4 translation;
- translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2]));
+ translation.setTranslation(LLVector3((F32)dom_value[0], (F32)dom_value[1], (F32)dom_value[2]));
translation *= mTransform;
mTransform = translation;
@@ -2036,7 +2036,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da
domFloat4 dom_value = rotate->getValue();
LLMatrix4 rotation;
- rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0));
+ rotation.initRotTrans((F32)dom_value[3] * DEG_TO_RAD, LLVector3((F32)dom_value[0], (F32)dom_value[1], (F32)dom_value[2]), LLVector3(0, 0, 0));
rotation *= mTransform;
mTransform = rotation;
@@ -2049,7 +2049,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da
domFloat3 dom_value = scale->getValue();
- LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]);
+ LLVector3 scale_vector = LLVector3((F32)dom_value[0], (F32)dom_value[1], (F32)dom_value[2]);
scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes
LLMatrix4 scaling;
scaling.initScale(scale_vector);
@@ -2070,7 +2070,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da
{
for(int j = 0; j < 4; j++)
{
- matrix_transform.mMatrix[i][j] = dom_value[i + j*4];
+ matrix_transform.mMatrix[i][j] = (F32)dom_value[i + j*4];
}
}
@@ -2338,7 +2338,7 @@ LLImportMaterial LLDAELoader::profileToMaterial(domProfile_COMMON* material, DAE
if (color)
{
domFx_color_common domfx_color = color->getValue();
- LLColor4 value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]);
+ LLColor4 value = LLColor4((F32)domfx_color[0], (F32)domfx_color[1], (F32)domfx_color[2], (F32)domfx_color[3]);
mat.mDiffuseColor = value;
}
}
@@ -2450,7 +2450,7 @@ LLColor4 LLDAELoader::getDaeColor(daeElement* element)
if (color)
{
domFx_color_common domfx_color = color->getValue();
- value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]);
+ value = LLColor4((F32)domfx_color[0], (F32)domfx_color[1], (F32)domfx_color[2], (F32)domfx_color[3]);
}
return value;
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index e8c9af5ea3..cc4921416f 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -790,7 +790,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
const LLSD& mf = data["mf"];
if (mf.isReal())
{
- mMetallicFactor = mf.asReal();
+ mMetallicFactor = (F32)mf.asReal();
if (mMetallicFactor == getDefaultMetallicFactor())
{
// HACK -- nudge by epsilon if we receive a default value (indicates override to default)
@@ -801,7 +801,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
const LLSD& rf = data["rf"];
if (rf.isReal())
{
- mRoughnessFactor = rf.asReal();
+ mRoughnessFactor = (F32)rf.asReal();
if (mRoughnessFactor == getDefaultRoughnessFactor())
{
// HACK -- nudge by epsilon if we receive a default value (indicates override to default)
@@ -819,7 +819,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
const LLSD& ac = data["ac"];
if (ac.isReal())
{
- mAlphaCutoff = ac.asReal();
+ mAlphaCutoff = (F32)ac.asReal();
if (mAlphaCutoff == getDefaultAlphaCutoff())
{
// HACK -- nudge by epsilon if we receive a default value (indicates override to default)
@@ -854,7 +854,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
const LLSD& r = ti[i]["r"];
if (r.isReal())
{
- mTextureTransform[i].mRotation = r.asReal();
+ mTextureTransform[i].mRotation = (F32)r.asReal();
}
}
}
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
index 847824d770..4992b282f3 100644
--- a/indra/llprimitive/llmaterialid.cpp
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -136,7 +136,7 @@ LLSD LLMaterialID::asLLSD() const
materialIDBinary.resize(MATERIAL_ID_SIZE * sizeof(U8));
memcpy(materialIDBinary.data(), mID, MATERIAL_ID_SIZE * sizeof(U8));
- LLSD materialID = materialIDBinary;
+ LLSD materialID = std::move(materialIDBinary);
return materialID;
}
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index e7152a2291..15087a7255 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1487,7 +1487,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
{
for (U32 k = 0; k < 4; k++)
{
- mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal();
+ mat.mMatrix[j][k] = (F32)skin["inverse_bind_matrix"][i][j*4+k].asReal();
}
}
@@ -1510,7 +1510,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
{
for (U32 k = 0; k < 4; k++)
{
- mat.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal();
+ mat.mMatrix[j][k] = (F32)skin["bind_shape_matrix"][j*4+k].asReal();
}
}
mBindShapeMatrix.loadu(mat);
@@ -1525,7 +1525,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
{
for (U32 k = 0; k < 4; k++)
{
- mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal();
+ mat.mMatrix[j][k] = (F32)skin["alt_inverse_bind_matrix"][i][j*4+k].asReal();
}
}
@@ -1535,7 +1535,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
if (skin.has("pelvis_offset"))
{
- mPelvisOffset = skin["pelvis_offset"].asReal();
+ mPelvisOffset = (F32)skin["pelvis_offset"].asReal();
}
if (skin.has("lock_scale_if_joint_position"))
@@ -1618,7 +1618,7 @@ void LLMeshSkinInfo::updateHash()
for (size_t i = 0, count = mInvBindMatrix.size() * 16; i < count; ++i)
{
- S32 t = llround(src[i] * 10000.f);
+ S32 t = ll_round(src[i] * 10000.f);
hash.update((const void*)&t, sizeof(S32));
}
//hash.update((const void*)mInvBindMatrix.data(), sizeof(LLMatrix4a) * mInvBindMatrix.size());
diff --git a/indra/llprimitive/lltreeparams.cpp b/indra/llprimitive/lltreeparams.cpp
index b85aa3acf2..b6216c022b 100644
--- a/indra/llprimitive/lltreeparams.cpp
+++ b/indra/llprimitive/lltreeparams.cpp
@@ -178,7 +178,7 @@ F32 LLTreeParams::ShapeRatio(EShapeRatio shape, F32 ratio)
case (SR_SPHERICAL):
return (.2f + .8f * sinf(F_PI*ratio));
case (SR_HEMISPHERICAL):
- return (.2f + .8f * sinf(.5*F_PI*ratio));
+ return (.2f + .8f * sinf(.5f*F_PI*ratio));
case (SR_CYLINDRICAL):
return (1);
case (SR_TAPERED_CYLINDRICAL):
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 741ed993b0..6128e03fa7 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -178,7 +178,7 @@ unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *
llifstream *file_stream = static_cast(stream->descriptor.pointer);
file_stream->seekg(offset, std::ios::beg);
file_stream->read((char*)buffer, count);
- return file_stream->gcount();
+ return (unsigned long)file_stream->gcount();
}
void ft_close_cb(FT_Stream stream) {
diff --git a/indra/llrender/llfontfreetypesvg.cpp b/indra/llrender/llfontfreetypesvg.cpp
index 355e8432aa..71f751329e 100644
--- a/indra/llrender/llfontfreetypesvg.cpp
+++ b/indra/llrender/llfontfreetypesvg.cpp
@@ -136,18 +136,18 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot,
float svg_scale = llmin(svg_x_scale, svg_y_scale);
datap->Scale = svg_scale;
- glyph_slot->bitmap.width = floorf(svg_width) * svg_scale;
- glyph_slot->bitmap.rows = floorf(svg_height) * svg_scale;
+ glyph_slot->bitmap.width = (unsigned int)(floorf(svg_width) * svg_scale);
+ glyph_slot->bitmap.rows = (unsigned int)(floorf(svg_height) * svg_scale);
glyph_slot->bitmap_left = (document->metrics.x_ppem - glyph_slot->bitmap.width) / 2;
- glyph_slot->bitmap_top = glyph_slot->face->size->metrics.ascender / 64.f;
+ glyph_slot->bitmap_top = (FT_Int)(glyph_slot->face->size->metrics.ascender / 64.f);
glyph_slot->bitmap.pitch = glyph_slot->bitmap.width * 4;
glyph_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
/* Copied as-is from fcft (MIT license) */
// Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box.
- float horiBearingX = 0.;
- float horiBearingY = -glyph_slot->bitmap_top;
+ float horiBearingX = 0.f;
+ float horiBearingY = -(float)glyph_slot->bitmap_top;
// XXX parentheses correct?
float vertBearingX = glyph_slot->metrics.horiBearingX / 64.0f - glyph_slot->metrics.horiAdvance / 64.0f / 2;
@@ -156,13 +156,13 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot,
// Do conversion in two steps to avoid 'bad function cast' warning
glyph_slot->metrics.width = glyph_slot->bitmap.width * 64;
glyph_slot->metrics.height = glyph_slot->bitmap.rows * 64;
- glyph_slot->metrics.horiBearingX = horiBearingX * 64;
- glyph_slot->metrics.horiBearingY = horiBearingY * 64;
- glyph_slot->metrics.vertBearingX = vertBearingX * 64;
- glyph_slot->metrics.vertBearingY = vertBearingY * 64;
+ glyph_slot->metrics.horiBearingX = (FT_Pos)(horiBearingX * 64);
+ glyph_slot->metrics.horiBearingY = (FT_Pos)(horiBearingY * 64);
+ glyph_slot->metrics.vertBearingX = (FT_Pos)(vertBearingX * 64);
+ glyph_slot->metrics.vertBearingY = (FT_Pos)(vertBearingY * 64);
if (glyph_slot->metrics.vertAdvance == 0)
{
- glyph_slot->metrics.vertAdvance = glyph_slot->bitmap.rows * 1.2f * 64;
+ glyph_slot->metrics.vertAdvance = (FT_Pos)(glyph_slot->bitmap.rows * 1.2f * 64);
}
return FT_Err_Ok;
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 59ee8ef84f..b6cdb81b33 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -112,7 +112,7 @@ S32 LLFontGL::getNumFaces(const std::string& filename)
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const
{
- LLRectf rect_float(rect.mLeft, rect.mTop, rect.mRight, rect.mBottom);
+ LLRectf rect_float((F32)rect.mLeft, (F32)rect.mTop, (F32)rect.mRight, (F32)rect.mBottom);
return render(wstr, begin_offset, rect_float, color, halign, valign, style, shadow, max_chars, right_x, use_ellipses, use_color);
}
@@ -138,7 +138,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec
y = rect.mBottom;
break;
}
- return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses, use_color);
+ return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, (S32)rect.getWidth(), right_x, use_ellipses, use_color);
}
@@ -406,7 +406,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
// recursively render ellipses at end of string
// we've already reserved enough room
gGL.pushUIMatrix();
- renderUTF8(std::string("..."),
+ static LLWString elipses_wstr(utf8string_to_wstring(std::string("...")));
+ render(elipses_wstr,
0,
(cur_x - origin.mV[VX]) / sScaleX, (F32)y,
color,
@@ -560,7 +561,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
void LLFontGL::generateASCIIglyphs()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
for (U32 i = 32; (i < 127); i++)
{
mFontFreetype->getGlyphInfo(i, EFontGlyphType::Grayscale);
@@ -570,7 +571,7 @@ void LLFontGL::generateASCIIglyphs()
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
if (!wchars || !wchars[0] || max_chars == 0)
{
return 0;
@@ -881,7 +882,7 @@ void LLFontGL::dumpFontTextures()
// static
bool LLFontGL::loadDefaultFonts()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
bool succ = true;
succ &= (NULL != getFontSansSerifSmall());
succ &= (NULL != getFontSansSerif());
@@ -894,7 +895,7 @@ bool LLFontGL::loadDefaultFonts()
void LLFontGL::loadCommonFonts()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
getFont(LLFontDescriptor("SansSerif", "Small", BOLD));
getFont(LLFontDescriptor("SansSerif", "Large", BOLD));
getFont(LLFontDescriptor("SansSerif", "Huge", BOLD));
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 62f4f35e3d..c48a389f6a 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -500,7 +500,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
// *HACK: Fallback fonts don't render, so we can use that to suppress
// creation of OpenGL textures for test apps. JC
bool is_fallback = !is_first_found || !mCreateGLTextures;
- F32 extra_scale = (is_fallback)?fallback_scale:1.0;
+ F32 extra_scale = (is_fallback) ? fallback_scale : 1.0f;
F32 point_size_scale = extra_scale * point_size;
bool is_font_loaded = false;
for(string_vec_t::iterator font_search_path_it = font_search_paths.begin();
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 909dad2e85..be1c0a532a 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -102,6 +102,9 @@ public:
bool mIsNVIDIA;
bool mIsIntel;
+ // hints to the render pipe
+ U32 mDownScaleMethod = 0; // see settings.xml RenderDownScaleMethod
+
#if LL_DARWIN
// Needed to distinguish problem cards on older Macs that break with Materials
bool mIsMobileGF;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 25e4a88f28..e76a30a954 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -190,7 +190,7 @@ void LLGLSLShader::dumpStats()
tris_sec /= seconds;
F32 pct_samples = (F32)((F64)mSamplesDrawn / (F64)sTotalSamplesDrawn) * 100.f;
- F32 samples_sec = (F32)mSamplesDrawn / 1000000000.0;
+ F32 samples_sec = (F32)(mSamplesDrawn / 1000000000.0);
samples_sec /= seconds;
F32 pct_binds = (F32)mBinds / (F32)sTotalBinds * 100.f;
@@ -1265,7 +1265,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1i(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f);
+ mValue[mUniform[index]] = LLVector4((F32)x, 0.f, 0.f, 0.f);
}
}
}
@@ -1405,7 +1405,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0], 0.f, 0.f, 0.f);
+ LLVector4 vec((F32)v[0], 0.f, 0.f, 0.f);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
glUniform1iv(mUniform[index], count, v);
@@ -1432,7 +1432,7 @@ void LLGLSLShader::uniform4iv(U32 index, U32 count, const GLint* v)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0], v[1], v[2], v[3]);
+ LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
glUniform1iv(mUniform[index], count, v);
@@ -1702,7 +1702,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(v, 0.f, 0.f, 0.f);
+ LLVector4 vec((F32)v, 0.f, 0.f, 0.f);
if (iter == mValue.end() || shouldChange(iter->second, vec))
{
glUniform1i(location, v);
@@ -1718,7 +1718,7 @@ void LLGLSLShader::uniform1iv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- LLVector4 vec(v[0], 0, 0, 0);
+ LLVector4 vec((F32)v[0], 0.f, 0.f, 0.f);
const auto& iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
@@ -1736,7 +1736,7 @@ void LLGLSLShader::uniform4iv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- LLVector4 vec(v[0], v[1], v[2], v[3]);
+ LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]);
const auto& iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
@@ -1755,7 +1755,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(i, j, 0.f, 0.f);
+ LLVector4 vec((F32)i, (F32)j, 0.f, 0.f);
if (iter == mValue.end() || shouldChange(iter->second, vec))
{
glUniform2i(location, i, j);
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index e614f45986..4dcca5a726 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -351,20 +351,6 @@ void LLGLTexture::forceUpdateBindStats(void) const
return mGLTexturep->forceUpdateBindStats() ;
}
-U32 LLGLTexture::getTexelsInAtlas() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTexelsInAtlas() ;
-}
-
-U32 LLGLTexture::getTexelsInGLTexture() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getTexelsInGLTexture() ;
-}
-
bool LLGLTexture::isGLTextureCreated() const
{
llassert(mGLTexturep.notNull()) ;
@@ -372,13 +358,6 @@ bool LLGLTexture::isGLTextureCreated() const
return mGLTexturep->isGLTextureCreated() ;
}
-S32 LLGLTexture::getDiscardLevelInAtlas() const
-{
- llassert(mGLTexturep.notNull()) ;
-
- return mGLTexturep->getDiscardLevelInAtlas() ;
-}
-
void LLGLTexture::destroyGLTexture()
{
if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 0901243f8f..a7de20dc5c 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -51,10 +51,10 @@ public:
BOOST_NONE = 0,
BOOST_AVATAR ,
BOOST_AVATAR_BAKED ,
- BOOST_SCULPTED ,
BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead.
BOOST_HIGH = 10,
+ BOOST_SCULPTED ,
BOOST_BUMP ,
BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug
BOOST_SELECTED ,
@@ -75,7 +75,6 @@ public:
AVATAR_SCRATCH_TEX,
DYNAMIC_TEX,
MEDIA,
- ATLAS,
OTHER,
MAX_GL_IMAGE_CATEGORY
};
@@ -156,10 +155,7 @@ public:
bool isJustBound()const ;
void forceUpdateBindStats(void) const;
- U32 getTexelsInAtlas() const ;
- U32 getTexelsInGLTexture() const ;
bool isGLTextureCreated() const ;
- S32 getDiscardLevelInAtlas() const ;
LLGLTextureState getTextureState() const { return mTextureState; }
//---------------------------------------------------------------------------------------------
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 7e5cd628c1..058afa0cf2 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -41,6 +41,7 @@
#include "llrender.h"
#include "llwindow.h"
#include "llframetimer.h"
+#include
extern LL_COMMON_API bool on_main_thread();
@@ -56,6 +57,9 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f;
U32 wpo2(U32 i);
+U32 LLImageGL::sFrameCount = 0;
+
+
// texture memory accounting (for macOS)
static LLMutex sTexMemMutex;
static std::unordered_map sTextureAllocs;
@@ -130,10 +134,9 @@ S32 LLImageGL::sCount = 0;
bool LLImageGL::sGlobalUseAnisotropic = false;
F32 LLImageGL::sLastFrameTime = 0.f;
-bool LLImageGL::sAllowReadBackRaw = false ;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
bool LLImageGL::sCompressTextures = false;
-std::set LLImageGL::sImageList;
+std::unordered_set LLImageGL::sImageList;
bool LLImageGLThread::sEnabledTextures = false;
@@ -150,6 +153,9 @@ S32 LLImageGL::sMaxCategories = 1 ;
//optimization for when we don't need to calculate mIsMask
bool LLImageGL::sSkipAnalyzeAlpha;
+U32 LLImageGL::sScratchPBO = 0;
+U32 LLImageGL::sScratchPBOSize = 0;
+
//------------------------
//****************************************************************************************************
@@ -159,20 +165,6 @@ bool LLImageGL::sSkipAnalyzeAlpha;
//**************************************************************************************
//below are functions for debug use
//do not delete them even though they are not currently being used.
-void check_all_images()
-{
- for (std::set::iterator iter = LLImageGL::sImageList.begin();
- iter != LLImageGL::sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if (glimage->getTexName() && glimage->isGLTextureCreated())
- {
- gGL.getTexUnit(0)->bind(glimage) ;
- glimage->checkTexSize() ;
- gGL.getTexUnit(0)->unbind(glimage->getTarget()) ;
- }
- }
-}
void LLImageGL::checkTexSize(bool forced) const
{
@@ -252,6 +244,11 @@ void LLImageGL::initClass(LLWindow* window, S32 num_catagories, bool skip_analyz
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
sSkipAnalyzeAlpha = skip_analyze_alpha;
+ if (sScratchPBO == 0)
+ {
+ glGenBuffers(1, &sScratchPBO);
+ }
+
if (thread_texture_loads || thread_media_updates)
{
LLImageGLThread::createInstance(window);
@@ -265,6 +262,12 @@ void LLImageGL::cleanupClass()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLImageGLThread::deleteSingleton();
+ if (sScratchPBO != 0)
+ {
+ glDeleteBuffers(1, &sScratchPBO);
+ sScratchPBO = 0;
+ sScratchPBOSize = 0;
+ }
}
@@ -360,66 +363,19 @@ void LLImageGL::updateStats(F32 current_time)
//----------------------------------------------------------------------------
//static
-void LLImageGL::destroyGL(bool save_state)
+void LLImageGL::destroyGL()
{
for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++)
{
gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
}
-
- sAllowReadBackRaw = true ;
- for (std::set::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if (glimage->mTexName)
- {
- if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
- {
- glimage->mSaveData = new LLImageRaw;
- if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
- {
- glimage->mSaveData = NULL ;
- }
- }
-
- glimage->destroyGLTexture();
- stop_glerror();
- }
- }
- sAllowReadBackRaw = false ;
-}
-
-//static
-void LLImageGL::restoreGL()
-{
- for (std::set::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if(glimage->getTexName())
- {
- LL_ERRS() << "tex name is not 0." << LL_ENDL ;
- }
- if (glimage->mSaveData.notNull())
- {
- if (glimage->getComponents() && glimage->mSaveData->getComponents())
- {
- glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, true, glimage->getCategory());
- stop_glerror();
- }
- glimage->mSaveData = NULL; // deletes data
- }
- }
}
//static
void LLImageGL::dirtyTexOptions()
{
- for (std::set::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
+ for (auto& glimage : sImageList)
{
- LLImageGL* glimage = *iter;
glimage->mTexOptionsDirty = true;
stop_glerror();
}
@@ -542,10 +498,6 @@ void LLImageGL::init(bool usemipmaps)
mHeight = 0;
mCurrentDiscardLevel = -1;
- mDiscardLevelInAtlas = -1 ;
- mTexelsInAtlas = 0 ;
- mTexelsInGLTexture = 0 ;
-
mAllowCompression = true;
mTarget = GL_TEXTURE_2D;
@@ -622,9 +574,6 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
return false;
}
- // pickmask validity depends on old image size, delete it
- freePickMask();
-
mWidth = width;
mHeight = height;
mComponents = ncomponents;
@@ -789,7 +738,7 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
}
if (is_compressed)
{
- S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
+ GLsizei tex_size = (GLsizei)dataFormatBytes(mFormatPrimary, w, h);
glCompressedTexImage2D(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
@@ -992,7 +941,7 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
S32 h = getHeight();
if (is_compressed)
{
- S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
+ GLsizei tex_size = (GLsizei)dataFormatBytes(mFormatPrimary, w, h);
glCompressedTexImage2D(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
@@ -1025,98 +974,6 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
return true;
}
-bool LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
-{
- //not compatible with core GL profile
- llassert(!LLRender::sGLCoreProfile);
-
- if (gGLManager.mIsDisabled)
- {
- LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
- return false;
- }
- llassert(gGLManager.mInited);
- stop_glerror();
-
- if (discard_level < 0)
- {
- llassert(mCurrentDiscardLevel >= 0);
- discard_level = mCurrentDiscardLevel;
- }
-
- // Actual image width/height = raw image width/height * 2^discard_level
- S32 w = raw_image->getWidth() << discard_level;
- S32 h = raw_image->getHeight() << discard_level;
-
- // setSize may call destroyGLTexture if the size does not match
- if (!setSize(w, h, raw_image->getComponents(), discard_level))
- {
- LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
- return false;
- }
-
- if (!mHasExplicitFormat)
- {
- switch (mComponents)
- {
- case 1:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8;
- mFormatPrimary = GL_LUMINANCE;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 2:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8_ALPHA8;
- mFormatPrimary = GL_LUMINANCE_ALPHA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 3:
- mFormatInternal = GL_RGB8;
- mFormatPrimary = GL_RGB;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 4:
- mFormatInternal = GL_RGBA8;
- mFormatPrimary = GL_RGBA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- default:
- LL_ERRS() << "Bad number of components for texture: " << (U32) getComponents() << LL_ENDL;
- }
- }
-
- mCurrentDiscardLevel = discard_level;
- mDiscardLevelInAtlas = discard_level;
- mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
- mLastBindTime = sLastFrameTime;
- mGLTextureCreated = false ;
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth());
- stop_glerror();
-
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
-
- return true ;
-}
-
-void LLImageGL::postAddToAtlas()
-{
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
- stop_glerror();
-}
-
U32 type_width_from_pixtype(U32 pixtype)
{
U32 type_width = 0;
@@ -1149,7 +1006,7 @@ bool should_stagger_image_set(bool compressed)
#else
// glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08
// Setting media textures off-thread seems faster when not using sub_image_lines (Nvidia/Windows 10) -Cosmic,2023-03-31
- return !compressed && on_main_thread();
+ return !compressed && on_main_thread() && !gGLManager.mIsIntel;
#endif
}
@@ -1331,13 +1188,37 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
}
}
+// static
+void LLImageGL::updateClass()
+{
+ sFrameCount++;
+}
+
// static
void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)
{
+ // wait a few frames before actually deleting the textures to avoid
+ // synchronization issues with the GPU
+ static std::vector sFreeList[4];
+
if (gGLManager.mInited)
{
- free_tex_images(numTextures, textures);
- glDeleteTextures(numTextures, textures);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ U32 idx = sFrameCount % 4;
+
+ for (S32 i = 0; i < numTextures; ++i)
+ {
+ sFreeList[idx].push_back(textures[i]);
+ }
+
+ idx = (sFrameCount + 3) % 4;
+
+ if (!sFreeList[idx].empty())
+ {
+ glDeleteTextures((GLsizei) sFreeList[idx].size(), sFreeList[idx].data());
+ free_tex_images((GLsizei) sFreeList[idx].size(), sFreeList[idx].data());
+ sFreeList[idx].resize(0);
+ }
}
}
@@ -1752,7 +1633,6 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_
mTextureMemory = (S64Bytes)getMipBytes(mCurrentDiscardLevel);
- mTexelsInGLTexture = getWidth() * getHeight();
// mark this as bound at this point, so we don't throw it out immediately
mLastBindTime = sLastFrameTime;
@@ -1830,8 +1710,7 @@ void LLImageGL::syncTexName(LLGLuint texname)
bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
{
- llassert_always(sAllowReadBackRaw) ;
- //LL_ERRS() << "should not call this function!" << LL_ENDL ;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (discard_level < 0)
{
@@ -2297,6 +2176,8 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
//----------------------------------------------------------------------------
U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ freePickMask();
U32 pick_width = pWidth/2 + 1;
U32 pick_height = pHeight/2 + 1;
@@ -2314,7 +2195,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
//----------------------------------------------------------------------------
void LLImageGL::freePickMask()
{
- // pickmask validity depends on old image size, delete it
if (mPickMask != NULL)
{
delete [] mPickMask;
@@ -2352,16 +2232,16 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
return ;
}
- freePickMask();
-
if (mFormatType != GL_UNSIGNED_BYTE ||
((mFormatPrimary != GL_RGBA)
&& (mFormatPrimary != GL_SRGB_ALPHA)))
{
//cannot generate a pick mask for this texture
+ freePickMask();
return;
}
+
#ifdef SHOW_ASSERT
const U32 pickSize = createPickMask(width, height);
#else // SHOW_ASSERT
@@ -2460,6 +2340,114 @@ void LLImageGL::resetCurTexSizebar()
sCurTexSizeBar = -1 ;
sCurTexPickSize = -1 ;
}
+
+bool LLImageGL::scaleDown(S32 desired_discard)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+
+ if (mTarget != GL_TEXTURE_2D)
+ {
+ return false;
+ }
+
+ desired_discard = llmin(desired_discard, mMaxDiscardLevel);
+
+ if (desired_discard <= mCurrentDiscardLevel)
+ {
+ return false;
+ }
+
+ S32 mip = desired_discard - mCurrentDiscardLevel;
+
+ S32 desired_width = getWidth(desired_discard);
+ S32 desired_height = getHeight(desired_discard);
+
+ if (gGLManager.mDownScaleMethod == 0)
+ { // use an FBO to downscale the texture
+ // allocate new texture
+ U32 temp_texname = 0;
+ generateTextures(1, &temp_texname);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, temp_texname, true);
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glTexImage2D");
+ glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, NULL);
+ }
+
+ // account for new texture getting created
+ alloc_tex_image(desired_width, desired_height, mFormatPrimary);
+
+ // Use render-to-texture to scale down the texture
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glFramebufferTexture2D");
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTarget, temp_texname, 0);
+ }
+
+ glViewport(0, 0, desired_width, desired_height);
+
+ // draw a full screen triangle
+ gGL.getTexUnit(0)->bind(this);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // delete old texture and assign new texture name
+ deleteTextures(1, &mTexName);
+ mTexName = temp_texname;
+
+ if (mHasMipMaps)
+ { // generate mipmaps if needed
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
+ gGL.getTexUnit(0)->bind(this);
+ glGenerateMipmap(mTarget);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ else
+ { // use a PBO to downscale the texture
+ U64 size = getBytes(desired_discard);
+ llassert(size <= 2048 * 2048 * 4); // we shouldn't be using this method to downscale huge textures, but it'll work
+ gGL.getTexUnit(0)->bind(this);
+
+ if (sScratchPBO == 0)
+ {
+ glGenBuffers(1, &sScratchPBO);
+ sScratchPBOSize = 0;
+ }
+
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, sScratchPBO);
+
+ if (size > sScratchPBOSize)
+ {
+ glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY);
+ sScratchPBOSize = (U32)size;
+ }
+
+ glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr);
+
+ free_tex_image(mTexName);
+
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sScratchPBO);
+ glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+
+ alloc_tex_image(desired_width, desired_height, mFormatPrimary);
+
+ if (mHasMipMaps)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
+ glGenerateMipmap(mTarget);
+ }
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+
+ mCurrentDiscardLevel = desired_discard;
+
+ return true;
+}
+
+
//----------------------------------------------------------------------------
#if LL_IMAGEGL_THREAD_CHECK
void LLImageGL::checkActiveThread()
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 5c7a5ce821..5073701c30 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -39,6 +39,7 @@
#include "llrender.h"
#include "threadpool.h"
#include "workqueue.h"
+#include
#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL
@@ -61,6 +62,9 @@ class LLImageGL : public LLRefCount
friend class LLTexUnit;
public:
+ // call once per frame
+ static void updateClass();
+
// Get an estimate of how many bytes have been allocated in vram for textures.
// Does not include mipmaps.
// NOTE: multiplying this number by two gives a good estimate for total
@@ -83,9 +87,8 @@ public:
// needs to be called every frame
static void updateStats(F32 current_time);
- // Save off / restore GL textures
- static void destroyGL(bool save_state = true);
- static void restoreGL();
+ // cleanup GL state
+ static void destroyGL();
static void dirtyTexOptions();
static bool checkSize(S32 width, S32 height);
@@ -148,6 +151,10 @@ public:
S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
+ // override the current discard level
+ // should only be used for local textures where you know exactly what you're doing
+ void setDiscardLevel(S32 level) { mCurrentDiscardLevel = level; }
+
S32 getCurrentWidth() const { return mWidth ;}
S32 getCurrentHeight() const { return mHeight ;}
S32 getWidth(S32 discard_level = -1) const;
@@ -194,26 +201,26 @@ public:
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; }
- LLGLenum getTexTarget()const { return mTarget ;}
- S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;}
- U32 getTexelsInAtlas()const { return mTexelsInAtlas ;}
- U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;}
-
+ LLGLenum getTexTarget()const { return mTarget; }
void init(bool usemipmaps);
virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
void setNeedsAlphaAndPickMask(bool need_mask);
- bool preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);
- void postAddToAtlas() ;
-
#if LL_IMAGEGL_THREAD_CHECK
// thread debugging
std::thread::id mActiveThread;
void checkActiveThread();
#endif
+ // scale down to the desired discard level using GPU
+ // returns true if texture was scaled down
+ // desired discard will be clamped to max discard
+ // if desired discard is less than or equal to current discard, no scaling will occur
+ // only works for GL_TEXTURE_2D target
+ bool scaleDown(S32 desired_discard);
+
public:
// Various GL/Rendering options
S64Bytes mTextureMemory;
@@ -240,15 +247,10 @@ private:
bool mGLTextureCreated ;
LLGLuint mTexName;
- //LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
U16 mWidth;
U16 mHeight;
S8 mCurrentDiscardLevel;
- S8 mDiscardLevelInAtlas;
- U32 mTexelsInAtlas ;
- U32 mTexelsInGLTexture;
-
bool mAllowCompression;
protected:
@@ -275,9 +277,9 @@ protected:
// STATICS
public:
- static std::set sImageList;
+ static std::unordered_set sImageList;
static S32 sCount;
-
+ static U32 sFrameCount;
static F32 sLastFrameTime;
// Global memory statistics
@@ -301,6 +303,8 @@ public:
private:
static S32 sMaxCategories;
static bool sSkipAnalyzeAlpha;
+ static U32 sScratchPBO;
+ static U32 sScratchPBOSize;
//the flag to allow to call readBackRaw(...).
//can be removed if we do not use that function at all.
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index 8ebd09f20d..eef7193c92 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -343,7 +343,7 @@ void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadIdentity();
- gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
+ gGL.ortho( 0.f, (GLfloat) width , (GLfloat) height , 0.f, -1.f, 1.f );
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
gGL.loadIdentity();
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index a0209fab43..1301d325a0 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1514,7 +1514,7 @@ LLLightState* LLRender::getLight(U32 index)
void LLRender::setAmbientLightColor(const LLColor4& color)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
if (color != mAmbientLightColor)
{
++mLightHash;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index be9f3895e7..010ab122b6 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -293,11 +293,18 @@ public:
enum eTexIndex : U8
{
- DIFFUSE_MAP = 0,
- ALTERNATE_DIFFUSE_MAP = 1,
- NORMAL_MAP = 1,
- SPECULAR_MAP = 2,
- NUM_TEXTURE_CHANNELS = 3,
+ // Channels for material textures
+ DIFFUSE_MAP = 0,
+ ALTERNATE_DIFFUSE_MAP = 1,
+ NORMAL_MAP = 1,
+ SPECULAR_MAP = 2,
+ // Channels for PBR textures
+ BASECOLOR_MAP = 3,
+ METALLIC_ROUGHNESS_MAP = 4,
+ GLTF_NORMAL_MAP = 5,
+ EMISSIVE_MAP = 6,
+ // Total number of channels
+ NUM_TEXTURE_CHANNELS = 7,
};
enum eVolumeTexIndex : U8
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index ef02fbd071..428370057e 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -364,7 +364,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
{
// add in offset of current image to current UI translation
const LLVector3 ui_scale = gGL.getUIScale();
- const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
+ const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3((F32)x, (F32)y, 0.f)).scaledVec(ui_scale);
F32 uv_width = uv_outer_rect.getWidth();
F32 uv_height = uv_outer_rect.getHeight();
@@ -375,8 +375,8 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
- F32 image_width = image->getWidth(0);
- F32 image_height = image->getHeight(0);
+ F32 image_width = (F32)image->getWidth(0);
+ F32 image_height = (F32)image->getHeight(0);
S32 image_natural_width = ll_round(image_width * uv_width);
S32 image_natural_height = ll_round(image_height * uv_height);
@@ -413,10 +413,10 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
draw_center_rect.setCenterAndSize(uv_center_rect.getCenterX() * width, uv_center_rect.getCenterY() * height, scaled_width, scaled_height);
}
- draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]);
- draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]);
- draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]);
- draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]);
+ draw_center_rect.mLeft = (F32)ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]);
+ draw_center_rect.mTop = (F32)ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]);
+ draw_center_rect.mRight = (F32)ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]);
+ draw_center_rect.mBottom = (F32)ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]);
LLRectf draw_outer_rect(ui_translation.mV[VX],
ui_translation.mV[VY] + height * ui_scale.mV[VY],
@@ -726,7 +726,7 @@ void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& c
}
gGL.end();
- LLRender2D::getInstance()->setLineWidth(1.f);
+ LLRender2D::setLineWidth(1.f);
}
void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, bool filled, F32 start_angle, F32 end_angle)
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
index 0d3efc38d6..096e7584f1 100644
--- a/indra/llrender/llrender2dutils.h
+++ b/indra/llrender/llrender2dutils.h
@@ -122,12 +122,13 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, bool
class LLImageProviderInterface;
-class LLRender2D : public LLParamSingleton
+class LLRender2D : public LLSimpleton
{
- LLSINGLETON(LLRender2D, LLImageProviderInterface* image_provider);
LOG_CLASS(LLRender2D);
- ~LLRender2D();
public:
+ LLRender2D(LLImageProviderInterface* image_provider);
+ ~LLRender2D();
+
static void pushMatrix();
static void popMatrix();
static void loadIdentity();
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index efdde77a32..f700201ace 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -123,7 +123,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT
if (mGenerateMipMaps != LLTexUnit::TMG_NONE) {
// Calculate the number of mip levels based upon resolution that we should have.
- mMipLevels = 1 + floor(log10((float)llmax(mResX, mResY))/log10(2.0));
+ mMipLevels = 1 + (U32)floor(log10((float)llmax(mResX, mResY)) / log10(2.0));
}
if (depth)
@@ -426,14 +426,17 @@ void LLRenderTarget::bindTarget()
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
- glDrawBuffers(static_cast(mTex.size()), drawbuffers);
if (mTex.empty())
{ //no color buffer to draw to
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
-
+ else
+ {
+ glDrawBuffers(static_cast(mTex.size()), drawbuffers);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ }
check_framebuffer_status();
glViewport(0, 0, mResX, mResY);
@@ -519,7 +522,8 @@ void LLRenderTarget::flush()
llassert(sCurFBO == mFBO);
llassert(sBoundTarget == this);
- if (mGenerateMipMaps == LLTexUnit::TMG_AUTO) {
+ if (mGenerateMipMaps == LLTexUnit::TMG_AUTO)
+ {
LL_PROFILE_GPU_ZONE("rt generate mipmaps");
bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
@@ -540,6 +544,8 @@ void LLRenderTarget::flush()
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
sCurResX = gGLViewport[2];
sCurResY = gGLViewport[3];
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_BACK);
}
}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 340276a752..cd3290cf66 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -61,7 +61,7 @@
class LLRenderTarget
{
public:
- //whether or not to use FBO implementation
+ // Whether or not to use FBO implementation
static bool sUseFBO;
static U32 sBytesAllocated;
static U32 sCurFBO;
@@ -172,6 +172,8 @@ public:
// *HACK
void swapFBORefs(LLRenderTarget& other);
+ static LLRenderTarget* sBoundTarget;
+
protected:
U32 mResX;
U32 mResY;
@@ -186,8 +188,6 @@ protected:
U32 mMipLevels;
LLTexUnit::eTextureType mUsage;
-
- static LLRenderTarget* sBoundTarget;
};
#endif
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index a8e9f20b40..bc542d325e 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -44,7 +44,6 @@ using std::make_pair;
using std::string;
LLShaderMgr * LLShaderMgr::sInstance = NULL;
-bool LLShaderMgr::sMirrorsEnabled = false;
LLShaderMgr::LLShaderMgr()
{
@@ -600,11 +599,6 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
}
- if (sMirrorsEnabled)
- {
- extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n");
- }
-
// Use alpha float to store bit flags
// See: C++: addDeferredAttachment(), shader: frag_data[2]
extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill
@@ -1003,7 +997,7 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
ProgramBinaryData binary_info = ProgramBinaryData();
binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger();
binary_info.mBinaryLength = data_pair.second["binary_size"].asInteger();
- binary_info.mLastUsedTime = data_pair.second["last_used"].asReal();
+ binary_info.mLastUsedTime = (F32)data_pair.second["last_used"].asReal();
mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info);
}
}
@@ -1034,7 +1028,7 @@ void LLShaderMgr::persistShaderCacheMetadata()
LLSD out = LLSD::emptyMap();
static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days
- const F32 current_time = LLTimer::getTotalSeconds();
+ const F32 current_time = (F32)LLTimer::getTotalSeconds();
for (auto it = mShaderBinaryCache.begin(); it != mShaderBinaryCache.end();)
{
const ProgramBinaryData& shader_metadata = it->second;
@@ -1093,7 +1087,7 @@ bool LLShaderMgr::loadCachedProgramBinary(LLGLSLShader* shader)
glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success);
if (error == GL_NO_ERROR && success == GL_TRUE)
{
- binary_iter->second.mLastUsedTime = LLTimer::getTotalSeconds();
+ binary_iter->second.mLastUsedTime = (F32)LLTimer::getTotalSeconds();
LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL;
return true;
}
@@ -1131,7 +1125,7 @@ bool LLShaderMgr::saveCachedProgramBinary(LLGLSLShader* shader)
fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile);
outfile.close();
- binary_info.mLastUsedTime = LLTimer::getTotalSeconds();
+ binary_info.mLastUsedTime = (F32)LLTimer::getTotalSeconds();
mShaderBinaryCache.insert_or_assign(shader->mShaderHash, binary_info);
return true;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index fe6137c448..921ef20997 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -378,7 +378,6 @@ public:
bool mShaderCacheInitialized = false;
bool mShaderCacheEnabled = false;
std::string mShaderCacheDir;
- static bool sMirrorsEnabled;
protected:
diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp
index bcf665ca18..dc18bf16bf 100644
--- a/indra/llrender/lluiimage.cpp
+++ b/indra/llrender/lluiimage.cpp
@@ -81,10 +81,10 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
}
}
- LLRender2D::getInstance()->pushMatrix();
+ LLRender2D::pushMatrix();
{
- LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
- LLRender2D::getInstance()->translate(rect_origin.mV[VX],
+ LLVector3 rect_origin = origin_agent + ((F32)rect.mLeft * x_axis) + ((F32)rect.mBottom * y_axis);
+ LLRender2D::translate(rect_origin.mV[VX],
rect_origin.mV[VY],
rect_origin.mV[VZ]);
gGL.getTexUnit(0)->bind(getImage());
@@ -100,10 +100,10 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
(rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
(rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
(border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
- rect.getWidth() * x_axis,
- rect.getHeight() * y_axis);
+ (F32)rect.getWidth() * x_axis,
+ (F32)rect.getHeight() * y_axis);
- } LLRender2D::getInstance()->popMatrix();
+ } LLRender2D::popMatrix();
}
//#include "lluiimage.inl"
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 2eb7c21f77..02afcf12c6 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -794,6 +794,18 @@ void LLVertexBuffer::setLabel(const char* label) {
}
#endif
+void LLVertexBuffer::clone(LLVertexBuffer& target) const
+{
+ target.mTypeMask = mTypeMask;
+ target.mIndicesType = mIndicesType;
+ target.mIndicesStride = mIndicesStride;
+ if (target.getNumVerts() != getNumVerts() ||
+ target.getNumIndices() != getNumIndices())
+ {
+ target.allocateBuffer(getNumVerts(), getNumIndices());
+ }
+}
+
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{
llassert(validateRange(start, end, count, indices_offset));
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 49500e28ce..4ada0c335b 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -163,13 +163,13 @@ public:
// set for rendering
// assumes (and will assert on) the following:
- // - this buffer has no pending unampBuffer call
+ // - this buffer has no pending unmapBuffer call
// - a shader is currently bound
// - This buffer has sufficient attributes within it to satisfy the needs of the currently bound shader
void setBuffer();
// Only call each getVertexPointer, etc, once before calling unmapBuffer()
- // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
+ // call unmapBuffer() after calls to getXXXStrider() before any calls to setBuffer()
// example:
// vb->getVertexBuffer(verts);
// vb->getNormalStrider(norms);
@@ -218,12 +218,12 @@ public:
U32 getNumIndices() const { return mNumIndices; }
U32 getTypeMask() const { return mTypeMask; }
- bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); }
+ bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); }
U32 getSize() const { return mSize; }
U32 getIndicesSize() const { return mIndicesSize; }
U8* getMappedData() const { return mMappedData; }
U8* getMappedIndices() const { return mMappedIndexData; }
- U32 getOffset(AttributeType type) const { return mOffsets[type]; }
+ U32 getOffset(AttributeType type) const { return mOffsets[type]; }
// these functions assume (and assert on) the current VBO being bound
// Detailed error checking can be enabled by setting gDebugGL to true
@@ -242,6 +242,7 @@ public:
void setLabel(const char* label);
#endif
+ void clone(LLVertexBuffer& target) const;
protected:
U32 mGLBuffer = 0; // GL VBO handle
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 4682044d6e..06f7a20add 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -379,12 +379,10 @@ void LLAccordionCtrl::initNoTabsWidget(const LLTextBox::Params& tb_params)
void LLAccordionCtrl::updateNoTabsHelpTextVisibility()
{
- bool visible_exists = false;
- std::vector::const_iterator it = mAccordionTabs.begin();
- const std::vector::const_iterator it_end = mAccordionTabs.end();
- while (it < it_end)
+ bool visible_exists{ false };
+ for (auto accordion_tab : mAccordionTabs)
{
- if ((*(it++))->getVisible())
+ if (accordion_tab->getVisible())
{
visible_exists = true;
break;
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 6d58a2545c..ac66525030 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -602,15 +602,13 @@ void LLAccordionCtrlTab::setSelected(bool is_selected)
LLView* LLAccordionCtrlTab::findContainerView()
{
- child_list_const_iter_t it = getChildList()->begin(), it_end = getChildList()->end();
- while (it != it_end)
+ for (auto child : *getChildList())
{
- LLView* child = *(it++);
if (DD_HEADER_NAME != child->getName() && child->getVisible())
return child;
}
- return NULL;
+ return nullptr;
}
void LLAccordionCtrlTab::selectOnFocusReceived()
diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp
index 3397c97ee1..399f79ad2e 100644
--- a/indra/llui/llbadge.cpp
+++ b/indra/llui/llbadge.cpp
@@ -36,7 +36,7 @@ static LLDefaultChildRegistry::Register r("badge");
static const S32 BADGE_OFFSET_NOT_SPECIFIED = 0x7FFFFFFF;
// Compiler optimization, generate extern template
-template class LLBadge* LLView::getChild(const std::string& name, bool recurse) const;
+template class LLBadge* LLView::getChild(std::string_view name, bool recurse) const;
LLBadge::Params::Params()
@@ -197,10 +197,10 @@ void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, cons
F32 x = LLFontGL::sCurOrigin.mX + centerX - width * 0.5f;
F32 y = LLFontGL::sCurOrigin.mY + centerY - height * 0.5f;
- LLRectf screen_rect(ll_round(x),
- ll_round(y),
- ll_round(x) + width,
- ll_round(y) + height);
+ LLRectf screen_rect((F32)ll_round(x),
+ (F32)ll_round(y),
+ (F32)ll_round(x) + width,
+ (F32)ll_round(y) + height);
LLVector3 vertices[4];
vertices[0] = LLVector3(screen_rect.mRight, screen_rect.mTop, 1.0f);
@@ -231,8 +231,6 @@ void LLBadge::draw()
// Calculate badge size based on label text
//
- LLWString badge_label_wstring = mLabel;
-
S32 badge_label_begin_offset = 0;
S32 badge_char_length = S32_MAX;
S32 badge_pixel_length = S32_MAX;
@@ -240,7 +238,7 @@ void LLBadge::draw()
bool do_not_use_ellipses = false;
F32 badge_width = (2.0f * mPaddingHoriz) +
- mGLFont->getWidthF32(badge_label_wstring.c_str(), badge_label_begin_offset, badge_char_length);
+ mGLFont->getWidthF32(mLabel.getWString().c_str(), badge_label_begin_offset, badge_char_length);
F32 badge_height = (2.0f * mPaddingVert) + mGLFont->getLineHeight();
@@ -302,7 +300,7 @@ void LLBadge::draw()
}
else
{
- badge_center_x = location_offset_horiz;
+ badge_center_x = (F32)location_offset_horiz;
}
// Compute y position
@@ -319,7 +317,7 @@ void LLBadge::draw()
}
else
{
- badge_center_y = location_offset_vert;
+ badge_center_y = (F32)location_offset_vert;
}
//
@@ -354,7 +352,7 @@ void LLBadge::draw()
// Draw the label
//
- mGLFont->render(badge_label_wstring,
+ mGLFont->render(mLabel.getWString(),
badge_label_begin_offset,
badge_center_x + mLabelOffsetHoriz,
badge_center_y + mLabelOffsetVert,
diff --git a/indra/llui/llbadge.h b/indra/llui/llbadge.h
index a6d584c6d7..77fe76f0da 100644
--- a/indra/llui/llbadge.h
+++ b/indra/llui/llbadge.h
@@ -171,7 +171,7 @@ private:
// Build time optimization, generate once in .cpp file
#ifndef LLBADGE_CPP
-extern template class LLBadge* LLView::getChild(const std::string& name, bool recurse) const;
+extern template class LLBadge* LLView::getChild(std::string_view name, bool recurse) const;
#endif
#endif // LL_LLBADGE_H
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index e6c045250e..30968225a8 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -56,7 +56,7 @@ static LLDefaultChildRegistry::Register r("button");
// Compiler optimization, generate extern template
template class LLButton* LLView::getChild(
- const std::string& name, bool recurse) const;
+ std::string_view name, bool recurse) const;
// globals
S32 LLBUTTON_H_PAD = 4;
@@ -188,7 +188,7 @@ LLButton::LLButton(const LLButton::Params& p)
// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
- F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
+ F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0f;
mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
}
else
@@ -796,9 +796,6 @@ void LLButton::draw()
if( ll::ui::SearchableControl::getHighlighted() )
label_color = ll::ui::SearchableControl::getHighlightColor();
- // Unselected label assignments
- LLWString label = getCurrentLabel();
-
// overlay with keyboard focus border
if (hasFocus())
{
@@ -927,8 +924,9 @@ void LLButton::draw()
}
// Draw label
- if( !label.empty() )
+ if( !getCurrentLabel().empty() ) // Unselected label assignments
{
+ LLWString label = getCurrentLabel();
LLWStringUtil::trim(label);
S32 x;
@@ -1082,10 +1080,10 @@ void LLButton::autoResize()
resize(getCurrentLabel());
}
-void LLButton::resize(LLUIString label)
+void LLButton::resize(const LLUIString& label)
{
// get label length
- S32 label_width = mGLFont->getWidth(label.getString());
+ S32 label_width = mGLFont->getWidth(label.getWString().c_str());
// get current btn length
S32 btn_width =getRect().getWidth();
// check if it need resize
@@ -1129,12 +1127,12 @@ void LLButton::setImageSelected(LLPointer image)
mImageSelected = image;
}
-void LLButton::setImageColor(const LLColor4& c)
+void LLButton::setImageColor(const LLUIColor& c)
{
mImageColor = c;
}
-void LLButton::setColor(const LLColor4& color)
+void LLButton::setColor(const LLUIColor& color)
{
setImageColor(color);
}
@@ -1273,7 +1271,7 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
// Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
// Set the clicked callback to toggle the floater
- button->setClickedCallback(boost::bind(&LLFloaterReg::toggleInstance, sdname, LLSD()));
+ button->setClickedCallback([=](LLUICtrl* ctrl, const LLSD& param) -> void { LLFloaterReg::toggleInstance(sdname.asString(), LLSD()); });
}
// static
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index fed5cdcc50..4ecea6d473 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -172,8 +172,8 @@ public:
virtual void onCommit();
- void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; }
- void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; }
+ void setUnselectedLabelColor( const LLUIColor& c ) { mUnselectedLabelColor = c; }
+ void setSelectedLabelColor( const LLUIColor& c ) { mSelectedLabelColor = c; }
void setUseEllipses( bool use_ellipses ) { mUseEllipses = use_ellipses; }
void setUseFontColor( bool use_font_color) { mUseFontColor = use_font_color; }
@@ -224,14 +224,14 @@ public:
const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); }
void setImageColor(const std::string& color_control);
- void setImageColor(const LLColor4& c);
- /*virtual*/ void setColor(const LLColor4& c);
+ void setImageColor(const LLUIColor& c);
+ /*virtual*/ void setColor(const LLUIColor& c);
void setImages(const std::string &image_name, const std::string &selected_name);
- void setDisabledImageColor(const LLColor4& c) { mDisabledImageColor = c; }
+ void setDisabledImageColor(const LLUIColor& c) { mDisabledImageColor = c; }
- void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
+ void setDisabledSelectedLabelColor( const LLUIColor& c ) { mDisabledSelectedLabelColor = c; }
void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
void setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
@@ -239,14 +239,14 @@ public:
LLFontGL::HAlign getImageOverlayHAlign() const { return mImageOverlayAlignment; }
void autoResize(); // resize with label of current btn state
- void resize(LLUIString label); // resize with label input
+ void resize(const LLUIString& label); // resize with label input
void setLabel(const std::string& label);
void setLabel(const LLUIString& label);
void setLabel( const LLStringExplicit& label);
virtual bool setLabelArg( const std::string& key, const LLStringExplicit& text );
void setLabelUnselected(const LLStringExplicit& label);
void setLabelSelected(const LLStringExplicit& label);
- void setDisabledLabelColor( const LLColor4& c ) { mDisabledLabelColor = c; }
+ void setDisabledLabelColor( const LLUIColor& c ) { mDisabledLabelColor = c; }
void setFont(const LLFontGL *font)
{ mGLFont = ( font ? font : LLFontGL::getFontSansSerif()); }
@@ -400,7 +400,7 @@ protected:
// Build time optimization, generate once in .cpp file
#ifndef LLBUTTON_CPP
extern template class LLButton* LLView::getChild(
- const std::string& name, bool recurse) const;
+ std::string_view name, bool recurse) const;
#endif
#endif // LL_LLBUTTON_H
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 3bcf0a6517..fc751cfc7f 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -45,7 +45,7 @@ static LLDefaultChildRegistry::Register r("check_box");
// Compiler optimization, generate extern template
template class LLCheckBoxCtrl* LLView::getChild(
- const std::string& name, bool recurse) const;
+ std::string_view name, bool recurse) const;
void LLCheckBoxCtrl::WordWrap::declareValues()
{
@@ -172,11 +172,11 @@ void LLCheckBoxCtrl::setEnabled(bool b)
if (b)
{
- mLabel->setColor( mTextEnabledColor.get() );
+ mLabel->setColor( mTextEnabledColor );
}
else
{
- mLabel->setColor( mTextDisabledColor.get() );
+ mLabel->setColor( mTextDisabledColor );
}
}
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 3058e946c3..135f128692 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -110,8 +110,8 @@ public:
void setBtnFocus() { mButton->setFocus(true); }
- void setEnabledColor( const LLColor4 &color ) { mTextEnabledColor = color; }
- void setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; }
+ void setEnabledColor( const LLUIColor&color ) { mTextEnabledColor = color; }
+ void setDisabledColor( const LLUIColor&color ) { mTextDisabledColor = color; }
void setLabel( const LLStringExplicit& label );
std::string getLabel() const;
@@ -151,7 +151,7 @@ protected:
// Build time optimization, generate once in .cpp file
#ifndef LLCHECKBOXCTRL_CPP
extern template class LLCheckBoxCtrl* LLView::getChild(
- const std::string& name, bool recurse) const;
+ std::string_view name, bool recurse) const;
#endif
#endif // LL_LLCHECKBOXCTRL_H
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 79dce1c714..ee1700e009 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -875,6 +875,20 @@ bool LLComboBox::handleUnicodeCharHere(llwchar uni_char)
return result;
}
+// virtual
+bool LLComboBox::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ if (mList->getVisible()) return mList->handleScrollWheel(x, y, clicks);
+ if (mAllowTextEntry) // We might be editable
+ if (!mList->getFirstSelected()) // We aren't in the list, don't kill their text
+ return false;
+
+ setCurrentByIndex(llclamp(getCurrentIndex() + clicks, 0, getItemCount() - 1));
+ prearrangeList();
+ onCommit();
+ return true;
+}
+
void LLComboBox::setTextEntry(const LLStringExplicit& text)
{
if (mTextEntry)
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index cc1c2885fc..9dc6fa9257 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -114,6 +114,7 @@ public:
virtual bool handleToolTip(S32 x, S32 y, MASK mask);
virtual bool handleKeyHere(KEY key, MASK mask);
virtual bool handleUnicodeCharHere(llwchar uni_char);
+ virtual bool handleScrollWheel(S32 x, S32 y, S32 clicks);
// LLUICtrl interface
virtual void clear(); // select nothing
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
index 9fbfb3e5fa..91e6f281da 100644
--- a/indra/llui/llconsole.cpp
+++ b/indra/llui/llconsole.cpp
@@ -80,7 +80,7 @@ void LLConsole::setLinePersistTime(F32 seconds)
void LLConsole::reshape(S32 width, S32 height, bool called_from_parent)
{
S32 new_width = llmax(50, llmin(getRect().getWidth(), width));
- S32 new_height = llmax(llfloor(mFont->getLineHeight()) + 15, llmin(getRect().getHeight(), height));
+ S32 new_height = llmax(mFont->getLineHeight() + 15, llmin(getRect().getHeight(), height));
if ( mConsoleWidth == new_width
&& mConsoleHeight == new_height )
@@ -183,10 +183,11 @@ void LLConsole::draw()
static LLCachedControl console_bg_opacity(*LLUI::getInstance()->mSettingGroups["config"], "ConsoleBackgroundOpacity", 0.7f);
F32 console_opacity = llclamp(console_bg_opacity(), 0.f, 1.f);
- LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground");
+ static LLUIColor console_color = LLUIColorTable::instance().getColor("ConsoleBackground");
+ LLColor4 color = console_color;
color.mV[VALPHA] *= console_opacity;
- F32 line_height = mFont->getLineHeight();
+ F32 line_height = (F32)mFont->getLineHeight();
for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++)
{
diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp
index 4c2912cde6..b414e4354d 100644
--- a/indra/llui/llcontainerview.cpp
+++ b/indra/llui/llcontainerview.cpp
@@ -46,7 +46,7 @@ static ContainerViewRegistry::Register r3("panel", &LLPanel::fromXML);
LLContainerView::LLContainerView(const LLContainerView::Params& p)
: LLView(p),
mShowLabel(p.show_label),
- mLabel(p.label),
+ mLabel(utf8str_to_wstring(p.label)),
mDisplayChildren(p.display_children)
{
mScrollContainer = NULL;
@@ -120,8 +120,8 @@ void LLContainerView::draw()
// Draw the label
if (mShowLabel)
{
- LLFontGL::getFontMonospace()->renderUTF8(
- mLabel, 0, 2, getRect().getHeight() - 2, LLColor4(1,1,1,1), LLFontGL::LEFT, LLFontGL::TOP);
+ LLFontGL::getFontMonospace()->render(
+ mLabel, 0, 2.f, (F32)(getRect().getHeight() - 2), LLColor4(1,1,1,1), LLFontGL::LEFT, LLFontGL::TOP);
}
LLView::draw();
@@ -285,7 +285,7 @@ LLRect LLContainerView::getRequiredRect()
void LLContainerView::setLabel(const std::string& label)
{
- mLabel = label;
+ mLabel = utf8str_to_wstring(label);
}
void LLContainerView::setDisplayChildren(bool displayChildren)
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
index 319fb7d5e9..c6dd401e85 100644
--- a/indra/llui/llcontainerview.h
+++ b/indra/llui/llcontainerview.h
@@ -89,6 +89,6 @@ public:
protected:
bool mDisplayChildren;
- std::string mLabel;
+ LLWString mLabel;
};
#endif // LL_CONTAINERVIEW_
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index bf0862e8a9..11dbad8c09 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -43,6 +43,8 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
mDockWidgetHandle = dockWidget->getHandle();
}
+ mNonToolbarPanelHandle = mDockableFloater->getRootView()->getChild("non_toolbar_panel")->getHandle();
+
if (dockableFloater->isDocked())
{
on();
@@ -97,7 +99,10 @@ void LLDockControl::setDock(LLView* dockWidget)
void LLDockControl::getAllowedRect(LLRect& rect)
{
- rect = mDockableFloater->getRootView()->getChild("non_toolbar_panel")->getRect();
+ if(!mNonToolbarPanelHandle.isDead())
+ {
+ rect = mNonToolbarPanelHandle.get()->getRect();
+ }
}
void LLDockControl::repositionDockable()
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index fb0bf7d251..7e31330713 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -84,6 +84,7 @@ private:
bool mDockWidgetVisible;
DocAt mDockAt;
LLHandle mDockWidgetHandle;
+ LLHandle mNonToolbarPanelHandle;
LLRect mPrevDockRect;
LLRect mRootRect;
LLRect mFloaterRect;
diff --git a/indra/llui/llemojihelper.cpp b/indra/llui/llemojihelper.cpp
index fbe313924c..b9441a9c91 100644
--- a/indra/llui/llemojihelper.cpp
+++ b/indra/llui/llemojihelper.cpp
@@ -76,7 +76,9 @@ bool LLEmojiHelper::isCursorInEmojiCode(const LLWString& wtext, S32 cursorPos, S
shortCodePos--;
}
- bool isShortCode = (L':' == wtext[shortCodePos - 1]) && (cursorPos - shortCodePos >= 2);
+ bool isShortCode = (cursorPos - shortCodePos >= 2) && (L':' == wtext[shortCodePos - 1]);
+ if(isShortCode && (shortCodePos >= 2) && isdigit(wtext[shortCodePos - 2])) // Add qualifier to avoid emoji pop-up when typing times.
+ isShortCode = false;
if (pShortCodePos)
*pShortCodePos = (isShortCode) ? shortCodePos - 1 : -1;
return isShortCode;
diff --git a/indra/llui/llf32uictrl.cpp b/indra/llui/llf32uictrl.cpp
index 52954ebbbb..9d041fffb0 100644
--- a/indra/llui/llf32uictrl.cpp
+++ b/indra/llui/llf32uictrl.cpp
@@ -37,7 +37,7 @@
LLF32UICtrl::LLF32UICtrl(const Params& p)
: LLUICtrl(p),
- mInitialValue(p.initial_value().asReal()),
+ mInitialValue((F32)p.initial_value().asReal()),
mMinValue(p.min_value),
mMaxValue(p.max_value),
mIncrement(p.increment)
@@ -47,5 +47,5 @@ LLF32UICtrl::LLF32UICtrl(const Params& p)
F32 LLF32UICtrl::getValueF32() const
{
- return mViewModel->getValue().asReal();
+ return (F32)mViewModel->getValue().asReal();
}
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 1799968afb..53f39766c6 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -1250,17 +1250,15 @@ void LLFlatListView::detachItems(std::vector& detached_items)
detached_items.clear();
// Go through items and detach valid items, remove them from items panel
// and add to detached_items.
- pairs_iterator_t iter = mItemPairs.begin(), iter_end = mItemPairs.end();
- while (iter != iter_end)
+ for (auto item_pair : mItemPairs)
{
- LLPanel* pItem = (*iter)->first;
+ LLPanel* pItem = item_pair->first;
if (1 == pItem->notify(action))
{
- selectItemPair((*iter), false);
+ selectItemPair(item_pair, false);
mItemsPanel->removeChild(pItem);
- detached_items.push_back(pItem);
+ detached_items.emplace_back(pItem);
}
- iter++;
}
if (!detached_items.empty())
{
@@ -1268,12 +1266,10 @@ void LLFlatListView::detachItems(std::vector& detached_items)
if (detached_items.size() == mItemPairs.size())
{
// This way will be faster if all items were disconnected
- pairs_iterator_t iter = mItemPairs.begin(), iter_end = mItemPairs.end();
- while (iter != iter_end)
+ for (auto item_pair : mItemPairs)
{
- (*iter)->first = NULL;
- delete *iter;
- iter++;
+ item_pair->first = nullptr;
+ delete item_pair;
}
mItemPairs.clear();
// Also set items panel height to zero.
@@ -1286,26 +1282,16 @@ void LLFlatListView::detachItems(std::vector& detached_items)
}
else
{
- std::vector::const_iterator
- detached_iter = detached_items.begin(),
- detached_iter_end = detached_items.end();
- while (detached_iter < detached_iter_end)
+ for (auto detached_item : detached_items)
{
- LLPanel* pDetachedItem = *detached_iter;
- pairs_iterator_t iter = mItemPairs.begin(), iter_end = mItemPairs.end();
- while (iter != iter_end)
+ auto found_pos = std::find_if(mItemPairs.begin(), mItemPairs.end(), [detached_item](auto item_pair) { return item_pair->first == detached_item; });
+ if (found_pos != mItemPairs.end())
{
- item_pair_t* item_pair = *iter;
- if (item_pair->first == pDetachedItem)
- {
- mItemPairs.erase(iter);
- item_pair->first = NULL;
- delete item_pair;
- break;
- }
- iter++;
+ mItemPairs.erase(found_pos);
+ auto item_pair = *found_pos;
+ item_pair->first = nullptr;
+ delete item_pair;
}
- detached_iter++;
}
rearrangeItems();
}
@@ -1412,11 +1398,10 @@ void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
action.with("match_filter", cur_filter);
mHasMatchedItems = false;
- bool visibility_changed = false;
- pairs_const_iterator_t iter = getItemPairs().begin(), iter_end = getItemPairs().end();
- while (iter != iter_end)
+ bool visibility_changed{ false };
+ for (auto item_pair : getItemPairs())
{
- LLPanel* pItem = (*(iter++))->first;
+ LLPanel* pItem = item_pair->first;
visibility_changed |= updateItemVisibility(pItem, action);
}
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index e6ecf3c283..12d5c41de1 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -960,8 +960,8 @@ bool LLFloater::applyRectControl()
&& !x_control->isDefault()
&& !y_control->isDefault())
{
- mPosition.mX = x_control->getValue().asReal();
- mPosition.mY = y_control->getValue().asReal();
+ mPosition.mX = (LL_COORD_FLOATER::value_t)x_control->getValue().asReal();
+ mPosition.mY = (LL_COORD_FLOATER::value_t)y_control->getValue().asReal();
mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
applyRelativePosition();
@@ -1205,24 +1205,64 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
{
S32 delta_x = 0;
S32 delta_y = 0;
+
+ // take translation of dependee floater into account
+ delta_x += new_rect.mLeft - old_rect.mLeft;
+ delta_y += new_rect.mBottom - old_rect.mBottom;
+
// check to see if it snapped to right or top, and move if dependee floater is resizing
LLRect dependent_rect = floaterp->getRect();
- if (dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right?
- dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right
+ if ((dependent_rect.mLeft - getRect().mLeft >= old_rect.getWidth() || // dependent on my right?
+ dependent_rect.mRight == getRect().mLeft + old_rect.getWidth()) // dependent aligned with my right
+ && dependent_rect.mBottom <= old_rect.mTop + 1)
{
// was snapped directly onto right side or aligned with it
delta_x += new_rect.getWidth() - old_rect.getWidth();
+
+ // make sure dependent still touches floater and din't go too high,
+ // it can go over edge, but should't detach completely
+ if (delta_y > 0
+ && dependent_rect.mBottom + delta_y > new_rect.mTop)
+ {
+ delta_y = llmax(new_rect.mTop - dependent_rect.mBottom, 0);
+ }
}
- if (dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() ||
- dependent_rect.mTop == getRect().mBottom + old_rect.getHeight())
+ else if (dependent_rect.mRight == old_rect.mLeft)
+ {
+ // make sure dependent still touches floater and don't go too high
+ if (delta_y > 0
+ && dependent_rect.mBottom <= old_rect.mTop
+ && dependent_rect.mBottom + delta_y > new_rect.mTop)
+ {
+ delta_y = llmax(new_rect.mTop - dependent_rect.mBottom, 0);
+ }
+ }
+
+ if ((dependent_rect.mBottom - getRect().mBottom >= old_rect.getHeight() ||
+ dependent_rect.mTop == getRect().mBottom + old_rect.getHeight())
+ && dependent_rect.mLeft <= old_rect.mRight + 1)
{
// was snapped directly onto top side or aligned with it
delta_y += new_rect.getHeight() - old_rect.getHeight();
- }
- // take translation of dependee floater into account as well
- delta_x += new_rect.mLeft - old_rect.mLeft;
- delta_y += new_rect.mBottom - old_rect.mBottom;
+ // make sure dependent still touches floater
+ // and din't go too far to the right
+ if (delta_x > 0
+ && dependent_rect.mLeft + delta_x > new_rect.mRight)
+ {
+ delta_x = llmax(new_rect.mRight - dependent_rect.mLeft, 0);
+ }
+ }
+ else if (dependent_rect.mTop == old_rect.mBottom)
+ {
+ // make sure dependent still touches floater and don't go too far to the right
+ if (delta_x > 0
+ && dependent_rect.mLeft <= old_rect.mRight
+ && dependent_rect.mLeft + delta_x > new_rect.mRight)
+ {
+ delta_x = llmax(new_rect.mRight - dependent_rect.mLeft, 0);
+ }
+ }
dependent_rect.translate(delta_x, delta_y);
floaterp->setShape(dependent_rect, by_user);
@@ -3618,7 +3658,7 @@ void LLFloater::applyRelativePosition()
LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater)
-: coord_t((S32)x, (S32)y)
+: coord_t(x, y)
{
mFloater = floater.getHandle();
}
@@ -3661,28 +3701,28 @@ LLCoordCommon LL_COORD_FLOATER::convertToCommon() const
LLCoordCommon out;
if (self.mX < -0.5f)
{
- out.mX = ll_round(rescale(self.mX, -1.f, -0.5f, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft));
+ out.mX = ll_round(rescale(self.mX, -1.f, -0.5f, (F32)(snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS)), (F32)snap_rect.mLeft));
}
else if (self.mX > 0.5f)
{
- out.mX = ll_round(rescale(self.mX, 0.5f, 1.f, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS));
+ out.mX = ll_round(rescale(self.mX, 0.5f, 1.f, (F32)(snap_rect.mRight - floater_width), (F32)(snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS)));
}
else
{
- out.mX = ll_round(rescale(self.mX, -0.5f, 0.5f, snap_rect.mLeft, snap_rect.mRight - floater_width));
+ out.mX = ll_round(rescale(self.mX, -0.5f, 0.5f, (F32)snap_rect.mLeft, (F32)(snap_rect.mRight - floater_width)));
}
if (self.mY < -0.5f)
{
- out.mY = ll_round(rescale(self.mY, -1.f, -0.5f, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom));
+ out.mY = ll_round(rescale(self.mY, -1.f, -0.5f, (F32)(snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS)), (F32)snap_rect.mBottom));
}
else if (self.mY > 0.5f)
{
- out.mY = ll_round(rescale(self.mY, 0.5f, 1.f, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS));
+ out.mY = ll_round(rescale(self.mY, 0.5f, 1.f, (F32)(snap_rect.mTop - floater_height), (F32)(snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS)));
}
else
{
- out.mY = ll_round(rescale(self.mY, -0.5f, 0.5f, snap_rect.mBottom, snap_rect.mTop - floater_height));
+ out.mY = ll_round(rescale(self.mY, -0.5f, 0.5f, (F32)snap_rect.mBottom, (F32)(snap_rect.mTop - floater_height)));
}
// return center point instead of lower left
@@ -3709,27 +3749,27 @@ void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from)
if (from_x < snap_rect.mLeft)
{
- self.mX = rescale(from_x, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft, -1.f, -0.5f);
+ self.mX = rescale((F32)from_x, (F32)(snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS)), (F32)snap_rect.mLeft, -1.f, -0.5f);
}
else if (from_x + floater_width > snap_rect.mRight)
{
- self.mX = rescale(from_x, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f);
+ self.mX = rescale((F32)from_x, (F32)(snap_rect.mRight - floater_width), (F32)(snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS), 0.5f, 1.f);
}
else
{
- self.mX = rescale(from_x, snap_rect.mLeft, snap_rect.mRight - floater_width, -0.5f, 0.5f);
+ self.mX = rescale((F32)from_x, (F32)snap_rect.mLeft, (F32)(snap_rect.mRight - floater_width), -0.5f, 0.5f);
}
if (from_y < snap_rect.mBottom)
{
- self.mY = rescale(from_y, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom, -1.f, -0.5f);
+ self.mY = rescale((F32)from_y, (F32)(snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS)), (F32)snap_rect.mBottom, -1.f, -0.5f);
}
else if (from_y + floater_height > snap_rect.mTop)
{
- self.mY = rescale(from_y, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f);
+ self.mY = rescale((F32)from_y, (F32)(snap_rect.mTop - floater_height), (F32)(snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS), 0.5f, 1.f);
}
else
{
- self.mY = rescale(from_y, snap_rect.mBottom, snap_rect.mTop - floater_height, -0.5f, 0.5f);
+ self.mY = rescale((F32)from_y, (F32)snap_rect.mBottom, (F32)(snap_rect.mTop - floater_height), -0.5f, 0.5f);
}
}
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index fd5a370bc3..a818e72f59 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -40,9 +40,9 @@
LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList;
LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;
LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;
-std::map LLFloaterReg::sGroupMap;
+std::map> LLFloaterReg::sGroupMap;
bool LLFloaterReg::sBlockShowFloaters = false;
-std::set LLFloaterReg::sAlwaysShowableList;
+std::set> LLFloaterReg::sAlwaysShowableList;
static LLFloaterRegListener sFloaterRegListener;
@@ -58,27 +58,31 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con
}
//static
-bool LLFloaterReg::isRegistered(const std::string& name)
+bool LLFloaterReg::isRegistered(std::string_view name)
{
return sBuildMap.find(name) != sBuildMap.end();
}
//static
-LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
+LLFloater* LLFloaterReg::getLastFloaterInGroup(std::string_view name)
{
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
+ auto it = sGroupMap.find(name);
+ if (it != sGroupMap.end())
{
- instance_list_t& list = sInstanceMap[groupname];
- if (!list.empty())
+ const std::string& groupname = it->second;
+ if (!groupname.empty())
{
- for (instance_list_t::reverse_iterator iter = list.rbegin(); iter != list.rend(); ++iter)
+ instance_list_t& list = sInstanceMap[groupname];
+ if (!list.empty())
{
- LLFloater* inst = *iter;
-
- if (inst->getVisible() && !inst->isMinimized())
+ for (instance_list_t::reverse_iterator iter = list.rbegin(), end = list.rend(); iter != end; ++iter)
{
- return inst;
+ LLFloater* inst = *iter;
+
+ if (inst->getVisible() && !inst->isMinimized())
+ {
+ return inst;
+ }
}
}
}
@@ -99,10 +103,8 @@ LLFloater* LLFloaterReg::getLastFloaterCascading()
instance_list_t& instances = sInstanceMap[group_name];
- for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
+ for (LLFloater* inst : instances)
{
- LLFloater* inst = *iter;
-
if (inst->getVisible()
&& (inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADING)
|| inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADE_GROUP)))
@@ -120,20 +122,23 @@ LLFloater* LLFloaterReg::getLastFloaterCascading()
}
//static
-LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
+LLFloater* LLFloaterReg::findInstance(std::string_view name, const LLSD& key)
{
LLFloater* res = NULL;
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
+ auto it = sGroupMap.find(name);
+ if (it != sGroupMap.end())
{
- instance_list_t& list = sInstanceMap[groupname];
- for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ const std::string& groupname = it->second;
+ if (!groupname.empty())
{
- LLFloater* inst = *iter;
- if (inst->matchesKey(key))
+ instance_list_t& list = sInstanceMap[groupname];
+ for (LLFloater* inst : list)
{
- res = inst;
- break;
+ if (inst->matchesKey(key))
+ {
+ res = inst;
+ break;
+ }
}
}
}
@@ -141,47 +146,55 @@ LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
}
//static
-LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
+LLFloater* LLFloaterReg::getInstance(std::string_view name, const LLSD& key)
{
LLFloater* res = findInstance(name, key);
if (!res)
{
- const LLFloaterBuildFunc& build_func = sBuildMap[name].mFunc;
- const std::string& xui_file = sBuildMap[name].mFile;
- if (build_func)
+ auto it = sBuildMap.find(name);
+ if (it != sBuildMap.end())
{
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
+ const LLFloaterBuildFunc& build_func = it->second.mFunc;
+ const std::string& xui_file = it->second.mFile;
+ if (build_func)
{
- instance_list_t& list = sInstanceMap[groupname];
-
- res = build_func(key);
- if (!res)
+ auto it = sGroupMap.find(name);
+ if (it != sGroupMap.end())
{
- LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
- return NULL;
+ const std::string& groupname = it->second;
+ if (!groupname.empty())
+ {
+ instance_list_t& list = sInstanceMap[groupname];
+
+ res = build_func(key);
+ if (!res)
+ {
+ LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
+ return NULL;
+ }
+ bool success = res->buildFromFile(xui_file);
+ if (!success)
+ {
+ LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
+ return NULL;
+ }
+
+ // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
+ if (res->mKey.isUndefined())
+ {
+ res->mKey = key;
+ }
+ res->setInstanceName(std::string(name));
+
+ LLFloater* last_floater = (list.empty() ? NULL : list.back());
+
+ res->applyControlsAndPosition(last_floater);
+
+ gFloaterView->adjustToFitScreen(res, false);
+
+ list.push_back(res);
+ }
}
- bool success = res->buildFromFile(xui_file);
- if (!success)
- {
- LL_WARNS() << "Failed to build floater type: '" << name << "'." << LL_ENDL;
- return NULL;
- }
-
- // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
- if (res->mKey.isUndefined())
- {
- res->mKey = key;
- }
- res->setInstanceName(name);
-
- LLFloater *last_floater = (list.empty() ? NULL : list.back());
-
- res->applyControlsAndPosition(last_floater);
-
- gFloaterView->adjustToFitScreen(res, false);
-
- list.push_back(res);
}
}
if (!res)
@@ -193,21 +206,25 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
}
//static
-LLFloater* LLFloaterReg::removeInstance(const std::string& name, const LLSD& key)
+LLFloater* LLFloaterReg::removeInstance(std::string_view name, const LLSD& key)
{
LLFloater* res = NULL;
- const std::string& groupname = sGroupMap[name];
- if (!groupname.empty())
+ auto it = sGroupMap.find(name);
+ if (it != sGroupMap.end())
{
- instance_list_t& list = sInstanceMap[groupname];
- for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
+ const std::string& groupname = it->second;
+ if (!groupname.empty())
{
- LLFloater* inst = *iter;
- if (inst->matchesKey(key))
+ instance_list_t& list = sInstanceMap[groupname];
+ for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
{
- res = inst;
- list.erase(iter);
- break;
+ LLFloater* inst = *iter;
+ if (inst->matchesKey(key))
+ {
+ res = inst;
+ list.erase(iter);
+ break;
+ }
}
}
}
@@ -216,7 +233,7 @@ LLFloater* LLFloaterReg::removeInstance(const std::string& name, const LLSD& key
//static
// returns true if the instance existed
-bool LLFloaterReg::destroyInstance(const std::string& name, const LLSD& key)
+bool LLFloaterReg::destroyInstance(std::string_view name, const LLSD& key)
{
LLFloater* inst = removeInstance(name, key);
if (inst)
@@ -232,7 +249,7 @@ bool LLFloaterReg::destroyInstance(const std::string& name, const LLSD& key)
// Iterators
//static
-LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::string& name)
+LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(std::string_view name)
{
instance_map_t::iterator iter = sInstanceMap.find(name);
if (iter != sInstanceMap.end())
@@ -248,7 +265,7 @@ LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::str
// Visibility Management
//static
-LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, bool focus)
+LLFloater* LLFloaterReg::showInstance(std::string_view name, const LLSD& key, bool focus)
{
if( sBlockShowFloaters
// see EXT-7090
@@ -266,7 +283,7 @@ LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key,
//static
// returns true if the instance exists
-bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
+bool LLFloaterReg::hideInstance(std::string_view name, const LLSD& key)
{
LLFloater* instance = findInstance(name, key);
if (instance)
@@ -278,7 +295,7 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
//static
// returns true if the instance is visible when completed
-bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
+bool LLFloaterReg::toggleInstance(std::string_view name, const LLSD& key)
{
LLFloater* instance = findInstance(name, key);
if (instance && instance->isShown())
@@ -294,7 +311,7 @@ bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
//static
// returns true if the instance exists and is visible (doesnt matter minimized or not)
-bool LLFloaterReg::instanceVisible(const std::string& name, const LLSD& key)
+bool LLFloaterReg::instanceVisible(std::string_view name, const LLSD& key)
{
LLFloater* instance = findInstance(name, key);
return LLFloater::isVisible(instance);
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 6a642cbb27..94a67c8d8b 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -51,26 +51,26 @@ public:
// 2) We can change the key of a floater without altering the list.
typedef std::list instance_list_t;
typedef const instance_list_t const_instance_list_t;
- typedef std::map instance_map_t;
+ typedef std::map> instance_map_t;
struct BuildData
{
LLFloaterBuildFunc mFunc;
std::string mFile;
};
- typedef std::map build_map_t;
+ typedef std::map> build_map_t;
private:
friend class LLFloaterRegListener;
static instance_list_t sNullInstanceList;
static instance_map_t sInstanceMap;
static build_map_t sBuildMap;
- static std::map sGroupMap;
+ static std::map> sGroupMap;
static bool sBlockShowFloaters;
/**
* Defines list of floater names that can be shown despite state of sBlockShowFloaters.
*/
- static std::set sAlwaysShowableList;
+ static std::set> sAlwaysShowableList;
public:
// Registration
@@ -85,30 +85,30 @@ public:
static void add(const std::string& name, const std::string& file, const LLFloaterBuildFunc& func,
const std::string& groupname = LLStringUtil::null);
- static bool isRegistered(const std::string& name);
+ static bool isRegistered(std::string_view name);
// Helpers
- static LLFloater* getLastFloaterInGroup(const std::string& name);
+ static LLFloater* getLastFloaterInGroup(std::string_view name);
static LLFloater* getLastFloaterCascading();
// Find / get (create) / remove / destroy
- static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());
- static LLFloater* getInstance(const std::string& name, const LLSD& key = LLSD());
- static LLFloater* removeInstance(const std::string& name, const LLSD& key = LLSD());
- static bool destroyInstance(const std::string& name, const LLSD& key = LLSD());
+ static LLFloater* findInstance(std::string_view name, const LLSD& key = LLSD());
+ static LLFloater* getInstance(std::string_view name, const LLSD& key = LLSD());
+ static LLFloater* removeInstance(std::string_view name, const LLSD& key = LLSD());
+ static bool destroyInstance(std::string_view name, const LLSD& key = LLSD());
// Iterators
- static const_instance_list_t& getFloaterList(const std::string& name);
+ static const_instance_list_t& getFloaterList(std::string_view name);
// Visibility Management
// return NULL if instance not found or can't create instance (no builder)
- static LLFloater* showInstance(const std::string& name, const LLSD& key = LLSD(), bool focus = false);
+ static LLFloater* showInstance(std::string_view name, const LLSD& key = LLSD(), bool focus = false);
// Close a floater (may destroy or set invisible)
// return false if can't find instance
- static bool hideInstance(const std::string& name, const LLSD& key = LLSD());
+ static bool hideInstance(std::string_view name, const LLSD& key = LLSD());
// return true if instance is visible:
- static bool toggleInstance(const std::string& name, const LLSD& key = LLSD());
- static bool instanceVisible(const std::string& name, const LLSD& key = LLSD());
+ static bool toggleInstance(std::string_view name, const LLSD& key = LLSD());
+ static bool instanceVisible(std::string_view name, const LLSD& key = LLSD());
static void showInitialVisibleInstances();
static void hideVisibleInstances(const std::set& exceptions = std::set());
@@ -133,19 +133,19 @@ public:
// Typed find / get / show
template
- static T* findTypedInstance(const std::string& name, const LLSD& key = LLSD())
+ static T* findTypedInstance(std::string_view name, const LLSD& key = LLSD())
{
return dynamic_cast(findInstance(name, key));
}
template
- static T* getTypedInstance(const std::string& name, const LLSD& key = LLSD())
+ static T* getTypedInstance(std::string_view name, const LLSD& key = LLSD())
{
return dynamic_cast(getInstance(name, key));
}
template
- static T* showTypedInstance(const std::string& name, const LLSD& key = LLSD(), bool focus = false)
+ static T* showTypedInstance(std::string_view name, const LLSD& key = LLSD(), bool focus = false)
{
return dynamic_cast(showInstance(name, key, focus));
}
diff --git a/indra/llui/llfloaterreglistener.cpp b/indra/llui/llfloaterreglistener.cpp
index aa3d1a1171..17641b8375 100644
--- a/indra/llui/llfloaterreglistener.cpp
+++ b/indra/llui/llfloaterreglistener.cpp
@@ -94,22 +94,22 @@ void LLFloaterRegListener::getBuildMap(const LLSD& event) const
void LLFloaterRegListener::showInstance(const LLSD& event) const
{
- LLFloaterReg::showInstance(event["name"], event["key"], event["focus"]);
+ LLFloaterReg::showInstance(event["name"].asString(), event["key"], event["focus"]);
}
void LLFloaterRegListener::hideInstance(const LLSD& event) const
{
- LLFloaterReg::hideInstance(event["name"], event["key"]);
+ LLFloaterReg::hideInstance(event["name"].asString(), event["key"]);
}
void LLFloaterRegListener::toggleInstance(const LLSD& event) const
{
- LLFloaterReg::toggleInstance(event["name"], event["key"]);
+ LLFloaterReg::toggleInstance(event["name"].asString(), event["key"]);
}
void LLFloaterRegListener::instanceVisible(const LLSD& event) const
{
- sendReply(LLSDMap("visible", LLFloaterReg::instanceVisible(event["name"], event["key"])),
+ sendReply(LLSDMap("visible", LLFloaterReg::instanceVisible(event["name"].asString(), event["key"])),
event);
}
@@ -119,7 +119,7 @@ void LLFloaterRegListener::clickButton(const LLSD& event) const
LLReqID reqID(event);
LLSD reply(reqID.makeResponse());
- LLFloater* floater = LLFloaterReg::findInstance(event["name"], event["key"]);
+ LLFloater* floater = LLFloaterReg::findInstance(event["name"].asString(), event["key"]);
if (! LLFloater::isShown(floater))
{
reply["type"] = "LLFloater";
@@ -131,7 +131,7 @@ void LLFloaterRegListener::clickButton(const LLSD& event) const
{
// Here 'floater' points to an LLFloater instance with the specified
// name and key which isShown().
- LLButton* button = floater->findChild(event["button"]);
+ LLButton* button = floater->findChild(event["button"].asString());
if (! LLButton::isAvailable(button))
{
reply["type"] = "LLButton";
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 937dde4def..c635d24f51 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -183,7 +183,7 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
}
}
- LLUI::getInstance()->removePopup(view);
+ if(LLUI::instanceExists()) LLUI::getInstance()->removePopup(view);
}
void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, bool lock, bool keystrokes_only)
@@ -481,7 +481,7 @@ void LLFocusMgr::setAppHasFocus(bool focus)
// release focus from "top ctrl"s, which generally hides them
if (!focus)
{
- LLUI::getInstance()->clearPopups();
+ if(LLUI::instanceExists()) LLUI::getInstance()->clearPopups();
}
mAppHasFocus = focus;
}
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 1d4ecbe9c9..388dc5b1ac 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -211,7 +211,7 @@ LLFolderView::LLFolderView(const Params& p)
//clear label
// go ahead and render root folder as usual
// just make sure the label ("Inventory Folder") never shows up
- mLabel = LLStringUtil::null;
+ mLabel.clear();
// Escape is handled by reverting the rename, not commiting it (default behavior)
LLLineEditor::Params params;
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 82cd2483e8..e4f5664908 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -140,7 +140,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mItemHeight(p.item_height),
mControlLabelRotation(0.f),
mDragAndDropTarget(false),
- mLabel(p.name),
+ mLabel(utf8str_to_wstring(p.name)),
mRoot(p.root),
mViewModelItem(p.listener),
mIsMouseOverTitle(false),
@@ -193,7 +193,7 @@ bool LLFolderViewItem::postBuild()
{
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
// it also sets search strings so it requires a filter reset
- mLabel = vmi->getDisplayName();
+ mLabel = utf8str_to_wstring(vmi->getDisplayName());
setToolTip(vmi->getName());
// Dirty the filter flag of the model from the view (CHUI-849)
@@ -306,7 +306,7 @@ void LLFolderViewItem::refresh()
{
LLFolderViewModelItem& vmi = *getViewModelItem();
- mLabel = vmi.getDisplayName();
+ mLabel = utf8str_to_wstring(vmi.getDisplayName());
setToolTip(vmi.getName());
// icons are slightly expensive to get, can be optimized
// see LLInventoryIcon::getIcon()
@@ -319,7 +319,7 @@ void LLFolderViewItem::refresh()
// Very Expensive!
// Can do a number of expensive checks, like checking active motions, wearables or friend list
mLabelStyle = vmi.getLabelStyle();
- mLabelSuffix = vmi.getLabelSuffix();
+ mLabelSuffix = utf8str_to_wstring(vmi.getLabelSuffix());
}
// Dirty the filter flag of the model from the view (CHUI-849)
@@ -344,7 +344,7 @@ void LLFolderViewItem::refreshSuffix()
// Very Expensive!
// Can do a number of expensive checks, like checking active motions, wearables or friend list
mLabelStyle = vmi->getLabelStyle();
- mLabelSuffix = vmi->getLabelSuffix();
+ mLabelSuffix = utf8str_to_wstring(vmi->getLabelSuffix());
}
mLabelWidthDirty = true;
@@ -405,7 +405,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
// it is purely visual, so it is fine to do at our laisure
refreshSuffix();
}
- mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(LLFontGL::NORMAL)->getWidth(mLabelSuffix) + mLabelPaddingRight;
+ mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel.c_str()) + getLabelFontForStyle(LLFontGL::NORMAL)->getWidth(mLabelSuffix.c_str()) + mLabelPaddingRight;
mLabelWidthDirty = false;
}
@@ -784,7 +784,7 @@ void LLFolderViewItem::drawHighlight(const bool showContent, const bool hasKeybo
const S32 FOCUS_LEFT = 1;
// Determine which background color to use for highlighting
- LLUIColor bgColor = (isFlashing() ? flashColor : selectColor);
+ const LLUIColor& bgColor = (isFlashing() ? flashColor : selectColor);
//--------------------------------------------------------------------------------//
// Draw highlight for selected items
@@ -890,7 +890,7 @@ void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y
//--------------------------------------------------------------------------------//
// Draw the actual label text
//
- font->renderUTF8(mLabel, 0, x, y, color,
+ font->render(mLabel, 0, x, y, color,
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, /*use_ellipses*/true);
}
@@ -944,18 +944,18 @@ void LLFolderViewItem::draw()
F32 right_x = 0;
F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
F32 text_left = (F32)getLabelXPos();
- std::string combined_string = mLabel + mLabelSuffix;
+ LLWString combined_string = mLabel + mLabelSuffix;
const LLFontGL* suffix_font = getLabelFontForStyle(LLFontGL::NORMAL);
S32 filter_offset = static_cast(mViewModelItem->getFilterStringOffset());
if (filter_string_length > 0)
{
- S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
+ S32 bottom = getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD;
S32 top = getRect().getHeight() - TOP_PAD;
if(mLabelSuffix.empty() || (font == suffix_font))
{
- S32 left = ll_round(text_left) + font->getWidth(combined_string, 0, static_cast(mViewModelItem->getFilterStringOffset())) - 2;
- S32 right = left + font->getWidth(combined_string, static_cast(mViewModelItem->getFilterStringOffset()), filter_string_length) + 2;
+ S32 left = ll_round(text_left) + font->getWidth(combined_string.c_str(), 0, static_cast(mViewModelItem->getFilterStringOffset())) - 2;
+ S32 right = left + font->getWidth(combined_string.c_str(), static_cast(mViewModelItem->getFilterStringOffset()), filter_string_length) + 2;
LLUIImage* box_image = default_params.selection_image;
LLRect box_rect(left, top, right, bottom);
@@ -966,8 +966,8 @@ void LLFolderViewItem::draw()
S32 label_filter_length = llmin((S32)mLabel.size() - filter_offset, (S32)filter_string_length);
if(label_filter_length > 0)
{
- S32 left = ll_round(text_left) + font->getWidthF32(mLabel, 0, llmin(filter_offset, (S32)mLabel.size())) - 2;
- S32 right = left + font->getWidthF32(mLabel, filter_offset, label_filter_length) + 2;
+ S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, llmin(filter_offset, (S32)mLabel.size()))) - 2;
+ S32 right = left + (S32)font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length) + 2;
LLUIImage* box_image = default_params.selection_image;
LLRect box_rect(left, top, right, bottom);
box_image->draw(box_rect, sFilterBGColor);
@@ -976,8 +976,8 @@ void LLFolderViewItem::draw()
if(suffix_filter_length > 0)
{
S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size());
- S32 left = ll_round(text_left) + font->getWidthF32(mLabel, 0, static_cast(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix, 0, suffix_offset) - 2;
- S32 right = left + suffix_font->getWidthF32(mLabelSuffix, suffix_offset, suffix_filter_length) + 2;
+ S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, static_cast(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset)) - 2;
+ S32 right = left + (S32)suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length) + 2;
LLUIImage* box_image = default_params.selection_image;
LLRect box_rect(left, top, right, bottom);
box_image->draw(box_rect, sFilterBGColor);
@@ -999,7 +999,7 @@ void LLFolderViewItem::draw()
//
if (!mLabelSuffix.empty())
{
- suffix_font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor,
+ suffix_font->render( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(),
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
S32_MAX, S32_MAX, &right_x);
}
@@ -1011,9 +1011,9 @@ void LLFolderViewItem::draw()
{
if(mLabelSuffix.empty() || (font == suffix_font))
{
- F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string, filter_offset, filter_string_length);
+ F32 match_string_left = text_left + font->getWidthF32(combined_string.c_str(), 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string.c_str(), filter_offset, filter_string_length);
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
- font->renderUTF8(combined_string, filter_offset, match_string_left, yy,
+ font->render(combined_string, filter_offset, match_string_left, yy,
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
filter_string_length, S32_MAX, &right_x);
}
@@ -1022,9 +1022,9 @@ void LLFolderViewItem::draw()
S32 label_filter_length = llmin((S32)mLabel.size() - filter_offset, (S32)filter_string_length);
if(label_filter_length > 0)
{
- F32 match_string_left = text_left + font->getWidthF32(mLabel, 0, filter_offset + label_filter_length) - font->getWidthF32(mLabel, filter_offset, label_filter_length);
+ F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, filter_offset + label_filter_length) - font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length);
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
- font->renderUTF8(mLabel, filter_offset, match_string_left, yy,
+ font->render(mLabel, filter_offset, match_string_left, yy,
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
label_filter_length, S32_MAX, &right_x);
}
@@ -1033,9 +1033,9 @@ void LLFolderViewItem::draw()
if(suffix_filter_length > 0)
{
S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size());
- F32 match_string_left = text_left + font->getWidthF32(mLabel, 0, static_cast(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix, 0, suffix_offset + suffix_filter_length) - suffix_font->getWidthF32(mLabelSuffix, suffix_offset, suffix_filter_length);
+ F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, static_cast(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset + suffix_filter_length) - suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length);
F32 yy = (F32)getRect().getHeight() - suffix_font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
- suffix_font->renderUTF8(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor,
+ suffix_font->render(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor,
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
suffix_filter_length, S32_MAX, &right_x);
}
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index f7ced81274..60cdac3ab9 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -89,14 +89,14 @@ protected:
LLFolderViewItem(const Params& p);
- std::string mLabel;
+ LLWString mLabel;
S32 mLabelWidth;
bool mLabelWidthDirty;
S32 mLabelPaddingRight;
LLFolderViewFolder* mParentFolder;
LLPointer mViewModelItem;
LLFontGL::StyleFlags mLabelStyle;
- std::string mLabelSuffix;
+ LLWString mLabelSuffix;
bool mSuffixNeedsRefresh; //suffix and icons
LLUIImagePtr mIcon,
mIconOpen,
@@ -242,7 +242,7 @@ public:
// This method returns the label displayed on the view. This
// method was primarily added to allow sorting on the folder
// contents possible before the entire view has been constructed.
- const std::string& getLabel() const { return mLabel; }
+ const LLWString& getLabel() const { return mLabel; }
LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index aae1d1d572..29d3f0c3d4 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -79,7 +79,7 @@ public:
std::string getImageName() const;
- void setColor(const LLColor4& color) { mColor = color; }
+ void setColor(const LLUIColor& color) { mColor = color; }
void setImage(LLPointer