Merge branch 'master' of https://github.com/FirestormViewer/phoenix-firestorm
# Conflicts: # autobuild.xml # indra/newview/llvoicevivox.cppmaster
commit
0cf61eed93
|
|
@ -0,0 +1,11 @@
|
|||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
|
|
@ -24,6 +24,8 @@ jobs:
|
|||
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 }}
|
||||
env:
|
||||
AUTOBUILD_ADDRSIZE: 64
|
||||
|
|
@ -33,12 +35,13 @@ jobs:
|
|||
AUTOBUILD_GITHUB_TOKEN: ${{ secrets.SHARED_AUTOBUILD_GITHUB_TOKEN }}
|
||||
AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables
|
||||
AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables
|
||||
# Direct autobuild to store vcs_url, vcs_branch and vcs_revision in
|
||||
# autobuild-package.xml.
|
||||
AUTOBUILD_VCS_INFO: "true"
|
||||
AUTOBUILD_VSVER: "170"
|
||||
DEVELOPER_DIR: ${{ matrix.developer_dir }}
|
||||
# Ensure that Linden viewer builds engage Bugsplat.
|
||||
BUGSPLAT_DB: ${{ matrix.configuration != 'ReleaseOS' && 'SecondLife_Viewer_2018' || '' }}
|
||||
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
|
||||
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
|
||||
build_coverity: false
|
||||
build_log_dir: ${{ github.workspace }}/.logs
|
||||
build_viewer: true
|
||||
|
|
@ -62,7 +65,7 @@ jobs:
|
|||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Setup python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
|
|
@ -70,7 +73,7 @@ jobs:
|
|||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: secondlife/build-variables
|
||||
ref: viewer
|
||||
ref: master
|
||||
path: .build-variables
|
||||
|
||||
- name: Checkout master-message-template
|
||||
|
|
@ -83,7 +86,7 @@ jobs:
|
|||
run: pip3 install autobuild llsd
|
||||
|
||||
- name: Cache autobuild packages
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
id: cache-installables
|
||||
with:
|
||||
path: .autobuild-installables
|
||||
|
|
@ -96,10 +99,17 @@ jobs:
|
|||
if: runner.os == 'Windows'
|
||||
run: choco install nsis-unicode
|
||||
|
||||
- name: Determine source branch
|
||||
id: which-branch
|
||||
uses: secondlife/viewer-build-util/which-branch@v1
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
shell: bash
|
||||
env:
|
||||
AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }}
|
||||
RUNNER_OS: ${{ runner.os }}
|
||||
run: |
|
||||
# set up things the viewer's build.sh script expects
|
||||
|
|
@ -150,7 +160,7 @@ jobs:
|
|||
}
|
||||
repo_branch()
|
||||
{
|
||||
git -C "$1" branch | grep '^* ' | cut -c 3-
|
||||
echo "$AUTOBUILD_VCS_BRANCH"
|
||||
}
|
||||
record_dependencies_graph()
|
||||
{
|
||||
|
|
@ -214,7 +224,7 @@ jobs:
|
|||
|
||||
- name: Upload executable
|
||||
if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.viewer_app
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ steps.build.outputs.artifact }}-app"
|
||||
path: |
|
||||
|
|
@ -224,7 +234,7 @@ jobs:
|
|||
# artifact for that too.
|
||||
- name: Upload symbol file
|
||||
if: matrix.configuration != 'ReleaseOS'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ steps.build.outputs.artifact }}-symbols"
|
||||
path: |
|
||||
|
|
@ -232,7 +242,7 @@ jobs:
|
|||
|
||||
- name: Upload metadata
|
||||
if: matrix.configuration != 'ReleaseOS'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ steps.build.outputs.artifact }}-metadata"
|
||||
# emitted by build.sh, possibly multiple lines
|
||||
|
|
@ -240,7 +250,7 @@ jobs:
|
|||
${{ steps.build.outputs.metadata }}
|
||||
|
||||
- name: Upload physics package
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
# should only be set for viewer-private
|
||||
if: matrix.configuration != 'ReleaseOS' && steps.build.outputs.physicstpv
|
||||
with:
|
||||
|
|
@ -250,23 +260,36 @@ jobs:
|
|||
${{ steps.build.outputs.physicstpv }}
|
||||
|
||||
sign-and-package-windows:
|
||||
env:
|
||||
AZURE_KEY_VAULT_URI: ${{ secrets.AZURE_KEY_VAULT_URI }}
|
||||
AZURE_CERT_NAME: ${{ secrets.AZURE_CERT_NAME }}
|
||||
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
needs: build
|
||||
runs-on: windows
|
||||
steps:
|
||||
- name: Sign and package Windows viewer
|
||||
if: env.AZURE_KEY_VAULT_URI && env.AZURE_CERT_NAME && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && env.AZURE_TENANT_ID
|
||||
uses: secondlife/viewer-build-util/sign-pkg-windows@v1
|
||||
with:
|
||||
vault_uri: "${{ secrets.AZURE_KEY_VAULT_URI }}"
|
||||
cert_name: "${{ secrets.AZURE_CERT_NAME }}"
|
||||
client_id: "${{ secrets.AZURE_CLIENT_ID }}"
|
||||
client_secret: "${{ secrets.AZURE_CLIENT_SECRET }}"
|
||||
tenant_id: "${{ secrets.AZURE_TENANT_ID }}"
|
||||
vault_uri: "${{ env.AZURE_KEY_VAULT_URI }}"
|
||||
cert_name: "${{ env.AZURE_CERT_NAME }}"
|
||||
client_id: "${{ env.AZURE_CLIENT_ID }}"
|
||||
client_secret: "${{ env.AZURE_CLIENT_SECRET }}"
|
||||
tenant_id: "${{ env.AZURE_TENANT_ID }}"
|
||||
|
||||
sign-and-package-mac:
|
||||
env:
|
||||
NOTARIZE_CREDS_MACOS: ${{ secrets.NOTARIZE_CREDS_MACOS }}
|
||||
SIGNING_CERT_MACOS: ${{ secrets.SIGNING_CERT_MACOS }}
|
||||
SIGNING_CERT_MACOS_IDENTITY: ${{ secrets.SIGNING_CERT_MACOS_IDENTITY }}
|
||||
SIGNING_CERT_MACOS_PASSWORD: ${{ secrets.SIGNING_CERT_MACOS_PASSWORD }}
|
||||
needs: build
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Unpack Mac notarization credentials
|
||||
if: env.NOTARIZE_CREDS_MACOS
|
||||
id: note-creds
|
||||
shell: bash
|
||||
run: |
|
||||
|
|
@ -274,7 +297,7 @@ jobs:
|
|||
# USERNAME="..."
|
||||
# PASSWORD="..."
|
||||
# TEAM_ID="..."
|
||||
eval "${{ secrets.NOTARIZE_CREDS_MACOS }}"
|
||||
eval "${{ env.NOTARIZE_CREDS_MACOS }}"
|
||||
echo "::add-mask::$USERNAME"
|
||||
echo "::add-mask::$PASSWORD"
|
||||
echo "::add-mask::$TEAM_ID"
|
||||
|
|
@ -286,45 +309,54 @@ jobs:
|
|||
[[ -n "$USERNAME" && -n "$PASSWORD" && -n "$TEAM_ID" ]]
|
||||
|
||||
- name: Sign and package Mac viewer
|
||||
if: env.SIGNING_CERT_MACOS && env.SIGNING_CERT_MACOS_IDENTITY && env.SIGNING_CERT_MACOS_PASSWORD && steps.note-creds.outputs.note_user && steps.note-creds.outputs.note_pass && steps.note-creds.outputs.note_team
|
||||
uses: secondlife/viewer-build-util/sign-pkg-mac@v1
|
||||
with:
|
||||
channel: ${{ needs.build.outputs.viewer_channel }}
|
||||
imagename: ${{ needs.build.outputs.imagename }}
|
||||
cert_base64: ${{ secrets.SIGNING_CERT_MACOS }}
|
||||
cert_name: ${{ secrets.SIGNING_CERT_MACOS_IDENTITY }}
|
||||
cert_pass: ${{ secrets.SIGNING_CERT_MACOS_PASSWORD }}
|
||||
cert_base64: ${{ env.SIGNING_CERT_MACOS }}
|
||||
cert_name: ${{ env.SIGNING_CERT_MACOS_IDENTITY }}
|
||||
cert_pass: ${{ env.SIGNING_CERT_MACOS_PASSWORD }}
|
||||
note_user: ${{ steps.note-creds.outputs.note_user }}
|
||||
note_pass: ${{ steps.note-creds.outputs.note_pass }}
|
||||
note_team: ${{ steps.note-creds.outputs.note_team }}
|
||||
|
||||
post-windows-symbols:
|
||||
env:
|
||||
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
|
||||
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Post Windows symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife/viewer-build-util/post-bugsplat-windows@v1
|
||||
with:
|
||||
username: ${{ secrets.BUGSPLAT_USER }}
|
||||
password: ${{ secrets.BUGSPLAT_PASS }}
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
channel: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }}
|
||||
|
||||
post-mac-symbols:
|
||||
env:
|
||||
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
|
||||
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Post Mac symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife/viewer-build-util/post-bugsplat-mac@v1
|
||||
with:
|
||||
username: ${{ secrets.BUGSPLAT_USER }}
|
||||
password: ${{ secrets.BUGSPLAT_PASS }}
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
channel: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }}
|
||||
|
||||
release:
|
||||
needs: [sign-and-package-windows, sign-and-package-mac]
|
||||
needs: [build, sign-and-package-windows, sign-and-package-mac]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life_')
|
||||
steps:
|
||||
|
|
@ -355,17 +387,31 @@ jobs:
|
|||
mv newview/viewer_version.txt macOS-viewer_version.txt
|
||||
|
||||
# forked from softprops/action-gh-release
|
||||
- uses: secondlife-3p/action-gh-release@v1
|
||||
- name: Create GitHub release
|
||||
id: release
|
||||
uses: secondlife-3p/action-gh-release@v1
|
||||
with:
|
||||
# name the release page for the build number so we can find it
|
||||
# easily (analogous to looking up a codeticket build page)
|
||||
name: "v${{ github.run_id }}"
|
||||
# name the release page for the branch
|
||||
name: "${{ needs.build.outputs.viewer_branch }}"
|
||||
# SL-20546: want the channel and version to be visible on the
|
||||
# release page
|
||||
body: |
|
||||
Build ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
${{ needs.build.outputs.viewer_channel }}
|
||||
${{ needs.build.outputs.viewer_version }}
|
||||
${{ needs.build.outputs.relnotes }}
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
# the only reason we generate a GH release is to post build products
|
||||
target_commitish: ${{ github.sha }}
|
||||
previous_tag: release
|
||||
append_body: true
|
||||
fail_on_unmatched_files: true
|
||||
files: |
|
||||
*.dmg
|
||||
*.exe
|
||||
*-autobuild-package.xml
|
||||
*-viewer_version.txt
|
||||
|
||||
- name: post release URL
|
||||
run: |
|
||||
echo "::notice::Release ${{ steps.release.outputs.url }}"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
build_matrix:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11,ubuntu-20.04,windows-2022]
|
||||
os: [macos-11,ubuntu-22.04,windows-2022]
|
||||
grid: [sl,os]
|
||||
addrsize: [64]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
|
@ -178,6 +178,8 @@ jobs:
|
|||
echo -n "$FS_CERT_PASS" >${build_secrets_checkout}/code-signing-osx/password.txt
|
||||
echo -n "$NOTARIZE_CREDS" | base64 --decode --output ${build_secrets_checkout}/code-signing-osx/notarize_creds.sh
|
||||
security create-keychain -p "$FS_KEYCHAIN_PASS" ~/Library/Keychains/viewer.keychain
|
||||
# notarize tool uses a specific database keychain by default we need to override this to ours.
|
||||
security default-keychain -s viewer.keychain
|
||||
security set-keychain-settings -lut 21600 ~/Library/Keychains/viewer.keychain
|
||||
security unlock-keychain -p "$FS_KEYCHAIN_PASS" ~/Library/Keychains/viewer.keychain
|
||||
security import ${build_secrets_checkout}/code-signing-osx/fs-cert.p12 -P "$FS_CERT_PASS" -A -t cert -f pkcs12 -k ~/Library/Keychains/viewer.keychain
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
configuration-path: .github/labeler.yaml
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- uses: pre-commit/action@v3.0.0
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
|
|
|
|||
|
|
@ -12,12 +12,13 @@ jobs:
|
|||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v6
|
||||
- uses: actions/stale@v9
|
||||
id: stale
|
||||
with:
|
||||
stale-pr-message: This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or it will be closed in 7 days
|
||||
days-before-stale: 30
|
||||
days-before-close: 7
|
||||
days-before-close: 7
|
||||
days-before-issue-close: -1
|
||||
exempt-pr-labels: blocked,must,should,keep
|
||||
stale-pr-label: stale
|
||||
- name: Print outputs
|
||||
|
|
|
|||
410
autobuild.xml
410
autobuild.xml
|
|
@ -22,11 +22,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>bcf0f9d160231c52869b8d81014d0ad3afe537fd</string>
|
||||
<string>0f6fbb52ffea1a55bf76a84a6688079f95674cbd</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/SDL2-2.28.5-linux64-233480131.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-sdl2/releases/download/v2.28.0-1dc88c1/SDL2-2.28.0-linux64-1dc88c1.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -138,9 +138,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>81fe1e927e4fe3c5e5f15ce6219ca883</string>
|
||||
<string>691fef2ddd57d7b6c26e87fc82d9ace3f54e078c</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/fltk-1.3.5.202282121-linux64-202282121.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-fltk/releases/download/v1.3.9-r1/fltk-1.3.9.8556992788-linux64-8556992788.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -381,36 +383,6 @@
|
|||
</map>
|
||||
</map>
|
||||
</map>
|
||||
<key>SDL</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 1997-2012 Sam Lantinga</string>
|
||||
<key>description</key>
|
||||
<string>Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.</string>
|
||||
<key>license</key>
|
||||
<string>lgpl</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/SDL.txt</string>
|
||||
<key>name</key>
|
||||
<string>SDL</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>64c1dff0e19792acec7fd32556bf4d7b</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/SDL-1.2.15-linux64-181411635.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.2.15</string>
|
||||
</map>
|
||||
<key>apr_suite</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -444,9 +416,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>1c341bdbb5fd0c8a8930f76e6c1647d4</string>
|
||||
<string>95137cd3f4d6ffa5bd7a00d7d91bd8fc272b7ca2</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/apr_suite-1.4.5.230921251-linux64-230921251.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.2-c5f3347/apr_suite-1.7.2-c5f3347-linux64-c5f3347.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -502,11 +476,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>5d1952e270a873d4587f7b943ed6e3f87d5023da</string>
|
||||
<string>a3bfbdba7e1977e7e65266ec654990bb13994bd3</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/boost-1.81-linux64-240621158.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-boost/releases/download/v1.81-3d0d7fc/boost-1.81-linux64-3d0d7fc.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -606,11 +580,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>83f9c9aff5a7b96711c04bd33cb453c108dee3a5</string>
|
||||
<string>cab0237b5194254c0c0ff6bf77bc6a2f946d4f57</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/colladadom-2.3.240621210-linux64-240621210.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-colladadom/releases/download/v2.3-2f532e1/colladadom-2.3.2f532e1-linux64-2f532e1.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -664,11 +638,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>64210ab1d7c881dbe5c78ef8f6db5a6d2b27e5d2</string>
|
||||
<string>aea0bed0f953a9371b9091f09230b41597f891f7</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/cubemaptoequirectangular-1.1.0-linux64-213500938.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-cb8785a/cubemaptoequirectangular-1.1.0-linux64-cb8785a.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -874,11 +848,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c036cc042523fb6a3dafb7134f83e52c566c0765</string>
|
||||
<string>5b957aa7f353b10ae17b7119e5b3668f48a35325</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/emoji_shortcodes-6.1.0.240620448-linux64-240620448.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-emoji-shortcodes/releases/download/v6.1.0.5413f58/emoji_shortcodes-6.1.0.5413f58-linux64-5413f58.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -932,9 +906,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>39702f98867a319b090ee04f22d82762</string>
|
||||
<string>4cd82e2dec06ddff19e9b3dc0254f2593ec80452</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/expat-2.5.0.230021327-linux64-230021327.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-expat/releases/download/v2.1.1.1f36d02/expat-2.1.1.1f36d02-linux64-1f36d02.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1017,36 +993,6 @@
|
|||
<key>version</key>
|
||||
<string>2.02.20</string>
|
||||
</map>
|
||||
<key>fontconfig</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Šegan, 2012 Google, Inc.</string>
|
||||
<key>description</key>
|
||||
<string>Fontconfig is a library for configuring and customizing font access.</string>
|
||||
<key>license</key>
|
||||
<string>bsd</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/fontconfig.txt</string>
|
||||
<key>name</key>
|
||||
<string>fontconfig</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>6fdcfcc9aa1d01164c0f7ca5590859bb</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/fontconfig-2.12.6-linux64-223020909.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>2.11.0</string>
|
||||
</map>
|
||||
<key>freetype</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -1080,11 +1026,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>a8326f592bf608095f0854383eec2baf36257ea9</string>
|
||||
<string>07a38133c008ce6f728d652d00a756bea3a70288</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/freetype-2.12.1.240700637-linux64-240700637.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-freetype/releases/download/v2.12.1-r1/freetype-2.12.1.8503093630-linux64-8503093630.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1229,34 +1175,6 @@
|
|||
<key>version</key>
|
||||
<string>1.7.0.2b109d4</string>
|
||||
</map>
|
||||
<key>gstreamer</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/></string>
|
||||
<key>license</key>
|
||||
<string>LGPL</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/gstreamer.txt</string>
|
||||
<key>name</key>
|
||||
<string>gstreamer</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>86a358f1b5a2c2baf68444b2bfc5bb32</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/gstreamer-0.10.6.180841551-linux64-180841551.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>0.10.6.314267</string>
|
||||
</map>
|
||||
<key>havok-source</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -1354,11 +1272,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>f5e5be3af96f1eb0842219a94765c04aa9c561c5</string>
|
||||
<string>bdd74e2a02c7b78fded9222140d197da4af9904e</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/icu4c-4.8.1-linux64-240621048.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-icu4c/releases/download/v4.8.1-8bff176/icu4c-4.8.1-linux64-8512575562.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1412,9 +1330,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>fd8060aa3c920e0fc63e7ecbea67bc5e</string>
|
||||
<string>23daab838f4b8f92e5dc1a2f6c568cb7b0cb43b7</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/jpegencoderbasic-1.0-linux64-213500937.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-790015a/jpegencoderbasic-1.0-linux64-790015a.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1470,9 +1390,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>324bb9deb00d256a12f8cbf686f413f0</string>
|
||||
<string>b4b2278bd2fcae85619e2145a243cca388d760d7</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/jpeglib-8c.180841548-linux64-180841548.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-jpeglib/releases/download/v8c.7846234/jpeglib-8c.7846234-linux64-7846234.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1528,9 +1450,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>352ab340f2091c93eb313cf80ac0c8cc</string>
|
||||
<string>66dce1d0c2fc19dff13db279d973773fc7e2aa13</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/jsoncpp-0.5.0.202052209-linux64-202052209.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-jsoncpp/releases/download/v0.5.0-cc63e92/jsoncpp-0.5.0.cc63e92-linux64-cc63e92.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1640,9 +1564,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>6555f040c686d8c1dec8e6264c2d3672</string>
|
||||
<string>6413d3bd4cd50c2a6b7f949eb4bd6f0c94feb984</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/libhunspell-1.3.2.180841552-linux64-180841552.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-libhunspell/releases/download/v1.3.2.650fb94/libhunspell-1.3.2.650fb94-linux64-650fb94.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1744,11 +1670,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e646a9da0ddfe1dfbffc6600d7d35f78ac48c75e</string>
|
||||
<string>39d5779fd79e23da16a7b5bf608008999004c828</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/libpng-1.6.38-240620624-linux64-240620624.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-libpng/releases/download/v1.16.38-d427738/libpng-1.6.38-8318603154-linux64-8318603154.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1909,18 +1835,18 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e50ea94bbaa4ff41bf53b84b7192df1a694c5337</string>
|
||||
<string>3a3e14563cd5fc019c3f139b82aa46ec79847709</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/llca/releases/download/v202310121525.0-d22bd98/llca-202310121530.0-common-d22bd98.tar.zst</string>
|
||||
<string>https://github.com/secondlife/llca/releases/download/v202312051403.17-0f5d9c3/llca-202312051404.0-common-0f5d9c3.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>202310121530.0</string>
|
||||
<string>202312051404.0</string>
|
||||
</map>
|
||||
<key>llphysicsextensions_source</key>
|
||||
<map>
|
||||
|
|
@ -1941,11 +1867,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>48bca5d0233d1e724a59f649a2c6c7ac5f40ec3c</string>
|
||||
<string>b037cc0b29ea70ee834cfae6dda5b7a25cd57174</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009335</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851460</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -1957,11 +1883,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>39f52d0350e130f41c5c758f7cb94e87b962c223</string>
|
||||
<string>bdea1fd5c4da9da5afde088d16188b45d0853e04</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009336</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851461</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1973,11 +1899,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>7b5e645fb7eb399abbea63bd21e8063bbb32a911</string>
|
||||
<string>f652ce0d6aef864689f0ed44255da4d9cd65a43f</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/117009339</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/144851463</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
|
@ -2151,9 +2077,11 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>50d647afc4e510af72f09dcd7a77e920</string>
|
||||
<string>6f4509dca9e32e3b4f9c4b13d875ce0e24340efc</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/meshoptimizer-0.16.222121104-linux64-222121104.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-meshoptimizer/releases/download/v160-4f905dd/meshoptimizer-160-linux64-4f905dd.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -2178,18 +2106,6 @@
|
|||
</map>
|
||||
<key>mikktspace</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
|
||||
<key>description</key>
|
||||
<string>Mikktspace Tangent Generator</string>
|
||||
<key>license</key>
|
||||
<string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
|
||||
<key>license_file</key>
|
||||
<string>mikktspace.txt</string>
|
||||
<key>name</key>
|
||||
<string>mikktspace</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
|
|
@ -2197,52 +2113,58 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b48b7ac0792d3ea8f087d99d9e4a29d8</string>
|
||||
<string>6cc1585dba85b0226a2e7033a7e2a2ceaae7c983</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104415/914944/mikktspace-1-darwin64-574859.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-darwin64-5cee1f4.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>5b719b8d3602f8dc9401cc92d606b34e</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/mikktspace-1-linux64-223421209.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>0a016b9c0c1e2c0b557e0124094da6c5</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104407/914918/mikktspace-1-windows-574859.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>02e9e5b6fe6788f4d2babb83ec544843</string>
|
||||
<string>6b7d01ad54e4a88a001f66840c32329cedb28202</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104406/914909/mikktspace-1-windows64-574859.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-windows64-5cee1f4.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>edc9782bf209e17ad1845498b42f16d733582082</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-mikktspace/releases/download/v1-5cee1f4/mikktspace-1-linux64-5cee1f4.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
|
||||
<key>license_file</key>
|
||||
<string>mikktspace.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
|
||||
<key>version</key>
|
||||
<string>1</string>
|
||||
<key>name</key>
|
||||
<string>mikktspace</string>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
|
||||
<key>description</key>
|
||||
<string>Mikktspace Tangent Generator</string>
|
||||
</map>
|
||||
<key>minizip-ng</key>
|
||||
<map>
|
||||
|
|
@ -2490,9 +2412,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>03b7df0406d7588c4fb49c2ddf0d8264</string>
|
||||
<string>90052be851c4fcecc35d8424b4f31352de14ab2f</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/ogg_vorbis-1.3.3-1.3.6.202241500-linux64-202241500.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.3-1.3.6-881f65e/ogg_vorbis-1.3.3-1.3.6.881f65e-linux64-881f65e.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -2536,11 +2460,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>52c4622c76c773deba056eeb6b0dc726cb3100bd</string>
|
||||
<string>2d20683554f0b00234bbb84d0ce7ac1be1ad70aa</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/open_libndofdev-0.14.233480318-linux64-233480318.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-open-libndofdev/releases/download/v1.14-r1/open_libndofdev-0.14.8503290964-linux64-8503290964.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -2582,9 +2506,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4f36ae378593240701fd4453bd6074c8</string>
|
||||
<string>e0fbc4874acc4167a6e2b6489fbb8258d98fd665</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/openal-1.12.854-1.1.0.180841552-linux64-180841552.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-openal-soft/releases/download/v1.23.1-18e315c/openal-1.23.1-linux64-18e315c.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -2640,9 +2566,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b1dad7c841118a3b6e03a01722d1846a</string>
|
||||
<string>8c277dde6076fb682cb07264dd70f6f2298b633f</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/openjpeg-2.5.0.230362345-linux64-230362345.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.0.ea12248/openjpeg-2.5.0.ea12248-linux64-ea12248.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -2870,9 +2798,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>d37be064bd851276dab423d723cb9b7d</string>
|
||||
<string>982c0fa427458082ea9e3cb9603904210732b64e</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/threejs-0.132.2-linux64-213500940.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-5da28d9/threejs-0.132.2-common-8454371083.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -2897,18 +2827,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>tinygltf</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-tinygltf</string>
|
||||
<key>copyright</key>
|
||||
<string>// Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors.</string>
|
||||
<key>description</key>
|
||||
<string>tinygltf import library</string>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/tinygltf_license.txt</string>
|
||||
<key>name</key>
|
||||
<string>tinygltf</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>common</key>
|
||||
|
|
@ -2916,20 +2834,34 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4dad1c0948141e1667c01a3ee755e4dc</string>
|
||||
<string>2c47ae2d0c38c86b8c2db8d9317f0ab15edfc74f</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105849/926137/tinygltf-v2.5.0-common-575729.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-tinygltf/releases/download/v2.5.0-1ae57fd/tinygltf-v2.5.0-common-1ae57fd.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/tinygltf_license.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>// Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors.</string>
|
||||
<key>version</key>
|
||||
<string>v2.5.0</string>
|
||||
<key>name</key>
|
||||
<string>tinygltf</string>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-tinygltf</string>
|
||||
<key>description</key>
|
||||
<string>tinygltf import library</string>
|
||||
<key>source</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-tinygltf</string>
|
||||
<key>source_type</key>
|
||||
<string>git</string>
|
||||
<key>version</key>
|
||||
<string>v2.5.0</string>
|
||||
</map>
|
||||
<key>tracy</key>
|
||||
<map>
|
||||
|
|
@ -2952,9 +2884,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9b6e1a1f4b0969d38a1ca8ee00aeb548</string>
|
||||
<string>49650353442698c3e05102676fe427d0ebe02f0b</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110584/960613/tracy-v0.8.1.578241-darwin64-578241.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-darwin64-eecbf72.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -2964,22 +2898,34 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>05b72ae5d733aed7d3bf142287601cc6</string>
|
||||
<string>2b80e7407e4f3e82eff3879add0e9ad63e7fcace</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110586/960637/tracy-v0.8.1.578241-windows64-578241.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-tracy/releases/download/v0.8.1-eecbf72/tracy-v0.8.1-eecbf72-windows64-eecbf72.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>bsd</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/tracy_license.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2017-2022, Bartosz Taudul (wolf@nereid.pl)</string>
|
||||
<key>version</key>
|
||||
<string>v0.8.1-eecbf72</string>
|
||||
<key>name</key>
|
||||
<string>tracy</string>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-tracy</string>
|
||||
<key>description</key>
|
||||
<string>Tracy Profiler Library</string>
|
||||
<key>source</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-tracy</string>
|
||||
<key>source_type</key>
|
||||
<string>git</string>
|
||||
<key>version</key>
|
||||
<string>v0.8.1.578241</string>
|
||||
</map>
|
||||
<key>tut</key>
|
||||
<map>
|
||||
|
|
@ -3046,9 +2992,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>0d6832fd958ec127f089e683c9b67169</string>
|
||||
<string>df66574b3d70f49570709eccd8a1cdeee996cb43</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://3p.firestormviewer.org/uriparser-0.9.4-linux64-211210958.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-uriparser/releases/download/v0.9.4-42d7a6d/uriparser-0.9.4-linux64-42d7a6d.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -3369,7 +3317,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<string>xmlrpc-epi</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<key>common</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
|
|
@ -3381,7 +3329,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<string>https://github.com/secondlife/3p-xmlrpc-epi/releases/download/v0.54.1.8a05acf/xmlrpc_epi-0.54.1.8a05acf-darwin64-8a05acf.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
<string>common</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
|
|
@ -3434,58 +3382,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e4f77ba0a9b8ec3cc3fabc51c4da81d2</string>
|
||||
<string>1a73c476b371b62066d1c3eced249660e9467e53</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/110070/956941/xxhash-0.8.1.578006-windows-578006.tar.bz2</string>
|
||||
<string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1-69ff69a/xxhash-0.8.1-69ff69a-common-69ff69a.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>fdcc803a76a3359bb426db7dac161406676d51e7</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-darwin64-7501c90.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>7acb3f94a549fbb9bd7bc16604e34f33c5365a9b</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-linux64-7501c90.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4522d075ea4703ef4b527c3039864ef735ea7953</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-xxhash/releases/download/v0.8.1.7501c90/xxhash-0.8.1.7501c90-windows64-7501c90.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>0.8.1.7501c90</string>
|
||||
<string>0.8.1-69ff69a</string>
|
||||
</map>
|
||||
<key>zlib-ng</key>
|
||||
<map>
|
||||
|
|
|
|||
25
build.sh
25
build.sh
|
|
@ -112,7 +112,8 @@ installer_CYGWIN()
|
|||
fi
|
||||
}
|
||||
|
||||
[[ -n "$GITHUB_OUTPUT" ]] || fatal "Need to export GITHUB_OUTPUT"
|
||||
# if someone wants to run build.sh outside the GitHub environment
|
||||
[[ -n "$GITHUB_OUTPUT" ]] || export GITHUB_OUTPUT='/dev/null'
|
||||
# The following is based on the Warning for GitHub multiline output strings:
|
||||
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
|
||||
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
|
||||
|
|
@ -175,28 +176,6 @@ pre_build()
|
|||
VIEWER_SYMBOL_FILE="$(native_path "$abs_build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2")"
|
||||
fi
|
||||
|
||||
# expect these variables to be set in the environment from GitHub secrets
|
||||
if [[ -n "$BUGSPLAT_DB" ]]
|
||||
then
|
||||
# don't spew credentials into build log
|
||||
set +x
|
||||
if [[ -z "$BUGSPLAT_USER" || -z "$BUGSPLAT_PASS" ]]
|
||||
then
|
||||
# older mechanism involving build-secrets repo -
|
||||
# if build_secrets_checkout isn't set, report its name
|
||||
bugsplat_sh="${build_secrets_checkout:-\$build_secrets_checkout}/bugsplat/bugsplat.sh"
|
||||
if [ -r "$bugsplat_sh" ]
|
||||
then # show that we're doing this, just not the contents
|
||||
echo source "$bugsplat_sh"
|
||||
source "$bugsplat_sh"
|
||||
else
|
||||
fatal "BUGSPLAT_USER or BUGSPLAT_PASS missing, and no $bugsplat_sh"
|
||||
fi
|
||||
fi
|
||||
set -x
|
||||
export BUGSPLAT_USER BUGSPLAT_PASS
|
||||
fi
|
||||
|
||||
# honor autobuild_configure_parameters same as sling-buildscripts
|
||||
eval_autobuild_configure_parameters=$(eval $(echo echo $autobuild_configure_parameters))
|
||||
|
||||
|
|
|
|||
|
|
@ -3,18 +3,23 @@
|
|||
> [!WARNING]
|
||||
> Please note that we do not give support for compiling the viewer on your own. However, there is a self-compilers group in Second Life that can be joined to ask questions related to compiling the viewer: [Firestorm Self Compilers](https://tinyurl.com/firestorm-self-compilers)
|
||||
|
||||
> [!NOTE]
|
||||
> These instructions only apply to Firestorm versions with AlexIvy code.
|
||||
|
||||
This procedure is based on discussions with the Firestorm Linux development team and is the only one recommended for Firestorm for Linux. System requirements are:
|
||||
- Ubuntu 20.04 x64 fully upgraded
|
||||
- Ubuntu 22.04 LTS (x86_64) - fully upgraded (this is also now the minimum requirement for running the viewer).
|
||||
- 16GB or more RAM ([Low Memory Caution](#common-issuesbugsglitches-and-solutions))
|
||||
- 64GB hard drive space
|
||||
- 4 or more core CPU (you could get by with 2 cores, but the process will take much longer)
|
||||
- GCC 11 compiler (which is the default version on Ubuntu 22.04 LTS)
|
||||
|
||||
Due to the age of the build OS, it is recommended that you use a virtual machine, ensuring the guest can meet the hardware requirements.
|
||||
It is recommended that you use a virtual machine for compiling, ensuring the guest can meet the hardware requirements.
|
||||
|
||||
This procedure may or may not work on other Linux distributions.
|
||||
This procedure may or may not work on other Linux distributions (or you might need to adjust some of the package names to suit the distribution you are using).
|
||||
|
||||
> [!WARNING]
|
||||
> A system with a glibc version of at least 2.34 is required (Ubuntu 22.04 LTS meets this requirement)
|
||||
> Building on a system with a glibc version older than 2.34 will likely result in linker errors.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Only 64 bit builds are possible - 32 bit support was dropped quite some time ago.
|
||||
|
||||
## Establish your programming environment
|
||||
|
||||
|
|
@ -31,35 +36,22 @@ A few packages must be installed on the build system. Some may already be instal
|
|||
| | | | | | |
|
||||
| --------------- | ---------------- | ------------- | ------------------ | ---------------- | ------ |
|
||||
| libgl1-mesa-dev | libglu1-mesa-dev | libpulse-dev | build-essential | python3-pip | git |
|
||||
| libssl-dev | libxinerama-dev | libxrandr-dev | libfontconfig1-dev | libfreetype6-dev | gcc-10 |
|
||||
| | | | | | |
|
||||
| libssl-dev | libxinerama-dev | libxrandr-dev | libfontconfig-dev | libfreetype6-dev | gcc-11 |
|
||||
| cmake | | | | | |
|
||||
|
||||
```
|
||||
sudo apt install libgl1-mesa-dev libglu1-mesa-dev libpulse-dev build-essential python3-pip git libssl-dev libxinerama-dev libxrandr-dev libfontconfig1-dev libfreetype6-dev gcc-10
|
||||
```
|
||||
|
||||
### CMake
|
||||
|
||||
CMake version 3.18 is required but not available in Ubuntu's repositories, we have to build it from source
|
||||
|
||||
```
|
||||
wget https://github.com/Kitware/CMake/releases/download/v3.18.0/cmake-3.18.0.tar.gz
|
||||
tar xvf cmake-3.18.0.tar.gz
|
||||
cd cmake-3.18.0
|
||||
./bootstrap --parallel=$(nproc) --prefix=/usr && make -j $(nproc) && sudo make install
|
||||
sudo apt install libgl1-mesa-dev libglu1-mesa-dev libpulse-dev build-essential python3-pip git libssl-dev libxinerama-dev libxrandr-dev libfontconfig-dev libfreetype6-dev gcc-11 cmake
|
||||
```
|
||||
|
||||
### Install Autobuild
|
||||
|
||||
Autobuild is a Linden Lab resource that does all the hard work.
|
||||
|
||||
You can install it using the same versions as our automated builds as follows:
|
||||
```
|
||||
sudo pip3 install --upgrade pip
|
||||
sudo pip3 install git+https://github.com/secondlife/autobuild.git#egg=autobuild
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Check Autobuild version to be "autobuild 3.8" or higher: `autobuild --version`
|
||||
|
||||
Check Autobuild version to be "autobuild 3.9.3" or higher: `autobuild --version`
|
||||
## Download the source code
|
||||
|
||||
There are two required repositories, the viewer itself and the build variables. An optional third repository is used to configure and package FMOD Studio.
|
||||
|
|
@ -81,7 +73,7 @@ The rest of this document will assume the default directory, `phoenix-firestorm`
|
|||
|
||||
### Clone the Autobuild build variables
|
||||
|
||||
Autobuild 3.0 uses a separate file to control compiler options, switches, and the like for different configurations.
|
||||
Autobuild uses a separate file to control compiler options, switches, and the like for different configurations.
|
||||
|
||||
```
|
||||
cd ~/src
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ sudo python3 get-pip.py
|
|||
The Linden Lab [Autobuild](https://github.com/secondlife/autobuild) tool.
|
||||
- Use the following command to install it on your machine:
|
||||
```
|
||||
pip3 install --user git+https://bitbucket.org/lindenlab/autobuild.git#egg=autobuild
|
||||
pip3 install --user -r requirements.txt
|
||||
```
|
||||
|
||||
- Add it to your PATH environment variable so it can be found by the shell. The macOS-approved way to do this is to issue the following command (This change will not take effect until the next time you open a Terminal window.):
|
||||
|
|
@ -53,7 +53,7 @@ echo '~/Library/Python/3.7/bin/' | sudo tee /etc/paths.d/99-autobuild
|
|||
export PATH=$PATH:~/Library/Python/3.7/bin/
|
||||
```
|
||||
|
||||
- Check Autobuild version to be "autobuild 3.8" or higher: `autobuild --version`
|
||||
- Check Autobuild version to be "autobuild 3.9.3" or higher: `autobuild --version`
|
||||
|
||||
### Additional third party libraries
|
||||
If you want to use licensed FMOD Studio API or KDU build libraries (they are optional) you have to provide these yourself. If you're building Firestorm as part of the project team, ask for the libraries for fmodstudio and kdu. Put them into `/opt/firestorm`.
|
||||
|
|
|
|||
|
|
@ -93,9 +93,11 @@ If they all report sensible values and not "Command not found" errors, then you
|
|||
### Set up Autobuild
|
||||
|
||||
- Install Autobuild
|
||||
You can install autobuild and its dependencies using the `requirements.txt` file that is part of the repo, this will build using the same versions that our official builds use.
|
||||
- Open Windows Command Prompt and enter: <code>pip install -r requirements.txt</code>
|
||||
- Autobuild will be installed. **Earlier versions of Autobuild could be made to work by just putting the source files into your path correctly; this is no longer true - Autobuild _must_ be installed as described here.**
|
||||
- Open Windows Command Prompt and enter:
|
||||
`pip install git+https://github.com/secondlife/autobuild.git#egg=autobuild`
|
||||
- Autobuild will be installed. **Earlier versions of Autobuild could be made to work by just putting the source files into your path correctly; this is no longer true - Autobuild _must_ be installed as described here.**
|
||||
- Set environment variable AUTOBUILD_VSVER to 170 (170 = Visual Studio 2022).
|
||||
- Check Autobuild version to be "autobuild 3.8" or higher:
|
||||
`autobuild --version`
|
||||
|
|
|
|||
|
|
@ -296,6 +296,7 @@ Beq Janus
|
|||
SL-18637
|
||||
SL-19317
|
||||
SL-19660
|
||||
SL-20610
|
||||
Beth Walcher
|
||||
Bezilon Kasei
|
||||
Biancaluce Robbiani
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
Textures imported via Build->Upload->Material that have an all opaque (255) alpha channel should have their alpha channel removed before upload.
|
||||
|
||||
1. Make 4 images that have different colors but all 255 alpha channels
|
||||
2. Upload them all using Build->Upload->Material, with one in each of the material texture slots
|
||||
3. Verify that using the textures as a blinn-phong diffuse map does not make the corresponding face render in the alpha pass (face should stay visible after disabling alpha pass by unchecking Advanced->Render Types->Alpha).
|
||||
|
|
@ -12,6 +12,6 @@ if (WINDOWS)
|
|||
elseif (DARWIN)
|
||||
target_link_libraries( ll::jsoncpp INTERFACE libjson_darwin_libmt.a )
|
||||
elseif (LINUX)
|
||||
target_link_libraries( ll::jsoncpp INTERFACE libjson_linux-gcc-5.4.0_libmt.a )
|
||||
target_link_libraries( ll::jsoncpp INTERFACE libjson_linux-gcc-11_libmt.a )
|
||||
endif (WINDOWS)
|
||||
target_include_directories( ll::jsoncpp SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@ public:
|
|||
* ClassicCallback must not itself be copied or moved! Once you've passed
|
||||
* get_userdata() to some API, this object MUST remain at that address.
|
||||
*/
|
||||
// However, we can't yet count on C++17 Class Template Argument Deduction,
|
||||
// which means makeClassicCallback() is still useful, which means we MUST
|
||||
// be able to return one to construct into caller's instance (move ctor).
|
||||
// Possible defense: bool 'referenced' data member set by get_userdata(),
|
||||
// with an llassert_always(! referenced) check in the move constructor.
|
||||
// However, makeClassicCallback() is useful for deducing the CALLABLE
|
||||
// type, which means we MUST be able to return one to construct into
|
||||
// caller's instance (move ctor). Possible defense: bool 'referenced' data
|
||||
// member set by get_userdata(), with an llassert_always(! referenced)
|
||||
// check in the move constructor.
|
||||
ClassicCallback(ClassicCallback const&) = delete;
|
||||
ClassicCallback(ClassicCallback&&) = default; // delete;
|
||||
ClassicCallback& operator=(ClassicCallback const&) = delete;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver
|
|||
const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector
|
||||
const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver
|
||||
const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver
|
||||
const LLUUID IMG_WHITE ("5748decc-f629-461c-9a36-a35a221fe21f"); // dataserver
|
||||
|
||||
const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver
|
||||
const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver
|
||||
|
|
@ -71,6 +72,11 @@ const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // V
|
|||
|
||||
const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER
|
||||
|
||||
const LLUUID DEFAULT_OBJECT_TEXTURE ("89556747-24cb-43ed-920b-47caed15465f"); // On dataserver
|
||||
const LLUUID DEFAULT_OBJECT_SPECULAR ("87e0e8f7-8729-1ea8-cfc9-8915773009db"); // On dataserver
|
||||
const LLUUID DEFAULT_OBJECT_NORMAL ("85f28839-7a1c-b4e3-d71d-967792970a7b"); // On dataserver
|
||||
const LLUUID BLANK_OBJECT_NORMAL ("5b53359e-59dd-d8a2-04c3-9e65134da47a"); // VIEWER (has a verion on dataserver, but with compression artifacts)
|
||||
|
||||
const LLUUID IMG_USE_BAKED_HEAD ("5a9f4a74-30f2-821c-b88d-70499d3e7183");
|
||||
const LLUUID IMG_USE_BAKED_UPPER ("ae2de45c-d252-50b8-5c6e-19f39ce79317");
|
||||
const LLUUID IMG_USE_BAKED_LOWER ("24daea5f-0539-cfcf-047f-fbc40b2786ba");
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ LL_COMMON_API extern const LLUUID IMG_FIRE;
|
|||
LL_COMMON_API extern const LLUUID IMG_FACE_SELECT;
|
||||
LL_COMMON_API extern const LLUUID IMG_DEFAULT_AVATAR;
|
||||
LL_COMMON_API extern const LLUUID IMG_INVISIBLE;
|
||||
LL_COMMON_API extern const LLUUID IMG_WHITE;
|
||||
|
||||
LL_COMMON_API extern const LLUUID IMG_EXPLOSION;
|
||||
LL_COMMON_API extern const LLUUID IMG_EXPLOSION_2;
|
||||
|
|
@ -234,6 +235,10 @@ LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX3;
|
|||
|
||||
LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL;
|
||||
|
||||
LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_TEXTURE;
|
||||
LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_SPECULAR;
|
||||
LL_COMMON_API extern const LLUUID DEFAULT_OBJECT_NORMAL;
|
||||
LL_COMMON_API extern const LLUUID BLANK_OBJECT_NORMAL;
|
||||
|
||||
// radius within which a chat message is fully audible
|
||||
const F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ BOOL LLApp::sLogInSignal = FALSE;
|
|||
// Keeps track of application status
|
||||
LLScalarCond<LLApp::EAppStatus> LLApp::sStatus{LLApp::APP_STATUS_STOPPED};
|
||||
LLAppErrorHandler LLApp::sErrorHandler = NULL;
|
||||
BOOL LLApp::sErrorThreadRunning = FALSE;
|
||||
|
||||
|
||||
LLApp::LLApp()
|
||||
|
|
@ -793,13 +792,8 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
|
|||
return;
|
||||
}
|
||||
|
||||
// Flag status to ERROR, so thread_error does its work.
|
||||
// Flag status to ERROR
|
||||
LLApp::setError();
|
||||
// Block in the signal handler until somebody says that we're done.
|
||||
while (LLApp::sErrorThreadRunning && !LLApp::isStopped())
|
||||
{
|
||||
ms_sleep(10);
|
||||
}
|
||||
|
||||
if (LLApp::sLogInSignal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -291,7 +291,6 @@ protected:
|
|||
|
||||
static void setStatus(EAppStatus status); // Use this to change the application status.
|
||||
static LLScalarCond<EAppStatus> sStatus; // Reflects current application status
|
||||
static BOOL sErrorThreadRunning; // Set while the error thread is running
|
||||
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
|
||||
std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ std::string LLBase64::encode(const U8* input, size_t input_size)
|
|||
&& input_size > 0)
|
||||
{
|
||||
// Yes, it returns int.
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow(input_size));
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow<size_t>(input_size));
|
||||
char* b64_buffer = new char[b64_buffer_length];
|
||||
|
||||
// This is faster than apr_base64_encode() if you know
|
||||
|
|
@ -52,7 +52,7 @@ std::string LLBase64::encode(const U8* input, size_t input_size)
|
|||
b64_buffer_length = apr_base64_encode_binary(
|
||||
b64_buffer,
|
||||
input,
|
||||
narrow(input_size));
|
||||
narrow<size_t>(input_size));
|
||||
output.assign(b64_buffer);
|
||||
delete[] b64_buffer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ LLCoros::LLCoros():
|
|||
// Previously we used
|
||||
// boost::context::guarded_stack_allocator::default_stacksize();
|
||||
// empirically this is insufficient.
|
||||
mStackSize(768*1024),
|
||||
mStackSize(900*1024),
|
||||
// mCurrent does NOT own the current CoroData instance -- it simply
|
||||
// points to it. So initialize it with a no-op deleter.
|
||||
mCurrent{ [](CoroData*){} }
|
||||
|
|
@ -278,6 +278,7 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
|
|||
catch (std::bad_alloc&)
|
||||
{
|
||||
// Out of memory on stack allocation?
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
printActiveCoroutines();
|
||||
LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,11 +87,10 @@ protected:
|
|||
}
|
||||
void addEntry(Index index, Entry *entry)
|
||||
{
|
||||
if (lookup(index))
|
||||
if (!this->emplace(index, entry).second)
|
||||
{
|
||||
LL_ERRS() << "Dictionary entry already added (attempted to add duplicate entry)" << LL_ENDL;
|
||||
}
|
||||
(*this)[index] = entry;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1619,6 +1619,48 @@ namespace LLError
|
|||
{
|
||||
return out << boost::stacktrace::stacktrace();
|
||||
}
|
||||
|
||||
// LLOutOfMemoryWarning
|
||||
std::string LLUserWarningMsg::sLocalizedOutOfMemoryTitle;
|
||||
std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning;
|
||||
LLUserWarningMsg::Handler LLUserWarningMsg::sHandler;
|
||||
|
||||
void LLUserWarningMsg::show(const std::string& message)
|
||||
{
|
||||
if (sHandler)
|
||||
{
|
||||
sHandler(std::string(), message);
|
||||
}
|
||||
}
|
||||
|
||||
void LLUserWarningMsg::showOutOfMemory()
|
||||
{
|
||||
if (sHandler && !sLocalizedOutOfMemoryTitle.empty())
|
||||
{
|
||||
sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning);
|
||||
}
|
||||
}
|
||||
|
||||
void LLUserWarningMsg::showMissingFiles()
|
||||
{
|
||||
// Files Are missing, likely can't localize.
|
||||
const std::string error_string =
|
||||
"Firestorm viewer couldn't access some of the files it needs and will be closed."
|
||||
"\n\nPlease reinstall viewer from https://firestormviewer.org/download and "
|
||||
"contact https://www.firestormviewer.org/support if issue persists after reinstall.";
|
||||
sHandler("Missing Files", error_string);
|
||||
}
|
||||
|
||||
void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler)
|
||||
{
|
||||
sHandler = handler;
|
||||
}
|
||||
|
||||
void LLUserWarningMsg::setOutOfMemoryStrings(const std::string& title, const std::string& message)
|
||||
{
|
||||
sLocalizedOutOfMemoryTitle = title;
|
||||
sLocalizedOutOfMemoryWarning = message;
|
||||
}
|
||||
}
|
||||
|
||||
void crashdriver(void (*callback)(int*))
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llpreprocessor.h"
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <functional> // std::function
|
||||
|
||||
// <FS:Ansariel> Disable C6011 code analyses warning for now popping up everywhere because of the LL_ENDL / LLERROR_CRASH macro
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -313,6 +314,28 @@ namespace LLError
|
|||
{
|
||||
friend std::ostream& operator<<(std::ostream& out, const LLStacktrace&);
|
||||
};
|
||||
|
||||
// Provides access to OS notification popup on error, since
|
||||
// not everything has access to OS's messages
|
||||
class LLUserWarningMsg
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(const std::string&, const std::string&)> Handler;
|
||||
static void setHandler(const Handler&);
|
||||
static void setOutOfMemoryStrings(const std::string& title, const std::string& message);
|
||||
|
||||
// When viewer encounters bad alloc or can't access files try warning user about reasons
|
||||
static void showOutOfMemory();
|
||||
static void showMissingFiles();
|
||||
// Genering error
|
||||
static void show(const std::string&);
|
||||
|
||||
private:
|
||||
// needs to be preallocated before viewer runs out of memory
|
||||
static std::string sLocalizedOutOfMemoryTitle;
|
||||
static std::string sLocalizedOutOfMemoryWarning;
|
||||
static Handler sHandler;
|
||||
};
|
||||
}
|
||||
|
||||
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llerror.h"
|
||||
#include "llerrorcontrol.h"
|
||||
|
||||
|
||||
// used to attach and extract stacktrace information to/from boost::exception,
|
||||
// see https://www.boost.org/doc/libs/release/doc/html/stacktrace/getting_started.html#stacktrace.getting_started.exceptions_with_stacktrace
|
||||
// apparently the struct passed as the first template param needs no definition?
|
||||
|
|
|
|||
|
|
@ -46,33 +46,32 @@
|
|||
template <class Type> class LLPointer
|
||||
{
|
||||
public:
|
||||
|
||||
LLPointer() :
|
||||
LLPointer() :
|
||||
mPointer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLPointer(Type* ptr) :
|
||||
LLPointer(Type* ptr) :
|
||||
mPointer(ptr)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
LLPointer(const LLPointer<Type>& ptr) :
|
||||
LLPointer(const LLPointer<Type>& ptr) :
|
||||
mPointer(ptr.mPointer)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
// Support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLPointer(const LLPointer<Subclass>& ptr) :
|
||||
LLPointer(const LLPointer<Subclass>& ptr) :
|
||||
mPointer(ptr.get())
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
~LLPointer()
|
||||
~LLPointer()
|
||||
{
|
||||
unref();
|
||||
}
|
||||
|
|
@ -83,39 +82,39 @@ public:
|
|||
const Type& operator*() const { return *mPointer; }
|
||||
Type& operator*() { return *mPointer; }
|
||||
|
||||
operator BOOL() const { return (mPointer != NULL); }
|
||||
operator bool() const { return (mPointer != NULL); }
|
||||
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 Type*() const { return mPointer; }
|
||||
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
operator Type*() const { return mPointer; }
|
||||
bool operator !=(Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
|
||||
LLPointer<Type>& operator =(Type* ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(Type* ptr)
|
||||
{
|
||||
assign(ptr);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
|
||||
{
|
||||
assign(ptr);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
|
||||
{
|
||||
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
|
||||
{
|
||||
assign(ptr.get());
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Just exchange the pointers, which will not change the reference counts.
|
||||
static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
|
||||
{
|
||||
|
|
@ -129,16 +128,6 @@ protected:
|
|||
void ref();
|
||||
void unref();
|
||||
#else
|
||||
|
||||
void assign(const LLPointer<Type>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.mPointer )
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
}
|
||||
void ref()
|
||||
{
|
||||
if (mPointer)
|
||||
|
|
@ -161,7 +150,18 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LL_LIBRARY_INCLUDE
|
||||
|
||||
void assign(const LLPointer<Type>& ptr)
|
||||
{
|
||||
if (mPointer != ptr.mPointer)
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Type* mPointer;
|
||||
};
|
||||
|
|
@ -169,18 +169,18 @@ protected:
|
|||
template <class Type> class LLConstPointer
|
||||
{
|
||||
public:
|
||||
LLConstPointer() :
|
||||
LLConstPointer() :
|
||||
mPointer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLConstPointer(const Type* ptr) :
|
||||
LLConstPointer(const Type* ptr) :
|
||||
mPointer(ptr)
|
||||
{
|
||||
ref();
|
||||
}
|
||||
|
||||
LLConstPointer(const LLConstPointer<Type>& ptr) :
|
||||
LLConstPointer(const LLConstPointer<Type>& ptr) :
|
||||
mPointer(ptr.mPointer)
|
||||
{
|
||||
ref();
|
||||
|
|
@ -188,7 +188,7 @@ public:
|
|||
|
||||
// support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLConstPointer(const LLConstPointer<Subclass>& ptr) :
|
||||
LLConstPointer(const LLConstPointer<Subclass>& ptr) :
|
||||
mPointer(ptr.get())
|
||||
{
|
||||
ref();
|
||||
|
|
@ -203,55 +203,55 @@ 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); }
|
||||
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 const Type*() const { return mPointer; }
|
||||
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
operator const Type*() const { return mPointer; }
|
||||
bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
|
||||
bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
|
||||
bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
|
||||
bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
|
||||
bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
|
||||
|
||||
LLConstPointer<Type>& operator =(const Type* ptr)
|
||||
LLConstPointer<Type>& operator =(const Type* ptr)
|
||||
{
|
||||
if( mPointer != ptr )
|
||||
{
|
||||
unref();
|
||||
mPointer = ptr;
|
||||
unref();
|
||||
mPointer = ptr;
|
||||
ref();
|
||||
}
|
||||
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
|
||||
{
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.mPointer )
|
||||
{
|
||||
unref();
|
||||
unref();
|
||||
mPointer = ptr.mPointer;
|
||||
ref();
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
|
||||
template<typename Subclass>
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
|
||||
{
|
||||
LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
|
||||
{
|
||||
if( mPointer != ptr.get() )
|
||||
{
|
||||
unref();
|
||||
unref();
|
||||
mPointer = ptr.get();
|
||||
ref();
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Just exchange the pointers, which will not change the reference counts.
|
||||
static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)
|
||||
{
|
||||
|
|
@ -262,11 +262,11 @@ public:
|
|||
|
||||
protected:
|
||||
#ifdef LL_LIBRARY_INCLUDE
|
||||
void ref();
|
||||
void ref();
|
||||
void unref();
|
||||
#else
|
||||
void ref()
|
||||
{
|
||||
#else // LL_LIBRARY_INCLUDE
|
||||
void ref()
|
||||
{
|
||||
if (mPointer)
|
||||
{
|
||||
mPointer->ref();
|
||||
|
|
@ -277,9 +277,9 @@ protected:
|
|||
{
|
||||
if (mPointer)
|
||||
{
|
||||
const Type *tempp = mPointer;
|
||||
const Type *temp = mPointer;
|
||||
mPointer = NULL;
|
||||
tempp->unref();
|
||||
temp->unref();
|
||||
if (mPointer != NULL)
|
||||
{
|
||||
LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
|
||||
|
|
@ -287,7 +287,8 @@ protected:
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // LL_LIBRARY_INCLUDE
|
||||
|
||||
protected:
|
||||
const Type* mPointer;
|
||||
};
|
||||
|
|
@ -297,13 +298,13 @@ class LLCopyOnWritePointer : public LLPointer<Type>
|
|||
{
|
||||
public:
|
||||
typedef LLCopyOnWritePointer<Type> self_t;
|
||||
typedef LLPointer<Type> pointer_t;
|
||||
|
||||
LLCopyOnWritePointer()
|
||||
typedef LLPointer<Type> pointer_t;
|
||||
|
||||
LLCopyOnWritePointer()
|
||||
: mStayUnique(false)
|
||||
{}
|
||||
|
||||
LLCopyOnWritePointer(Type* ptr)
|
||||
LLCopyOnWritePointer(Type* ptr)
|
||||
: LLPointer<Type>(ptr),
|
||||
mStayUnique(false)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@
|
|||
* to restore uniform distribution.
|
||||
*/
|
||||
|
||||
static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
|
||||
// gRandomGenerator is a stateful static object, which is therefore not
|
||||
// inherently thread-safe.
|
||||
static thread_local LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
|
||||
|
||||
// no default implementation, only specific F64 and F32 specializations
|
||||
template <typename REAL>
|
||||
|
|
@ -71,7 +73,7 @@ inline F64 ll_internal_random<F64>()
|
|||
// CPUs (or at least multi-threaded processes) seem to
|
||||
// occasionally give an obviously incorrect random number -- like
|
||||
// 5^15 or something. Sooooo, clamp it as described above.
|
||||
F64 rv = gRandomGenerator();
|
||||
F64 rv{ gRandomGenerator() };
|
||||
if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0);
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -79,7 +81,13 @@ inline F64 ll_internal_random<F64>()
|
|||
template <>
|
||||
inline F32 ll_internal_random<F32>()
|
||||
{
|
||||
return F32(ll_internal_random<F64>());
|
||||
// *HACK: clamp the result as described above.
|
||||
// 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<F32>(gRandomGenerator()) };
|
||||
if(!((rv >= 0.0f) && (rv < 1.0f))) return fmodf(rv, 1.0f);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*------------------------------ F64 aliases -------------------------------*/
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "llerror.h"
|
||||
|
||||
// maximum reference count before sounding memory leak alarm
|
||||
const S32 gMaxRefCount = S32_MAX;
|
||||
const S32 gMaxRefCount = LL_REFCOUNT_FREE;
|
||||
|
||||
LLRefCount::LLRefCount(const LLRefCount& other)
|
||||
: mRef(0)
|
||||
|
|
@ -49,7 +49,7 @@ LLRefCount::LLRefCount() :
|
|||
}
|
||||
|
||||
LLRefCount::~LLRefCount()
|
||||
{
|
||||
{
|
||||
if (mRef != LL_REFCOUNT_FREE && mRef != 0)
|
||||
{
|
||||
LL_ERRS() << "deleting non-zero reference" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -51,24 +51,20 @@ protected:
|
|||
public:
|
||||
LLRefCount();
|
||||
|
||||
inline void validateRefCount() const
|
||||
{
|
||||
llassert(mRef > 0); // ref count below 0, likely corrupted
|
||||
llassert(mRef < gMaxRefCount); // ref count excessive, likely memory leak
|
||||
}
|
||||
|
||||
inline void ref() const
|
||||
{
|
||||
mRef++;
|
||||
validateRefCount();
|
||||
}
|
||||
{
|
||||
llassert(mRef != LL_REFCOUNT_FREE); // object is deleted
|
||||
mRef++;
|
||||
llassert(mRef < gMaxRefCount); // ref count excessive, likely memory leak
|
||||
}
|
||||
|
||||
inline S32 unref() const
|
||||
{
|
||||
validateRefCount();
|
||||
llassert(mRef != LL_REFCOUNT_FREE); // object is deleted
|
||||
llassert(mRef > 0); // ref count below 1, likely corrupted
|
||||
if (0 == --mRef)
|
||||
{
|
||||
mRef = LL_REFCOUNT_FREE; // set to nonsense yet recognizable value to aid in debugging
|
||||
mRef = LL_REFCOUNT_FREE; // set to nonsense yet recognizable value to aid in debugging
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -82,8 +78,8 @@ public:
|
|||
return mRef;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable S32 mRef;
|
||||
private:
|
||||
mutable S32 mRef;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -106,7 +102,7 @@ protected:
|
|||
public:
|
||||
LLThreadSafeRefCount();
|
||||
LLThreadSafeRefCount(const LLThreadSafeRefCount&);
|
||||
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
|
||||
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
|
||||
{
|
||||
mRef = 0;
|
||||
return *this;
|
||||
|
|
@ -114,8 +110,8 @@ public:
|
|||
|
||||
void ref()
|
||||
{
|
||||
mRef++;
|
||||
}
|
||||
mRef++;
|
||||
}
|
||||
|
||||
void unref()
|
||||
{
|
||||
|
|
@ -136,36 +132,36 @@ public:
|
|||
return currentVal;
|
||||
}
|
||||
|
||||
private:
|
||||
LLAtomicS32 mRef;
|
||||
private:
|
||||
LLAtomicS32 mRef;
|
||||
};
|
||||
|
||||
/**
|
||||
* intrusive pointer support for LLThreadSafeRefCount
|
||||
* this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
|
||||
*/
|
||||
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
|
||||
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
|
||||
inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
p->unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* intrusive pointer support
|
||||
* this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
|
||||
*/
|
||||
inline void intrusive_ptr_add_ref(LLRefCount* p)
|
||||
inline void intrusive_ptr_add_ref(LLRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLRefCount* p)
|
||||
inline void intrusive_ptr_release(LLRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
p->unref();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -197,12 +197,12 @@ public:
|
|||
typename std::enable_if<std::is_integral<VALUE>::value &&
|
||||
! std::is_same<VALUE, Boolean>::value,
|
||||
bool>::type = true>
|
||||
LLSD(VALUE v): LLSD(Integer(narrow(v))) {}
|
||||
LLSD(VALUE v): LLSD(Integer(narrow<VALUE>(v))) {}
|
||||
// support construction from F32 et al.
|
||||
template <typename VALUE,
|
||||
typename std::enable_if<std::is_floating_point<VALUE>::value,
|
||||
bool>::type = true>
|
||||
LLSD(VALUE v): LLSD(Real(narrow(v))) {}
|
||||
LLSD(VALUE v): LLSD(Real(narrow<VALUE>(v))) {}
|
||||
//@}
|
||||
|
||||
/** @name Scalar Assignment */
|
||||
|
|
|
|||
|
|
@ -2174,7 +2174,7 @@ std::string zip_llsd(LLSD& data)
|
|||
|
||||
U8 out[CHUNK];
|
||||
|
||||
strm.avail_in = narrow(source.size());
|
||||
strm.avail_in = narrow<size_t>(source.size());
|
||||
strm.next_in = (U8*) source.data();
|
||||
U8* output = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -197,12 +197,12 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr,
|
|||
// *FIX: memory inefficient.
|
||||
// *TODO: convert to use LLBase64
|
||||
ostr << pre << "<binary encoding=\"base64\">";
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow(buffer.size()));
|
||||
int b64_buffer_length = apr_base64_encode_len(narrow<size_t>(buffer.size()));
|
||||
char* b64_buffer = new char[b64_buffer_length];
|
||||
b64_buffer_length = apr_base64_encode_binary(
|
||||
b64_buffer,
|
||||
&buffer[0],
|
||||
narrow(buffer.size()));
|
||||
narrow<size_t>(buffer.size()));
|
||||
ostr.write(b64_buffer, b64_buffer_length - 1);
|
||||
delete[] b64_buffer;
|
||||
ostr << "</binary>" << post;
|
||||
|
|
@ -415,11 +415,18 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
|
|||
if (buffer)
|
||||
{
|
||||
((char*) buffer)[count ? count - 1 : 0] = '\0';
|
||||
if (mEmitErrors)
|
||||
{
|
||||
LL_INFOS() << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*)buffer << LL_ENDL;
|
||||
}
|
||||
}
|
||||
if (mEmitErrors)
|
||||
{
|
||||
LL_INFOS() << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mEmitErrors)
|
||||
{
|
||||
LL_INFOS() << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR, null buffer" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
data = LLSD();
|
||||
return LLSDParser::PARSE_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -496,7 +496,7 @@ public:
|
|||
|
||||
static DERIVED_TYPE* getInstance()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
|
||||
//LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; // TODO -- reenable this when we have a fix for using Tracy with coroutines
|
||||
// We know the viewer has LLSingleton dependency circularities. If you
|
||||
// feel strongly motivated to eliminate them, cheers and good luck.
|
||||
// (At that point we could consider a much simpler locking mechanism.)
|
||||
|
|
|
|||
|
|
@ -1533,9 +1533,17 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// EXT-1565 : Zai Lynch, James Linden : 15/Oct/09
|
||||
// [BSI] Feedback: Viewer clock mentions SLT, but would prefer it to show PST/PDT
|
||||
// "slt" = Second Life Time, which is deprecated.
|
||||
// If not utc or user local time, fallback to Pacific time
|
||||
replacement = LLStringOps::getPacificDaylightTime() ? "PDT" : "PST";
|
||||
#else
|
||||
// SL-20370 : Steeltoe Linden : 29/Sep/23
|
||||
// Change "PDT" to "SLT" on menu bar
|
||||
replacement = "SLT";
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -929,7 +929,7 @@ void LLMemoryInfo::stream(std::ostream& s) const
|
|||
// Now stream stats
|
||||
BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
|
||||
{
|
||||
s << pfx << std::setw(narrow(key_width+1)) << (pair.first + ':') << ' ';
|
||||
s << pfx << std::setw(narrow<size_t>(key_width+1)) << (pair.first + ':') << ' ';
|
||||
LLSD value(pair.second);
|
||||
if (value.isInteger())
|
||||
s << std::setw(12) << value.asInteger();
|
||||
|
|
|
|||
|
|
@ -113,15 +113,16 @@ LL_COMMON_API bool on_main_thread()
|
|||
return (LLThread::currentID() == main_thread());
|
||||
}
|
||||
|
||||
LL_COMMON_API void assert_main_thread()
|
||||
LL_COMMON_API bool assert_main_thread()
|
||||
{
|
||||
auto curr = LLThread::currentID();
|
||||
auto main = main_thread();
|
||||
if (curr != main)
|
||||
{
|
||||
LL_WARNS() << "Illegal execution from thread id " << curr
|
||||
<< " outside main thread " << main << LL_ENDL;
|
||||
}
|
||||
if (curr == main)
|
||||
return true;
|
||||
|
||||
LL_WARNS() << "Illegal execution from thread id " << curr
|
||||
<< " outside main thread " << main << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// this function has become moot
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public:
|
|||
|
||||
//============================================================================
|
||||
|
||||
extern LL_COMMON_API void assert_main_thread();
|
||||
extern LL_COMMON_API bool assert_main_thread();
|
||||
extern LL_COMMON_API bool on_main_thread();
|
||||
|
||||
#endif // LL_LLTHREAD_H
|
||||
|
|
|
|||
|
|
@ -342,13 +342,7 @@ bool LLThreadSafeQueue<ElementT, QueueT>::pushIfOpen(T&& element)
|
|||
return true;
|
||||
|
||||
// Storage Full. Wait for signal.
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour. Time bound the sleep
|
||||
// mCapacityCond.wait(lock1);
|
||||
// When the queue is full and the consuming thread has exited we would never wake up.
|
||||
// For safety, we now wait max half a second then recheck close.
|
||||
const auto timeout = std::chrono::milliseconds(500);
|
||||
mCapacityCond.wait_for(lock1, timeout);
|
||||
// </FS:Beq>
|
||||
mCapacityCond.wait(lock1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
MemStatHandle gTraceMemStat("LLTrace");
|
||||
|
||||
StatBase::StatBase( const char* name, const char* description )
|
||||
: mName(name),
|
||||
mDescription(description ? description : "")
|
||||
|
|
@ -65,7 +63,7 @@ void TimeBlockTreeNode::setParent( BlockTimerStatHandle* parent )
|
|||
llassert_always(parent != mBlock);
|
||||
llassert_always(parent != NULL);
|
||||
|
||||
TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(narrow(parent->getIndex()));
|
||||
TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(narrow<size_t>(parent->getIndex()));
|
||||
if (!parent_tree_node) return;
|
||||
|
||||
if (mParent)
|
||||
|
|
|
|||
|
|
@ -211,61 +211,6 @@ void add(CountStatHandle<T>& count, VALUE_T value)
|
|||
#endif
|
||||
}
|
||||
|
||||
template<>
|
||||
class StatType<MemAccumulator::AllocationFacet>
|
||||
: public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
|
||||
StatType(const char* name, const char* description = "")
|
||||
: StatType<MemAccumulator>(name, description)
|
||||
{}
|
||||
};
|
||||
|
||||
template<>
|
||||
class StatType<MemAccumulator::DeallocationFacet>
|
||||
: public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
|
||||
StatType(const char* name, const char* description = "")
|
||||
: StatType<MemAccumulator>(name, description)
|
||||
{}
|
||||
};
|
||||
|
||||
class MemStatHandle : public StatType<MemAccumulator>
|
||||
{
|
||||
public:
|
||||
typedef StatType<MemAccumulator> stat_t;
|
||||
MemStatHandle(const char* name, const char* description = "")
|
||||
: stat_t(name, description)
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
void setName(const char* name)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mName = name;
|
||||
setKey(name);
|
||||
}
|
||||
|
||||
/*virtual*/ const char* getUnitLabel() const { return "KB"; }
|
||||
|
||||
StatType<MemAccumulator::AllocationFacet>& allocations()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return static_cast<StatType<MemAccumulator::AllocationFacet>&>(*(StatType<MemAccumulator>*)this);
|
||||
}
|
||||
|
||||
StatType<MemAccumulator::DeallocationFacet>& deallocations()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return static_cast<StatType<MemAccumulator::DeallocationFacet>&>(*(StatType<MemAccumulator>*)this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// measures effective memory footprint of specified type
|
||||
// specialize to cover different types
|
||||
template<typename T, typename IS_MEM_TRACKABLE = void, typename IS_UNITS = void>
|
||||
|
|
@ -352,33 +297,6 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES>
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void claim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
auto size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
MemAccumulator& accumulator = measurement.getCurrentAccumulator();
|
||||
accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
|
||||
accumulator.mAllocations.record(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void disclaim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
auto size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
MemAccumulator& accumulator = measurement.getCurrentAccumulator();
|
||||
accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
|
||||
accumulator.mDeallocations.add(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // LL_LLTRACE_H
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracesampler.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -32,73 +32,52 @@
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// AccumulatorBufferGroup
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup()
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
claim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
claim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup(const AccumulatorBufferGroup& other)
|
||||
: mCounts(other.mCounts),
|
||||
mSamples(other.mSamples),
|
||||
mEvents(other.mEvents),
|
||||
mStackTimers(other.mStackTimers),
|
||||
mMemStats(other.mMemStats)
|
||||
mStackTimers(other.mStackTimers)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
claim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
claim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
AccumulatorBufferGroup::~AccumulatorBufferGroup()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemAccumulator));
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
other.mCounts.reset(&mCounts);
|
||||
other.mSamples.reset(&mSamples);
|
||||
other.mEvents.reset(&mEvents);
|
||||
other.mStackTimers.reset(&mStackTimers);
|
||||
other.mMemStats.reset(&mMemStats);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::makeCurrent()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.makeCurrent();
|
||||
mSamples.makeCurrent();
|
||||
mEvents.makeCurrent();
|
||||
mStackTimers.makeCurrent();
|
||||
mMemStats.makeCurrent();
|
||||
|
||||
ThreadRecorder* thread_recorder = get_thread_recorder();
|
||||
AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
|
||||
// update stacktimer parent pointers
|
||||
for (size_t i = 0, end_i = mStackTimers.size(); i < end_i; i++)
|
||||
{
|
||||
TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(narrow(i));
|
||||
TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(narrow<size_t>(i));
|
||||
if (tree_node)
|
||||
{
|
||||
timer_accumulator_buffer[i].mParent = tree_node->mParent;
|
||||
|
|
@ -109,12 +88,11 @@ void AccumulatorBufferGroup::makeCurrent()
|
|||
//static
|
||||
void AccumulatorBufferGroup::clearCurrent()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
AccumulatorBuffer<CountAccumulator>::clearCurrent();
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
AccumulatorBuffer<CountAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<SampleAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<EventAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<TimeBlockAccumulator>::clearCurrent();
|
||||
AccumulatorBuffer<MemAccumulator>::clearCurrent();
|
||||
}
|
||||
|
||||
bool AccumulatorBufferGroup::isCurrent() const
|
||||
|
|
@ -124,44 +102,39 @@ bool AccumulatorBufferGroup::isCurrent() const
|
|||
|
||||
void AccumulatorBufferGroup::append( const AccumulatorBufferGroup& other )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.addSamples(other.mCounts, SEQUENTIAL);
|
||||
mSamples.addSamples(other.mSamples, SEQUENTIAL);
|
||||
mEvents.addSamples(other.mEvents, SEQUENTIAL);
|
||||
mMemStats.addSamples(other.mMemStats, SEQUENTIAL);
|
||||
mStackTimers.addSamples(other.mStackTimers, SEQUENTIAL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::merge( const AccumulatorBufferGroup& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.addSamples(other.mCounts, NON_SEQUENTIAL);
|
||||
mSamples.addSamples(other.mSamples, NON_SEQUENTIAL);
|
||||
mEvents.addSamples(other.mEvents, NON_SEQUENTIAL);
|
||||
mMemStats.addSamples(other.mMemStats, NON_SEQUENTIAL);
|
||||
// for now, hold out timers from merge, need to be displayed per thread
|
||||
//mStackTimers.addSamples(other.mStackTimers, NON_SEQUENTIAL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::reset(AccumulatorBufferGroup* other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mCounts.reset(other ? &other->mCounts : NULL);
|
||||
mSamples.reset(other ? &other->mSamples : NULL);
|
||||
mEvents.reset(other ? &other->mEvents : NULL);
|
||||
mStackTimers.reset(other ? &other->mStackTimers : NULL);
|
||||
mMemStats.reset(other ? &other->mMemStats : NULL);
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::sync()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (isCurrent())
|
||||
{
|
||||
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
|
||||
|
||||
mSamples.sync(time_stamp);
|
||||
mMemStats.sync(time_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,10 +170,9 @@ F64 SampleAccumulator::mergeSumsOfSquares(const SampleAccumulator& a, const Samp
|
|||
return a.getSumOfSquares();
|
||||
}
|
||||
|
||||
|
||||
void SampleAccumulator::addSamples( const SampleAccumulator& other, EBufferAppendType append_type )
|
||||
{
|
||||
if (append_type == NON_SEQUENTIAL)
|
||||
if (append_type == NON_SEQUENTIAL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -299,7 +271,7 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT
|
|||
|
||||
void EventAccumulator::reset( const EventAccumulator* other )
|
||||
{
|
||||
mNumSamples = 0;
|
||||
mNumSamples = 0;
|
||||
mSum = 0;
|
||||
mMin = F32(NaN);
|
||||
mMax = F32(NaN);
|
||||
|
|
@ -308,5 +280,4 @@ void EventAccumulator::reset( const EventAccumulator* other )
|
|||
mLastValue = other ? other->mLastValue : NaN;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
|
||||
/**
|
||||
/**
|
||||
* @file lltraceaccumulators.h
|
||||
* @brief Storage for accumulating statistics
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -28,7 +28,6 @@
|
|||
#ifndef LL_LLTRACEACCUMULATORS_H
|
||||
#define LL_LLTRACEACCUMULATORS_H
|
||||
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "llpreprocessor.h"
|
||||
#include "llunits.h"
|
||||
|
|
@ -66,7 +65,7 @@ namespace LLTrace
|
|||
: mStorageSize(0),
|
||||
mStorage(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
const AccumulatorBuffer& other = *getDefaultBuffer();
|
||||
resize(sNextStorageSlot);
|
||||
for (S32 i = 0; i < sNextStorageSlot; i++)
|
||||
|
|
@ -77,7 +76,7 @@ namespace LLTrace
|
|||
|
||||
~AccumulatorBuffer()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (isCurrent())
|
||||
{
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
|
|
@ -85,14 +84,14 @@ namespace LLTrace
|
|||
delete[] mStorage;
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
|
||||
{
|
||||
return mStorage[index];
|
||||
LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
|
||||
{
|
||||
return mStorage[index];
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const
|
||||
{
|
||||
return mStorage[index];
|
||||
{
|
||||
return mStorage[index];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -100,7 +99,7 @@ namespace LLTrace
|
|||
: mStorageSize(0),
|
||||
mStorage(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
resize(sNextStorageSlot);
|
||||
for (S32 i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -110,7 +109,7 @@ namespace LLTrace
|
|||
|
||||
void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other, EBufferAppendType append_type)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -120,7 +119,7 @@ namespace LLTrace
|
|||
|
||||
void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -130,7 +129,7 @@ namespace LLTrace
|
|||
|
||||
void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -140,7 +139,7 @@ namespace LLTrace
|
|||
|
||||
void sync(F64SecondsImplicit time_stamp)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
llassert(mStorageSize >= sNextStorageSlot);
|
||||
for (size_t i = 0; i < sNextStorageSlot; i++)
|
||||
{
|
||||
|
|
@ -160,13 +159,13 @@ namespace LLTrace
|
|||
|
||||
static void clearCurrent()
|
||||
{
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
|
||||
}
|
||||
|
||||
// NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
|
||||
size_t reserveSlot()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
size_t next_slot = sNextStorageSlot++;
|
||||
if (next_slot >= mStorageSize)
|
||||
{
|
||||
|
|
@ -180,7 +179,7 @@ namespace LLTrace
|
|||
|
||||
void resize(size_t new_size)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
if (new_size <= mStorageSize) return;
|
||||
|
||||
ACCUMULATOR* old_storage = mStorage;
|
||||
|
|
@ -214,14 +213,14 @@ namespace LLTrace
|
|||
return mStorageSize;
|
||||
}
|
||||
|
||||
static size_t getNumIndices()
|
||||
static size_t getNumIndices()
|
||||
{
|
||||
return sNextStorageSlot;
|
||||
}
|
||||
|
||||
static self_t* getDefaultBuffer()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
static bool sInitialized = false;
|
||||
if (!sInitialized)
|
||||
{
|
||||
|
|
@ -336,7 +335,7 @@ namespace LLTrace
|
|||
|
||||
void sample(F64 value)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
F64SecondsImplicit time_stamp = LLTimer::getTotalSeconds();
|
||||
|
||||
// store effect of last value
|
||||
|
|
@ -399,7 +398,7 @@ namespace LLTrace
|
|||
F64 mMean,
|
||||
mSumOfSquares;
|
||||
|
||||
F64SecondsImplicit
|
||||
F64SecondsImplicit
|
||||
mLastSampleTimeStamp,
|
||||
mTotalSamplingTime;
|
||||
|
||||
|
|
@ -409,7 +408,7 @@ namespace LLTrace
|
|||
S32 mNumSamples;
|
||||
// distinct from mNumSamples, since we might have inherited a last value from
|
||||
// a previous sampling period
|
||||
bool mHasValue;
|
||||
bool mHasValue;
|
||||
};
|
||||
|
||||
class CountAccumulator
|
||||
|
|
@ -457,14 +456,14 @@ namespace LLTrace
|
|||
|
||||
class alignas(32) TimeBlockAccumulator
|
||||
{
|
||||
public:
|
||||
public:
|
||||
typedef F64Seconds value_t;
|
||||
static F64Seconds getDefaultValue() { return F64Seconds(0); }
|
||||
|
||||
typedef TimeBlockAccumulator self_t;
|
||||
|
||||
// fake classes that allows us to view different facets of underlying statistic
|
||||
struct CallCountFacet
|
||||
struct CallCountFacet
|
||||
{
|
||||
typedef S32 value_t;
|
||||
};
|
||||
|
|
@ -515,12 +514,12 @@ namespace LLTrace
|
|||
BlockTimerStatHandle* getParent() { return mParent; }
|
||||
|
||||
BlockTimerStatHandle* mBlock;
|
||||
BlockTimerStatHandle* mParent;
|
||||
BlockTimerStatHandle* mParent;
|
||||
std::vector<BlockTimerStatHandle*> mChildren;
|
||||
bool mCollapsed;
|
||||
bool mNeedsSorting;
|
||||
};
|
||||
|
||||
|
||||
struct BlockTimerStackRecord
|
||||
{
|
||||
class BlockTimer* mActiveTimer;
|
||||
|
|
@ -528,65 +527,6 @@ namespace LLTrace
|
|||
U64 mChildTime;
|
||||
};
|
||||
|
||||
struct MemAccumulator
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
|
||||
typedef MemAccumulator self_t;
|
||||
|
||||
// fake classes that allows us to view different facets of underlying statistic
|
||||
struct AllocationFacet
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
};
|
||||
|
||||
struct DeallocationFacet
|
||||
{
|
||||
typedef F64Bytes value_t;
|
||||
static F64Bytes getDefaultValue() { return F64Bytes(0); }
|
||||
};
|
||||
|
||||
void addSamples(const MemAccumulator& other, EBufferAppendType append_type)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAllocations.addSamples(other.mAllocations, append_type);
|
||||
mDeallocations.addSamples(other.mDeallocations, append_type);
|
||||
|
||||
if (append_type == SEQUENTIAL)
|
||||
{
|
||||
mSize.addSamples(other.mSize, SEQUENTIAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
F64 allocation_delta(other.mAllocations.getSum() - other.mDeallocations.getSum());
|
||||
mSize.sample(mSize.hasValue()
|
||||
? mSize.getLastValue() + allocation_delta
|
||||
: allocation_delta);
|
||||
}
|
||||
}
|
||||
|
||||
void reset(const MemAccumulator* other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mSize.reset(other ? &other->mSize : NULL);
|
||||
mAllocations.reset(other ? &other->mAllocations : NULL);
|
||||
mDeallocations.reset(other ? &other->mDeallocations : NULL);
|
||||
}
|
||||
|
||||
void sync(F64SecondsImplicit time_stamp)
|
||||
{
|
||||
mSize.sync(time_stamp);
|
||||
}
|
||||
|
||||
bool hasValue() const { return mSize.hasValue(); }
|
||||
|
||||
SampleAccumulator mSize;
|
||||
EventAccumulator mAllocations;
|
||||
CountAccumulator mDeallocations;
|
||||
};
|
||||
|
||||
struct AccumulatorBufferGroup : public LLRefCount
|
||||
{
|
||||
AccumulatorBufferGroup();
|
||||
|
|
@ -607,9 +547,7 @@ namespace LLTrace
|
|||
AccumulatorBuffer<SampleAccumulator> mSamples;
|
||||
AccumulatorBuffer<EventAccumulator> mEvents;
|
||||
AccumulatorBuffer<TimeBlockAccumulator> mStackTimers;
|
||||
AccumulatorBuffer<MemAccumulator> mMemStats;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LL_LLTRACEACCUMULATORS_H
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracesampler.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
#include "lltracethreadrecorder.h"
|
||||
#include "llthread.h"
|
||||
|
||||
inline F64 lerp(F64 a, F64 b, F64 u)
|
||||
inline F64 lerp(F64 a, F64 b, F64 u)
|
||||
{
|
||||
return a + ((b - a) * u);
|
||||
}
|
||||
|
|
@ -40,34 +40,29 @@ inline F64 lerp(F64 a, F64 b, F64 u)
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Recording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
Recording::Recording(EPlayState state)
|
||||
Recording::Recording(EPlayState state)
|
||||
: mElapsedSeconds(0),
|
||||
mActiveBuffers(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mBuffers = new AccumulatorBufferGroup();
|
||||
claim_alloc(gTraceMemStat, mBuffers);
|
||||
setPlayState(state);
|
||||
}
|
||||
|
||||
Recording::Recording( const Recording& other )
|
||||
: mActiveBuffers(NULL)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Recording& Recording::operator = (const Recording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// this will allow us to seamlessly start without affecting any data we've acquired from other
|
||||
setPlayState(PAUSED);
|
||||
|
||||
|
|
@ -85,14 +80,11 @@ Recording& Recording::operator = (const Recording& other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Recording::~Recording()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
disclaim_alloc(gTraceMemStat, mBuffers);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
|
||||
// allow recording destruction without thread recorder running,
|
||||
// allow recording destruction without thread recorder running,
|
||||
// otherwise thread shutdown could crash if a recording outlives the thread recorder
|
||||
// besides, recording construction and destruction is fine without a recorder...just don't attempt to start one
|
||||
if (isStarted() && LLTrace::get_thread_recorder() != NULL)
|
||||
|
|
@ -107,14 +99,14 @@ void Recording::update()
|
|||
#if LL_TRACE_ENABLED
|
||||
if (isStarted())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
|
||||
// must have
|
||||
llassert(mActiveBuffers != NULL
|
||||
// must have
|
||||
llassert(mActiveBuffers != NULL
|
||||
&& LLTrace::get_thread_recorder() != NULL);
|
||||
|
||||
if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
|
||||
if (!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL)
|
||||
{
|
||||
AccumulatorBufferGroup* buffers = mBuffers.write();
|
||||
LLTrace::get_thread_recorder()->deactivate(buffers);
|
||||
|
|
@ -128,7 +120,7 @@ void Recording::update()
|
|||
|
||||
void Recording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mBuffers.write()->reset();
|
||||
|
||||
|
|
@ -139,7 +131,7 @@ void Recording::handleReset()
|
|||
|
||||
void Recording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mSamplingTimer.reset();
|
||||
mBuffers.setStayUnique(true);
|
||||
|
|
@ -151,7 +143,7 @@ void Recording::handleStart()
|
|||
|
||||
void Recording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
#if LL_TRACE_ENABLED
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
// must have thread recorder running on this thread
|
||||
|
|
@ -204,7 +196,6 @@ F64Seconds Recording::getSum(const StatType<TimeBlockAccumulator::SelfTimeFacet>
|
|||
return F64Seconds(((F64)(accumulator.mSelfTimeCounter) + (F64)(active_accumulator ? active_accumulator->mSelfTimeCounter : 0)) / (F64)LLTrace::BlockTimer::countsPerSecond());
|
||||
}
|
||||
|
||||
|
||||
S32 Recording::getSum(const StatType<TimeBlockAccumulator::CallCountFacet>& stat)
|
||||
{
|
||||
update();
|
||||
|
|
@ -219,7 +210,7 @@ F64Seconds Recording::getPerSec(const StatType<TimeBlockAccumulator>& stat)
|
|||
const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
|
||||
const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL;
|
||||
|
||||
return F64Seconds((F64)(accumulator.mTotalTimeCounter + (active_accumulator ? active_accumulator->mTotalTimeCounter : 0))
|
||||
return F64Seconds((F64)(accumulator.mTotalTimeCounter + (active_accumulator ? active_accumulator->mTotalTimeCounter : 0))
|
||||
/ ((F64)LLTrace::BlockTimer::countsPerSecond() * mElapsedSeconds.value()));
|
||||
}
|
||||
|
||||
|
|
@ -241,144 +232,9 @@ F32 Recording::getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& s
|
|||
return (F32)(accumulator.mCalls + (active_accumulator ? active_accumulator->mCalls : 0)) / mElapsedSeconds.value();
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mSize.hasValue() || (active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.hasValue() : false);
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMin(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(llmin(accumulator.mSize.getMin(), (active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMin() : F32_MAX)));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMean(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
|
||||
if (active_accumulator && active_accumulator->mSize.hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.mSize.getSampleCount() + active_accumulator->mSize.getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->mSize.getSampleCount() / div;
|
||||
}
|
||||
return F64Bytes(lerp(accumulator.mSize.getMean(), active_accumulator->mSize.getMean(), t));
|
||||
}
|
||||
else
|
||||
{
|
||||
return F64Bytes(accumulator.mSize.getMean());
|
||||
}
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getMax(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(llmax(accumulator.mSize.getMax(), active_accumulator && active_accumulator->mSize.hasValue() ? active_accumulator->mSize.getMax() : F32_MIN));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getStandardDeviation(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F64 sum_of_squares = SampleAccumulator::mergeSumsOfSquares(accumulator.mSize, active_accumulator->mSize);
|
||||
return F64Bytes(sqrtf(sum_of_squares / (accumulator.mSize.getSamplingTime().value() + active_accumulator->mSize.getSamplingTime().value())));
|
||||
}
|
||||
else
|
||||
{
|
||||
return F64Bytes(accumulator.mSize.getStandardDeviation());
|
||||
}
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getLastValue(const StatType<MemAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(active_accumulator ? active_accumulator->mSize.getLastValue() : accumulator.mSize.getLastValue());
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mAllocations.hasValue() || (active_accumulator ? active_accumulator->mAllocations.hasValue() : false);
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes((accumulator.mAllocations.getSum() + (active_accumulator ? active_accumulator->mAllocations.getSum() : 0)) / mElapsedSeconds.value());
|
||||
}
|
||||
|
||||
S32 Recording::getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mAllocations.getSampleCount() + (active_accumulator ? active_accumulator->mAllocations.getSampleCount() : 0);
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mDeallocations.hasValue() || (active_accumulator ? active_accumulator->mDeallocations.hasValue() : false);
|
||||
}
|
||||
|
||||
|
||||
F64Kilobytes Recording::getSum(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes(accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0));
|
||||
}
|
||||
|
||||
F64Kilobytes Recording::getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return F64Bytes((accumulator.mDeallocations.getSum() + (active_accumulator ? active_accumulator->mDeallocations.getSum() : 0)) / mElapsedSeconds.value());
|
||||
}
|
||||
|
||||
S32 Recording::getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat)
|
||||
{
|
||||
update();
|
||||
const MemAccumulator& accumulator = mBuffers->mMemStats[stat.getIndex()];
|
||||
const MemAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mMemStats[stat.getIndex()] : NULL;
|
||||
return accumulator.mDeallocations.getSampleCount() + (active_accumulator ? active_accumulator->mDeallocations.getSampleCount() : 0);
|
||||
}
|
||||
|
||||
bool Recording::hasValue(const StatType<CountAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator ? active_accumulator->hasValue() : false);
|
||||
|
|
@ -386,7 +242,7 @@ bool Recording::hasValue(const StatType<CountAccumulator>& stat)
|
|||
|
||||
F64 Recording::getSum(const StatType<CountAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
|
||||
|
|
@ -394,7 +250,7 @@ F64 Recording::getSum(const StatType<CountAccumulator>& stat)
|
|||
|
||||
F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
F64 sum = accumulator.getSum() + (active_accumulator ? active_accumulator->getSum() : 0);
|
||||
|
|
@ -403,7 +259,7 @@ F64 Recording::getPerSec( const StatType<CountAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const CountAccumulator& accumulator = mBuffers->mCounts[stat.getIndex()];
|
||||
const CountAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mCounts[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -411,7 +267,7 @@ S32 Recording::getSampleCount( const StatType<CountAccumulator>& stat )
|
|||
|
||||
bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
|
||||
|
|
@ -419,7 +275,7 @@ bool Recording::hasValue(const StatType<SampleAccumulator>& stat)
|
|||
|
||||
F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
|
||||
|
|
@ -427,7 +283,7 @@ F64 Recording::getMin( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
|
||||
|
|
@ -435,17 +291,17 @@ F64 Recording::getMax( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
|
||||
}
|
||||
else
|
||||
|
|
@ -456,7 +312,7 @@ F64 Recording::getMean( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
|
||||
|
|
@ -473,7 +329,7 @@ F64 Recording::getStandardDeviation( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getLastValue() : accumulator.getLastValue());
|
||||
|
|
@ -481,7 +337,7 @@ F64 Recording::getLastValue( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const SampleAccumulator& accumulator = mBuffers->mSamples[stat.getIndex()];
|
||||
const SampleAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mSamples[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -489,7 +345,7 @@ S32 Recording::getSampleCount( const StatType<SampleAccumulator>& stat )
|
|||
|
||||
bool Recording::hasValue(const StatType<EventAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return accumulator.hasValue() || (active_accumulator && active_accumulator->hasValue());
|
||||
|
|
@ -497,7 +353,7 @@ bool Recording::hasValue(const StatType<EventAccumulator>& stat)
|
|||
|
||||
F64 Recording::getSum( const StatType<EventAccumulator>& stat)
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return (F64)(accumulator.getSum() + (active_accumulator && active_accumulator->hasValue() ? active_accumulator->getSum() : 0));
|
||||
|
|
@ -505,7 +361,7 @@ F64 Recording::getSum( const StatType<EventAccumulator>& stat)
|
|||
|
||||
F64 Recording::getMin( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return llmin(accumulator.getMin(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMin() : F32_MAX);
|
||||
|
|
@ -513,7 +369,7 @@ F64 Recording::getMin( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMax( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return llmax(accumulator.getMax(), active_accumulator && active_accumulator->hasValue() ? active_accumulator->getMax() : F32_MIN);
|
||||
|
|
@ -521,17 +377,17 @@ F64 Recording::getMax( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getMean( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
if (active_accumulator && active_accumulator->hasValue())
|
||||
{
|
||||
F32 t = 0.0f;
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
S32 div = accumulator.getSampleCount() + active_accumulator->getSampleCount();
|
||||
if (div > 0)
|
||||
{
|
||||
t = active_accumulator->getSampleCount() / div;
|
||||
}
|
||||
return lerp(accumulator.getMean(), active_accumulator->getMean(), t);
|
||||
}
|
||||
else
|
||||
|
|
@ -542,7 +398,7 @@ F64 Recording::getMean( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
|
||||
|
|
@ -559,7 +415,7 @@ F64 Recording::getStandardDeviation( const StatType<EventAccumulator>& stat )
|
|||
|
||||
F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return active_accumulator ? active_accumulator->getLastValue() : accumulator.getLastValue();
|
||||
|
|
@ -567,7 +423,7 @@ F64 Recording::getLastValue( const StatType<EventAccumulator>& stat )
|
|||
|
||||
S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
|
||||
{
|
||||
update();
|
||||
update();
|
||||
const EventAccumulator& accumulator = mBuffers->mEvents[stat.getIndex()];
|
||||
const EventAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mEvents[stat.getIndex()] : NULL;
|
||||
return accumulator.getSampleCount() + (active_accumulator ? active_accumulator->getSampleCount() : 0);
|
||||
|
|
@ -577,7 +433,7 @@ S32 Recording::getSampleCount( const StatType<EventAccumulator>& stat )
|
|||
// PeriodicRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
||||
PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
||||
: mAutoResize(num_periods == 0),
|
||||
mCurPeriod(0),
|
||||
mNumRecordedPeriods(0),
|
||||
|
|
@ -585,15 +441,13 @@ PeriodicRecording::PeriodicRecording( size_t num_periods, EPlayState state)
|
|||
// code in several methods.
|
||||
mRecordingPeriods(num_periods ? num_periods : 1)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
setPlayState(state);
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
}
|
||||
|
||||
PeriodicRecording::~PeriodicRecording()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
}
|
||||
|
||||
void PeriodicRecording::nextPeriod()
|
||||
|
|
@ -615,12 +469,11 @@ void PeriodicRecording::nextPeriod()
|
|||
|
||||
void PeriodicRecording::appendRecording(Recording& recording)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().appendRecording(recording);
|
||||
nextPeriod();
|
||||
}
|
||||
|
||||
|
||||
void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
|
|
@ -693,16 +546,14 @@ F64Seconds PeriodicRecording::getDuration() const
|
|||
return duration;
|
||||
}
|
||||
|
||||
|
||||
LLTrace::Recording PeriodicRecording::snapshotCurRecording() const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
Recording recording_copy(getCurRecording());
|
||||
recording_copy.stop();
|
||||
return recording_copy;
|
||||
}
|
||||
|
||||
|
||||
Recording& PeriodicRecording::getLastRecording()
|
||||
{
|
||||
return getPrevRecording(1);
|
||||
|
|
@ -737,19 +588,19 @@ const Recording& PeriodicRecording::getPrevRecording( size_t offset ) const
|
|||
|
||||
void PeriodicRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().start();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().pause();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().stop();
|
||||
|
||||
if (mAutoResize)
|
||||
|
|
@ -771,13 +622,13 @@ void PeriodicRecording::handleReset()
|
|||
|
||||
void PeriodicRecording::handleSplitTo(PeriodicRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
getCurRecording().splitTo(other.getCurRecording());
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -792,14 +643,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -814,15 +665,15 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
// calculates means using aggregates per period
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 mean = 0;
|
||||
|
|
@ -838,14 +689,14 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, si
|
|||
}
|
||||
}
|
||||
|
||||
return valid_period_count
|
||||
return valid_period_count
|
||||
? mean / (F64)valid_period_count
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 period_mean = getPeriodMean(stat, num_periods);
|
||||
|
|
@ -870,7 +721,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat
|
|||
|
||||
F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -885,14 +736,14 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, si
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -907,15 +758,15 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, siz
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: NaN;
|
||||
}
|
||||
|
||||
|
||||
F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
S32 valid_period_count = 0;
|
||||
|
|
@ -938,7 +789,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, s
|
|||
|
||||
F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
std::vector<F64> buf;
|
||||
|
|
@ -964,7 +815,7 @@ F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat,
|
|||
|
||||
F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 period_mean = getPeriodMean(stat, num_periods);
|
||||
|
|
@ -987,105 +838,13 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula
|
|||
: NaN;
|
||||
}
|
||||
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes min_val(std::numeric_limits<F64>::max());
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
min_val = llmin(min_val, recording.getMin(stat));
|
||||
}
|
||||
|
||||
return min_val;
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMin(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes max_val(0.0);
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
max_val = llmax(max_val, recording.getMax(stat));
|
||||
}
|
||||
|
||||
return max_val;
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMax(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes mean(0);
|
||||
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
mean += recording.getMean(stat);
|
||||
}
|
||||
|
||||
return mean / F64(num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodMean(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= std::numeric_limits<size_t>::max()*/ )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64Kilobytes period_mean = getPeriodMean(stat, num_periods);
|
||||
S32 valid_period_count = 0;
|
||||
F64 sum_of_squares = 0;
|
||||
|
||||
for (size_t i = 1; i <= num_periods; i++)
|
||||
{
|
||||
Recording& recording = getPrevRecording(i);
|
||||
if (recording.hasValue(stat))
|
||||
{
|
||||
F64Kilobytes delta = recording.getMean(stat) - period_mean;
|
||||
sum_of_squares += delta.value() * delta.value();
|
||||
valid_period_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return F64Kilobytes(valid_period_count
|
||||
? sqrt(sum_of_squares / (F64)valid_period_count)
|
||||
: NaN);
|
||||
}
|
||||
|
||||
F64Kilobytes PeriodicRecording::getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods)
|
||||
{
|
||||
return getPeriodStandardDeviation(static_cast<const StatType<MemAccumulator>&>(stat), num_periods);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ExtendableRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExtendableRecording::extend()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// push the data back to accepted recording
|
||||
mAcceptedRecording.appendRecording(mPotentialRecording);
|
||||
// flush data, so we can start from scratch
|
||||
|
|
@ -1094,76 +853,72 @@ void ExtendableRecording::extend()
|
|||
|
||||
void ExtendableRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.start();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.pause();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAcceptedRecording.reset();
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleSplitTo(ExtendableRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.splitTo(other.mPotentialRecording);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ExtendablePeriodicRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ExtendablePeriodicRecording::ExtendablePeriodicRecording()
|
||||
: mAcceptedRecording(0),
|
||||
ExtendablePeriodicRecording::ExtendablePeriodicRecording()
|
||||
: mAcceptedRecording(0),
|
||||
mPotentialRecording(0)
|
||||
{}
|
||||
|
||||
void ExtendablePeriodicRecording::extend()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
// push the data back to accepted recording
|
||||
mAcceptedRecording.appendPeriodicRecording(mPotentialRecording);
|
||||
// flush data, so we can start from scratch
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
|
||||
void ExtendablePeriodicRecording::handleStart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.start();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleStop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.pause();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleReset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mAcceptedRecording.reset();
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& other)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
mPotentialRecording.splitTo(other.mPotentialRecording);
|
||||
}
|
||||
|
||||
|
||||
PeriodicRecording& get_frame_recording()
|
||||
{
|
||||
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
|
||||
|
|
@ -1174,7 +929,7 @@ PeriodicRecording& get_frame_recording()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::start()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1196,7 +951,7 @@ void LLStopWatchControlsMixinCommon::start()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::stop()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1216,7 +971,7 @@ void LLStopWatchControlsMixinCommon::stop()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::pause()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1236,7 +991,7 @@ void LLStopWatchControlsMixinCommon::pause()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::unpause()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1256,7 +1011,7 @@ void LLStopWatchControlsMixinCommon::unpause()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::resume()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1277,7 +1032,7 @@ void LLStopWatchControlsMixinCommon::resume()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::restart()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
@ -1301,13 +1056,13 @@ void LLStopWatchControlsMixinCommon::restart()
|
|||
|
||||
void LLStopWatchControlsMixinCommon::reset()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
handleReset();
|
||||
}
|
||||
|
||||
void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state )
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
switch(state)
|
||||
{
|
||||
case STOPPED:
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @file lltracerecording.h
|
||||
* @brief Sampling object for collecting runtime statistics originating from lltrace.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, 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$
|
||||
*/
|
||||
|
|
@ -112,7 +112,6 @@ private:
|
|||
// atomically stop this object while starting the other
|
||||
// no data can be missed in between stop and start
|
||||
virtual void handleSplitTo(DERIVED& other) {};
|
||||
|
||||
};
|
||||
|
||||
namespace LLTrace
|
||||
|
|
@ -129,8 +128,6 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
class EventStatHandle;
|
||||
|
||||
class MemStatHandle;
|
||||
|
||||
template<typename T>
|
||||
struct RelatedTypes
|
||||
{
|
||||
|
|
@ -152,7 +149,7 @@ namespace LLTrace
|
|||
typedef S32 sum_t;
|
||||
};
|
||||
|
||||
class Recording
|
||||
class Recording
|
||||
: public LLStopWatchControlsMixin<Recording>
|
||||
{
|
||||
public:
|
||||
|
|
@ -182,24 +179,6 @@ namespace LLTrace
|
|||
F64Seconds getPerSec(const StatType<TimeBlockAccumulator::SelfTimeFacet>& stat);
|
||||
F32 getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& stat);
|
||||
|
||||
// Memory accessors
|
||||
bool hasValue(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMin(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMean(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getMax(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getStandardDeviation(const StatType<MemAccumulator>& stat);
|
||||
F64Kilobytes getLastValue(const StatType<MemAccumulator>& stat);
|
||||
|
||||
bool hasValue(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
F64Kilobytes getSum(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
F64Kilobytes getPerSec(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
S32 getSampleCount(const StatType<MemAccumulator::AllocationFacet>& stat);
|
||||
|
||||
bool hasValue(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
F64Kilobytes getSum(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
F64Kilobytes getPerSec(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
S32 getSampleCount(const StatType<MemAccumulator::DeallocationFacet>& stat);
|
||||
|
||||
// CountStatHandle accessors
|
||||
bool hasValue(const StatType<CountAccumulator>& stat);
|
||||
F64 getSum(const StatType<CountAccumulator>& stat);
|
||||
|
|
@ -318,7 +297,7 @@ namespace LLTrace
|
|||
/*virtual*/ void handleSplitTo(Recording& other);
|
||||
|
||||
// returns data for current thread
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
|
||||
LLTimer mSamplingTimer;
|
||||
F64Seconds mElapsedSeconds;
|
||||
|
|
@ -335,10 +314,10 @@ namespace LLTrace
|
|||
~PeriodicRecording();
|
||||
|
||||
void nextPeriod();
|
||||
auto getNumRecordedPeriods()
|
||||
{
|
||||
auto getNumRecordedPeriods()
|
||||
{
|
||||
// current period counts if not active
|
||||
return mNumRecordedPeriods + (isStarted() ? 0 : 1);
|
||||
return mNumRecordedPeriods + (isStarted() ? 0 : 1);
|
||||
}
|
||||
|
||||
F64Seconds getDuration() const;
|
||||
|
|
@ -367,7 +346,7 @@ namespace LLTrace
|
|||
}
|
||||
return num_samples;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// PERIODIC MIN
|
||||
//
|
||||
|
|
@ -376,7 +355,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -391,15 +370,15 @@ namespace LLTrace
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? min_val
|
||||
return has_value
|
||||
? min_val
|
||||
: T::getDefaultValue();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -407,7 +386,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -415,17 +394,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t min_val(std::numeric_limits<F64>::max());
|
||||
|
|
@ -440,7 +416,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -452,7 +428,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
bool has_value = false;
|
||||
|
|
@ -467,15 +443,15 @@ namespace LLTrace
|
|||
}
|
||||
}
|
||||
|
||||
return has_value
|
||||
? max_val
|
||||
return has_value
|
||||
? max_val
|
||||
: T::getDefaultValue();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +459,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -491,17 +467,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
F64 max_val = std::numeric_limits<F64>::min();
|
||||
|
|
@ -516,7 +489,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +501,7 @@ namespace LLTrace
|
|||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean(0);
|
||||
|
|
@ -549,14 +522,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -564,17 +537,14 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template <typename T>
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
num_periods = llmin(num_periods, getNumRecordedPeriods());
|
||||
|
||||
typename RelatedTypes<typename T::value_t>::fractional_t mean = 0;
|
||||
|
|
@ -596,7 +566,7 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -635,10 +605,10 @@ namespace LLTrace
|
|||
|
||||
F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
|
|
@ -646,13 +616,10 @@ namespace LLTrace
|
|||
template<typename T>
|
||||
typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
|
||||
return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods));
|
||||
}
|
||||
|
||||
F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = std::numeric_limits<size_t>::max());
|
||||
|
||||
private:
|
||||
// implementation for LLStopWatchControlsMixin
|
||||
/*virtual*/ void handleStart();
|
||||
|
|
@ -731,7 +698,7 @@ namespace LLTrace
|
|||
|
||||
PeriodicRecording& getResults() { return mAcceptedRecording; }
|
||||
const PeriodicRecording& getResults() const {return mAcceptedRecording;}
|
||||
|
||||
|
||||
void nextPeriod() { mPotentialRecording.nextPeriod(); }
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
namespace LLTrace
|
||||
{
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
//extern MemStatHandle gTraceMemStat;
|
||||
|
||||
static ThreadRecorder* sMasterThreadRecorder = NULL;
|
||||
|
||||
|
|
@ -81,9 +81,9 @@ void ThreadRecorder::init()
|
|||
|
||||
BlockTimer::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1;
|
||||
|
||||
claim_alloc(gTraceMemStat, this);
|
||||
claim_alloc(gTraceMemStat, mRootTimer);
|
||||
claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
//claim_alloc(gTraceMemStat, this);
|
||||
//claim_alloc(gTraceMemStat, mRootTimer);
|
||||
//claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -101,9 +101,9 @@ ThreadRecorder::~ThreadRecorder()
|
|||
#if LL_TRACE_ENABLED
|
||||
LLThreadLocalSingletonPointer<BlockTimerStackRecord>::setInstance(NULL);
|
||||
|
||||
disclaim_alloc(gTraceMemStat, this);
|
||||
disclaim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
//disclaim_alloc(gTraceMemStat, this);
|
||||
//disclaim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
//disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
|
||||
deactivate(&mThreadRecordingBuffers);
|
||||
|
||||
|
|
|
|||
|
|
@ -164,8 +164,10 @@ void LLUriParser::extractParts()
|
|||
#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.
|
||||
|
|
@ -179,8 +181,10 @@ S32 LLUriParser::normalize()
|
|||
if (!mRes)
|
||||
{
|
||||
#if LL_DARWIN
|
||||
sighandler_t last_handler;
|
||||
last_handler = signal(SIGILL, &uri_signal_handler); // illegal instruction
|
||||
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
|
||||
|
|
@ -194,8 +198,9 @@ S32 LLUriParser::normalize()
|
|||
// if this can be handled by NSexception, it needs to be remade
|
||||
llassert(0);
|
||||
|
||||
LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL;
|
||||
signal(SIGILL, last_handler);
|
||||
LL_WARNS() << "Uriparser crashed with " << sLastSignal << " , while processing: " << mNormalizedUri << LL_ENDL;
|
||||
signal(SIGILL, last_sigill_handler);
|
||||
signal(SIGBUS, last_sigbus_handler);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -203,7 +208,8 @@ S32 LLUriParser::normalize()
|
|||
mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
|
||||
|
||||
#if LL_DARWIN
|
||||
signal(SIGILL, last_handler);
|
||||
signal(SIGILL, last_sigill_handler);
|
||||
signal(SIGBUS, last_sigbus_handler);
|
||||
#endif
|
||||
|
||||
if (!mRes)
|
||||
|
|
@ -226,7 +232,7 @@ S32 LLUriParser::normalize()
|
|||
}
|
||||
}
|
||||
|
||||
if(mTmpScheme)
|
||||
if(mTmpScheme && mNormalizedUri.size() > 7)
|
||||
{
|
||||
mNormalizedUri = mNormalizedUri.substr(7);
|
||||
mTmpScheme = false;
|
||||
|
|
|
|||
|
|
@ -156,18 +156,15 @@ typedef int intptr_t;
|
|||
* type.
|
||||
*/
|
||||
// narrow_holder is a struct that accepts the passed value as its original
|
||||
// type and provides templated conversion functions to other types. Once we're
|
||||
// building with compilers that support Class Template Argument Deduction, we
|
||||
// can rename this class template 'narrow' and eliminate the narrow() factory
|
||||
// function below.
|
||||
// type and provides templated conversion functions to other types.
|
||||
template <typename FROM>
|
||||
class narrow_holder
|
||||
class narrow
|
||||
{
|
||||
private:
|
||||
FROM mValue;
|
||||
|
||||
public:
|
||||
narrow_holder(FROM value): mValue(value) {}
|
||||
narrow(FROM value): mValue(value) {}
|
||||
|
||||
/*---------------------- Narrowing unsigned to signed ----------------------*/
|
||||
template <typename TO,
|
||||
|
|
@ -207,13 +204,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// narrow() factory function returns a narrow_holder<FROM>(), which can be
|
||||
/// implicitly converted to the target type.
|
||||
template <typename FROM>
|
||||
inline
|
||||
narrow_holder<FROM> narrow(FROM value)
|
||||
{
|
||||
return { value };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,11 +46,12 @@ namespace tut
|
|||
// the real time required for each push() call. Explicitly increment
|
||||
// the timestamp for each one -- but since we're passing explicit
|
||||
// timestamps, make the queue reorder them.
|
||||
queue.push(Queue::TimeTuple(Queue::Clock::now() + 200ms, "ghi"));
|
||||
auto now{ Queue::Clock::now() };
|
||||
queue.push(Queue::TimeTuple(now + 200ms, "ghi"));
|
||||
// Given the various push() overloads, you have to match the type
|
||||
// exactly: conversions are ambiguous.
|
||||
queue.push("abc"s);
|
||||
queue.push(Queue::Clock::now() + 100ms, "def");
|
||||
queue.push(now + 100ms, "def");
|
||||
queue.close();
|
||||
auto entry = queue.pop();
|
||||
ensure_equals("failed to pop first", std::get<0>(entry), "abc"s);
|
||||
|
|
|
|||
|
|
@ -60,12 +60,15 @@ struct sleepy_robin: public boost::fibers::algo::round_robin
|
|||
/*****************************************************************************
|
||||
* ThreadPoolBase
|
||||
*****************************************************************************/
|
||||
LL::ThreadPoolBase::ThreadPoolBase(const std::string& name, size_t threads,
|
||||
WorkQueueBase* queue):
|
||||
LL::ThreadPoolBase::ThreadPoolBase(const std::string& name,
|
||||
size_t threads,
|
||||
WorkQueueBase* queue,
|
||||
bool auto_shutdown):
|
||||
super(name),
|
||||
mName("ThreadPool:" + name),
|
||||
mThreadCount(getConfiguredWidth(name, threads)),
|
||||
mQueue(queue)
|
||||
mQueue(queue),
|
||||
mAutomaticShutdown(auto_shutdown)
|
||||
{}
|
||||
|
||||
void LL::ThreadPoolBase::start()
|
||||
|
|
@ -80,6 +83,14 @@ void LL::ThreadPoolBase::start()
|
|||
run(tname);
|
||||
});
|
||||
}
|
||||
|
||||
if (!mAutomaticShutdown)
|
||||
{
|
||||
// Some threads, like main window's might need to run a bit longer
|
||||
// to wait for a proper shutdown message
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen on "LLApp", and when the app is shutting down, close the queue
|
||||
// and join the workers.
|
||||
LLEventPumps::instance().obtain("LLApp").listen(
|
||||
|
|
@ -110,8 +121,11 @@ void LL::ThreadPoolBase::close()
|
|||
mQueue->close();
|
||||
for (auto& pair: mThreads)
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL;
|
||||
pair.second.join();
|
||||
if (pair.second.joinable())
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL;
|
||||
pair.second.join();
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace LL
|
|||
* overrides this parameter.
|
||||
*/
|
||||
ThreadPoolBase(const std::string& name, size_t threads,
|
||||
WorkQueueBase* queue);
|
||||
WorkQueueBase* queue, bool auto_shutdown = true);
|
||||
virtual ~ThreadPoolBase();
|
||||
|
||||
/**
|
||||
|
|
@ -55,10 +55,7 @@ namespace LL
|
|||
* ThreadPool listens for application shutdown messages on the "LLApp"
|
||||
* LLEventPump. Call close() to shut down this ThreadPool early.
|
||||
*/
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
// void close();
|
||||
virtual void close();
|
||||
// </FS:Beq>
|
||||
|
||||
std::string getName() const { return mName; }
|
||||
size_t getWidth() const { return mThreads.size(); }
|
||||
|
|
@ -90,14 +87,14 @@ namespace LL
|
|||
|
||||
protected:
|
||||
std::unique_ptr<WorkQueueBase> mQueue;
|
||||
std::vector<std::pair<std::string, std::thread>> mThreads;
|
||||
bool mAutomaticShutdown;
|
||||
|
||||
private:
|
||||
void run(const std::string& name);
|
||||
|
||||
protected: // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
|
||||
std::string mName;
|
||||
size_t mThreadCount;
|
||||
std::vector<std::pair<std::string, std::thread>> mThreads;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -121,8 +118,11 @@ namespace LL
|
|||
* Constraining the queue can cause a submitter to block. Do not
|
||||
* constrain any ThreadPool accepting work from the main thread.
|
||||
*/
|
||||
ThreadPoolUsing(const std::string& name, size_t threads=1, size_t capacity=1024*1024):
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity))
|
||||
ThreadPoolUsing(const std::string& name,
|
||||
size_t threads=1,
|
||||
size_t capacity=1024*1024,
|
||||
bool auto_shutdown = true):
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity), auto_shutdown)
|
||||
{}
|
||||
~ThreadPoolUsing() override {}
|
||||
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
|
|||
LLMemory::logMemoryInfo(TRUE);
|
||||
|
||||
//output possible call stacks to log file.
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LLError::LLCallStacks::print();
|
||||
|
||||
LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ int BufferArray::findBlock(size_t pos, size_t * ret_offset)
|
|||
if (pos >= mLen)
|
||||
return -1; // Doesn't exist
|
||||
|
||||
const int block_limit(narrow(mBlocks.size()));
|
||||
const int block_limit(narrow<size_t>(mBlocks.size()));
|
||||
for (int i(0); i < block_limit; ++i)
|
||||
{
|
||||
if (pos < mBlocks[i]->mUsed)
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ bool LLImageBMP::updateData()
|
|||
mColorPalette = new(std::nothrow) U8[color_palette_size];
|
||||
if (!mColorPalette)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_WARNS() << "Out of memory in LLImageBMP::updateData(), size: " << color_palette_size << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
|
|||
|
||||
if (file_size == 0)
|
||||
{
|
||||
mWarning = "texture_load_empty_file";
|
||||
setLastError("File is empty",src_filename);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -90,6 +91,7 @@ bool LLImageDimensionsInfo::getImageDimensionsBmp()
|
|||
if (signature[0] != 'B' || signature[1] != 'M')
|
||||
{
|
||||
LL_WARNS() << "Not a BMP" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +142,7 @@ bool LLImageDimensionsInfo::getImageDimensionsPng()
|
|||
if (memcmp(signature, png_magic, PNG_MAGIC_SIZE) != 0)
|
||||
{
|
||||
LL_WARNS() << "Not a PNG" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +187,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
|
|||
if (memcmp(signature, jpeg_magic, JPEG_MAGIC_SIZE) != 0)
|
||||
{
|
||||
LL_WARNS() << "Not a JPEG" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
fclose(fp); // <FS:ND/> Don't leak the file handle
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ public:
|
|||
{
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
const std::string& getWarningName()
|
||||
{
|
||||
return mWarning;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void clean()
|
||||
|
|
@ -129,6 +135,7 @@ protected:
|
|||
std::string mSrcFilename;
|
||||
|
||||
std::string mLastError;
|
||||
std::string mWarning;
|
||||
|
||||
U8* mData;
|
||||
|
||||
|
|
|
|||
|
|
@ -437,6 +437,7 @@ bool LLImageDXT::convertToDXR()
|
|||
U8* newdata = (U8*)ll_aligned_malloc_16(total_bytes);
|
||||
if (!newdata)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS() << "Out of memory in LLImageDXT::convertToDXR()" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@ bool LLImageTGA::updateData()
|
|||
mColorMap = new(std::nothrow) U8[ color_map_bytes ];
|
||||
if (!mColorMap)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_WARNS() << "Out of Memory in bool LLImageTGA::updateData(), size: " << color_map_bytes << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ class ImageRequest
|
|||
{
|
||||
public:
|
||||
ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard, BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder);
|
||||
S32 discard,
|
||||
BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder,
|
||||
U32 request_id);
|
||||
virtual ~ImageRequest();
|
||||
|
||||
/*virtual*/ bool processRequest();
|
||||
|
|
@ -48,6 +50,7 @@ private:
|
|||
// input
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
S32 mDiscardLevel;
|
||||
U32 mRequestId;
|
||||
BOOL mNeedsAux;
|
||||
// output
|
||||
LLPointer<LLImageRaw> mDecodedImageRaw;
|
||||
|
|
@ -62,6 +65,7 @@ private:
|
|||
|
||||
// MAIN THREAD
|
||||
LLImageDecodeThread::LLImageDecodeThread(bool /*threaded*/)
|
||||
: mDecodeCount(0)
|
||||
{
|
||||
mThreadPool.reset(new LL::ThreadPool("ImageDecode", 8));
|
||||
mThreadPool->start();
|
||||
|
|
@ -92,9 +96,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
|
|||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
U32 decode_id = ++mDecodeCount;
|
||||
// Instantiate the ImageRequest right in the lambda, why not?
|
||||
bool posted = mThreadPool->getQueue().post(
|
||||
[req = ImageRequest(image, discard, needs_aux, responder)]
|
||||
[req = ImageRequest(image, discard, needs_aux, responder, decode_id)]
|
||||
() mutable
|
||||
{
|
||||
auto done = req.processRequest();
|
||||
|
|
@ -103,13 +108,10 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
|
|||
if (! posted)
|
||||
{
|
||||
LL_DEBUGS() << "Tried to start decoding on shutdown" << LL_ENDL;
|
||||
// should this return 0?
|
||||
return 0;
|
||||
}
|
||||
|
||||
// It's important to our consumer (LLTextureFetchWorker) that we return a
|
||||
// nonzero handle. It is NOT important that the nonzero handle be unique:
|
||||
// nothing is ever done with it except to compare it to zero, or zero it.
|
||||
return 17;
|
||||
return decode_id;
|
||||
}
|
||||
|
||||
void LLImageDecodeThread::shutdown()
|
||||
|
|
@ -123,15 +125,18 @@ LLImageDecodeThread::Responder::~Responder()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard, BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder)
|
||||
ImageRequest::ImageRequest(const LLPointer<LLImageFormatted>& image,
|
||||
S32 discard,
|
||||
BOOL needs_aux,
|
||||
const LLPointer<LLImageDecodeThread::Responder>& responder,
|
||||
U32 request_id)
|
||||
: mFormattedImage(image),
|
||||
mDiscardLevel(discard),
|
||||
mNeedsAux(needs_aux),
|
||||
mDecodedRaw(FALSE),
|
||||
mDecodedAux(FALSE),
|
||||
mResponder(responder)
|
||||
mResponder(responder),
|
||||
mRequestId(request_id)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +216,7 @@ void ImageRequest::finishRequest(bool completed)
|
|||
if (mResponder.notNull())
|
||||
{
|
||||
bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
|
||||
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
|
||||
mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux, mRequestId);
|
||||
}
|
||||
// Will automatically be deleted
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public:
|
|||
protected:
|
||||
virtual ~Responder();
|
||||
public:
|
||||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0;
|
||||
virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -53,6 +53,7 @@ public:
|
|||
const LLPointer<Responder>& responder);
|
||||
size_t getPending();
|
||||
size_t update(F32 max_time_ms);
|
||||
S32 getTotalDecodeCount() { return mDecodeCount; }
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
|
|
@ -60,6 +61,7 @@ private:
|
|||
// LLQueuedThread - instead this is the API by which we submit work to the
|
||||
// "ImageDecode" ThreadPool.
|
||||
std::unique_ptr<LL::ThreadPool> mThreadPool;
|
||||
LLAtomicU32 mDecodeCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5630,9 +5630,9 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
|
||||
U32 stream_count = data.w.empty() ? 4 : 5;
|
||||
|
||||
U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count);
|
||||
size_t vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count);
|
||||
|
||||
if (vert_count < 65535)
|
||||
if (vert_count < 65535 && vert_count != 0)
|
||||
{
|
||||
std::vector<U32> indices;
|
||||
indices.resize(mNumIndices);
|
||||
|
|
@ -5651,6 +5651,13 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
{
|
||||
U32 src_idx = i;
|
||||
U32 dst_idx = remap[i];
|
||||
if (dst_idx >= mNumVertices)
|
||||
{
|
||||
dst_idx = mNumVertices - 1;
|
||||
// Shouldn't happen, figure out what gets returned in remap and why.
|
||||
llassert(false);
|
||||
LL_DEBUGS_ONCE("LLVOLUME") << "Invalid destination index, substituting" << LL_ENDL;
|
||||
}
|
||||
mIndices[i] = dst_idx;
|
||||
|
||||
mPositions[dst_idx].load3(data.p[src_idx].mV);
|
||||
|
|
@ -5684,6 +5691,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (vert_count == 0)
|
||||
{
|
||||
LL_WARNS_ONCE("LLVOLUME") << "meshopt_generateVertexRemapMulti failed to process a model or model was invalid" << LL_ENDL;
|
||||
}
|
||||
// blew past the max vertex size limit, use legacy tangent generation which never adds verts
|
||||
createTangents();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -386,12 +386,3 @@ std::ostream& operator<< (std::ostream& os, LLXfer &hh)
|
|||
os << hh.getFileName() ;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1056,7 +1056,12 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
|||
weight_map::iterator iterPos = mSkinWeights.begin();
|
||||
weight_map::iterator iterEnd = mSkinWeights.end();
|
||||
|
||||
llassert(!mSkinWeights.empty());
|
||||
if (mSkinWeights.empty())
|
||||
{
|
||||
// function calls iter->second on all return paths
|
||||
// everything that calls this function should precheck that there is data.
|
||||
LL_ERRS() << "called getJointInfluences with empty weights list" << LL_ENDL;
|
||||
}
|
||||
|
||||
for ( ; iterPos!=iterEnd; ++iterPos )
|
||||
{
|
||||
|
|
@ -1083,11 +1088,16 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
|||
const F32 epsilon = 1e-5f;
|
||||
weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
|
||||
weight_map::iterator iter_down = iter_up;
|
||||
if (iter_up != mSkinWeights.end())
|
||||
{
|
||||
iter_down = ++iter_up;
|
||||
}
|
||||
weight_map::iterator best = iter_up;
|
||||
weight_map::iterator best = iter_up;
|
||||
if (iter_up != mSkinWeights.end())
|
||||
{
|
||||
iter_down = ++iter_up;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assumes that there is at least one element
|
||||
--best;
|
||||
}
|
||||
|
||||
// <FS:ND> FIRE-9251; There is no way iter can be valid here, otherwise we had hit the if branch and not the else branch.
|
||||
// F32 min_dist = (iter->first - pos).magVec();
|
||||
|
|
|
|||
|
|
@ -101,6 +101,17 @@ void APIENTRY gl_debug_callback(GLenum source,
|
|||
return;
|
||||
}*/
|
||||
|
||||
if (gGLManager.mIsDisabled &&
|
||||
severity == GL_DEBUG_SEVERITY_HIGH_ARB &&
|
||||
source == GL_DEBUG_SOURCE_API_ARB &&
|
||||
type == GL_DEBUG_TYPE_ERROR_ARB &&
|
||||
id == GL_INVALID_VALUE)
|
||||
{
|
||||
// Suppress messages about deleting already deleted objects called from LLViewerWindow::stopGL()
|
||||
// "GL_INVALID_VALUE error generated. Handle does not refer to an object generated by OpenGL."
|
||||
return;
|
||||
}
|
||||
|
||||
// list of messages to suppress
|
||||
const char* suppress[] =
|
||||
{
|
||||
|
|
@ -155,8 +166,9 @@ void APIENTRY gl_debug_callback(GLenum source,
|
|||
glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_SIZE, &ubo_size);
|
||||
glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE, &ubo_immutable);
|
||||
}
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH)
|
||||
|
||||
// No needs to halt when is called from LLViewerWindow::stopGL()
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH && !gGLManager.mIsDisabled)
|
||||
{
|
||||
LL_ERRS() << "Halting on GL Error" << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1353,6 +1353,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
scratch = new(std::nothrow) U32[width * height];
|
||||
if (!scratch)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
|
||||
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
|
||||
}
|
||||
|
|
@ -1378,6 +1379,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
scratch = new(std::nothrow) U32[width * height];
|
||||
if (!scratch)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
|
||||
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
|
||||
}
|
||||
|
|
@ -1406,6 +1408,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
|
|||
scratch = new(std::nothrow) U32[width * height];
|
||||
if (!scratch)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
|
||||
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -862,7 +862,7 @@ LLRender::~LLRender()
|
|||
shutdown();
|
||||
}
|
||||
|
||||
void LLRender::init(bool needs_vertex_buffer)
|
||||
bool LLRender::init(bool needs_vertex_buffer)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
if (gGLManager.mHasDebugOutput && gDebugGL)
|
||||
|
|
@ -884,6 +884,13 @@ void LLRender::init(bool needs_vertex_buffer)
|
|||
// necessary for reflection maps
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (glGenVertexArrays == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
{ //bind a dummy vertex array object so we're core profile compliant
|
||||
U32 ret;
|
||||
glGenVertexArrays(1, &ret);
|
||||
|
|
@ -904,6 +911,8 @@ void LLRender::init(bool needs_vertex_buffer)
|
|||
stop_glerror();
|
||||
mMaxLineWidthSmooth = range[1];
|
||||
// </FS:Ansariel>
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLRender::initVertexBuffer()
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ public:
|
|||
|
||||
LLRender();
|
||||
~LLRender();
|
||||
void init(bool needs_vertex_buffer);
|
||||
bool init(bool needs_vertex_buffer);
|
||||
void initVertexBuffer();
|
||||
void resetVertexBuffer();
|
||||
void shutdown();
|
||||
|
|
|
|||
|
|
@ -40,20 +40,20 @@ LLRenderNavPrim gRenderNav;
|
|||
//=============================================================================
|
||||
void LLRenderNavPrim::renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const
|
||||
{
|
||||
LLColor4 cV(color);
|
||||
gGL.color4fv( cV.mV );
|
||||
gGL.begin(LLRender::TRIANGLES);
|
||||
gGL.color4ubv(color.mV);
|
||||
|
||||
gGL.begin(LLRender::TRIANGLES);
|
||||
{
|
||||
gGL.vertex3fv( a.mV );
|
||||
gGL.vertex3fv( b.mV );
|
||||
gGL.vertex3fv( c.mV );
|
||||
}
|
||||
gGL.end();
|
||||
gGL.end();
|
||||
}
|
||||
//=============================================================================
|
||||
void LLRenderNavPrim::renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt )
|
||||
{
|
||||
pVBO->setBuffer();
|
||||
pVBO->drawArrays( mode, 0, vertCnt );
|
||||
pVBO->drawArrays( mode, 0, vertCnt );
|
||||
}
|
||||
//=============================================================================
|
||||
|
|
|
|||
|
|
@ -126,12 +126,12 @@ public:
|
|||
|
||||
void setSelected(bool is_selected);
|
||||
|
||||
bool getCollapsible() {return mCollapsible;};
|
||||
bool getCollapsible() { return mCollapsible; };
|
||||
|
||||
void setCollapsible(bool collapsible) {mCollapsible = collapsible;};
|
||||
void setCollapsible(bool collapsible) { mCollapsible = collapsible; };
|
||||
void changeOpenClose(bool is_open);
|
||||
|
||||
void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close;};
|
||||
void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close; };
|
||||
bool canOpenClose() const { return mCanOpenClose; };
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
|
@ -142,8 +142,8 @@ public:
|
|||
|
||||
void draw();
|
||||
|
||||
void storeOpenCloseState ();
|
||||
void restoreOpenCloseState ();
|
||||
void storeOpenCloseState();
|
||||
void restoreOpenCloseState();
|
||||
|
||||
protected:
|
||||
LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&);
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ void LLContainerView::setLabel(const std::string& label)
|
|||
mLabel = label;
|
||||
}
|
||||
|
||||
void LLContainerView::setDisplayChildren(const BOOL displayChildren)
|
||||
void LLContainerView::setDisplayChildren(BOOL displayChildren)
|
||||
{
|
||||
mDisplayChildren = displayChildren;
|
||||
for (child_list_const_iter_t child_iter = getChildList()->begin();
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public:
|
|||
|
||||
void setLabel(const std::string& label);
|
||||
void showLabel(BOOL show) { mShowLabel = show; }
|
||||
void setDisplayChildren(const BOOL displayChildren);
|
||||
void setDisplayChildren(BOOL displayChildren);
|
||||
BOOL getDisplayChildren() { return mDisplayChildren; }
|
||||
void setScrollContainer(LLScrollContainer* scroll) {mScrollContainer = scroll;}
|
||||
|
||||
|
|
|
|||
|
|
@ -1373,26 +1373,28 @@ void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show)
|
|||
mForceShowingUnmatchedItems = show;
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str)
|
||||
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str, bool notify_parent)
|
||||
{
|
||||
if (0 != LLStringUtil::compareInsensitive(filter_str, mFilterSubString))
|
||||
{
|
||||
mFilterSubString = filter_str;
|
||||
updateNoItemsMessage(mFilterSubString);
|
||||
filterItems();
|
||||
filterItems(false, notify_parent);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
||||
bool LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
||||
{
|
||||
if (!item) return;
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
BOOL visible = TRUE;
|
||||
|
||||
// 0 signifies that filter is matched,
|
||||
// i.e. we don't hide items that don't support 'match_filter' action, separators etc.
|
||||
if (0 == item->notify(action))
|
||||
{
|
||||
mHasMatchedItems = true;
|
||||
item->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1400,34 +1402,45 @@ void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
|
|||
if (!mForceShowingUnmatchedItems)
|
||||
{
|
||||
selectItem(item, false);
|
||||
visible = FALSE;
|
||||
}
|
||||
item->setVisible(mForceShowingUnmatchedItems);
|
||||
}
|
||||
|
||||
if (item->getVisible() != visible)
|
||||
{
|
||||
item->setVisible(visible);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::filterItems()
|
||||
void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
|
||||
{
|
||||
typedef std::vector <LLPanel*> item_panel_list_t;
|
||||
|
||||
std::string cur_filter = mFilterSubString;
|
||||
LLStringUtil::toUpper(cur_filter);
|
||||
|
||||
LLSD action;
|
||||
action.with("match_filter", cur_filter);
|
||||
|
||||
item_panel_list_t items;
|
||||
getItems(items);
|
||||
|
||||
mHasMatchedItems = false;
|
||||
item_panel_list_t::iterator iter = items.begin(), iter_end = items.end();
|
||||
while (iter < iter_end)
|
||||
bool visibility_changed = false;
|
||||
pairs_const_iterator_t iter = getItemPairs().begin(), iter_end = getItemPairs().end();
|
||||
while (iter != iter_end)
|
||||
{
|
||||
LLPanel* pItem = *(iter++);
|
||||
updateItemVisibility(pItem, action);
|
||||
LLPanel* pItem = (*(iter++))->first;
|
||||
visibility_changed |= updateItemVisibility(pItem, action);
|
||||
}
|
||||
|
||||
sort();
|
||||
notifyParentItemsRectChanged();
|
||||
if (re_sort)
|
||||
{
|
||||
sort();
|
||||
}
|
||||
|
||||
if (visibility_changed && notify_parent)
|
||||
{
|
||||
notifyParentItemsRectChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFlatListViewEx::hasMatchedItems()
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ public:
|
|||
virtual S32 notify(const LLSD& info) ;
|
||||
|
||||
virtual ~LLFlatListView();
|
||||
|
||||
protected:
|
||||
|
||||
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
|
||||
|
|
@ -383,7 +384,9 @@ protected:
|
|||
|
||||
LLRect getLastSelectedItemRect();
|
||||
|
||||
void ensureSelectedVisible();
|
||||
void ensureSelectedVisible();
|
||||
|
||||
const pairs_list_t& getItemPairs() { return mItemPairs; }
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -496,14 +499,14 @@ public:
|
|||
/**
|
||||
* Sets up new filter string and filters the list.
|
||||
*/
|
||||
void setFilterSubString(const std::string& filter_str);
|
||||
void setFilterSubString(const std::string& filter_str, bool notify_parent);
|
||||
std::string getFilterSubString() { return mFilterSubString; }
|
||||
|
||||
/**
|
||||
* Filters the list, rearranges and notifies parent about shape changes.
|
||||
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
|
||||
*/
|
||||
void filterItems();
|
||||
void filterItems(bool re_sort, bool notify_parent);
|
||||
|
||||
/**
|
||||
* Returns true if last call of filterItems() found at least one matching item
|
||||
|
|
@ -527,7 +530,7 @@ protected:
|
|||
* @param item - item we are changing
|
||||
* @param item - action - parameters to determin visibility from
|
||||
*/
|
||||
void updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
bool updateItemVisibility(LLPanel* item, const LLSD &action);
|
||||
|
||||
private:
|
||||
std::string mNoFilteredItemsMsg;
|
||||
|
|
|
|||
|
|
@ -541,7 +541,6 @@ void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
|
|||
|
||||
void LLFloater::destroy()
|
||||
{
|
||||
gFloaterView->onDestroyFloater(this);
|
||||
// LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before
|
||||
// it was deleted via LLMortician::updateClass(). See EXT-8458.
|
||||
LLFloaterReg::removeInstance(mInstanceName, mKey);
|
||||
|
|
@ -2631,8 +2630,7 @@ LLFloaterView::LLFloaterView (const Params& p)
|
|||
mSnapOffsetBottom(0),
|
||||
mSnapOffsetChatBar(0),
|
||||
mSnapOffsetLeft(0),
|
||||
mSnapOffsetRight(0),
|
||||
mFrontChild(NULL)
|
||||
mSnapOffsetRight(0)
|
||||
{
|
||||
mSnapView = getHandle();
|
||||
}
|
||||
|
|
@ -2788,7 +2786,8 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore
|
|||
if (!child)
|
||||
return;
|
||||
|
||||
if (mFrontChild == child)
|
||||
LLFloater* front_child = mFrontChildHandle.get();
|
||||
if (front_child == child)
|
||||
{
|
||||
if (give_focus && child->canFocusStealFrontmost() && !gFocusMgr.childHasKeyboardFocus(child))
|
||||
{
|
||||
|
|
@ -2797,12 +2796,12 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus, BOOL restore
|
|||
return;
|
||||
}
|
||||
|
||||
if (mFrontChild && !mFrontChild->isDead())
|
||||
if (front_child && !front_child->isDead() && front_child->getVisible())
|
||||
{
|
||||
mFrontChild->goneFromFront();
|
||||
front_child->goneFromFront();
|
||||
}
|
||||
|
||||
mFrontChild = child;
|
||||
mFrontChildHandle = child->getHandle();
|
||||
|
||||
// *TODO: make this respect floater's mAutoFocus value, instead of
|
||||
// using parameter
|
||||
|
|
@ -3389,7 +3388,8 @@ LLFloater *LLFloaterView::getBackmost() const
|
|||
|
||||
void LLFloaterView::syncFloaterTabOrder()
|
||||
{
|
||||
if (mFrontChild && !mFrontChild->isDead() && mFrontChild->getIsChrome())
|
||||
LLFloater* front_child = mFrontChildHandle.get();
|
||||
if (front_child && front_child->getIsChrome())
|
||||
return;
|
||||
|
||||
// look for a visible modal dialog, starting from first
|
||||
|
|
@ -3427,11 +3427,12 @@ void LLFloaterView::syncFloaterTabOrder()
|
|||
LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
|
||||
if (gFocusMgr.childHasKeyboardFocus(floaterp))
|
||||
{
|
||||
if (mFrontChild != floaterp)
|
||||
LLFloater* front_child = mFrontChildHandle.get();
|
||||
if (front_child != floaterp)
|
||||
{
|
||||
// Grab a list of the top floaters that want to stay on top of the focused floater
|
||||
std::list<LLFloater*> listTop;
|
||||
if (mFrontChild && !mFrontChild->canFocusStealFrontmost())
|
||||
if (front_child && !front_child->canFocusStealFrontmost())
|
||||
{
|
||||
for (LLView* childp : *getChildList())
|
||||
{
|
||||
|
|
@ -3451,7 +3452,7 @@ void LLFloaterView::syncFloaterTabOrder()
|
|||
{
|
||||
sendChildToFront(childp);
|
||||
}
|
||||
mFrontChild = listTop.back();
|
||||
mFrontChildHandle = listTop.back()->getHandle();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3547,14 +3548,6 @@ void LLFloaterView::setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LL
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterView::onDestroyFloater(LLFloater* floater)
|
||||
{
|
||||
if (mFrontChild == floater)
|
||||
{
|
||||
mFrontChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
void LLFloaterView::setMainChatbarRect(LLLayoutPanel* panel, const LLRect& chatbar_rect)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -645,7 +645,6 @@ public:
|
|||
// </FS:KC> Fix for bad edge snapping
|
||||
|
||||
void setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect);
|
||||
void onDestroyFloater(LLFloater* floater);
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
void setMainChatbarRect(LLLayoutPanel* panel, const LLRect& chatbar_rect);
|
||||
|
|
@ -670,7 +669,7 @@ private:
|
|||
S32 mMinimizePositionVOffset;
|
||||
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
|
||||
hidden_floaters_t mHiddenFloaters;
|
||||
LLFloater * mFrontChild;
|
||||
LLHandle<LLFloater> mFrontChildHandle;
|
||||
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
LLRect mMainChatbarRect;
|
||||
|
|
|
|||
|
|
@ -206,14 +206,18 @@ LLFolderViewItem::~LLFolderViewItem()
|
|||
|
||||
BOOL LLFolderViewItem::postBuild()
|
||||
{
|
||||
LLFolderViewModelItem& vmi = *getViewModelItem();
|
||||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = vmi.getDisplayName();
|
||||
setToolTip(vmi.getName());
|
||||
LLFolderViewModelItem* vmi = getViewModelItem();
|
||||
llassert(vmi); // not supposed to happen, if happens, find out why and fix
|
||||
if (vmi)
|
||||
{
|
||||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = vmi->getDisplayName();
|
||||
setToolTip(vmi->getName());
|
||||
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi.dirtyFilter();
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
vmi->dirtyFilter();
|
||||
}
|
||||
|
||||
// Don't do full refresh on constructor if it is possible to avoid
|
||||
// it significantly slows down bulk view creation.
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ LLTrace::BlockTimerStatHandle FTM_SYNTAX_COLORING("Syntax Coloring");
|
|||
|
||||
// Walk through a string, applying the rules specified by the keyword token list and
|
||||
// create a list of color segments.
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, const LLColor4 &defaultColor, LLTextEditor& editor)
|
||||
void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLWString& wtext, LLTextEditor& editor, LLStyleConstSP style)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_SYNTAX_COLORING);
|
||||
seg_list->clear();
|
||||
|
|
@ -515,10 +515,10 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
S32 text_len = wtext.size() + 1;
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//seg_list->push_back( new LLNormalTextSegment( defaultColor, 0, text_len, editor ) );
|
||||
LLStyleSP style = getDefaultStyle(editor);
|
||||
style->setColor(defaultColor);
|
||||
seg_list->push_back( new LLNormalTextSegment( style, 0, text_len, editor ) );
|
||||
//seg_list->push_back( new LLNormalTextSegment( style, 0, text_len, editor ) );
|
||||
LLStyleSP actual_style = getDefaultStyle(editor);
|
||||
actual_style->setColor(style->getColor());
|
||||
seg_list->push_back( new LLNormalTextSegment( actual_style, 0, text_len, editor ) );
|
||||
// </FS:Ansariel>
|
||||
|
||||
const llwchar* base = wtext.c_str();
|
||||
|
|
@ -530,11 +530,11 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
if( *cur == '\n' )
|
||||
{
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(cur-base);
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(style, cur-base);
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(getDefaultStyle(editor), cur-base);
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( 0 );
|
||||
insertSegment( *seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( *seg_list, text_segment, text_len, style, editor);
|
||||
cur++;
|
||||
if( !*cur || *cur == '\n' )
|
||||
{
|
||||
|
|
@ -572,7 +572,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
S32 seg_end = cur - base;
|
||||
|
||||
//create segments from seg_start to seg_end
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, style, editor);
|
||||
line_done = TRUE; // to break out of second loop.
|
||||
break;
|
||||
}
|
||||
|
|
@ -679,7 +679,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
|
||||
}
|
||||
|
||||
insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, style, editor);
|
||||
/*
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor );
|
||||
|
|
@ -723,7 +723,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
|
||||
// LL_INFOS("SyntaxLSL") << "Seg: [" << word.c_str() << "]" << LL_ENDL;
|
||||
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, defaultColor, editor);
|
||||
insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, style, editor);
|
||||
}
|
||||
cur += seg_len;
|
||||
continue;
|
||||
|
|
@ -738,9 +738,12 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
|
|||
}
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, const LLColor4 &defaultColor, LLTextEditor& editor )
|
||||
void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmentPtr>& seg_list, LLKeywordToken* cur_token, S32 text_len, S32 seg_start, S32 seg_end, LLStyleConstSP style, LLTextEditor& editor )
|
||||
{
|
||||
std::string::size_type pos = wtext.find('\n',seg_start);
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLStyleConstSP cur_token_style = new LLStyle(LLStyle::Params().font(style->getFont()).color(cur_token->getColor()));
|
||||
|
||||
while (pos!=-1 && pos < (std::string::size_type)seg_end)
|
||||
{
|
||||
|
|
@ -753,28 +756,28 @@ void LLKeywords::insertSegments(const LLWString& wtext, std::vector<LLTextSegmen
|
|||
LLTextSegmentPtr text_segment = new LLNormalTextSegment( style, seg_start, pos, editor );
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(pos);
|
||||
//LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(style, pos);
|
||||
LLTextSegmentPtr text_segment = new LLLineBreakTextSegment(getDefaultStyle(editor), pos);
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
|
||||
seg_start = pos+1;
|
||||
pos = wtext.find('\n',seg_start);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_token->getColor(), seg_start, seg_end, editor );
|
||||
LLStyleSP style = getDefaultStyle(editor);
|
||||
style->setColor(cur_token->getColor());
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment( style, seg_start, seg_end, editor );
|
||||
//LLTextSegmentPtr text_segment = new LLNormalTextSegment(cur_token_style, seg_start, seg_end, editor);
|
||||
LLStyleSP actual_style = getDefaultStyle(editor);
|
||||
actual_style->setColor(cur_token->getColor());
|
||||
LLTextSegmentPtr text_segment = new LLNormalTextSegment(actual_style, seg_start, seg_end, editor);
|
||||
// </FS:Ansariel>
|
||||
text_segment->setToken( cur_token );
|
||||
insertSegment( seg_list, text_segment, text_len, defaultColor, editor);
|
||||
insertSegment( seg_list, text_segment, text_len, style, editor);
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, const LLColor4 &defaultColor, LLTextEditor& editor )
|
||||
|
|
@ -803,6 +806,32 @@ void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSe
|
|||
}
|
||||
}
|
||||
|
||||
void LLKeywords::insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, LLStyleConstSP style, LLTextEditor& editor )
|
||||
{
|
||||
LLTextSegmentPtr last = seg_list.back();
|
||||
S32 new_seg_end = new_segment->getEnd();
|
||||
|
||||
if( new_segment->getStart() == last->getStart() )
|
||||
{
|
||||
seg_list.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
last->setEnd( new_segment->getStart() );
|
||||
}
|
||||
seg_list.push_back( new_segment );
|
||||
|
||||
if( new_seg_end < text_len )
|
||||
{
|
||||
// <FS:Ansariel> Script editor ignoring font selection
|
||||
//seg_list.push_back( new LLNormalTextSegment( style, new_seg_end, text_len, editor ) );
|
||||
LLStyleSP actual_style = getDefaultStyle(editor);
|
||||
actual_style->setColor(style->getColor());
|
||||
seg_list.push_back(new LLNormalTextSegment(actual_style, new_seg_end, text_len, editor));
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Re-add support for Cinder's legacy file format
|
||||
bool LLKeywords::loadFromLegacyFile(const std::string& filename)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llstyle.h"
|
||||
#include "llstring.h"
|
||||
#include "v3color.h"
|
||||
#include "v4color.h"
|
||||
|
|
@ -121,8 +122,8 @@ public:
|
|||
|
||||
void findSegments(std::vector<LLTextSegmentPtr> *seg_list,
|
||||
const LLWString& text,
|
||||
const LLColor4 &defaultColor,
|
||||
class LLTextEditor& editor);
|
||||
class LLTextEditor& editor,
|
||||
LLStyleConstSP style);
|
||||
void initialize(LLSD SyntaxXML);
|
||||
void processTokens();
|
||||
|
||||
|
|
@ -187,9 +188,11 @@ protected:
|
|||
S32 text_len,
|
||||
S32 seg_start,
|
||||
S32 seg_end,
|
||||
const LLColor4 &defaultColor,
|
||||
LLStyleConstSP style,
|
||||
LLTextEditor& editor);
|
||||
|
||||
void insertSegment(std::vector<LLTextSegmentPtr>& seg_list, LLTextSegmentPtr new_segment, S32 text_len, LLStyleConstSP style, LLTextEditor& editor );
|
||||
|
||||
bool mLoaded;
|
||||
LLSD mSyntax;
|
||||
word_token_map_t mWordTokenMap;
|
||||
|
|
|
|||
|
|
@ -1811,7 +1811,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
|
|||
mNeedsArrange(FALSE),
|
||||
mAlwaysShowMenu(FALSE),
|
||||
mResetScrollPositionOnShow(true),
|
||||
mShortcutPad(p.shortcut_pad)
|
||||
mShortcutPad(p.shortcut_pad),
|
||||
mFont(p.font)
|
||||
{
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep("_");
|
||||
|
|
@ -3682,6 +3683,7 @@ BOOL LLMenuBarGL::appendMenu( LLMenuGL* menu )
|
|||
p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
|
||||
p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
|
||||
p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
|
||||
p.font = menu->getFont();
|
||||
|
||||
LLMenuItemBranchDownGL* branch = LLUICtrlFactory::create<LLMenuItemBranchDownGL>(p);
|
||||
success &= branch->addToAcceleratorList(&mAccelerators);
|
||||
|
|
|
|||
|
|
@ -563,6 +563,8 @@ public:
|
|||
// add a context menu branch
|
||||
BOOL appendContextSubMenu(LLMenuGL *menu);
|
||||
|
||||
const LLFontGL *getFont() const { return mFont; }
|
||||
|
||||
// <FS:Ansariel> Items-accessor
|
||||
typedef std::list< LLMenuItemGL* > item_list_t;
|
||||
item_list_t* getItems() { return &mItems; }
|
||||
|
|
@ -599,6 +601,9 @@ protected:
|
|||
BOOL mKeepFixedSize;
|
||||
BOOL mNeedsArrange;
|
||||
|
||||
// Font for top menu items only
|
||||
const LLFontGL* mFont;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1562,6 +1562,7 @@ bool LLNotifications::loadTemplates()
|
|||
|
||||
if (!success || root.isNull() || !root->hasName( "notifications" ))
|
||||
{
|
||||
LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
|
||||
LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1572,6 +1573,7 @@ bool LLNotifications::loadTemplates()
|
|||
|
||||
if(!params.validateBlock())
|
||||
{
|
||||
LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
|
||||
LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1638,6 +1640,7 @@ bool LLNotifications::loadVisibilityRules()
|
|||
|
||||
if(!params.validateBlock())
|
||||
{
|
||||
LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
|
||||
LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ LLStatBar::LLStatBar(const Params& p)
|
|||
mTargetMinBar(llmin(p.bar_min, p.bar_max)),
|
||||
mTargetMaxBar(llmax(p.bar_max, p.bar_min)),
|
||||
mCurMaxBar(p.bar_max),
|
||||
mCurMinBar(0),
|
||||
mCurMinBar(0),
|
||||
mDecimalDigits(p.decimal_digits),
|
||||
mNumHistoryFrames(p.num_frames),
|
||||
mNumShortHistoryFrames(p.num_frames_short),
|
||||
|
|
@ -279,9 +279,6 @@ BOOL LLStatBar::handleHover(S32 x, S32 y, MASK mask)
|
|||
case STAT_SAMPLE:
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.sampleStatp->getDescription()).sticky_rect(calcScreenRect()));
|
||||
break;
|
||||
case STAT_MEM:
|
||||
LLToolTipMgr::instance().show(LLToolTip::Params().message(mStat.memStatp->getDescription()).sticky_rect(calcScreenRect()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -430,18 +427,6 @@ void LLStatBar::draw()
|
|||
}
|
||||
}
|
||||
break;
|
||||
case STAT_MEM:
|
||||
{
|
||||
const LLTrace::StatType<LLTrace::MemAccumulator>& mem_stat = *mStat.memStatp;
|
||||
|
||||
unit_label = mUnitLabel.empty() ? mem_stat.getUnitLabel() : mUnitLabel;
|
||||
current = last_frame_recording.getLastValue(mem_stat).value();
|
||||
min = frame_recording.getPeriodMin(mem_stat, num_frames).value();
|
||||
max = frame_recording.getPeriodMax(mem_stat, num_frames).value();
|
||||
mean = frame_recording.getPeriodMean(mem_stat, num_frames).value();
|
||||
display_value = current;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -560,11 +545,6 @@ void LLStatBar::draw()
|
|||
max_value = recording.getMax(*mStat.sampleStatp);
|
||||
num_samples = recording.getSampleCount(*mStat.sampleStatp);
|
||||
break;
|
||||
case STAT_MEM:
|
||||
min_value = recording.getMin(*mStat.memStatp).value();
|
||||
max_value = recording.getMax(*mStat.memStatp).value();
|
||||
num_samples = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -661,14 +641,8 @@ void LLStatBar::setStat(const std::string& stat_name)
|
|||
mStat.sampleStatp = sample_stat.get();
|
||||
mStatType = STAT_SAMPLE;
|
||||
}
|
||||
else if (auto mem_stat = StatType<MemAccumulator>::getInstance(stat_name))
|
||||
{
|
||||
mStat.memStatp = mem_stat.get();
|
||||
mStatType = STAT_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLStatBar::setRange(F32 bar_min, F32 bar_max)
|
||||
{
|
||||
mTargetMinBar = llmin(bar_min, bar_max);
|
||||
|
|
|
|||
|
|
@ -100,17 +100,15 @@ private:
|
|||
STAT_NONE,
|
||||
STAT_COUNT,
|
||||
STAT_EVENT,
|
||||
STAT_SAMPLE,
|
||||
STAT_MEM
|
||||
STAT_SAMPLE
|
||||
} mStatType;
|
||||
|
||||
union
|
||||
{
|
||||
void* valid;
|
||||
void* valid;
|
||||
const LLTrace::StatType<LLTrace::CountAccumulator>* countStatp;
|
||||
const LLTrace::StatType<LLTrace::EventAccumulator>* eventStatp;
|
||||
const LLTrace::StatType<LLTrace::SampleAccumulator>* sampleStatp;
|
||||
const LLTrace::StatType<LLTrace::MemAccumulator>* memStatp;
|
||||
const LLTrace::StatType<LLTrace::SampleAccumulator>* sampleStatp;
|
||||
} mStat;
|
||||
|
||||
LLUIString mLabel;
|
||||
|
|
|
|||
|
|
@ -58,10 +58,7 @@ LLStatView::~LLStatView()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static StatViewRegistry::Register<LLStatBar> r1("stat_bar");
|
||||
static StatViewRegistry::Register<LLStatView> r2("stat_view");
|
||||
// stat_view can be a child of panels/etc.
|
||||
static LLDefaultChildRegistry::Register<LLStatView> r3("stat_view");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ protected:
|
|||
friend class LLUICtrlFactory;
|
||||
|
||||
protected:
|
||||
std::string mSetting;
|
||||
|
||||
const std::string mSetting;
|
||||
};
|
||||
|
||||
#endif // LL_STATVIEW_
|
||||
|
|
|
|||
|
|
@ -1657,25 +1657,23 @@ BOOL LLTabContainer::selectTab(S32 which)
|
|||
|
||||
LLTabTuple* selected_tuple = getTab(which);
|
||||
if (!selected_tuple)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
LLSD cbdata;
|
||||
if (selected_tuple->mTabPanel)
|
||||
cbdata = selected_tuple->mTabPanel->getName();
|
||||
|
||||
BOOL res = FALSE;
|
||||
if( !mValidateSignal || (*mValidateSignal)( this, cbdata ) )
|
||||
BOOL result = FALSE;
|
||||
if (!mValidateSignal || (*mValidateSignal)(this, cbdata))
|
||||
{
|
||||
res = setTab(which);
|
||||
if (res && mCommitSignal)
|
||||
result = setTab(which);
|
||||
if (result && mCommitSignal)
|
||||
{
|
||||
(*mCommitSignal)(this, cbdata);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// private
|
||||
|
|
|
|||
|
|
@ -3829,7 +3829,7 @@ BOOL LLNormalTextSegment::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
if (mToken && !mToken->getToolTip().empty())
|
||||
{
|
||||
const LLWString& wmsg = mToken->getToolTip();
|
||||
LLToolTipMgr::instance().show(wstring_to_utf8str(wmsg));
|
||||
LLToolTipMgr::instance().show(wstring_to_utf8str(wmsg), (mToken->getType() == LLKeywordToken::TT_FUNCTION));
|
||||
return TRUE;
|
||||
}
|
||||
// or do we have an explicitly set tooltip (e.g., for Urls)
|
||||
|
|
|
|||
|
|
@ -2048,7 +2048,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
|
|||
}
|
||||
|
||||
if (mEnableTooltipPaste &&
|
||||
LLToolTipMgr::instance().toolTipVisible() &&
|
||||
LLToolTipMgr::instance().toolTipVisible() &&
|
||||
LLToolTipMgr::instance().isTooltipPastable() &&
|
||||
KEY_TAB == key)
|
||||
{ // Paste the first line of a tooltip into the editor
|
||||
std::string message;
|
||||
|
|
@ -2901,6 +2902,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length )
|
|||
char* text = new char[ text_len + 1];
|
||||
if (text == NULL)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS() << "Memory allocation failure." << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,8 @@ LLToolTip::Params::Params()
|
|||
text_color("text_color"),
|
||||
time_based_media("time_based_media", false),
|
||||
web_based_media("web_based_media", false),
|
||||
media_playing("media_playing", false)
|
||||
media_playing("media_playing", false),
|
||||
allow_paste_tooltip("allow_paste_tooltip", false)
|
||||
{
|
||||
changeDefault(chrome, true);
|
||||
}
|
||||
|
|
@ -167,7 +168,8 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
|
|||
mTextBox(NULL),
|
||||
mInfoButton(NULL),
|
||||
mPlayMediaButton(NULL),
|
||||
mHomePageButton(NULL)
|
||||
mHomePageButton(NULL),
|
||||
mIsTooltipPastable(p.allow_paste_tooltip)
|
||||
{
|
||||
LLTextBox::Params params;
|
||||
params.name = params.initial_value().asString();
|
||||
|
|
@ -289,6 +291,8 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
|
|||
mTextBox->setText(p.message());
|
||||
}
|
||||
|
||||
mIsTooltipPastable = p.allow_paste_tooltip;
|
||||
|
||||
updateTextBox();
|
||||
snapToChildren();
|
||||
}
|
||||
|
|
@ -483,9 +487,9 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
|
|||
}
|
||||
|
||||
|
||||
void LLToolTipMgr::show(const std::string& msg)
|
||||
void LLToolTipMgr::show(const std::string& msg, bool allow_paste_tooltip)
|
||||
{
|
||||
show(LLToolTip::Params().message(msg));
|
||||
show(LLToolTip::Params().message(msg).allow_paste_tooltip(allow_paste_tooltip));
|
||||
}
|
||||
|
||||
void LLToolTipMgr::show(const LLToolTip::Params& params)
|
||||
|
|
@ -625,5 +629,13 @@ void LLToolTipMgr::getToolTipMessage(std::string & message)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLToolTipMgr::isTooltipPastable()
|
||||
{
|
||||
if (toolTipVisible())
|
||||
{
|
||||
return mToolTip->isTooltipPastable();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ public:
|
|||
padding;
|
||||
Optional<bool> wrap;
|
||||
|
||||
Optional<bool> allow_paste_tooltip;
|
||||
|
||||
Params();
|
||||
};
|
||||
/*virtual*/ void draw();
|
||||
|
|
@ -109,6 +111,7 @@ public:
|
|||
virtual void initFromParams(const LLToolTip::Params& params);
|
||||
|
||||
void getToolTipMessage(std::string & message);
|
||||
bool isTooltipPastable() { return mIsTooltipPastable; }
|
||||
|
||||
protected:
|
||||
void updateTextBox();
|
||||
|
|
@ -125,6 +128,8 @@ protected:
|
|||
bool mHasClickCallback;
|
||||
S32 mPadding; // pixels
|
||||
S32 mMaxWidth;
|
||||
|
||||
bool mIsTooltipPastable;
|
||||
};
|
||||
|
||||
// used for the inspector tooltips which need different background images etc.
|
||||
|
|
@ -142,7 +147,7 @@ class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
|
|||
|
||||
public:
|
||||
void show(const LLToolTip::Params& params);
|
||||
void show(const std::string& message);
|
||||
void show(const std::string& message, bool allow_paste_tooltip = false);
|
||||
|
||||
void unblockToolTips();
|
||||
void blockToolTips();
|
||||
|
|
@ -154,6 +159,7 @@ public:
|
|||
void updateToolTipVisibility();
|
||||
|
||||
void getToolTipMessage(std::string & message);
|
||||
bool isTooltipPastable();
|
||||
|
||||
private:
|
||||
void createToolTip(const LLToolTip::Params& params);
|
||||
|
|
|
|||
|
|
@ -44,8 +44,13 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
|
|||
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
|
||||
if (!success)
|
||||
{
|
||||
const std::string error_string =
|
||||
"Firestorm viewer couldn't access some of the files it needs and will be closed."
|
||||
"\n\nPlease reinstall viewer from https://firestormviewer.org/download and "
|
||||
"contact https://www.firestormviewer.org/support if issue persists after reinstall.";
|
||||
LLError::LLUserWarningMsg::show(error_string);
|
||||
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
|
||||
LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://www.firestormviewer.org/choose-your-platform/ and contact https://www.firestormviewer.org/support if issue persists after reinstall." << LL_ENDL;
|
||||
LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +65,7 @@ bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename)
|
|||
|
||||
if (!success)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showMissingFiles();
|
||||
LL_ERRS() << "Couldn't load localization table " << xml_filename << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,14 +237,20 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
|
|||
|
||||
std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
|
||||
{
|
||||
if (url.empty())
|
||||
{
|
||||
return url;
|
||||
}
|
||||
LLUriParser up(escapeUrl(url));
|
||||
up.normalize();
|
||||
if (up.normalize() == 0)
|
||||
{
|
||||
std::string label;
|
||||
up.extractParts();
|
||||
up.glueFirst(label);
|
||||
|
||||
std::string label;
|
||||
up.extractParts();
|
||||
up.glueFirst(label);
|
||||
|
||||
return unescapeUrl(label);
|
||||
return unescapeUrl(label);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
|
||||
|
|
|
|||
|
|
@ -293,16 +293,18 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
|
|||
//if (match_entry == mUrlEntryTrusted)
|
||||
//{
|
||||
// LLUriParser up(url);
|
||||
// up.normalize();
|
||||
// url = up.normalizedUri();
|
||||
// if (up.normalize() == 0)
|
||||
// {
|
||||
// url = up.normalizedUri();
|
||||
// }
|
||||
//}
|
||||
if (match_entry != mUrlEntryNoLink && match_entry == mUrlEntryTrustedUrl)
|
||||
{
|
||||
LLUriParser up(url);
|
||||
if (!up.normalize())
|
||||
{
|
||||
url = up.normalizedUri();
|
||||
}
|
||||
if (up.normalize() == 0)
|
||||
{
|
||||
url = up.normalizedUri();
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "llwindowcallbacks.h"
|
||||
|
||||
// Linden library includes
|
||||
#include "llapp.h" // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
#include "llerror.h"
|
||||
#include "llexception.h"
|
||||
#include "llfasttimer.h"
|
||||
|
|
@ -94,7 +93,6 @@ const UINT WM_DUMMY_(WM_USER + 0x0017);
|
|||
const UINT WM_POST_FUNCTION_(WM_USER + 0x0018);
|
||||
|
||||
extern BOOL gDebugWindowProc;
|
||||
extern BOOL gDisconnected; // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
|
||||
static std::thread::id sWindowThreadId;
|
||||
static std::thread::id sMainThreadId;
|
||||
|
|
@ -353,7 +351,10 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
LLWindowWin32Thread();
|
||||
|
||||
void run() override;
|
||||
void close() override; // <FS:Beq/> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
void close() override;
|
||||
|
||||
// closes queue, wakes thread, waits until thread closes
|
||||
void wakeAndDestroy();
|
||||
|
||||
void glReady()
|
||||
{
|
||||
|
|
@ -366,6 +367,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
// initialize D3D (if DXGI cannot be used)
|
||||
void initD3D();
|
||||
|
||||
//clean up DXGI/D3D resources
|
||||
void cleanupDX();
|
||||
|
||||
// call periodically to update available VRAM
|
||||
void updateVRAMUsage();
|
||||
|
||||
|
|
@ -415,8 +419,8 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
using FuncType = std::function<void()>;
|
||||
// call GetMessage() and pull enqueue messages for later processing
|
||||
void gatherInput();
|
||||
HWND mWindowHandle = NULL;
|
||||
HDC mhDC = 0;
|
||||
HWND mWindowHandleThrd = NULL;
|
||||
HDC mhDCThrd = 0;
|
||||
|
||||
// *HACK: Attempt to prevent startup crashes by deferring memory accounting
|
||||
// until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
|
||||
|
|
@ -992,53 +996,10 @@ void LLWindowWin32::close()
|
|||
|
||||
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
|
||||
|
||||
mWindowThread->post([=]()
|
||||
{
|
||||
if (IsWindow(mWindowHandle))
|
||||
{
|
||||
if (mhDC)
|
||||
{
|
||||
if (!ReleaseDC(mWindowHandle, mhDC))
|
||||
{
|
||||
LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we don't leave a blank toolbar button.
|
||||
ShowWindow(mWindowHandle, SW_HIDE);
|
||||
|
||||
// This causes WM_DESTROY to be sent *immediately*
|
||||
if (!destroy_window_handler(mWindowHandle))
|
||||
{
|
||||
// <FS:Beq> Can't use a message box here because we're about to stop servicing the events.
|
||||
// OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
|
||||
// mCallbacks->translateString("MBShutdownErr"),
|
||||
// OSMB_OK);
|
||||
LL_INFOS("Window") << "Destroying Window failed" << LL_ENDL;
|
||||
// </FS:Beq>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something killed the window while we were busy destroying gl or handle somehow got broken
|
||||
LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
|
||||
}
|
||||
|
||||
});
|
||||
// Window thread might be waiting for a getMessage(), give it
|
||||
// a push to enshure it will process destroy_window_handler
|
||||
kickWindowThread();
|
||||
|
||||
// Even though the above lambda might not yet have run, we've already
|
||||
// bound mWindowHandle into it by value, which should suffice for the
|
||||
// operations we're asking. That's the last time WE should touch it.
|
||||
mhDC = NULL;
|
||||
mWindowHandle = NULL;
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] close the related queues first to prevent spinning.
|
||||
mFunctionQueue.close();
|
||||
mMouseQueue.close();
|
||||
// </FS:Beq>
|
||||
mWindowThread->close();
|
||||
|
||||
mWindowThread->wakeAndDestroy();
|
||||
}
|
||||
|
||||
BOOL LLWindowWin32::isValid()
|
||||
|
|
@ -1791,8 +1752,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
|
|||
()
|
||||
{
|
||||
LL_DEBUGS("Window") << "recreateWindow(): window_work entry" << LL_ENDL;
|
||||
self->mWindowHandle = 0;
|
||||
self->mhDC = 0;
|
||||
self->mWindowHandleThrd = 0;
|
||||
self->mhDCThrd = 0;
|
||||
|
||||
if (oldWindowHandle)
|
||||
{
|
||||
|
|
@ -1826,20 +1787,20 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
|
|||
{
|
||||
// Failed to create window: clear the variables. This
|
||||
// assignment is valid because we're running on mWindowThread.
|
||||
self->mWindowHandle = NULL;
|
||||
self->mhDC = 0;
|
||||
self->mWindowHandleThrd = NULL;
|
||||
self->mhDCThrd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update mWindowThread's own mWindowHandle and mhDC.
|
||||
self->mWindowHandle = handle;
|
||||
self->mhDC = GetDC(handle);
|
||||
self->mWindowHandleThrd = handle;
|
||||
self->mhDCThrd = GetDC(handle);
|
||||
}
|
||||
|
||||
updateWindowRect();
|
||||
|
||||
// It's important to wake up the future either way.
|
||||
promise.set_value(std::make_pair(self->mWindowHandle, self->mhDC));
|
||||
promise.set_value(std::make_pair(self->mWindowHandleThrd, self->mhDCThrd));
|
||||
LL_DEBUGS("Window") << "recreateWindow(): window_work done" << LL_ENDL;
|
||||
};
|
||||
// But how we pass window_work to the window thread depends on whether we
|
||||
|
|
@ -3723,6 +3684,7 @@ void LLWindowWin32::swapBuffers()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LLSplashScreenImp
|
||||
//
|
||||
|
|
@ -3745,6 +3707,9 @@ void LLSplashScreenWin32::showImpl()
|
|||
NULL, // no parent
|
||||
(DLGPROC) LLSplashScreenWin32::windowProc);
|
||||
ShowWindow(mWindow, SW_SHOW);
|
||||
|
||||
// Should set taskbar text without creating a header for the window (caption)
|
||||
SetWindowTextA(mWindow, APP_NAME.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4708,11 +4673,25 @@ void LLWindowWin32::getWindowChrome( U32 &aChromeW, U32 &aChromeH )
|
|||
#endif // LL_WINDOWS
|
||||
|
||||
inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()
|
||||
: LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE)
|
||||
: LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, true /*should be false, temporary workaround for SL-18721*/)
|
||||
{
|
||||
LL::ThreadPool::start();
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::close()
|
||||
{
|
||||
if (!mQueue->isClosed())
|
||||
{
|
||||
LL_WARNS() << "Closing window thread without using destroy_window_handler" << LL_ENDL;
|
||||
LL::ThreadPool::close();
|
||||
|
||||
// Workaround for SL-18721 in case window closes too early and abruptly
|
||||
LLSplashScreen::show();
|
||||
LLSplashScreen::update("..."); // will be updated later
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LogChange is to log changes in status while trying to avoid spamming the
|
||||
* log with repeated messages, especially in a tight loop. It refuses to log
|
||||
|
|
@ -4864,7 +4843,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
|
|||
{
|
||||
if (!mGLReady) { return; }
|
||||
|
||||
if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0)
|
||||
if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandleThrd != 0)
|
||||
{
|
||||
mD3D = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
|
||||
|
|
@ -4874,7 +4853,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
|
|||
d3dpp.Windowed = TRUE;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
|
||||
HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice);
|
||||
HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandleThrd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice);
|
||||
|
||||
if (FAILED(res))
|
||||
{
|
||||
|
|
@ -4887,6 +4866,28 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()
|
|||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::cleanupDX()
|
||||
{
|
||||
//clean up DXGI/D3D resources
|
||||
if (mDXGIAdapter)
|
||||
{
|
||||
mDXGIAdapter->Release();
|
||||
mDXGIAdapter = nullptr;
|
||||
}
|
||||
|
||||
if (mD3DDevice)
|
||||
{
|
||||
mD3DDevice->Release();
|
||||
mD3DDevice = nullptr;
|
||||
}
|
||||
|
||||
if (mD3D)
|
||||
{
|
||||
mD3D->Release();
|
||||
mD3D = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
|
@ -4960,45 +4961,10 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
|
|||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
// Provide a close() override that ignores the initial close triggered by the threadpool detecting "quit"
|
||||
// but waits for the viewer to be disconected and the second close call triggered by the app window destructor
|
||||
void LLWindowWin32::LLWindowWin32Thread::close()
|
||||
{
|
||||
assert_main_thread();
|
||||
if (!mQueue->isClosed() && gDisconnected)
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL;
|
||||
mQueue->close();
|
||||
for (auto& pair: mThreads)
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL;
|
||||
// As we cannot seem to rely on the clean and timely exit of the windows thread in ALL situations we apply a timeout.
|
||||
std::future<void> f = std::async(std::launch::async, [&] { pair.second.join(); });
|
||||
if (f.wait_until(std::chrono::steady_clock::now() + std::chrono::seconds(5)) == std::future_status::ready) {
|
||||
LL_DEBUGS("ThreadPool") << mName << " joined normally." << LL_ENDL;
|
||||
} else {
|
||||
LL_WARNS("ThreadPool") << mName << " join timed out." << LL_ENDL;
|
||||
// the specified time point was reached before the thread finished execution and could be joined
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("ThreadPool") << mName << " shutdown complete" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("ThreadPool") << mName << " shutdown request ignored - not yet disconneced." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::run()
|
||||
{
|
||||
sWindowThreadId = std::this_thread::get_id();
|
||||
LogChange logger("Window");
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
try
|
||||
{
|
||||
// </FS:Beq>
|
||||
//as good a place as any to up the MM timer resolution (see ms_sleep)
|
||||
//attempt to set timer resolution to 1ms
|
||||
TIMECAPS tc;
|
||||
|
|
@ -5014,7 +4980,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
// lazily call initD3D inside this loop to catch when mGLReady has been set to true
|
||||
initDX();
|
||||
|
||||
if (mWindowHandle != 0)
|
||||
if (mWindowHandleThrd != 0)
|
||||
{
|
||||
// lazily call initD3D inside this loop to catch when mWindowHandle has been set, and mGLReady has been set to true
|
||||
// *TODO: Shutdown if this fails when mWindowHandle exists
|
||||
|
|
@ -5022,16 +4988,16 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
|
||||
MSG msg;
|
||||
BOOL status;
|
||||
if (mhDC == 0)
|
||||
if (mhDCThrd == 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - PeekMessage");
|
||||
logger.onChange("PeekMessage(", std::hex, mWindowHandle, ")");
|
||||
status = PeekMessage(&msg, mWindowHandle, 0, 0, PM_REMOVE);
|
||||
logger.onChange("PeekMessage(", std::hex, mWindowHandleThrd, ")");
|
||||
status = PeekMessage(&msg, mWindowHandleThrd, 0, 0, PM_REMOVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - GetMessage");
|
||||
logger.always("GetMessage(", std::hex, mWindowHandle, ")");
|
||||
logger.always("GetMessage(", std::hex, mWindowHandleThrd, ")");
|
||||
status = GetMessage(&msg, NULL, 0, 0);
|
||||
}
|
||||
if (status > 0)
|
||||
|
|
@ -5040,21 +5006,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
", ", msg.wParam, ")");
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
// mMessageQueue.pushFront(msg);
|
||||
try
|
||||
{
|
||||
// <FS:Beq> Nobody is reading this queue once we are quitting. Writing to it causes a hang.
|
||||
if(!LLApp::isQuitting())
|
||||
mMessageQueue.pushFront(msg);
|
||||
}
|
||||
catch (const LLThreadSafeQueueInterrupt&)
|
||||
{
|
||||
// Shutdown timing is tricky. The main thread can end up trying
|
||||
// to post a cursor position after having closed the WorkQueue.
|
||||
logger.always("Message procesing tried to push() to closed MessageQueue - caught");
|
||||
}
|
||||
// </FS:Beq>
|
||||
mMessageQueue.pushFront(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5080,38 +5032,111 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
}
|
||||
#endif
|
||||
}
|
||||
// <FS:Beq> [FIRE-32453][BUG-232971] Improve shutdown behaviour.
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
logger.always("Windows thread exiting - Exception: ", e.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
logger.always("Windows thread exiting - Exception: Unknown");
|
||||
}
|
||||
logger.always("done - queue closed on windows thread.");
|
||||
// </FS:Beq>
|
||||
|
||||
//clean up DXGI/D3D resources
|
||||
if (mDXGIAdapter)
|
||||
cleanupDX();
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy()
|
||||
{
|
||||
if (mQueue->isClosed())
|
||||
{
|
||||
mDXGIAdapter->Release();
|
||||
mDXGIAdapter = nullptr;
|
||||
LL_WARNS() << "Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mD3DDevice)
|
||||
// Make sure we don't leave a blank toolbar button.
|
||||
// Also hiding window now prevents user from suspending it
|
||||
// via some action (like dragging it around)
|
||||
ShowWindow(mWindowHandleThrd, SW_HIDE);
|
||||
|
||||
// Schedule destruction
|
||||
HWND old_handle = mWindowHandleThrd;
|
||||
post([this]()
|
||||
{
|
||||
if (IsWindow(mWindowHandleThrd))
|
||||
{
|
||||
if (mhDCThrd)
|
||||
{
|
||||
if (!ReleaseDC(mWindowHandleThrd, mhDCThrd))
|
||||
{
|
||||
LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;
|
||||
}
|
||||
mhDCThrd = NULL;
|
||||
}
|
||||
|
||||
// This causes WM_DESTROY to be sent *immediately*
|
||||
if (!destroy_window_handler(mWindowHandleThrd))
|
||||
{
|
||||
LL_WARNS("Window") << "Failed to destroy Window! " << std::hex << GetLastError() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something killed the window while we were busy destroying gl or handle somehow got broken
|
||||
LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
|
||||
}
|
||||
mWindowHandleThrd = NULL;
|
||||
mhDCThrd = NULL;
|
||||
mGLReady = false;
|
||||
});
|
||||
|
||||
LL_DEBUGS("Window") << "Closing window's pool queue" << LL_ENDL;
|
||||
mQueue->close();
|
||||
|
||||
// Post a nonsense user message to wake up the thread in
|
||||
// case it is waiting for a getMessage()
|
||||
if (old_handle)
|
||||
{
|
||||
mD3DDevice->Release();
|
||||
mD3DDevice = nullptr;
|
||||
WPARAM wparam{ 0xB0B0 };
|
||||
LL_DEBUGS("Window") << "PostMessage(" << std::hex << old_handle
|
||||
<< ", " << WM_DUMMY_
|
||||
<< ", " << wparam << ")" << std::dec << LL_ENDL;
|
||||
PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337);
|
||||
}
|
||||
|
||||
if (mD3D)
|
||||
// There are cases where window will refuse to close,
|
||||
// can't wait forever on join, check state instead
|
||||
LLTimer timeout;
|
||||
timeout.setTimerExpirySec(2.0);
|
||||
while (!getQueue().done() && !timeout.hasExpired() && mWindowHandleThrd)
|
||||
{
|
||||
mD3D->Release();
|
||||
mD3D = nullptr;
|
||||
ms_sleep(100);
|
||||
}
|
||||
|
||||
if (getQueue().done() || mWindowHandleThrd == NULL)
|
||||
{
|
||||
// Window is closed, started closing or is cleaning up
|
||||
// now wait for our single thread to die.
|
||||
if (mWindowHandleThrd)
|
||||
{
|
||||
LL_INFOS("Window") << "Window is closing, waiting on pool's thread to join, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Window") << "Waiting on pool's thread, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL;
|
||||
}
|
||||
for (auto& pair : mThreads)
|
||||
{
|
||||
pair.second.join();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something suspended window thread, can't afford to wait forever
|
||||
// so kill thread instead
|
||||
// Ex: This can happen if user starts dragging window arround (if it
|
||||
// was visible) or a modal notification pops up
|
||||
LL_WARNS("Window") << "Window is frozen, couldn't perform clean exit" << LL_ENDL;
|
||||
|
||||
for (auto& pair : mThreads)
|
||||
{
|
||||
// very unsafe
|
||||
TerminateThread(pair.second.native_handle(), 0);
|
||||
pair.second.detach();
|
||||
cleanupDX();
|
||||
}
|
||||
}
|
||||
LL_DEBUGS("Window") << "thread pool shutdown complete" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLWindowWin32::post(const std::function<void()>& func)
|
||||
|
|
|
|||
|
|
@ -286,7 +286,11 @@ void VolumeCatcherImpl::setVolume(F32 volume)
|
|||
|
||||
void VolumeCatcherImpl::pump()
|
||||
{
|
||||
return;
|
||||
// <FS:Beq> PR#17 makidoll: Fix Linux volume catcher
|
||||
if (mGotSyms && mMainloop) {
|
||||
llpa_mainloop_iterate(mMainloop, 0, NULL);
|
||||
}
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
void VolumeCatcherImpl::connected_okay()
|
||||
|
|
|
|||
|
|
@ -21,5 +21,6 @@ LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v);
|
|||
LL_PA_SYM(true, pa_mainloop_free, void, pa_mainloop* m);
|
||||
LL_PA_SYM(true, pa_mainloop_get_api, pa_mainloop_api*, pa_mainloop* m);
|
||||
LL_PA_SYM(true, pa_mainloop_new, pa_mainloop*, void);
|
||||
LL_PA_SYM(true, pa_mainloop_iterate, int, pa_mainloop*, int, int*);
|
||||
|
||||
// optional symbols to grab
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ set(viewer_SOURCE_FILES
|
|||
fsnearbychatvoicemonitor.cpp
|
||||
fspanelblocklist.cpp
|
||||
fspanelcontactsets.cpp
|
||||
fspanelface.cpp
|
||||
fspanelimcontrolpanel.cpp
|
||||
fspanellogin.cpp
|
||||
fspanelprefs.cpp
|
||||
|
|
@ -944,6 +945,7 @@ set(viewer_HEADER_FILES
|
|||
fsnearbychatvoicemonitor.h
|
||||
fspanelblocklist.h
|
||||
fspanelcontactsets.h
|
||||
fspanelface.h
|
||||
fspanelimcontrolpanel.h
|
||||
fspanellogin.h
|
||||
fspanelprefs.h
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
<string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSAppSleepDisabled</key>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
7.1.4
|
||||
7.1.6
|
||||
|
|
|
|||
|
|
@ -5152,171 +5152,6 @@
|
|||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemTrace</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemUI</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemFonts</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemInventory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemObjects</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemOctreeGroupData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemOctreeData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemObjectCache</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemDrawable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemFaceData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemDrawInfo</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemTextureData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemImageData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemGLImageData</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMemVertexBuffer</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Mode of stat in Statistics floater</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>DebugStatModeMaterials</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -5354,17 +5189,6 @@
|
|||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DefaultBlankNormalTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string>
|
||||
</map>
|
||||
<key>DefaultFemaleAvatar</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -5398,39 +5222,6 @@
|
|||
<key>Value</key>
|
||||
<string>Male Shape & Outfit</string>
|
||||
</map>
|
||||
<key>DefaultObjectNormalTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>85f28839-7a1c-b4e3-d71d-967792970a7b</string>
|
||||
</map>
|
||||
<key>DefaultObjectSpecularTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string>
|
||||
</map>
|
||||
<key>DefaultObjectTexture</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Texture used as 'Default' in texture picker. (UUID texture reference)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>89556747-24cb-43ed-920b-47caed15465f</string>
|
||||
</map>
|
||||
<key>DefaultUploadCost</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7776,6 +7567,17 @@
|
|||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>LSLFontSizeName</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>UNUSED - Text font size in LSL editor</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Monospace</string>
|
||||
</map>
|
||||
<key>GridStatusRSS</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -10386,21 +10188,10 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatAdvanced</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand advanced performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatBasic</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand basic performance stats display</string>
|
||||
<string>Expand Basic performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10408,10 +10199,10 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatNet</key>
|
||||
<key>OpenDebugStatAdvanced</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand network stats display</string>
|
||||
<string>Expand Advanced performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10422,18 +10213,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>OpenDebugStatRender</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand render stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSim</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand simulator performance stats display</string>
|
||||
<string>Expand Render performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10452,10 +10232,32 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSimPathfinding</key>
|
||||
<key>OpenDebugStatNet</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Pathfinding performance stats display</string>
|
||||
<string>Expand Network performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatSim</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Simulator performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatPhysicsDetails</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Physics Details performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10463,10 +10265,10 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatPhysicsDetails</key>
|
||||
<key>OpenDebugStatPathfinding</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Physics Details performance stats display</string>
|
||||
<string>Expand Pathfinding performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -10496,17 +10298,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OpenDebugStatMemory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Expand Memory performance stats display</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OutBandwidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -13787,7 +13578,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>2.0</real>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>RendeSkyAutoAdjustBlueHorizonScale</key>
|
||||
<map>
|
||||
|
|
@ -13831,7 +13622,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.001</real>
|
||||
<real>0.01</real>
|
||||
</map>
|
||||
<key>RenderSkySunlightScale</key>
|
||||
<map>
|
||||
|
|
@ -16846,17 +16637,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<string>F3E07BC8-A973-476D-8C7F-F3B7293975D1</string>
|
||||
</map>
|
||||
<key>UIImgWhiteUUID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string />
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
|
||||
</map>
|
||||
<key>UIImgTransparentUUID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -18172,6 +17952,21 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSShowSelectedInBlinnPhong</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show BlinnPhong while selected (non-persistent).This setting is driven by the code, not by user</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>ShowSpecificLODInEdit</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -21791,17 +21586,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSDisplaySavedOutfitsCap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display only so many saved outfits in edit appearance. 0 to disable.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSAdvancedWorldmapRegionInfo</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -25000,17 +24784,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>VoiceMultiInstance</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enables using voice in multiple simultaneous viewer instances</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSSoundCacheLocation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -26792,5 +26565,57 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>128578</integer>
|
||||
</map>
|
||||
</map>
|
||||
<key>FSUseNewTexturePanel</key>
|
||||
<map>
|
||||
<key>Backup</key>
|
||||
<boolean>1</boolean>
|
||||
<key>Comment</key>
|
||||
<string>Use the new Texture/Material editor panel in build mode</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<boolean>1</boolean>
|
||||
</map>
|
||||
<key>FSInternalCanEditObjectFaces</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Internal control to show/hide object texture/material edit controls</string>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSInternalFaceHasBPNormalMap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Internal control to store a flag about the edited face having a Blinn-Phong normal map or not</string>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSInternalFaceHasBPSpecularMap</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Internal control to store a flag about the edited face having a Blinn-Phong specular map or not</string>
|
||||
<key>HideFromEditor</key>
|
||||
<integer>1</integer>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
|
|
@ -2023,7 +2023,7 @@
|
|||
value_min="-1"
|
||||
value_max="1">
|
||||
<param_skeleton>
|
||||
|
||||
|
||||
<bone
|
||||
name="mEyeLeft"
|
||||
scale="0 0 0"
|
||||
|
|
@ -2033,9 +2033,8 @@
|
|||
name="mEyeRight"
|
||||
scale="0 0 0"
|
||||
offset="-.005 0 0" />
|
||||
|
||||
|
||||
<bone
|
||||
|
||||
<bone
|
||||
name="mFaceEyeAltLeft"
|
||||
scale="0 0 0"
|
||||
offset="-.005 0 0" />
|
||||
|
|
@ -2044,7 +2043,7 @@
|
|||
name="mFaceEyeAltRight"
|
||||
scale="0 0 0"
|
||||
offset="-.005 0 0" />
|
||||
|
||||
|
||||
<bone
|
||||
name="mFaceEyeLidLowerRight"
|
||||
scale="0 0.3 0.7"
|
||||
|
|
@ -2055,7 +2054,7 @@
|
|||
scale="0 0.3 0.7"
|
||||
offset="0 0 0" />
|
||||
|
||||
<bone
|
||||
<bone
|
||||
name="mFaceEyeLidUpperRight"
|
||||
scale="0 0.3 0.7"
|
||||
offset=" 0 0 0" />
|
||||
|
|
@ -2064,17 +2063,17 @@
|
|||
name="mFaceEyeLidUpperLeft"
|
||||
scale="0 0.3 0.7"
|
||||
offset=" 0 0 0" />
|
||||
|
||||
|
||||
<bone
|
||||
name="mFaceEyecornerInnerLeft"
|
||||
scale="0 0 0"
|
||||
offset="-0.005 -0.008 0.0" />
|
||||
|
||||
|
||||
<bone
|
||||
name="mFaceEyecornerInnerRight"
|
||||
scale="0 0 0"
|
||||
offset="-0.005 0.008 0.0" />
|
||||
|
||||
|
||||
</param_skeleton>
|
||||
</param>
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue